linux/drivers/clk/zynqmp/clkc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Zynq UltraScale+ MPSoC clock controller
   4 *
   5 *  Copyright (C) 2016-2018 Xilinx
   6 *
   7 * Based on drivers/clk/zynq/clkc.c
   8 */
   9
  10#include <linux/clk.h>
  11#include <linux/clk-provider.h>
  12#include <linux/clk/zynqmp.h>
  13#include <linux/io.h>
  14#include <linux/of.h>
  15#include <linux/of_address.h>
  16#include <linux/slab.h>
  17#include <linux/string.h>
  18
  19#define MAX_PARENT                      100
  20#define MAX_NODES                       6
  21#define MAX_NAME_LEN                    50
  22#define MAX_CLOCK                       300
  23
  24#define CLK_INIT_ENABLE_SHIFT           1
  25#define CLK_TYPE_SHIFT                  2
  26
  27#define PM_API_PAYLOAD_LEN              3
  28
  29#define NA_PARENT                       -1
  30#define DUMMY_PARENT                    -2
  31
  32#define CLK_TYPE_FIELD_LEN              4
  33#define CLK_TOPOLOGY_NODE_OFFSET        16
  34#define NODES_PER_RESP                  3
  35
  36#define CLK_TYPE_FIELD_MASK             0xF
  37#define CLK_FLAG_FIELD_SHIFT            8
  38#define CLK_FLAG_FIELD_MASK             0x3FFF
  39#define CLK_TYPE_FLAG_FIELD_SHIFT       24
  40#define CLK_TYPE_FLAG_FIELD_MASK        0xFF
  41
  42#define CLK_PARENTS_ID_LEN              16
  43#define CLK_PARENTS_ID_MASK             0xFFFF
  44
  45/* Flags for parents */
  46#define PARENT_CLK_SELF                 0
  47#define PARENT_CLK_NODE1                1
  48#define PARENT_CLK_NODE2                2
  49#define PARENT_CLK_NODE3                3
  50#define PARENT_CLK_NODE4                4
  51#define PARENT_CLK_EXTERNAL             5
  52
  53#define END_OF_CLK_NAME                 "END_OF_CLK"
  54#define RESERVED_CLK_NAME               ""
  55
  56#define CLK_VALID_MASK                  0x1
  57#define CLK_INIT_ENABLE_MASK            (0x1 << CLK_INIT_ENABLE_SHIFT)
  58
  59enum clk_type {
  60        CLK_TYPE_OUTPUT,
  61        CLK_TYPE_EXTERNAL,
  62};
  63
  64/**
  65 * struct clock_parent - Structure for parent of clock
  66 * @name:       Parent name
  67 * @id:         Parent clock ID
  68 * @flag:       Parent flags
  69 */
  70struct clock_parent {
  71        char name[MAX_NAME_LEN];
  72        int id;
  73        u32 flag;
  74};
  75
  76/**
  77 * struct clock_topology - Structure for topology of clock
  78 * @type:       Type of topology
  79 * @flag:       Topology flags
  80 * @type_flag:  Topology type specific flag
  81 */
  82struct clock_topology {
  83        u32 type;
  84        u32 flag;
  85        u32 type_flag;
  86};
  87
  88/**
  89 * struct zynqmp_clock - Structure for clock
  90 * @clk_name:           Clock name
  91 * @valid:              Validity flag of clock
  92 * @init_enable:        init_enable flag of clock
  93 * @type:               Clock type (Output/External)
  94 * @node:               Clock tolology nodes
  95 * @num_nodes:          Number of nodes present in topology
  96 * @parent:             structure of parent of clock
  97 * @num_parents:        Number of parents of clock
  98 */
  99struct zynqmp_clock {
 100        char clk_name[MAX_NAME_LEN];
 101        u32 valid;
 102        u32 init_enable;
 103        enum clk_type type;
 104        struct clock_topology node[MAX_NODES];
 105        u32 num_nodes;
 106        struct clock_parent parent[MAX_PARENT];
 107        u32 num_parents;
 108};
 109
 110static const char clk_type_postfix[][10] = {
 111        [TYPE_INVALID] = "",
 112        [TYPE_MUX] = "_mux",
 113        [TYPE_GATE] = "",
 114        [TYPE_DIV1] = "_div1",
 115        [TYPE_DIV2] = "_div2",
 116        [TYPE_FIXEDFACTOR] = "_ff",
 117        [TYPE_PLL] = ""
 118};
 119
 120static struct zynqmp_clock clock[MAX_CLOCK];
 121static struct clk_onecell_data zynqmp_clk_data;
 122static struct clk *zynqmp_clks[MAX_CLOCK];
 123static unsigned int clock_max_idx;
 124static const struct zynqmp_eemi_ops *eemi_ops;
 125
 126/**
 127 * is_valid_clock() - Check whether clock is valid or not
 128 * @clk_id:     Clock index.
 129 * @valid:      1: if clock is valid.
 130 *              0: invalid clock.
 131 *
 132 * Return: 0 on success else error code.
 133 */
 134static int is_valid_clock(u32 clk_id, u32 *valid)
 135{
 136        if (clk_id < 0 || clk_id > clock_max_idx)
 137                return -ENODEV;
 138
 139        *valid = clock[clk_id].valid;
 140
 141        return *valid ? 0 : -EINVAL;
 142}
 143
 144/**
 145 * zynqmp_get_clock_name() - Get name of clock from Clock index
 146 * @clk_id:     Clock index.
 147 * @clk_name:   Name of clock.
 148 *
 149 * Return: 0 on success else error code.
 150 */
 151static int zynqmp_get_clock_name(u32 clk_id, char *clk_name)
 152{
 153        int ret;
 154        u32 valid;
 155
 156        ret = is_valid_clock(clk_id, &valid);
 157        if (!ret && valid) {
 158                strncpy(clk_name, clock[clk_id].clk_name, MAX_NAME_LEN);
 159                return 0;
 160        } else {
 161                return ret;
 162        }
 163}
 164
 165/**
 166 * get_clock_type() - Get type of clock
 167 * @clk_id:     Clock index.
 168 * @type:       Clock type: CLK_TYPE_OUTPUT or CLK_TYPE_EXTERNAL.
 169 *
 170 * Return: 0 on success else error code.
 171 */
 172static int get_clock_type(u32 clk_id, u32 *type)
 173{
 174        int ret;
 175        u32 valid;
 176
 177        ret = is_valid_clock(clk_id, &valid);
 178        if (!ret && valid) {
 179                *type = clock[clk_id].type;
 180                return 0;
 181        } else {
 182                return ret;
 183        }
 184}
 185
 186/**
 187 * zynqmp_pm_clock_get_name() - Get the name of clock for given id
 188 * @clock_id:   ID of the clock to be queried.
 189 * @name:       Name of given clock.
 190 *
 191 * This function is used to get name of clock specified by given
 192 * clock ID.
 193 *
 194 * Return: Returns 0, in case of error name would be 0.
 195 */
 196static int zynqmp_pm_clock_get_name(u32 clock_id, char *name)
 197{
 198        struct zynqmp_pm_query_data qdata = {0};
 199        u32 ret_payload[PAYLOAD_ARG_CNT];
 200
 201        qdata.qid = PM_QID_CLOCK_GET_NAME;
 202        qdata.arg1 = clock_id;
 203
 204        eemi_ops->query_data(qdata, ret_payload);
 205        memcpy(name, ret_payload, CLK_GET_NAME_RESP_LEN);
 206
 207        return 0;
 208}
 209
 210/**
 211 * zynqmp_pm_clock_get_topology() - Get the topology of clock for given id
 212 * @clock_id:   ID of the clock to be queried.
 213 * @index:      Node index of clock topology.
 214 * @topology:   Buffer to store nodes in topology and flags.
 215 *
 216 * This function is used to get topology information for the clock
 217 * specified by given clock ID.
 218 *
 219 * This API will return 3 node of topology with a single response. To get
 220 * other nodes, master should call same API in loop with new
 221 * index till error is returned. E.g First call should have
 222 * index 0 which will return nodes 0,1 and 2. Next call, index
 223 * should be 3 which will return nodes 3,4 and 5 and so on.
 224 *
 225 * Return: Returns status, either success or error+reason.
 226 */
 227static int zynqmp_pm_clock_get_topology(u32 clock_id, u32 index, u32 *topology)
 228{
 229        struct zynqmp_pm_query_data qdata = {0};
 230        u32 ret_payload[PAYLOAD_ARG_CNT];
 231        int ret;
 232
 233        qdata.qid = PM_QID_CLOCK_GET_TOPOLOGY;
 234        qdata.arg1 = clock_id;
 235        qdata.arg2 = index;
 236
 237        ret = eemi_ops->query_data(qdata, ret_payload);
 238        memcpy(topology, &ret_payload[1], CLK_GET_TOPOLOGY_RESP_WORDS * 4);
 239
 240        return ret;
 241}
 242
 243/**
 244 * zynqmp_pm_clock_get_fixedfactor_params() - Get clock's fixed factor params
 245 * @clock_id:   Clock ID.
 246 * @mul:        Multiplication value.
 247 * @div:        Divisor value.
 248 *
 249 * This function is used to get fixed factor parameers for the fixed
 250 * clock. This API is application only for the fixed clock.
 251 *
 252 * Return: Returns status, either success or error+reason.
 253 */
 254static int zynqmp_pm_clock_get_fixedfactor_params(u32 clock_id,
 255                                                  u32 *mul,
 256                                                  u32 *div)
 257{
 258        struct zynqmp_pm_query_data qdata = {0};
 259        u32 ret_payload[PAYLOAD_ARG_CNT];
 260        int ret;
 261
 262        qdata.qid = PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS;
 263        qdata.arg1 = clock_id;
 264
 265        ret = eemi_ops->query_data(qdata, ret_payload);
 266        *mul = ret_payload[1];
 267        *div = ret_payload[2];
 268
 269        return ret;
 270}
 271
 272/**
 273 * zynqmp_pm_clock_get_parents() - Get the first 3 parents of clock for given id
 274 * @clock_id:   Clock ID.
 275 * @index:      Parent index.
 276 * @parents:    3 parents of the given clock.
 277 *
 278 * This function is used to get 3 parents for the clock specified by
 279 * given clock ID.
 280 *
 281 * This API will return 3 parents with a single response. To get
 282 * other parents, master should call same API in loop with new
 283 * parent index till error is returned. E.g First call should have
 284 * index 0 which will return parents 0,1 and 2. Next call, index
 285 * should be 3 which will return parent 3,4 and 5 and so on.
 286 *
 287 * Return: Returns status, either success or error+reason.
 288 */
 289static int zynqmp_pm_clock_get_parents(u32 clock_id, u32 index, u32 *parents)
 290{
 291        struct zynqmp_pm_query_data qdata = {0};
 292        u32 ret_payload[PAYLOAD_ARG_CNT];
 293        int ret;
 294
 295        qdata.qid = PM_QID_CLOCK_GET_PARENTS;
 296        qdata.arg1 = clock_id;
 297        qdata.arg2 = index;
 298
 299        ret = eemi_ops->query_data(qdata, ret_payload);
 300        memcpy(parents, &ret_payload[1], CLK_GET_PARENTS_RESP_WORDS * 4);
 301
 302        return ret;
 303}
 304
 305/**
 306 * zynqmp_pm_clock_get_attributes() - Get the attributes of clock for given id
 307 * @clock_id:   Clock ID.
 308 * @attr:       Clock attributes.
 309 *
 310 * This function is used to get clock's attributes(e.g. valid, clock type, etc).
 311 *
 312 * Return: Returns status, either success or error+reason.
 313 */
 314static int zynqmp_pm_clock_get_attributes(u32 clock_id, u32 *attr)
 315{
 316        struct zynqmp_pm_query_data qdata = {0};
 317        u32 ret_payload[PAYLOAD_ARG_CNT];
 318        int ret;
 319
 320        qdata.qid = PM_QID_CLOCK_GET_ATTRIBUTES;
 321        qdata.arg1 = clock_id;
 322
 323        ret = eemi_ops->query_data(qdata, ret_payload);
 324        memcpy(attr, &ret_payload[1], CLK_GET_ATTR_RESP_WORDS * 4);
 325
 326        return ret;
 327}
 328
 329/**
 330 * clock_get_topology() - Get topology of clock from firmware using PM_API
 331 * @clk_id:     Clock index.
 332 * @clk_topology: Structure of clock topology.
 333 * @num_nodes: number of nodes.
 334 *
 335 * Return: Returns status, either success or error+reason.
 336 */
 337static int clock_get_topology(u32 clk_id, struct clock_topology *clk_topology,
 338                              u32 *num_nodes)
 339{
 340        int j, k = 0, ret;
 341        u32 pm_resp[PM_API_PAYLOAD_LEN] = {0};
 342
 343        *num_nodes = 0;
 344        for (j = 0; j <= MAX_NODES; j += 3) {
 345                ret = zynqmp_pm_clock_get_topology(clk_id, j, pm_resp);
 346                if (ret)
 347                        return ret;
 348                for (k = 0; k < PM_API_PAYLOAD_LEN; k++) {
 349                        if (!(pm_resp[k] & CLK_TYPE_FIELD_MASK))
 350                                goto done;
 351                        clk_topology[*num_nodes].type = pm_resp[k] &
 352                                                        CLK_TYPE_FIELD_MASK;
 353                        clk_topology[*num_nodes].flag =
 354                                        (pm_resp[k] >> CLK_FLAG_FIELD_SHIFT) &
 355                                        CLK_FLAG_FIELD_MASK;
 356                        clk_topology[*num_nodes].type_flag =
 357                                (pm_resp[k] >> CLK_TYPE_FLAG_FIELD_SHIFT) &
 358                                CLK_TYPE_FLAG_FIELD_MASK;
 359                        (*num_nodes)++;
 360                }
 361        }
 362done:
 363        return 0;
 364}
 365
 366/**
 367 * clock_get_parents() - Get parents info from firmware using PM_API
 368 * @clk_id:             Clock index.
 369 * @parents:            Structure of parent information.
 370 * @num_parents:        Total number of parents.
 371 *
 372 * Return: Returns status, either success or error+reason.
 373 */
 374static int clock_get_parents(u32 clk_id, struct clock_parent *parents,
 375                             u32 *num_parents)
 376{
 377        int j = 0, k, ret, total_parents = 0;
 378        u32 pm_resp[PM_API_PAYLOAD_LEN] = {0};
 379
 380        do {
 381                /* Get parents from firmware */
 382                ret = zynqmp_pm_clock_get_parents(clk_id, j, pm_resp);
 383                if (ret)
 384                        return ret;
 385
 386                for (k = 0; k < PM_API_PAYLOAD_LEN; k++) {
 387                        if (pm_resp[k] == (u32)NA_PARENT) {
 388                                *num_parents = total_parents;
 389                                return 0;
 390                        }
 391
 392                        parents[k + j].id = pm_resp[k] & CLK_PARENTS_ID_MASK;
 393                        if (pm_resp[k] == (u32)DUMMY_PARENT) {
 394                                strncpy(parents[k + j].name,
 395                                        "dummy_name", MAX_NAME_LEN);
 396                                parents[k + j].flag = 0;
 397                        } else {
 398                                parents[k + j].flag = pm_resp[k] >>
 399                                                        CLK_PARENTS_ID_LEN;
 400                                if (zynqmp_get_clock_name(parents[k + j].id,
 401                                                          parents[k + j].name))
 402                                        continue;
 403                        }
 404                        total_parents++;
 405                }
 406                j += PM_API_PAYLOAD_LEN;
 407        } while (total_parents <= MAX_PARENT);
 408        return 0;
 409}
 410
 411/**
 412 * get_parent_list() - Create list of parents name
 413 * @np:                 Device node.
 414 * @clk_id:             Clock index.
 415 * @parent_list:        List of parent's name.
 416 * @num_parents:        Total number of parents.
 417 *
 418 * Return: Returns status, either success or error+reason.
 419 */
 420static int get_parent_list(struct device_node *np, u32 clk_id,
 421                           const char **parent_list, u32 *num_parents)
 422{
 423        int i = 0, ret;
 424        u32 total_parents = clock[clk_id].num_parents;
 425        struct clock_topology *clk_nodes;
 426        struct clock_parent *parents;
 427
 428        clk_nodes = clock[clk_id].node;
 429        parents = clock[clk_id].parent;
 430
 431        for (i = 0; i < total_parents; i++) {
 432                if (!parents[i].flag) {
 433                        parent_list[i] = parents[i].name;
 434                } else if (parents[i].flag == PARENT_CLK_EXTERNAL) {
 435                        ret = of_property_match_string(np, "clock-names",
 436                                                       parents[i].name);
 437                        if (ret < 0)
 438                                strncpy(parents[i].name,
 439                                        "dummy_name", MAX_NAME_LEN);
 440                        parent_list[i] = parents[i].name;
 441                } else {
 442                        strcat(parents[i].name,
 443                               clk_type_postfix[clk_nodes[parents[i].flag - 1].
 444                               type]);
 445                        parent_list[i] = parents[i].name;
 446                }
 447        }
 448
 449        *num_parents = total_parents;
 450        return 0;
 451}
 452
 453/**
 454 * zynqmp_register_clk_topology() - Register clock topology
 455 * @clk_id:             Clock index.
 456 * @clk_name:           Clock Name.
 457 * @num_parents:        Total number of parents.
 458 * @parent_names:       List of parents name.
 459 *
 460 * Return: Returns status, either success or error+reason.
 461 */
 462static struct clk *zynqmp_register_clk_topology(int clk_id, char *clk_name,
 463                                                int num_parents,
 464                                                const char **parent_names)
 465{
 466        int j, ret;
 467        u32 num_nodes, mult, div;
 468        char *clk_out = NULL;
 469        struct clock_topology *nodes;
 470        struct clk *clk = NULL;
 471
 472        nodes = clock[clk_id].node;
 473        num_nodes = clock[clk_id].num_nodes;
 474
 475        for (j = 0; j < num_nodes; j++) {
 476                if (j != (num_nodes - 1)) {
 477                        clk_out = kasprintf(GFP_KERNEL, "%s%s", clk_name,
 478                                            clk_type_postfix[nodes[j].type]);
 479                } else {
 480                        clk_out = kasprintf(GFP_KERNEL, "%s", clk_name);
 481                }
 482
 483                switch (nodes[j].type) {
 484                case TYPE_MUX:
 485                        clk = zynqmp_clk_register_mux(NULL, clk_out,
 486                                                      clk_id, parent_names,
 487                                                      num_parents,
 488                                                      nodes[j].flag,
 489                                                      nodes[j].type_flag);
 490                        break;
 491                case TYPE_PLL:
 492                        clk = clk_register_zynqmp_pll(clk_out, clk_id,
 493                                                      parent_names, 1,
 494                                                      nodes[j].flag);
 495                        break;
 496                case TYPE_FIXEDFACTOR:
 497                        ret = zynqmp_pm_clock_get_fixedfactor_params(clk_id,
 498                                                                     &mult,
 499                                                                     &div);
 500                        clk = clk_register_fixed_factor(NULL, clk_out,
 501                                                        parent_names[0],
 502                                                        nodes[j].flag, mult,
 503                                                        div);
 504                        break;
 505                case TYPE_DIV1:
 506                case TYPE_DIV2:
 507                        clk = zynqmp_clk_register_divider(NULL, clk_out, clk_id,
 508                                                          nodes[j].type,
 509                                                          parent_names, 1,
 510                                                          nodes[j].flag,
 511                                                          nodes[j].type_flag);
 512                        break;
 513                case TYPE_GATE:
 514                        clk = zynqmp_clk_register_gate(NULL, clk_out, clk_id,
 515                                                       parent_names, 1,
 516                                                       nodes[j].flag,
 517                                                       nodes[j].type_flag);
 518                        break;
 519                default:
 520                        pr_err("%s() Unknown topology for %s\n",
 521                               __func__, clk_out);
 522                        break;
 523                }
 524                if (IS_ERR(clk))
 525                        pr_warn_once("%s() %s register fail with %ld\n",
 526                                     __func__, clk_name, PTR_ERR(clk));
 527
 528                parent_names[0] = clk_out;
 529        }
 530        kfree(clk_out);
 531        return clk;
 532}
 533
 534/**
 535 * zynqmp_register_clocks() - Register clocks
 536 * @np:         Device node.
 537 *
 538 * Return: 0 on success else error code
 539 */
 540static int zynqmp_register_clocks(struct device_node *np)
 541{
 542        int ret;
 543        u32 i, total_parents = 0, type = 0;
 544        const char *parent_names[MAX_PARENT];
 545
 546        for (i = 0; i < clock_max_idx; i++) {
 547                char clk_name[MAX_NAME_LEN];
 548
 549                /* get clock name, continue to next clock if name not found */
 550                if (zynqmp_get_clock_name(i, clk_name))
 551                        continue;
 552
 553                /* Check if clock is valid and output clock.
 554                 * Do not regiter invalid or external clock.
 555                 */
 556                ret = get_clock_type(i, &type);
 557                if (ret || type != CLK_TYPE_OUTPUT)
 558                        continue;
 559
 560                /* Get parents of clock*/
 561                if (get_parent_list(np, i, parent_names, &total_parents)) {
 562                        WARN_ONCE(1, "No parents found for %s\n",
 563                                  clock[i].clk_name);
 564                        continue;
 565                }
 566
 567                zynqmp_clks[i] = zynqmp_register_clk_topology(i, clk_name,
 568                                                              total_parents,
 569                                                              parent_names);
 570
 571                /* Enable clock if init_enable flag is 1 */
 572                if (clock[i].init_enable)
 573                        clk_prepare_enable(zynqmp_clks[i]);
 574        }
 575
 576        for (i = 0; i < clock_max_idx; i++) {
 577                if (IS_ERR(zynqmp_clks[i])) {
 578                        pr_err("Zynq Ultrascale+ MPSoC clk %s: register failed with %ld\n",
 579                               clock[i].clk_name, PTR_ERR(zynqmp_clks[i]));
 580                        WARN_ON(1);
 581                }
 582        }
 583        return 0;
 584}
 585
 586/**
 587 * zynqmp_get_clock_info() - Get clock information from firmware using PM_API
 588 */
 589static void zynqmp_get_clock_info(void)
 590{
 591        int i, ret;
 592        u32 attr, type = 0;
 593
 594        memset(clock, 0, sizeof(clock));
 595        for (i = 0; i < MAX_CLOCK; i++) {
 596                zynqmp_pm_clock_get_name(i, clock[i].clk_name);
 597                if (!strncmp(clock[i].clk_name, END_OF_CLK_NAME,
 598                             MAX_NAME_LEN)) {
 599                        clock_max_idx = i;
 600                        break;
 601                } else if (!strncmp(clock[i].clk_name, RESERVED_CLK_NAME,
 602                                    MAX_NAME_LEN)) {
 603                        continue;
 604                }
 605
 606                ret = zynqmp_pm_clock_get_attributes(i, &attr);
 607                if (ret)
 608                        continue;
 609
 610                clock[i].valid = attr & CLK_VALID_MASK;
 611                clock[i].init_enable = !!(attr & CLK_INIT_ENABLE_MASK);
 612                clock[i].type = attr >> CLK_TYPE_SHIFT ? CLK_TYPE_EXTERNAL :
 613                                                        CLK_TYPE_OUTPUT;
 614        }
 615
 616        /* Get topology of all clock */
 617        for (i = 0; i < clock_max_idx; i++) {
 618                ret = get_clock_type(i, &type);
 619                if (ret || type != CLK_TYPE_OUTPUT)
 620                        continue;
 621
 622                ret = clock_get_topology(i, clock[i].node, &clock[i].num_nodes);
 623                if (ret)
 624                        continue;
 625
 626                ret = clock_get_parents(i, clock[i].parent,
 627                                        &clock[i].num_parents);
 628                if (ret)
 629                        continue;
 630        }
 631}
 632
 633/**
 634 * zynqmp_clk_setup() - Setup the clock framework and register clocks
 635 * @np:         Device node
 636 */
 637static void __init zynqmp_clk_setup(struct device_node *np)
 638{
 639        int idx;
 640
 641        idx = of_property_match_string(np, "clock-names", "pss_ref_clk");
 642        if (idx < 0) {
 643                pr_err("pss_ref_clk not provided\n");
 644                return;
 645        }
 646        idx = of_property_match_string(np, "clock-names", "video_clk");
 647        if (idx < 0) {
 648                pr_err("video_clk not provided\n");
 649                return;
 650        }
 651        idx = of_property_match_string(np, "clock-names", "pss_alt_ref_clk");
 652        if (idx < 0) {
 653                pr_err("pss_alt_ref_clk not provided\n");
 654                return;
 655        }
 656        idx = of_property_match_string(np, "clock-names", "aux_ref_clk");
 657        if (idx < 0) {
 658                pr_err("aux_ref_clk not provided\n");
 659                return;
 660        }
 661        idx = of_property_match_string(np, "clock-names", "gt_crx_ref_clk");
 662        if (idx < 0) {
 663                pr_err("aux_ref_clk not provided\n");
 664                return;
 665        }
 666
 667        zynqmp_get_clock_info();
 668        zynqmp_register_clocks(np);
 669
 670        zynqmp_clk_data.clks = zynqmp_clks;
 671        zynqmp_clk_data.clk_num = clock_max_idx;
 672        of_clk_add_provider(np, of_clk_src_onecell_get, &zynqmp_clk_data);
 673}
 674
 675/**
 676 * zynqmp_clock_init() - Initialize zynqmp clocks
 677 *
 678 * Return: 0 always
 679 */
 680static int __init zynqmp_clock_init(void)
 681{
 682        struct device_node *np;
 683
 684        np = of_find_compatible_node(NULL, NULL, "xlnx,zynqmp");
 685        if (!np)
 686                return 0;
 687        of_node_put(np);
 688
 689        np = of_find_compatible_node(NULL, NULL, "xlnx,zynqmp-clkc");
 690        if (np)
 691                panic("%s: %s binding is deprecated, please use new DT binding\n",
 692                       __func__, np->name);
 693
 694        np = of_find_compatible_node(NULL, NULL, "xlnx,zynqmp-clk");
 695        if (!np) {
 696                pr_err("%s: clk node not found\n", __func__);
 697                of_node_put(np);
 698                return 0;
 699        }
 700
 701        eemi_ops = zynqmp_pm_get_eemi_ops();
 702        if (!eemi_ops || !eemi_ops->query_data) {
 703                pr_err("%s: clk data not found\n", __func__);
 704                of_node_put(np);
 705                return 0;
 706        }
 707
 708        zynqmp_clk_setup(np);
 709
 710        return 0;
 711}
 712arch_initcall(zynqmp_clock_init);
 713