linux/drivers/clk/qcom/clk-smd-rpm.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2016, Linaro Limited
   3 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
   4 *
   5 * This software is licensed under the terms of the GNU General Public
   6 * License version 2, as published by the Free Software Foundation, and
   7 * may be copied, distributed, and modified under those terms.
   8 *
   9 * This program is distributed in the hope that it will be useful,
  10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 * GNU General Public License for more details.
  13 */
  14
  15#include <linux/clk-provider.h>
  16#include <linux/err.h>
  17#include <linux/export.h>
  18#include <linux/init.h>
  19#include <linux/kernel.h>
  20#include <linux/module.h>
  21#include <linux/mutex.h>
  22#include <linux/of.h>
  23#include <linux/of_device.h>
  24#include <linux/platform_device.h>
  25#include <linux/soc/qcom/smd-rpm.h>
  26
  27#include <dt-bindings/clock/qcom,rpmcc.h>
  28#include <dt-bindings/mfd/qcom-rpm.h>
  29
  30#define QCOM_RPM_KEY_SOFTWARE_ENABLE                    0x6e657773
  31#define QCOM_RPM_KEY_PIN_CTRL_CLK_BUFFER_ENABLE_KEY     0x62636370
  32#define QCOM_RPM_SMD_KEY_RATE                           0x007a484b
  33#define QCOM_RPM_SMD_KEY_ENABLE                         0x62616e45
  34#define QCOM_RPM_SMD_KEY_STATE                          0x54415453
  35#define QCOM_RPM_SCALING_ENABLE_ID                      0x2
  36
  37#define __DEFINE_CLK_SMD_RPM(_platform, _name, _active, type, r_id, stat_id,  \
  38                             key)                                             \
  39        static struct clk_smd_rpm _platform##_##_active;                      \
  40        static struct clk_smd_rpm _platform##_##_name = {                     \
  41                .rpm_res_type = (type),                                       \
  42                .rpm_clk_id = (r_id),                                         \
  43                .rpm_status_id = (stat_id),                                   \
  44                .rpm_key = (key),                                             \
  45                .peer = &_platform##_##_active,                               \
  46                .rate = INT_MAX,                                              \
  47                .hw.init = &(struct clk_init_data){                           \
  48                        .ops = &clk_smd_rpm_ops,                              \
  49                        .name = #_name,                                       \
  50                        .parent_names = (const char *[]){ "xo_board" },       \
  51                        .num_parents = 1,                                     \
  52                },                                                            \
  53        };                                                                    \
  54        static struct clk_smd_rpm _platform##_##_active = {                   \
  55                .rpm_res_type = (type),                                       \
  56                .rpm_clk_id = (r_id),                                         \
  57                .rpm_status_id = (stat_id),                                   \
  58                .active_only = true,                                          \
  59                .rpm_key = (key),                                             \
  60                .peer = &_platform##_##_name,                                 \
  61                .rate = INT_MAX,                                              \
  62                .hw.init = &(struct clk_init_data){                           \
  63                        .ops = &clk_smd_rpm_ops,                              \
  64                        .name = #_active,                                     \
  65                        .parent_names = (const char *[]){ "xo_board" },       \
  66                        .num_parents = 1,                                     \
  67                },                                                            \
  68        }
  69
  70#define __DEFINE_CLK_SMD_RPM_BRANCH(_platform, _name, _active, type, r_id,    \
  71                                    stat_id, r, key)                          \
  72        static struct clk_smd_rpm _platform##_##_active;                      \
  73        static struct clk_smd_rpm _platform##_##_name = {                     \
  74                .rpm_res_type = (type),                                       \
  75                .rpm_clk_id = (r_id),                                         \
  76                .rpm_status_id = (stat_id),                                   \
  77                .rpm_key = (key),                                             \
  78                .branch = true,                                               \
  79                .peer = &_platform##_##_active,                               \
  80                .rate = (r),                                                  \
  81                .hw.init = &(struct clk_init_data){                           \
  82                        .ops = &clk_smd_rpm_branch_ops,                       \
  83                        .name = #_name,                                       \
  84                        .parent_names = (const char *[]){ "xo_board" },       \
  85                        .num_parents = 1,                                     \
  86                },                                                            \
  87        };                                                                    \
  88        static struct clk_smd_rpm _platform##_##_active = {                   \
  89                .rpm_res_type = (type),                                       \
  90                .rpm_clk_id = (r_id),                                         \
  91                .rpm_status_id = (stat_id),                                   \
  92                .active_only = true,                                          \
  93                .rpm_key = (key),                                             \
  94                .branch = true,                                               \
  95                .peer = &_platform##_##_name,                                 \
  96                .rate = (r),                                                  \
  97                .hw.init = &(struct clk_init_data){                           \
  98                        .ops = &clk_smd_rpm_branch_ops,                       \
  99                        .name = #_active,                                     \
 100                        .parent_names = (const char *[]){ "xo_board" },       \
 101                        .num_parents = 1,                                     \
 102                },                                                            \
 103        }
 104
 105#define DEFINE_CLK_SMD_RPM(_platform, _name, _active, type, r_id)             \
 106                __DEFINE_CLK_SMD_RPM(_platform, _name, _active, type, r_id,   \
 107                0, QCOM_RPM_SMD_KEY_RATE)
 108
 109#define DEFINE_CLK_SMD_RPM_BRANCH(_platform, _name, _active, type, r_id, r)   \
 110                __DEFINE_CLK_SMD_RPM_BRANCH(_platform, _name, _active, type,  \
 111                r_id, 0, r, QCOM_RPM_SMD_KEY_ENABLE)
 112
 113#define DEFINE_CLK_SMD_RPM_QDSS(_platform, _name, _active, type, r_id)        \
 114                __DEFINE_CLK_SMD_RPM(_platform, _name, _active, type, r_id,   \
 115                0, QCOM_RPM_SMD_KEY_STATE)
 116
 117#define DEFINE_CLK_SMD_RPM_XO_BUFFER(_platform, _name, _active, r_id)         \
 118                __DEFINE_CLK_SMD_RPM_BRANCH(_platform, _name, _active,        \
 119                QCOM_SMD_RPM_CLK_BUF_A, r_id, 0, 1000,                        \
 120                QCOM_RPM_KEY_SOFTWARE_ENABLE)
 121
 122#define DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(_platform, _name, _active, r_id) \
 123                __DEFINE_CLK_SMD_RPM_BRANCH(_platform, _name, _active,        \
 124                QCOM_SMD_RPM_CLK_BUF_A, r_id, 0, 1000,                        \
 125                QCOM_RPM_KEY_PIN_CTRL_CLK_BUFFER_ENABLE_KEY)
 126
 127#define to_clk_smd_rpm(_hw) container_of(_hw, struct clk_smd_rpm, hw)
 128
 129struct clk_smd_rpm {
 130        const int rpm_res_type;
 131        const int rpm_key;
 132        const int rpm_clk_id;
 133        const int rpm_status_id;
 134        const bool active_only;
 135        bool enabled;
 136        bool branch;
 137        struct clk_smd_rpm *peer;
 138        struct clk_hw hw;
 139        unsigned long rate;
 140        struct qcom_smd_rpm *rpm;
 141};
 142
 143struct clk_smd_rpm_req {
 144        __le32 key;
 145        __le32 nbytes;
 146        __le32 value;
 147};
 148
 149struct rpm_cc {
 150        struct qcom_rpm *rpm;
 151        struct clk_smd_rpm **clks;
 152        size_t num_clks;
 153};
 154
 155struct rpm_smd_clk_desc {
 156        struct clk_smd_rpm **clks;
 157        size_t num_clks;
 158};
 159
 160static DEFINE_MUTEX(rpm_smd_clk_lock);
 161
 162static int clk_smd_rpm_handoff(struct clk_smd_rpm *r)
 163{
 164        int ret;
 165        struct clk_smd_rpm_req req = {
 166                .key = cpu_to_le32(r->rpm_key),
 167                .nbytes = cpu_to_le32(sizeof(u32)),
 168                .value = cpu_to_le32(r->branch ? 1 : INT_MAX),
 169        };
 170
 171        ret = qcom_rpm_smd_write(r->rpm, QCOM_SMD_RPM_ACTIVE_STATE,
 172                                 r->rpm_res_type, r->rpm_clk_id, &req,
 173                                 sizeof(req));
 174        if (ret)
 175                return ret;
 176        ret = qcom_rpm_smd_write(r->rpm, QCOM_SMD_RPM_SLEEP_STATE,
 177                                 r->rpm_res_type, r->rpm_clk_id, &req,
 178                                 sizeof(req));
 179        if (ret)
 180                return ret;
 181
 182        return 0;
 183}
 184
 185static int clk_smd_rpm_set_rate_active(struct clk_smd_rpm *r,
 186                                       unsigned long rate)
 187{
 188        struct clk_smd_rpm_req req = {
 189                .key = cpu_to_le32(r->rpm_key),
 190                .nbytes = cpu_to_le32(sizeof(u32)),
 191                .value = cpu_to_le32(DIV_ROUND_UP(rate, 1000)), /* to kHz */
 192        };
 193
 194        return qcom_rpm_smd_write(r->rpm, QCOM_SMD_RPM_ACTIVE_STATE,
 195                                  r->rpm_res_type, r->rpm_clk_id, &req,
 196                                  sizeof(req));
 197}
 198
 199static int clk_smd_rpm_set_rate_sleep(struct clk_smd_rpm *r,
 200                                      unsigned long rate)
 201{
 202        struct clk_smd_rpm_req req = {
 203                .key = cpu_to_le32(r->rpm_key),
 204                .nbytes = cpu_to_le32(sizeof(u32)),
 205                .value = cpu_to_le32(DIV_ROUND_UP(rate, 1000)), /* to kHz */
 206        };
 207
 208        return qcom_rpm_smd_write(r->rpm, QCOM_SMD_RPM_SLEEP_STATE,
 209                                  r->rpm_res_type, r->rpm_clk_id, &req,
 210                                  sizeof(req));
 211}
 212
 213static void to_active_sleep(struct clk_smd_rpm *r, unsigned long rate,
 214                            unsigned long *active, unsigned long *sleep)
 215{
 216        *active = rate;
 217
 218        /*
 219         * Active-only clocks don't care what the rate is during sleep. So,
 220         * they vote for zero.
 221         */
 222        if (r->active_only)
 223                *sleep = 0;
 224        else
 225                *sleep = *active;
 226}
 227
 228static int clk_smd_rpm_prepare(struct clk_hw *hw)
 229{
 230        struct clk_smd_rpm *r = to_clk_smd_rpm(hw);
 231        struct clk_smd_rpm *peer = r->peer;
 232        unsigned long this_rate = 0, this_sleep_rate = 0;
 233        unsigned long peer_rate = 0, peer_sleep_rate = 0;
 234        unsigned long active_rate, sleep_rate;
 235        int ret = 0;
 236
 237        mutex_lock(&rpm_smd_clk_lock);
 238
 239        /* Don't send requests to the RPM if the rate has not been set. */
 240        if (!r->rate)
 241                goto out;
 242
 243        to_active_sleep(r, r->rate, &this_rate, &this_sleep_rate);
 244
 245        /* Take peer clock's rate into account only if it's enabled. */
 246        if (peer->enabled)
 247                to_active_sleep(peer, peer->rate,
 248                                &peer_rate, &peer_sleep_rate);
 249
 250        active_rate = max(this_rate, peer_rate);
 251
 252        if (r->branch)
 253                active_rate = !!active_rate;
 254
 255        ret = clk_smd_rpm_set_rate_active(r, active_rate);
 256        if (ret)
 257                goto out;
 258
 259        sleep_rate = max(this_sleep_rate, peer_sleep_rate);
 260        if (r->branch)
 261                sleep_rate = !!sleep_rate;
 262
 263        ret = clk_smd_rpm_set_rate_sleep(r, sleep_rate);
 264        if (ret)
 265                /* Undo the active set vote and restore it */
 266                ret = clk_smd_rpm_set_rate_active(r, peer_rate);
 267
 268out:
 269        if (!ret)
 270                r->enabled = true;
 271
 272        mutex_unlock(&rpm_smd_clk_lock);
 273
 274        return ret;
 275}
 276
 277static void clk_smd_rpm_unprepare(struct clk_hw *hw)
 278{
 279        struct clk_smd_rpm *r = to_clk_smd_rpm(hw);
 280        struct clk_smd_rpm *peer = r->peer;
 281        unsigned long peer_rate = 0, peer_sleep_rate = 0;
 282        unsigned long active_rate, sleep_rate;
 283        int ret;
 284
 285        mutex_lock(&rpm_smd_clk_lock);
 286
 287        if (!r->rate)
 288                goto out;
 289
 290        /* Take peer clock's rate into account only if it's enabled. */
 291        if (peer->enabled)
 292                to_active_sleep(peer, peer->rate, &peer_rate,
 293                                &peer_sleep_rate);
 294
 295        active_rate = r->branch ? !!peer_rate : peer_rate;
 296        ret = clk_smd_rpm_set_rate_active(r, active_rate);
 297        if (ret)
 298                goto out;
 299
 300        sleep_rate = r->branch ? !!peer_sleep_rate : peer_sleep_rate;
 301        ret = clk_smd_rpm_set_rate_sleep(r, sleep_rate);
 302        if (ret)
 303                goto out;
 304
 305        r->enabled = false;
 306
 307out:
 308        mutex_unlock(&rpm_smd_clk_lock);
 309}
 310
 311static int clk_smd_rpm_set_rate(struct clk_hw *hw, unsigned long rate,
 312                                unsigned long parent_rate)
 313{
 314        struct clk_smd_rpm *r = to_clk_smd_rpm(hw);
 315        struct clk_smd_rpm *peer = r->peer;
 316        unsigned long active_rate, sleep_rate;
 317        unsigned long this_rate = 0, this_sleep_rate = 0;
 318        unsigned long peer_rate = 0, peer_sleep_rate = 0;
 319        int ret = 0;
 320
 321        mutex_lock(&rpm_smd_clk_lock);
 322
 323        if (!r->enabled)
 324                goto out;
 325
 326        to_active_sleep(r, rate, &this_rate, &this_sleep_rate);
 327
 328        /* Take peer clock's rate into account only if it's enabled. */
 329        if (peer->enabled)
 330                to_active_sleep(peer, peer->rate,
 331                                &peer_rate, &peer_sleep_rate);
 332
 333        active_rate = max(this_rate, peer_rate);
 334        ret = clk_smd_rpm_set_rate_active(r, active_rate);
 335        if (ret)
 336                goto out;
 337
 338        sleep_rate = max(this_sleep_rate, peer_sleep_rate);
 339        ret = clk_smd_rpm_set_rate_sleep(r, sleep_rate);
 340        if (ret)
 341                goto out;
 342
 343        r->rate = rate;
 344
 345out:
 346        mutex_unlock(&rpm_smd_clk_lock);
 347
 348        return ret;
 349}
 350
 351static long clk_smd_rpm_round_rate(struct clk_hw *hw, unsigned long rate,
 352                                   unsigned long *parent_rate)
 353{
 354        /*
 355         * RPM handles rate rounding and we don't have a way to
 356         * know what the rate will be, so just return whatever
 357         * rate is requested.
 358         */
 359        return rate;
 360}
 361
 362static unsigned long clk_smd_rpm_recalc_rate(struct clk_hw *hw,
 363                                             unsigned long parent_rate)
 364{
 365        struct clk_smd_rpm *r = to_clk_smd_rpm(hw);
 366
 367        /*
 368         * RPM handles rate rounding and we don't have a way to
 369         * know what the rate will be, so just return whatever
 370         * rate was set.
 371         */
 372        return r->rate;
 373}
 374
 375static int clk_smd_rpm_enable_scaling(struct qcom_smd_rpm *rpm)
 376{
 377        int ret;
 378        struct clk_smd_rpm_req req = {
 379                .key = cpu_to_le32(QCOM_RPM_SMD_KEY_ENABLE),
 380                .nbytes = cpu_to_le32(sizeof(u32)),
 381                .value = cpu_to_le32(1),
 382        };
 383
 384        ret = qcom_rpm_smd_write(rpm, QCOM_SMD_RPM_SLEEP_STATE,
 385                                 QCOM_SMD_RPM_MISC_CLK,
 386                                 QCOM_RPM_SCALING_ENABLE_ID, &req, sizeof(req));
 387        if (ret) {
 388                pr_err("RPM clock scaling (sleep set) not enabled!\n");
 389                return ret;
 390        }
 391
 392        ret = qcom_rpm_smd_write(rpm, QCOM_SMD_RPM_ACTIVE_STATE,
 393                                 QCOM_SMD_RPM_MISC_CLK,
 394                                 QCOM_RPM_SCALING_ENABLE_ID, &req, sizeof(req));
 395        if (ret) {
 396                pr_err("RPM clock scaling (active set) not enabled!\n");
 397                return ret;
 398        }
 399
 400        pr_debug("%s: RPM clock scaling is enabled\n", __func__);
 401        return 0;
 402}
 403
 404static const struct clk_ops clk_smd_rpm_ops = {
 405        .prepare        = clk_smd_rpm_prepare,
 406        .unprepare      = clk_smd_rpm_unprepare,
 407        .set_rate       = clk_smd_rpm_set_rate,
 408        .round_rate     = clk_smd_rpm_round_rate,
 409        .recalc_rate    = clk_smd_rpm_recalc_rate,
 410};
 411
 412static const struct clk_ops clk_smd_rpm_branch_ops = {
 413        .prepare        = clk_smd_rpm_prepare,
 414        .unprepare      = clk_smd_rpm_unprepare,
 415};
 416
 417/* msm8916 */
 418DEFINE_CLK_SMD_RPM(msm8916, pcnoc_clk, pcnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0);
 419DEFINE_CLK_SMD_RPM(msm8916, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1);
 420DEFINE_CLK_SMD_RPM(msm8916, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0);
 421DEFINE_CLK_SMD_RPM_QDSS(msm8916, qdss_clk, qdss_a_clk, QCOM_SMD_RPM_MISC_CLK, 1);
 422DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8916, bb_clk1, bb_clk1_a, 1);
 423DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8916, bb_clk2, bb_clk2_a, 2);
 424DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8916, rf_clk1, rf_clk1_a, 4);
 425DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8916, rf_clk2, rf_clk2_a, 5);
 426DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8916, bb_clk1_pin, bb_clk1_a_pin, 1);
 427DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8916, bb_clk2_pin, bb_clk2_a_pin, 2);
 428DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8916, rf_clk1_pin, rf_clk1_a_pin, 4);
 429DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8916, rf_clk2_pin, rf_clk2_a_pin, 5);
 430
 431static struct clk_smd_rpm *msm8916_clks[] = {
 432        [RPM_SMD_PCNOC_CLK]             = &msm8916_pcnoc_clk,
 433        [RPM_SMD_PCNOC_A_CLK]           = &msm8916_pcnoc_a_clk,
 434        [RPM_SMD_SNOC_CLK]              = &msm8916_snoc_clk,
 435        [RPM_SMD_SNOC_A_CLK]            = &msm8916_snoc_a_clk,
 436        [RPM_SMD_BIMC_CLK]              = &msm8916_bimc_clk,
 437        [RPM_SMD_BIMC_A_CLK]            = &msm8916_bimc_a_clk,
 438        [RPM_SMD_QDSS_CLK]              = &msm8916_qdss_clk,
 439        [RPM_SMD_QDSS_A_CLK]            = &msm8916_qdss_a_clk,
 440        [RPM_SMD_BB_CLK1]               = &msm8916_bb_clk1,
 441        [RPM_SMD_BB_CLK1_A]             = &msm8916_bb_clk1_a,
 442        [RPM_SMD_BB_CLK2]               = &msm8916_bb_clk2,
 443        [RPM_SMD_BB_CLK2_A]             = &msm8916_bb_clk2_a,
 444        [RPM_SMD_RF_CLK1]               = &msm8916_rf_clk1,
 445        [RPM_SMD_RF_CLK1_A]             = &msm8916_rf_clk1_a,
 446        [RPM_SMD_RF_CLK2]               = &msm8916_rf_clk2,
 447        [RPM_SMD_RF_CLK2_A]             = &msm8916_rf_clk2_a,
 448        [RPM_SMD_BB_CLK1_PIN]           = &msm8916_bb_clk1_pin,
 449        [RPM_SMD_BB_CLK1_A_PIN]         = &msm8916_bb_clk1_a_pin,
 450        [RPM_SMD_BB_CLK2_PIN]           = &msm8916_bb_clk2_pin,
 451        [RPM_SMD_BB_CLK2_A_PIN]         = &msm8916_bb_clk2_a_pin,
 452        [RPM_SMD_RF_CLK1_PIN]           = &msm8916_rf_clk1_pin,
 453        [RPM_SMD_RF_CLK1_A_PIN]         = &msm8916_rf_clk1_a_pin,
 454        [RPM_SMD_RF_CLK2_PIN]           = &msm8916_rf_clk2_pin,
 455        [RPM_SMD_RF_CLK2_A_PIN]         = &msm8916_rf_clk2_a_pin,
 456};
 457
 458static const struct rpm_smd_clk_desc rpm_clk_msm8916 = {
 459        .clks = msm8916_clks,
 460        .num_clks = ARRAY_SIZE(msm8916_clks),
 461};
 462
 463/* msm8974 */
 464DEFINE_CLK_SMD_RPM(msm8974, pnoc_clk, pnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0);
 465DEFINE_CLK_SMD_RPM(msm8974, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1);
 466DEFINE_CLK_SMD_RPM(msm8974, cnoc_clk, cnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 2);
 467DEFINE_CLK_SMD_RPM(msm8974, mmssnoc_ahb_clk, mmssnoc_ahb_a_clk, QCOM_SMD_RPM_BUS_CLK, 3);
 468DEFINE_CLK_SMD_RPM(msm8974, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0);
 469DEFINE_CLK_SMD_RPM(msm8974, gfx3d_clk_src, gfx3d_a_clk_src, QCOM_SMD_RPM_MEM_CLK, 1);
 470DEFINE_CLK_SMD_RPM(msm8974, ocmemgx_clk, ocmemgx_a_clk, QCOM_SMD_RPM_MEM_CLK, 2);
 471DEFINE_CLK_SMD_RPM_QDSS(msm8974, qdss_clk, qdss_a_clk, QCOM_SMD_RPM_MISC_CLK, 1);
 472DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, cxo_d0, cxo_d0_a, 1);
 473DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, cxo_d1, cxo_d1_a, 2);
 474DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, cxo_a0, cxo_a0_a, 4);
 475DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, cxo_a1, cxo_a1_a, 5);
 476DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, cxo_a2, cxo_a2_a, 6);
 477DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, diff_clk, diff_a_clk, 7);
 478DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, div_clk1, div_a_clk1, 11);
 479DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, div_clk2, div_a_clk2, 12);
 480DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8974, cxo_d0_pin, cxo_d0_a_pin, 1);
 481DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8974, cxo_d1_pin, cxo_d1_a_pin, 2);
 482DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8974, cxo_a0_pin, cxo_a0_a_pin, 4);
 483DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8974, cxo_a1_pin, cxo_a1_a_pin, 5);
 484DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8974, cxo_a2_pin, cxo_a2_a_pin, 6);
 485
 486static struct clk_smd_rpm *msm8974_clks[] = {
 487        [RPM_SMD_PNOC_CLK]              = &msm8974_pnoc_clk,
 488        [RPM_SMD_PNOC_A_CLK]            = &msm8974_pnoc_a_clk,
 489        [RPM_SMD_SNOC_CLK]              = &msm8974_snoc_clk,
 490        [RPM_SMD_SNOC_A_CLK]            = &msm8974_snoc_a_clk,
 491        [RPM_SMD_CNOC_CLK]              = &msm8974_cnoc_clk,
 492        [RPM_SMD_CNOC_A_CLK]            = &msm8974_cnoc_a_clk,
 493        [RPM_SMD_MMSSNOC_AHB_CLK]       = &msm8974_mmssnoc_ahb_clk,
 494        [RPM_SMD_MMSSNOC_AHB_A_CLK]     = &msm8974_mmssnoc_ahb_a_clk,
 495        [RPM_SMD_BIMC_CLK]              = &msm8974_bimc_clk,
 496        [RPM_SMD_BIMC_A_CLK]            = &msm8974_bimc_a_clk,
 497        [RPM_SMD_OCMEMGX_CLK]           = &msm8974_ocmemgx_clk,
 498        [RPM_SMD_OCMEMGX_A_CLK]         = &msm8974_ocmemgx_a_clk,
 499        [RPM_SMD_QDSS_CLK]              = &msm8974_qdss_clk,
 500        [RPM_SMD_QDSS_A_CLK]            = &msm8974_qdss_a_clk,
 501        [RPM_SMD_CXO_D0]                = &msm8974_cxo_d0,
 502        [RPM_SMD_CXO_D0_A]              = &msm8974_cxo_d0_a,
 503        [RPM_SMD_CXO_D1]                = &msm8974_cxo_d1,
 504        [RPM_SMD_CXO_D1_A]              = &msm8974_cxo_d1_a,
 505        [RPM_SMD_CXO_A0]                = &msm8974_cxo_a0,
 506        [RPM_SMD_CXO_A0_A]              = &msm8974_cxo_a0_a,
 507        [RPM_SMD_CXO_A1]                = &msm8974_cxo_a1,
 508        [RPM_SMD_CXO_A1_A]              = &msm8974_cxo_a1_a,
 509        [RPM_SMD_CXO_A2]                = &msm8974_cxo_a2,
 510        [RPM_SMD_CXO_A2_A]              = &msm8974_cxo_a2_a,
 511        [RPM_SMD_DIFF_CLK]              = &msm8974_diff_clk,
 512        [RPM_SMD_DIFF_A_CLK]            = &msm8974_diff_a_clk,
 513        [RPM_SMD_DIV_CLK1]              = &msm8974_div_clk1,
 514        [RPM_SMD_DIV_A_CLK1]            = &msm8974_div_a_clk1,
 515        [RPM_SMD_DIV_CLK2]              = &msm8974_div_clk2,
 516        [RPM_SMD_DIV_A_CLK2]            = &msm8974_div_a_clk2,
 517        [RPM_SMD_CXO_D0_PIN]            = &msm8974_cxo_d0_pin,
 518        [RPM_SMD_CXO_D0_A_PIN]          = &msm8974_cxo_d0_a_pin,
 519        [RPM_SMD_CXO_D1_PIN]            = &msm8974_cxo_d1_pin,
 520        [RPM_SMD_CXO_D1_A_PIN]          = &msm8974_cxo_d1_a_pin,
 521        [RPM_SMD_CXO_A0_PIN]            = &msm8974_cxo_a0_pin,
 522        [RPM_SMD_CXO_A0_A_PIN]          = &msm8974_cxo_a0_a_pin,
 523        [RPM_SMD_CXO_A1_PIN]            = &msm8974_cxo_a1_pin,
 524        [RPM_SMD_CXO_A1_A_PIN]          = &msm8974_cxo_a1_a_pin,
 525        [RPM_SMD_CXO_A2_PIN]            = &msm8974_cxo_a2_pin,
 526        [RPM_SMD_CXO_A2_A_PIN]          = &msm8974_cxo_a2_a_pin,
 527};
 528
 529static const struct rpm_smd_clk_desc rpm_clk_msm8974 = {
 530        .clks = msm8974_clks,
 531        .num_clks = ARRAY_SIZE(msm8974_clks),
 532};
 533
 534/* msm8996 */
 535DEFINE_CLK_SMD_RPM(msm8996, pcnoc_clk, pcnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0);
 536DEFINE_CLK_SMD_RPM(msm8996, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1);
 537DEFINE_CLK_SMD_RPM(msm8996, cnoc_clk, cnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 2);
 538DEFINE_CLK_SMD_RPM(msm8996, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0);
 539DEFINE_CLK_SMD_RPM(msm8996, mmssnoc_axi_rpm_clk, mmssnoc_axi_rpm_a_clk,
 540                   QCOM_SMD_RPM_MMAXI_CLK, 0);
 541DEFINE_CLK_SMD_RPM(msm8996, ipa_clk, ipa_a_clk, QCOM_SMD_RPM_IPA_CLK, 0);
 542DEFINE_CLK_SMD_RPM(msm8996, ce1_clk, ce1_a_clk, QCOM_SMD_RPM_CE_CLK, 0);
 543DEFINE_CLK_SMD_RPM_BRANCH(msm8996, aggre1_noc_clk, aggre1_noc_a_clk,
 544                          QCOM_SMD_RPM_AGGR_CLK, 1, 1000);
 545DEFINE_CLK_SMD_RPM_BRANCH(msm8996, aggre2_noc_clk, aggre2_noc_a_clk,
 546                          QCOM_SMD_RPM_AGGR_CLK, 2, 1000);
 547DEFINE_CLK_SMD_RPM_QDSS(msm8996, qdss_clk, qdss_a_clk,
 548                        QCOM_SMD_RPM_MISC_CLK, 1);
 549DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, bb_clk1, bb_clk1_a, 1);
 550DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, bb_clk2, bb_clk2_a, 2);
 551DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, rf_clk1, rf_clk1_a, 4);
 552DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, rf_clk2, rf_clk2_a, 5);
 553DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, ln_bb_clk, ln_bb_a_clk, 8);
 554DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, div_clk1, div_clk1_a, 0xb);
 555DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, div_clk2, div_clk2_a, 0xc);
 556DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, div_clk3, div_clk3_a, 0xd);
 557DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8996, bb_clk1_pin, bb_clk1_a_pin, 1);
 558DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8996, bb_clk2_pin, bb_clk2_a_pin, 2);
 559DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8996, rf_clk1_pin, rf_clk1_a_pin, 4);
 560DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8996, rf_clk2_pin, rf_clk2_a_pin, 5);
 561
 562static struct clk_smd_rpm *msm8996_clks[] = {
 563        [RPM_SMD_PCNOC_CLK] = &msm8996_pcnoc_clk,
 564        [RPM_SMD_PCNOC_A_CLK] = &msm8996_pcnoc_a_clk,
 565        [RPM_SMD_SNOC_CLK] = &msm8996_snoc_clk,
 566        [RPM_SMD_SNOC_A_CLK] = &msm8996_snoc_a_clk,
 567        [RPM_SMD_CNOC_CLK] = &msm8996_cnoc_clk,
 568        [RPM_SMD_CNOC_A_CLK] = &msm8996_cnoc_a_clk,
 569        [RPM_SMD_BIMC_CLK] = &msm8996_bimc_clk,
 570        [RPM_SMD_BIMC_A_CLK] = &msm8996_bimc_a_clk,
 571        [RPM_SMD_MMAXI_CLK] = &msm8996_mmssnoc_axi_rpm_clk,
 572        [RPM_SMD_MMAXI_A_CLK] = &msm8996_mmssnoc_axi_rpm_a_clk,
 573        [RPM_SMD_IPA_CLK] = &msm8996_ipa_clk,
 574        [RPM_SMD_IPA_A_CLK] = &msm8996_ipa_a_clk,
 575        [RPM_SMD_CE1_CLK] = &msm8996_ce1_clk,
 576        [RPM_SMD_CE1_A_CLK] = &msm8996_ce1_a_clk,
 577        [RPM_SMD_AGGR1_NOC_CLK] = &msm8996_aggre1_noc_clk,
 578        [RPM_SMD_AGGR1_NOC_A_CLK] = &msm8996_aggre1_noc_a_clk,
 579        [RPM_SMD_AGGR2_NOC_CLK] = &msm8996_aggre2_noc_clk,
 580        [RPM_SMD_AGGR2_NOC_A_CLK] = &msm8996_aggre2_noc_a_clk,
 581        [RPM_SMD_QDSS_CLK] = &msm8996_qdss_clk,
 582        [RPM_SMD_QDSS_A_CLK] = &msm8996_qdss_a_clk,
 583        [RPM_SMD_BB_CLK1] = &msm8996_bb_clk1,
 584        [RPM_SMD_BB_CLK1_A] = &msm8996_bb_clk1_a,
 585        [RPM_SMD_BB_CLK2] = &msm8996_bb_clk2,
 586        [RPM_SMD_BB_CLK2_A] = &msm8996_bb_clk2_a,
 587        [RPM_SMD_RF_CLK1] = &msm8996_rf_clk1,
 588        [RPM_SMD_RF_CLK1_A] = &msm8996_rf_clk1_a,
 589        [RPM_SMD_RF_CLK2] = &msm8996_rf_clk2,
 590        [RPM_SMD_RF_CLK2_A] = &msm8996_rf_clk2_a,
 591        [RPM_SMD_LN_BB_CLK] = &msm8996_ln_bb_clk,
 592        [RPM_SMD_LN_BB_A_CLK] = &msm8996_ln_bb_a_clk,
 593        [RPM_SMD_DIV_CLK1] = &msm8996_div_clk1,
 594        [RPM_SMD_DIV_A_CLK1] = &msm8996_div_clk1_a,
 595        [RPM_SMD_DIV_CLK2] = &msm8996_div_clk2,
 596        [RPM_SMD_DIV_A_CLK2] = &msm8996_div_clk2_a,
 597        [RPM_SMD_DIV_CLK3] = &msm8996_div_clk3,
 598        [RPM_SMD_DIV_A_CLK3] = &msm8996_div_clk3_a,
 599        [RPM_SMD_BB_CLK1_PIN] = &msm8996_bb_clk1_pin,
 600        [RPM_SMD_BB_CLK1_A_PIN] = &msm8996_bb_clk1_a_pin,
 601        [RPM_SMD_BB_CLK2_PIN] = &msm8996_bb_clk2_pin,
 602        [RPM_SMD_BB_CLK2_A_PIN] = &msm8996_bb_clk2_a_pin,
 603        [RPM_SMD_RF_CLK1_PIN] = &msm8996_rf_clk1_pin,
 604        [RPM_SMD_RF_CLK1_A_PIN] = &msm8996_rf_clk1_a_pin,
 605        [RPM_SMD_RF_CLK2_PIN] = &msm8996_rf_clk2_pin,
 606        [RPM_SMD_RF_CLK2_A_PIN] = &msm8996_rf_clk2_a_pin,
 607};
 608
 609static const struct rpm_smd_clk_desc rpm_clk_msm8996 = {
 610        .clks = msm8996_clks,
 611        .num_clks = ARRAY_SIZE(msm8996_clks),
 612};
 613
 614static const struct of_device_id rpm_smd_clk_match_table[] = {
 615        { .compatible = "qcom,rpmcc-msm8916", .data = &rpm_clk_msm8916 },
 616        { .compatible = "qcom,rpmcc-msm8974", .data = &rpm_clk_msm8974 },
 617        { .compatible = "qcom,rpmcc-msm8996", .data = &rpm_clk_msm8996 },
 618        { }
 619};
 620MODULE_DEVICE_TABLE(of, rpm_smd_clk_match_table);
 621
 622static struct clk_hw *qcom_smdrpm_clk_hw_get(struct of_phandle_args *clkspec,
 623                                             void *data)
 624{
 625        struct rpm_cc *rcc = data;
 626        unsigned int idx = clkspec->args[0];
 627
 628        if (idx >= rcc->num_clks) {
 629                pr_err("%s: invalid index %u\n", __func__, idx);
 630                return ERR_PTR(-EINVAL);
 631        }
 632
 633        return rcc->clks[idx] ? &rcc->clks[idx]->hw : ERR_PTR(-ENOENT);
 634}
 635
 636static int rpm_smd_clk_probe(struct platform_device *pdev)
 637{
 638        struct rpm_cc *rcc;
 639        int ret;
 640        size_t num_clks, i;
 641        struct qcom_smd_rpm *rpm;
 642        struct clk_smd_rpm **rpm_smd_clks;
 643        const struct rpm_smd_clk_desc *desc;
 644
 645        rpm = dev_get_drvdata(pdev->dev.parent);
 646        if (!rpm) {
 647                dev_err(&pdev->dev, "Unable to retrieve handle to RPM\n");
 648                return -ENODEV;
 649        }
 650
 651        desc = of_device_get_match_data(&pdev->dev);
 652        if (!desc)
 653                return -EINVAL;
 654
 655        rpm_smd_clks = desc->clks;
 656        num_clks = desc->num_clks;
 657
 658        rcc = devm_kzalloc(&pdev->dev, sizeof(*rcc), GFP_KERNEL);
 659        if (!rcc)
 660                return -ENOMEM;
 661
 662        rcc->clks = rpm_smd_clks;
 663        rcc->num_clks = num_clks;
 664
 665        for (i = 0; i < num_clks; i++) {
 666                if (!rpm_smd_clks[i])
 667                        continue;
 668
 669                rpm_smd_clks[i]->rpm = rpm;
 670
 671                ret = clk_smd_rpm_handoff(rpm_smd_clks[i]);
 672                if (ret)
 673                        goto err;
 674        }
 675
 676        ret = clk_smd_rpm_enable_scaling(rpm);
 677        if (ret)
 678                goto err;
 679
 680        for (i = 0; i < num_clks; i++) {
 681                if (!rpm_smd_clks[i])
 682                        continue;
 683
 684                ret = devm_clk_hw_register(&pdev->dev, &rpm_smd_clks[i]->hw);
 685                if (ret)
 686                        goto err;
 687        }
 688
 689        ret = devm_of_clk_add_hw_provider(&pdev->dev, qcom_smdrpm_clk_hw_get,
 690                                     rcc);
 691        if (ret)
 692                goto err;
 693
 694        return 0;
 695err:
 696        dev_err(&pdev->dev, "Error registering SMD clock driver (%d)\n", ret);
 697        return ret;
 698}
 699
 700static struct platform_driver rpm_smd_clk_driver = {
 701        .driver = {
 702                .name = "qcom-clk-smd-rpm",
 703                .of_match_table = rpm_smd_clk_match_table,
 704        },
 705        .probe = rpm_smd_clk_probe,
 706};
 707
 708static int __init rpm_smd_clk_init(void)
 709{
 710        return platform_driver_register(&rpm_smd_clk_driver);
 711}
 712core_initcall(rpm_smd_clk_init);
 713
 714static void __exit rpm_smd_clk_exit(void)
 715{
 716        platform_driver_unregister(&rpm_smd_clk_driver);
 717}
 718module_exit(rpm_smd_clk_exit);
 719
 720MODULE_DESCRIPTION("Qualcomm RPM over SMD Clock Controller Driver");
 721MODULE_LICENSE("GPL v2");
 722MODULE_ALIAS("platform:qcom-clk-smd-rpm");
 723