linux/drivers/clk/samsung/clk-pll.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
   4 * Copyright (c) 2013 Linaro Ltd.
   5 *
   6 * This file contains the utility functions to register the pll clocks.
   7*/
   8
   9#include <linux/errno.h>
  10#include <linux/hrtimer.h>
  11#include <linux/iopoll.h>
  12#include <linux/delay.h>
  13#include <linux/slab.h>
  14#include <linux/timekeeping.h>
  15#include <linux/clk-provider.h>
  16#include <linux/io.h>
  17#include "clk.h"
  18#include "clk-pll.h"
  19
  20#define PLL_TIMEOUT_US          20000U
  21#define PLL_TIMEOUT_LOOPS       1000000U
  22
  23struct samsung_clk_pll {
  24        struct clk_hw           hw;
  25        void __iomem            *lock_reg;
  26        void __iomem            *con_reg;
  27        /* PLL enable control bit offset in @con_reg register */
  28        unsigned short          enable_offs;
  29        /* PLL lock status bit offset in @con_reg register */
  30        unsigned short          lock_offs;
  31        enum samsung_pll_type   type;
  32        unsigned int            rate_count;
  33        const struct samsung_pll_rate_table *rate_table;
  34};
  35
  36#define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
  37
  38static const struct samsung_pll_rate_table *samsung_get_pll_settings(
  39                                struct samsung_clk_pll *pll, unsigned long rate)
  40{
  41        const struct samsung_pll_rate_table  *rate_table = pll->rate_table;
  42        int i;
  43
  44        for (i = 0; i < pll->rate_count; i++) {
  45                if (rate == rate_table[i].rate)
  46                        return &rate_table[i];
  47        }
  48
  49        return NULL;
  50}
  51
  52static long samsung_pll_round_rate(struct clk_hw *hw,
  53                        unsigned long drate, unsigned long *prate)
  54{
  55        struct samsung_clk_pll *pll = to_clk_pll(hw);
  56        const struct samsung_pll_rate_table *rate_table = pll->rate_table;
  57        int i;
  58
  59        /* Assumming rate_table is in descending order */
  60        for (i = 0; i < pll->rate_count; i++) {
  61                if (drate >= rate_table[i].rate)
  62                        return rate_table[i].rate;
  63        }
  64
  65        /* return minimum supported value */
  66        return rate_table[i - 1].rate;
  67}
  68
  69static bool pll_early_timeout = true;
  70
  71static int __init samsung_pll_disable_early_timeout(void)
  72{
  73        pll_early_timeout = false;
  74        return 0;
  75}
  76arch_initcall(samsung_pll_disable_early_timeout);
  77
  78/* Wait until the PLL is locked */
  79static int samsung_pll_lock_wait(struct samsung_clk_pll *pll,
  80                                 unsigned int reg_mask)
  81{
  82        int i, ret;
  83        u32 val;
  84
  85        /*
  86         * This function might be called when the timekeeping API can't be used
  87         * to detect timeouts. One situation is when the clocksource is not yet
  88         * initialized, another when the timekeeping is suspended. udelay() also
  89         * cannot be used when the clocksource is not running on arm64, since
  90         * the current timer is used as cycle counter. So a simple busy loop
  91         * is used here in that special cases. The limit of iterations has been
  92         * derived from experimental measurements of various PLLs on multiple
  93         * Exynos SoC variants. Single register read time was usually in range
  94         * 0.4...1.5 us, never less than 0.4 us.
  95         */
  96        if (pll_early_timeout || timekeeping_suspended) {
  97                i = PLL_TIMEOUT_LOOPS;
  98                while (i-- > 0) {
  99                        if (readl_relaxed(pll->con_reg) & reg_mask)
 100                                return 0;
 101
 102                        cpu_relax();
 103                }
 104                ret = -ETIMEDOUT;
 105        } else {
 106                ret = readl_relaxed_poll_timeout_atomic(pll->con_reg, val,
 107                                        val & reg_mask, 0, PLL_TIMEOUT_US);
 108        }
 109
 110        if (ret < 0)
 111                pr_err("Could not lock PLL %s\n", clk_hw_get_name(&pll->hw));
 112
 113        return ret;
 114}
 115
 116static int samsung_pll3xxx_enable(struct clk_hw *hw)
 117{
 118        struct samsung_clk_pll *pll = to_clk_pll(hw);
 119        u32 tmp;
 120
 121        tmp = readl_relaxed(pll->con_reg);
 122        tmp |= BIT(pll->enable_offs);
 123        writel_relaxed(tmp, pll->con_reg);
 124
 125        return samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
 126}
 127
 128static void samsung_pll3xxx_disable(struct clk_hw *hw)
 129{
 130        struct samsung_clk_pll *pll = to_clk_pll(hw);
 131        u32 tmp;
 132
 133        tmp = readl_relaxed(pll->con_reg);
 134        tmp &= ~BIT(pll->enable_offs);
 135        writel_relaxed(tmp, pll->con_reg);
 136}
 137
 138/*
 139 * PLL2126 Clock Type
 140 */
 141
 142#define PLL2126_MDIV_MASK       (0xff)
 143#define PLL2126_PDIV_MASK       (0x3f)
 144#define PLL2126_SDIV_MASK       (0x3)
 145#define PLL2126_MDIV_SHIFT      (16)
 146#define PLL2126_PDIV_SHIFT      (8)
 147#define PLL2126_SDIV_SHIFT      (0)
 148
 149static unsigned long samsung_pll2126_recalc_rate(struct clk_hw *hw,
 150                                unsigned long parent_rate)
 151{
 152        struct samsung_clk_pll *pll = to_clk_pll(hw);
 153        u32 pll_con, mdiv, pdiv, sdiv;
 154        u64 fvco = parent_rate;
 155
 156        pll_con = readl_relaxed(pll->con_reg);
 157        mdiv = (pll_con >> PLL2126_MDIV_SHIFT) & PLL2126_MDIV_MASK;
 158        pdiv = (pll_con >> PLL2126_PDIV_SHIFT) & PLL2126_PDIV_MASK;
 159        sdiv = (pll_con >> PLL2126_SDIV_SHIFT) & PLL2126_SDIV_MASK;
 160
 161        fvco *= (mdiv + 8);
 162        do_div(fvco, (pdiv + 2) << sdiv);
 163
 164        return (unsigned long)fvco;
 165}
 166
 167static const struct clk_ops samsung_pll2126_clk_ops = {
 168        .recalc_rate = samsung_pll2126_recalc_rate,
 169};
 170
 171/*
 172 * PLL3000 Clock Type
 173 */
 174
 175#define PLL3000_MDIV_MASK       (0xff)
 176#define PLL3000_PDIV_MASK       (0x3)
 177#define PLL3000_SDIV_MASK       (0x3)
 178#define PLL3000_MDIV_SHIFT      (16)
 179#define PLL3000_PDIV_SHIFT      (8)
 180#define PLL3000_SDIV_SHIFT      (0)
 181
 182static unsigned long samsung_pll3000_recalc_rate(struct clk_hw *hw,
 183                                unsigned long parent_rate)
 184{
 185        struct samsung_clk_pll *pll = to_clk_pll(hw);
 186        u32 pll_con, mdiv, pdiv, sdiv;
 187        u64 fvco = parent_rate;
 188
 189        pll_con = readl_relaxed(pll->con_reg);
 190        mdiv = (pll_con >> PLL3000_MDIV_SHIFT) & PLL3000_MDIV_MASK;
 191        pdiv = (pll_con >> PLL3000_PDIV_SHIFT) & PLL3000_PDIV_MASK;
 192        sdiv = (pll_con >> PLL3000_SDIV_SHIFT) & PLL3000_SDIV_MASK;
 193
 194        fvco *= (2 * (mdiv + 8));
 195        do_div(fvco, pdiv << sdiv);
 196
 197        return (unsigned long)fvco;
 198}
 199
 200static const struct clk_ops samsung_pll3000_clk_ops = {
 201        .recalc_rate = samsung_pll3000_recalc_rate,
 202};
 203
 204/*
 205 * PLL35xx Clock Type
 206 */
 207/* Maximum lock time can be 270 * PDIV cycles */
 208#define PLL35XX_LOCK_FACTOR     (270)
 209
 210#define PLL35XX_MDIV_MASK       (0x3FF)
 211#define PLL35XX_PDIV_MASK       (0x3F)
 212#define PLL35XX_SDIV_MASK       (0x7)
 213#define PLL35XX_MDIV_SHIFT      (16)
 214#define PLL35XX_PDIV_SHIFT      (8)
 215#define PLL35XX_SDIV_SHIFT      (0)
 216#define PLL35XX_LOCK_STAT_SHIFT (29)
 217#define PLL35XX_ENABLE_SHIFT    (31)
 218
 219static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
 220                                unsigned long parent_rate)
 221{
 222        struct samsung_clk_pll *pll = to_clk_pll(hw);
 223        u32 mdiv, pdiv, sdiv, pll_con;
 224        u64 fvco = parent_rate;
 225
 226        pll_con = readl_relaxed(pll->con_reg);
 227        mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
 228        pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
 229        sdiv = (pll_con >> PLL35XX_SDIV_SHIFT) & PLL35XX_SDIV_MASK;
 230
 231        fvco *= mdiv;
 232        do_div(fvco, (pdiv << sdiv));
 233
 234        return (unsigned long)fvco;
 235}
 236
 237static inline bool samsung_pll35xx_mp_change(
 238                const struct samsung_pll_rate_table *rate, u32 pll_con)
 239{
 240        u32 old_mdiv, old_pdiv;
 241
 242        old_mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
 243        old_pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
 244
 245        return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv);
 246}
 247
 248static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
 249                                        unsigned long prate)
 250{
 251        struct samsung_clk_pll *pll = to_clk_pll(hw);
 252        const struct samsung_pll_rate_table *rate;
 253        u32 tmp;
 254
 255        /* Get required rate settings from table */
 256        rate = samsung_get_pll_settings(pll, drate);
 257        if (!rate) {
 258                pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
 259                        drate, clk_hw_get_name(hw));
 260                return -EINVAL;
 261        }
 262
 263        tmp = readl_relaxed(pll->con_reg);
 264
 265        if (!(samsung_pll35xx_mp_change(rate, tmp))) {
 266                /* If only s change, change just s value only*/
 267                tmp &= ~(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT);
 268                tmp |= rate->sdiv << PLL35XX_SDIV_SHIFT;
 269                writel_relaxed(tmp, pll->con_reg);
 270
 271                return 0;
 272        }
 273
 274        /* Set PLL lock time. */
 275        writel_relaxed(rate->pdiv * PLL35XX_LOCK_FACTOR,
 276                        pll->lock_reg);
 277
 278        /* Change PLL PMS values */
 279        tmp &= ~((PLL35XX_MDIV_MASK << PLL35XX_MDIV_SHIFT) |
 280                        (PLL35XX_PDIV_MASK << PLL35XX_PDIV_SHIFT) |
 281                        (PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT));
 282        tmp |= (rate->mdiv << PLL35XX_MDIV_SHIFT) |
 283                        (rate->pdiv << PLL35XX_PDIV_SHIFT) |
 284                        (rate->sdiv << PLL35XX_SDIV_SHIFT);
 285        writel_relaxed(tmp, pll->con_reg);
 286
 287        /* Wait for PLL lock if the PLL is enabled */
 288        if (tmp & BIT(pll->enable_offs))
 289                return samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
 290
 291        return 0;
 292}
 293
 294static const struct clk_ops samsung_pll35xx_clk_ops = {
 295        .recalc_rate = samsung_pll35xx_recalc_rate,
 296        .round_rate = samsung_pll_round_rate,
 297        .set_rate = samsung_pll35xx_set_rate,
 298        .enable = samsung_pll3xxx_enable,
 299        .disable = samsung_pll3xxx_disable,
 300};
 301
 302static const struct clk_ops samsung_pll35xx_clk_min_ops = {
 303        .recalc_rate = samsung_pll35xx_recalc_rate,
 304};
 305
 306/*
 307 * PLL36xx Clock Type
 308 */
 309/* Maximum lock time can be 3000 * PDIV cycles */
 310#define PLL36XX_LOCK_FACTOR    (3000)
 311
 312#define PLL36XX_KDIV_MASK       (0xFFFF)
 313#define PLL36XX_MDIV_MASK       (0x1FF)
 314#define PLL36XX_PDIV_MASK       (0x3F)
 315#define PLL36XX_SDIV_MASK       (0x7)
 316#define PLL36XX_MDIV_SHIFT      (16)
 317#define PLL36XX_PDIV_SHIFT      (8)
 318#define PLL36XX_SDIV_SHIFT      (0)
 319#define PLL36XX_KDIV_SHIFT      (0)
 320#define PLL36XX_LOCK_STAT_SHIFT (29)
 321#define PLL36XX_ENABLE_SHIFT    (31)
 322
 323static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
 324                                unsigned long parent_rate)
 325{
 326        struct samsung_clk_pll *pll = to_clk_pll(hw);
 327        u32 mdiv, pdiv, sdiv, pll_con0, pll_con1;
 328        s16 kdiv;
 329        u64 fvco = parent_rate;
 330
 331        pll_con0 = readl_relaxed(pll->con_reg);
 332        pll_con1 = readl_relaxed(pll->con_reg + 4);
 333        mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
 334        pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
 335        sdiv = (pll_con0 >> PLL36XX_SDIV_SHIFT) & PLL36XX_SDIV_MASK;
 336        kdiv = (s16)(pll_con1 & PLL36XX_KDIV_MASK);
 337
 338        fvco *= (mdiv << 16) + kdiv;
 339        do_div(fvco, (pdiv << sdiv));
 340        fvco >>= 16;
 341
 342        return (unsigned long)fvco;
 343}
 344
 345static inline bool samsung_pll36xx_mpk_change(
 346        const struct samsung_pll_rate_table *rate, u32 pll_con0, u32 pll_con1)
 347{
 348        u32 old_mdiv, old_pdiv, old_kdiv;
 349
 350        old_mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
 351        old_pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
 352        old_kdiv = (pll_con1 >> PLL36XX_KDIV_SHIFT) & PLL36XX_KDIV_MASK;
 353
 354        return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
 355                rate->kdiv != old_kdiv);
 356}
 357
 358static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate,
 359                                        unsigned long parent_rate)
 360{
 361        struct samsung_clk_pll *pll = to_clk_pll(hw);
 362        u32 pll_con0, pll_con1;
 363        const struct samsung_pll_rate_table *rate;
 364
 365        rate = samsung_get_pll_settings(pll, drate);
 366        if (!rate) {
 367                pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
 368                        drate, clk_hw_get_name(hw));
 369                return -EINVAL;
 370        }
 371
 372        pll_con0 = readl_relaxed(pll->con_reg);
 373        pll_con1 = readl_relaxed(pll->con_reg + 4);
 374
 375        if (!(samsung_pll36xx_mpk_change(rate, pll_con0, pll_con1))) {
 376                /* If only s change, change just s value only*/
 377                pll_con0 &= ~(PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT);
 378                pll_con0 |= (rate->sdiv << PLL36XX_SDIV_SHIFT);
 379                writel_relaxed(pll_con0, pll->con_reg);
 380
 381                return 0;
 382        }
 383
 384        /* Set PLL lock time. */
 385        writel_relaxed(rate->pdiv * PLL36XX_LOCK_FACTOR, pll->lock_reg);
 386
 387         /* Change PLL PMS values */
 388        pll_con0 &= ~((PLL36XX_MDIV_MASK << PLL36XX_MDIV_SHIFT) |
 389                        (PLL36XX_PDIV_MASK << PLL36XX_PDIV_SHIFT) |
 390                        (PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT));
 391        pll_con0 |= (rate->mdiv << PLL36XX_MDIV_SHIFT) |
 392                        (rate->pdiv << PLL36XX_PDIV_SHIFT) |
 393                        (rate->sdiv << PLL36XX_SDIV_SHIFT);
 394        writel_relaxed(pll_con0, pll->con_reg);
 395
 396        pll_con1 &= ~(PLL36XX_KDIV_MASK << PLL36XX_KDIV_SHIFT);
 397        pll_con1 |= rate->kdiv << PLL36XX_KDIV_SHIFT;
 398        writel_relaxed(pll_con1, pll->con_reg + 4);
 399
 400        if (pll_con0 & BIT(pll->enable_offs))
 401                return samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
 402
 403        return 0;
 404}
 405
 406static const struct clk_ops samsung_pll36xx_clk_ops = {
 407        .recalc_rate = samsung_pll36xx_recalc_rate,
 408        .set_rate = samsung_pll36xx_set_rate,
 409        .round_rate = samsung_pll_round_rate,
 410        .enable = samsung_pll3xxx_enable,
 411        .disable = samsung_pll3xxx_disable,
 412};
 413
 414static const struct clk_ops samsung_pll36xx_clk_min_ops = {
 415        .recalc_rate = samsung_pll36xx_recalc_rate,
 416};
 417
 418/*
 419 * PLL45xx Clock Type
 420 */
 421#define PLL4502_LOCK_FACTOR     400
 422#define PLL4508_LOCK_FACTOR     240
 423
 424#define PLL45XX_MDIV_MASK       (0x3FF)
 425#define PLL45XX_PDIV_MASK       (0x3F)
 426#define PLL45XX_SDIV_MASK       (0x7)
 427#define PLL45XX_AFC_MASK        (0x1F)
 428#define PLL45XX_MDIV_SHIFT      (16)
 429#define PLL45XX_PDIV_SHIFT      (8)
 430#define PLL45XX_SDIV_SHIFT      (0)
 431#define PLL45XX_AFC_SHIFT       (0)
 432
 433#define PLL45XX_ENABLE          BIT(31)
 434#define PLL45XX_LOCKED          BIT(29)
 435
 436static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw,
 437                                unsigned long parent_rate)
 438{
 439        struct samsung_clk_pll *pll = to_clk_pll(hw);
 440        u32 mdiv, pdiv, sdiv, pll_con;
 441        u64 fvco = parent_rate;
 442
 443        pll_con = readl_relaxed(pll->con_reg);
 444        mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
 445        pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
 446        sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK;
 447
 448        if (pll->type == pll_4508)
 449                sdiv = sdiv - 1;
 450
 451        fvco *= mdiv;
 452        do_div(fvco, (pdiv << sdiv));
 453
 454        return (unsigned long)fvco;
 455}
 456
 457static bool samsung_pll45xx_mp_change(u32 pll_con0, u32 pll_con1,
 458                                const struct samsung_pll_rate_table *rate)
 459{
 460        u32 old_mdiv, old_pdiv, old_afc;
 461
 462        old_mdiv = (pll_con0 >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
 463        old_pdiv = (pll_con0 >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
 464        old_afc = (pll_con1 >> PLL45XX_AFC_SHIFT) & PLL45XX_AFC_MASK;
 465
 466        return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv
 467                || old_afc != rate->afc);
 468}
 469
 470static int samsung_pll45xx_set_rate(struct clk_hw *hw, unsigned long drate,
 471                                        unsigned long prate)
 472{
 473        struct samsung_clk_pll *pll = to_clk_pll(hw);
 474        const struct samsung_pll_rate_table *rate;
 475        u32 con0, con1;
 476
 477        /* Get required rate settings from table */
 478        rate = samsung_get_pll_settings(pll, drate);
 479        if (!rate) {
 480                pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
 481                        drate, clk_hw_get_name(hw));
 482                return -EINVAL;
 483        }
 484
 485        con0 = readl_relaxed(pll->con_reg);
 486        con1 = readl_relaxed(pll->con_reg + 0x4);
 487
 488        if (!(samsung_pll45xx_mp_change(con0, con1, rate))) {
 489                /* If only s change, change just s value only*/
 490                con0 &= ~(PLL45XX_SDIV_MASK << PLL45XX_SDIV_SHIFT);
 491                con0 |= rate->sdiv << PLL45XX_SDIV_SHIFT;
 492                writel_relaxed(con0, pll->con_reg);
 493
 494                return 0;
 495        }
 496
 497        /* Set PLL PMS values. */
 498        con0 &= ~((PLL45XX_MDIV_MASK << PLL45XX_MDIV_SHIFT) |
 499                        (PLL45XX_PDIV_MASK << PLL45XX_PDIV_SHIFT) |
 500                        (PLL45XX_SDIV_MASK << PLL45XX_SDIV_SHIFT));
 501        con0 |= (rate->mdiv << PLL45XX_MDIV_SHIFT) |
 502                        (rate->pdiv << PLL45XX_PDIV_SHIFT) |
 503                        (rate->sdiv << PLL45XX_SDIV_SHIFT);
 504
 505        /* Set PLL AFC value. */
 506        con1 = readl_relaxed(pll->con_reg + 0x4);
 507        con1 &= ~(PLL45XX_AFC_MASK << PLL45XX_AFC_SHIFT);
 508        con1 |= (rate->afc << PLL45XX_AFC_SHIFT);
 509
 510        /* Set PLL lock time. */
 511        switch (pll->type) {
 512        case pll_4502:
 513                writel_relaxed(rate->pdiv * PLL4502_LOCK_FACTOR, pll->lock_reg);
 514                break;
 515        case pll_4508:
 516                writel_relaxed(rate->pdiv * PLL4508_LOCK_FACTOR, pll->lock_reg);
 517                break;
 518        default:
 519                break;
 520        }
 521
 522        /* Set new configuration. */
 523        writel_relaxed(con1, pll->con_reg + 0x4);
 524        writel_relaxed(con0, pll->con_reg);
 525
 526        /* Wait for PLL lock */
 527        return samsung_pll_lock_wait(pll, PLL45XX_LOCKED);
 528}
 529
 530static const struct clk_ops samsung_pll45xx_clk_ops = {
 531        .recalc_rate = samsung_pll45xx_recalc_rate,
 532        .round_rate = samsung_pll_round_rate,
 533        .set_rate = samsung_pll45xx_set_rate,
 534};
 535
 536static const struct clk_ops samsung_pll45xx_clk_min_ops = {
 537        .recalc_rate = samsung_pll45xx_recalc_rate,
 538};
 539
 540/*
 541 * PLL46xx Clock Type
 542 */
 543#define PLL46XX_LOCK_FACTOR     3000
 544
 545#define PLL46XX_VSEL_MASK       (1)
 546#define PLL46XX_MDIV_MASK       (0x1FF)
 547#define PLL1460X_MDIV_MASK      (0x3FF)
 548
 549#define PLL46XX_PDIV_MASK       (0x3F)
 550#define PLL46XX_SDIV_MASK       (0x7)
 551#define PLL46XX_VSEL_SHIFT      (27)
 552#define PLL46XX_MDIV_SHIFT      (16)
 553#define PLL46XX_PDIV_SHIFT      (8)
 554#define PLL46XX_SDIV_SHIFT      (0)
 555
 556#define PLL46XX_KDIV_MASK       (0xFFFF)
 557#define PLL4650C_KDIV_MASK      (0xFFF)
 558#define PLL46XX_KDIV_SHIFT      (0)
 559#define PLL46XX_MFR_MASK        (0x3F)
 560#define PLL46XX_MRR_MASK        (0x1F)
 561#define PLL46XX_KDIV_SHIFT      (0)
 562#define PLL46XX_MFR_SHIFT       (16)
 563#define PLL46XX_MRR_SHIFT       (24)
 564
 565#define PLL46XX_ENABLE          BIT(31)
 566#define PLL46XX_LOCKED          BIT(29)
 567#define PLL46XX_VSEL            BIT(27)
 568
 569static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw,
 570                                unsigned long parent_rate)
 571{
 572        struct samsung_clk_pll *pll = to_clk_pll(hw);
 573        u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1, shift;
 574        u64 fvco = parent_rate;
 575
 576        pll_con0 = readl_relaxed(pll->con_reg);
 577        pll_con1 = readl_relaxed(pll->con_reg + 4);
 578        mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & ((pll->type == pll_1460x) ?
 579                                PLL1460X_MDIV_MASK : PLL46XX_MDIV_MASK);
 580        pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
 581        sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK;
 582        kdiv = pll->type == pll_4650c ? pll_con1 & PLL4650C_KDIV_MASK :
 583                                        pll_con1 & PLL46XX_KDIV_MASK;
 584
 585        shift = ((pll->type == pll_4600) || (pll->type == pll_1460x)) ? 16 : 10;
 586
 587        fvco *= (mdiv << shift) + kdiv;
 588        do_div(fvco, (pdiv << sdiv));
 589        fvco >>= shift;
 590
 591        return (unsigned long)fvco;
 592}
 593
 594static bool samsung_pll46xx_mpk_change(u32 pll_con0, u32 pll_con1,
 595                                const struct samsung_pll_rate_table *rate)
 596{
 597        u32 old_mdiv, old_pdiv, old_kdiv;
 598
 599        old_mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
 600        old_pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
 601        old_kdiv = (pll_con1 >> PLL46XX_KDIV_SHIFT) & PLL46XX_KDIV_MASK;
 602
 603        return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv
 604                || old_kdiv != rate->kdiv);
 605}
 606
 607static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate,
 608                                        unsigned long prate)
 609{
 610        struct samsung_clk_pll *pll = to_clk_pll(hw);
 611        const struct samsung_pll_rate_table *rate;
 612        u32 con0, con1, lock;
 613
 614        /* Get required rate settings from table */
 615        rate = samsung_get_pll_settings(pll, drate);
 616        if (!rate) {
 617                pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
 618                        drate, clk_hw_get_name(hw));
 619                return -EINVAL;
 620        }
 621
 622        con0 = readl_relaxed(pll->con_reg);
 623        con1 = readl_relaxed(pll->con_reg + 0x4);
 624
 625        if (!(samsung_pll46xx_mpk_change(con0, con1, rate))) {
 626                /* If only s change, change just s value only*/
 627                con0 &= ~(PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
 628                con0 |= rate->sdiv << PLL46XX_SDIV_SHIFT;
 629                writel_relaxed(con0, pll->con_reg);
 630
 631                return 0;
 632        }
 633
 634        /* Set PLL lock time. */
 635        lock = rate->pdiv * PLL46XX_LOCK_FACTOR;
 636        if (lock > 0xffff)
 637                /* Maximum lock time bitfield is 16-bit. */
 638                lock = 0xffff;
 639
 640        /* Set PLL PMS and VSEL values. */
 641        if (pll->type == pll_1460x) {
 642                con0 &= ~((PLL1460X_MDIV_MASK << PLL46XX_MDIV_SHIFT) |
 643                        (PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) |
 644                        (PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT));
 645        } else {
 646                con0 &= ~((PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT) |
 647                        (PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) |
 648                        (PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT) |
 649                        (PLL46XX_VSEL_MASK << PLL46XX_VSEL_SHIFT));
 650                con0 |= rate->vsel << PLL46XX_VSEL_SHIFT;
 651        }
 652
 653        con0 |= (rate->mdiv << PLL46XX_MDIV_SHIFT) |
 654                        (rate->pdiv << PLL46XX_PDIV_SHIFT) |
 655                        (rate->sdiv << PLL46XX_SDIV_SHIFT);
 656
 657        /* Set PLL K, MFR and MRR values. */
 658        con1 = readl_relaxed(pll->con_reg + 0x4);
 659        con1 &= ~((PLL46XX_KDIV_MASK << PLL46XX_KDIV_SHIFT) |
 660                        (PLL46XX_MFR_MASK << PLL46XX_MFR_SHIFT) |
 661                        (PLL46XX_MRR_MASK << PLL46XX_MRR_SHIFT));
 662        con1 |= (rate->kdiv << PLL46XX_KDIV_SHIFT) |
 663                        (rate->mfr << PLL46XX_MFR_SHIFT) |
 664                        (rate->mrr << PLL46XX_MRR_SHIFT);
 665
 666        /* Write configuration to PLL */
 667        writel_relaxed(lock, pll->lock_reg);
 668        writel_relaxed(con0, pll->con_reg);
 669        writel_relaxed(con1, pll->con_reg + 0x4);
 670
 671        /* Wait for PLL lock */
 672        return samsung_pll_lock_wait(pll, PLL46XX_LOCKED);
 673}
 674
 675static const struct clk_ops samsung_pll46xx_clk_ops = {
 676        .recalc_rate = samsung_pll46xx_recalc_rate,
 677        .round_rate = samsung_pll_round_rate,
 678        .set_rate = samsung_pll46xx_set_rate,
 679};
 680
 681static const struct clk_ops samsung_pll46xx_clk_min_ops = {
 682        .recalc_rate = samsung_pll46xx_recalc_rate,
 683};
 684
 685/*
 686 * PLL6552 Clock Type
 687 */
 688
 689#define PLL6552_MDIV_MASK       0x3ff
 690#define PLL6552_PDIV_MASK       0x3f
 691#define PLL6552_SDIV_MASK       0x7
 692#define PLL6552_MDIV_SHIFT      16
 693#define PLL6552_MDIV_SHIFT_2416 14
 694#define PLL6552_PDIV_SHIFT      8
 695#define PLL6552_PDIV_SHIFT_2416 5
 696#define PLL6552_SDIV_SHIFT      0
 697
 698static unsigned long samsung_pll6552_recalc_rate(struct clk_hw *hw,
 699                                                unsigned long parent_rate)
 700{
 701        struct samsung_clk_pll *pll = to_clk_pll(hw);
 702        u32 mdiv, pdiv, sdiv, pll_con;
 703        u64 fvco = parent_rate;
 704
 705        pll_con = readl_relaxed(pll->con_reg);
 706        if (pll->type == pll_6552_s3c2416) {
 707                mdiv = (pll_con >> PLL6552_MDIV_SHIFT_2416) & PLL6552_MDIV_MASK;
 708                pdiv = (pll_con >> PLL6552_PDIV_SHIFT_2416) & PLL6552_PDIV_MASK;
 709        } else {
 710                mdiv = (pll_con >> PLL6552_MDIV_SHIFT) & PLL6552_MDIV_MASK;
 711                pdiv = (pll_con >> PLL6552_PDIV_SHIFT) & PLL6552_PDIV_MASK;
 712        }
 713        sdiv = (pll_con >> PLL6552_SDIV_SHIFT) & PLL6552_SDIV_MASK;
 714
 715        fvco *= mdiv;
 716        do_div(fvco, (pdiv << sdiv));
 717
 718        return (unsigned long)fvco;
 719}
 720
 721static const struct clk_ops samsung_pll6552_clk_ops = {
 722        .recalc_rate = samsung_pll6552_recalc_rate,
 723};
 724
 725/*
 726 * PLL6553 Clock Type
 727 */
 728
 729#define PLL6553_MDIV_MASK       0xff
 730#define PLL6553_PDIV_MASK       0x3f
 731#define PLL6553_SDIV_MASK       0x7
 732#define PLL6553_KDIV_MASK       0xffff
 733#define PLL6553_MDIV_SHIFT      16
 734#define PLL6553_PDIV_SHIFT      8
 735#define PLL6553_SDIV_SHIFT      0
 736#define PLL6553_KDIV_SHIFT      0
 737
 738static unsigned long samsung_pll6553_recalc_rate(struct clk_hw *hw,
 739                                                unsigned long parent_rate)
 740{
 741        struct samsung_clk_pll *pll = to_clk_pll(hw);
 742        u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1;
 743        u64 fvco = parent_rate;
 744
 745        pll_con0 = readl_relaxed(pll->con_reg);
 746        pll_con1 = readl_relaxed(pll->con_reg + 0x4);
 747        mdiv = (pll_con0 >> PLL6553_MDIV_SHIFT) & PLL6553_MDIV_MASK;
 748        pdiv = (pll_con0 >> PLL6553_PDIV_SHIFT) & PLL6553_PDIV_MASK;
 749        sdiv = (pll_con0 >> PLL6553_SDIV_SHIFT) & PLL6553_SDIV_MASK;
 750        kdiv = (pll_con1 >> PLL6553_KDIV_SHIFT) & PLL6553_KDIV_MASK;
 751
 752        fvco *= (mdiv << 16) + kdiv;
 753        do_div(fvco, (pdiv << sdiv));
 754        fvco >>= 16;
 755
 756        return (unsigned long)fvco;
 757}
 758
 759static const struct clk_ops samsung_pll6553_clk_ops = {
 760        .recalc_rate = samsung_pll6553_recalc_rate,
 761};
 762
 763/*
 764 * PLL Clock Type of S3C24XX before S3C2443
 765 */
 766
 767#define PLLS3C2410_MDIV_MASK            (0xff)
 768#define PLLS3C2410_PDIV_MASK            (0x1f)
 769#define PLLS3C2410_SDIV_MASK            (0x3)
 770#define PLLS3C2410_MDIV_SHIFT           (12)
 771#define PLLS3C2410_PDIV_SHIFT           (4)
 772#define PLLS3C2410_SDIV_SHIFT           (0)
 773
 774#define PLLS3C2410_ENABLE_REG_OFFSET    0x10
 775
 776static unsigned long samsung_s3c2410_pll_recalc_rate(struct clk_hw *hw,
 777                                        unsigned long parent_rate)
 778{
 779        struct samsung_clk_pll *pll = to_clk_pll(hw);
 780        u32 pll_con, mdiv, pdiv, sdiv;
 781        u64 fvco = parent_rate;
 782
 783        pll_con = readl_relaxed(pll->con_reg);
 784        mdiv = (pll_con >> PLLS3C2410_MDIV_SHIFT) & PLLS3C2410_MDIV_MASK;
 785        pdiv = (pll_con >> PLLS3C2410_PDIV_SHIFT) & PLLS3C2410_PDIV_MASK;
 786        sdiv = (pll_con >> PLLS3C2410_SDIV_SHIFT) & PLLS3C2410_SDIV_MASK;
 787
 788        fvco *= (mdiv + 8);
 789        do_div(fvco, (pdiv + 2) << sdiv);
 790
 791        return (unsigned int)fvco;
 792}
 793
 794static unsigned long samsung_s3c2440_mpll_recalc_rate(struct clk_hw *hw,
 795                                        unsigned long parent_rate)
 796{
 797        struct samsung_clk_pll *pll = to_clk_pll(hw);
 798        u32 pll_con, mdiv, pdiv, sdiv;
 799        u64 fvco = parent_rate;
 800
 801        pll_con = readl_relaxed(pll->con_reg);
 802        mdiv = (pll_con >> PLLS3C2410_MDIV_SHIFT) & PLLS3C2410_MDIV_MASK;
 803        pdiv = (pll_con >> PLLS3C2410_PDIV_SHIFT) & PLLS3C2410_PDIV_MASK;
 804        sdiv = (pll_con >> PLLS3C2410_SDIV_SHIFT) & PLLS3C2410_SDIV_MASK;
 805
 806        fvco *= (2 * (mdiv + 8));
 807        do_div(fvco, (pdiv + 2) << sdiv);
 808
 809        return (unsigned int)fvco;
 810}
 811
 812static int samsung_s3c2410_pll_set_rate(struct clk_hw *hw, unsigned long drate,
 813                                        unsigned long prate)
 814{
 815        struct samsung_clk_pll *pll = to_clk_pll(hw);
 816        const struct samsung_pll_rate_table *rate;
 817        u32 tmp;
 818
 819        /* Get required rate settings from table */
 820        rate = samsung_get_pll_settings(pll, drate);
 821        if (!rate) {
 822                pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
 823                        drate, clk_hw_get_name(hw));
 824                return -EINVAL;
 825        }
 826
 827        tmp = readl_relaxed(pll->con_reg);
 828
 829        /* Change PLL PMS values */
 830        tmp &= ~((PLLS3C2410_MDIV_MASK << PLLS3C2410_MDIV_SHIFT) |
 831                        (PLLS3C2410_PDIV_MASK << PLLS3C2410_PDIV_SHIFT) |
 832                        (PLLS3C2410_SDIV_MASK << PLLS3C2410_SDIV_SHIFT));
 833        tmp |= (rate->mdiv << PLLS3C2410_MDIV_SHIFT) |
 834                        (rate->pdiv << PLLS3C2410_PDIV_SHIFT) |
 835                        (rate->sdiv << PLLS3C2410_SDIV_SHIFT);
 836        writel_relaxed(tmp, pll->con_reg);
 837
 838        /* Time to settle according to the manual */
 839        udelay(300);
 840
 841        return 0;
 842}
 843
 844static int samsung_s3c2410_pll_enable(struct clk_hw *hw, int bit, bool enable)
 845{
 846        struct samsung_clk_pll *pll = to_clk_pll(hw);
 847        u32 pll_en = readl_relaxed(pll->lock_reg + PLLS3C2410_ENABLE_REG_OFFSET);
 848        u32 pll_en_orig = pll_en;
 849
 850        if (enable)
 851                pll_en &= ~BIT(bit);
 852        else
 853                pll_en |= BIT(bit);
 854
 855        writel_relaxed(pll_en, pll->lock_reg + PLLS3C2410_ENABLE_REG_OFFSET);
 856
 857        /* if we started the UPLL, then allow to settle */
 858        if (enable && (pll_en_orig & BIT(bit)))
 859                udelay(300);
 860
 861        return 0;
 862}
 863
 864static int samsung_s3c2410_mpll_enable(struct clk_hw *hw)
 865{
 866        return samsung_s3c2410_pll_enable(hw, 5, true);
 867}
 868
 869static void samsung_s3c2410_mpll_disable(struct clk_hw *hw)
 870{
 871        samsung_s3c2410_pll_enable(hw, 5, false);
 872}
 873
 874static int samsung_s3c2410_upll_enable(struct clk_hw *hw)
 875{
 876        return samsung_s3c2410_pll_enable(hw, 7, true);
 877}
 878
 879static void samsung_s3c2410_upll_disable(struct clk_hw *hw)
 880{
 881        samsung_s3c2410_pll_enable(hw, 7, false);
 882}
 883
 884static const struct clk_ops samsung_s3c2410_mpll_clk_min_ops = {
 885        .recalc_rate = samsung_s3c2410_pll_recalc_rate,
 886        .enable = samsung_s3c2410_mpll_enable,
 887        .disable = samsung_s3c2410_mpll_disable,
 888};
 889
 890static const struct clk_ops samsung_s3c2410_upll_clk_min_ops = {
 891        .recalc_rate = samsung_s3c2410_pll_recalc_rate,
 892        .enable = samsung_s3c2410_upll_enable,
 893        .disable = samsung_s3c2410_upll_disable,
 894};
 895
 896static const struct clk_ops samsung_s3c2440_mpll_clk_min_ops = {
 897        .recalc_rate = samsung_s3c2440_mpll_recalc_rate,
 898        .enable = samsung_s3c2410_mpll_enable,
 899        .disable = samsung_s3c2410_mpll_disable,
 900};
 901
 902static const struct clk_ops samsung_s3c2410_mpll_clk_ops = {
 903        .recalc_rate = samsung_s3c2410_pll_recalc_rate,
 904        .enable = samsung_s3c2410_mpll_enable,
 905        .disable = samsung_s3c2410_mpll_disable,
 906        .round_rate = samsung_pll_round_rate,
 907        .set_rate = samsung_s3c2410_pll_set_rate,
 908};
 909
 910static const struct clk_ops samsung_s3c2410_upll_clk_ops = {
 911        .recalc_rate = samsung_s3c2410_pll_recalc_rate,
 912        .enable = samsung_s3c2410_upll_enable,
 913        .disable = samsung_s3c2410_upll_disable,
 914        .round_rate = samsung_pll_round_rate,
 915        .set_rate = samsung_s3c2410_pll_set_rate,
 916};
 917
 918static const struct clk_ops samsung_s3c2440_mpll_clk_ops = {
 919        .recalc_rate = samsung_s3c2440_mpll_recalc_rate,
 920        .enable = samsung_s3c2410_mpll_enable,
 921        .disable = samsung_s3c2410_mpll_disable,
 922        .round_rate = samsung_pll_round_rate,
 923        .set_rate = samsung_s3c2410_pll_set_rate,
 924};
 925
 926/*
 927 * PLL2550x Clock Type
 928 */
 929
 930#define PLL2550X_R_MASK       (0x1)
 931#define PLL2550X_P_MASK       (0x3F)
 932#define PLL2550X_M_MASK       (0x3FF)
 933#define PLL2550X_S_MASK       (0x7)
 934#define PLL2550X_R_SHIFT      (20)
 935#define PLL2550X_P_SHIFT      (14)
 936#define PLL2550X_M_SHIFT      (4)
 937#define PLL2550X_S_SHIFT      (0)
 938
 939static unsigned long samsung_pll2550x_recalc_rate(struct clk_hw *hw,
 940                                unsigned long parent_rate)
 941{
 942        struct samsung_clk_pll *pll = to_clk_pll(hw);
 943        u32 r, p, m, s, pll_stat;
 944        u64 fvco = parent_rate;
 945
 946        pll_stat = readl_relaxed(pll->con_reg);
 947        r = (pll_stat >> PLL2550X_R_SHIFT) & PLL2550X_R_MASK;
 948        if (!r)
 949                return 0;
 950        p = (pll_stat >> PLL2550X_P_SHIFT) & PLL2550X_P_MASK;
 951        m = (pll_stat >> PLL2550X_M_SHIFT) & PLL2550X_M_MASK;
 952        s = (pll_stat >> PLL2550X_S_SHIFT) & PLL2550X_S_MASK;
 953
 954        fvco *= m;
 955        do_div(fvco, (p << s));
 956
 957        return (unsigned long)fvco;
 958}
 959
 960static const struct clk_ops samsung_pll2550x_clk_ops = {
 961        .recalc_rate = samsung_pll2550x_recalc_rate,
 962};
 963
 964/*
 965 * PLL2550xx Clock Type
 966 */
 967
 968/* Maximum lock time can be 270 * PDIV cycles */
 969#define PLL2550XX_LOCK_FACTOR 270
 970
 971#define PLL2550XX_M_MASK                0x3FF
 972#define PLL2550XX_P_MASK                0x3F
 973#define PLL2550XX_S_MASK                0x7
 974#define PLL2550XX_LOCK_STAT_MASK        0x1
 975#define PLL2550XX_M_SHIFT               9
 976#define PLL2550XX_P_SHIFT               3
 977#define PLL2550XX_S_SHIFT               0
 978#define PLL2550XX_LOCK_STAT_SHIFT       21
 979
 980static unsigned long samsung_pll2550xx_recalc_rate(struct clk_hw *hw,
 981                                unsigned long parent_rate)
 982{
 983        struct samsung_clk_pll *pll = to_clk_pll(hw);
 984        u32 mdiv, pdiv, sdiv, pll_con;
 985        u64 fvco = parent_rate;
 986
 987        pll_con = readl_relaxed(pll->con_reg);
 988        mdiv = (pll_con >> PLL2550XX_M_SHIFT) & PLL2550XX_M_MASK;
 989        pdiv = (pll_con >> PLL2550XX_P_SHIFT) & PLL2550XX_P_MASK;
 990        sdiv = (pll_con >> PLL2550XX_S_SHIFT) & PLL2550XX_S_MASK;
 991
 992        fvco *= mdiv;
 993        do_div(fvco, (pdiv << sdiv));
 994
 995        return (unsigned long)fvco;
 996}
 997
 998static inline bool samsung_pll2550xx_mp_change(u32 mdiv, u32 pdiv, u32 pll_con)
 999{
1000        u32 old_mdiv, old_pdiv;
1001
1002        old_mdiv = (pll_con >> PLL2550XX_M_SHIFT) & PLL2550XX_M_MASK;
1003        old_pdiv = (pll_con >> PLL2550XX_P_SHIFT) & PLL2550XX_P_MASK;
1004
1005        return mdiv != old_mdiv || pdiv != old_pdiv;
1006}
1007
1008static int samsung_pll2550xx_set_rate(struct clk_hw *hw, unsigned long drate,
1009                                        unsigned long prate)
1010{
1011        struct samsung_clk_pll *pll = to_clk_pll(hw);
1012        const struct samsung_pll_rate_table *rate;
1013        u32 tmp;
1014
1015        /* Get required rate settings from table */
1016        rate = samsung_get_pll_settings(pll, drate);
1017        if (!rate) {
1018                pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
1019                        drate, clk_hw_get_name(hw));
1020                return -EINVAL;
1021        }
1022
1023        tmp = readl_relaxed(pll->con_reg);
1024
1025        if (!(samsung_pll2550xx_mp_change(rate->mdiv, rate->pdiv, tmp))) {
1026                /* If only s change, change just s value only*/
1027                tmp &= ~(PLL2550XX_S_MASK << PLL2550XX_S_SHIFT);
1028                tmp |= rate->sdiv << PLL2550XX_S_SHIFT;
1029                writel_relaxed(tmp, pll->con_reg);
1030
1031                return 0;
1032        }
1033
1034        /* Set PLL lock time. */
1035        writel_relaxed(rate->pdiv * PLL2550XX_LOCK_FACTOR, pll->lock_reg);
1036
1037        /* Change PLL PMS values */
1038        tmp &= ~((PLL2550XX_M_MASK << PLL2550XX_M_SHIFT) |
1039                        (PLL2550XX_P_MASK << PLL2550XX_P_SHIFT) |
1040                        (PLL2550XX_S_MASK << PLL2550XX_S_SHIFT));
1041        tmp |= (rate->mdiv << PLL2550XX_M_SHIFT) |
1042                        (rate->pdiv << PLL2550XX_P_SHIFT) |
1043                        (rate->sdiv << PLL2550XX_S_SHIFT);
1044        writel_relaxed(tmp, pll->con_reg);
1045
1046        /* Wait for PLL lock */
1047        return samsung_pll_lock_wait(pll,
1048                        PLL2550XX_LOCK_STAT_MASK << PLL2550XX_LOCK_STAT_SHIFT);
1049}
1050
1051static const struct clk_ops samsung_pll2550xx_clk_ops = {
1052        .recalc_rate = samsung_pll2550xx_recalc_rate,
1053        .round_rate = samsung_pll_round_rate,
1054        .set_rate = samsung_pll2550xx_set_rate,
1055};
1056
1057static const struct clk_ops samsung_pll2550xx_clk_min_ops = {
1058        .recalc_rate = samsung_pll2550xx_recalc_rate,
1059};
1060
1061/*
1062 * PLL2650x Clock Type
1063 */
1064
1065/* Maximum lock time can be 3000 * PDIV cycles */
1066#define PLL2650X_LOCK_FACTOR            3000
1067
1068#define PLL2650X_M_MASK                 0x1ff
1069#define PLL2650X_P_MASK                 0x3f
1070#define PLL2650X_S_MASK                 0x7
1071#define PLL2650X_K_MASK                 0xffff
1072#define PLL2650X_LOCK_STAT_MASK         0x1
1073#define PLL2650X_M_SHIFT                16
1074#define PLL2650X_P_SHIFT                8
1075#define PLL2650X_S_SHIFT                0
1076#define PLL2650X_K_SHIFT                0
1077#define PLL2650X_LOCK_STAT_SHIFT        29
1078#define PLL2650X_PLL_ENABLE_SHIFT       31
1079
1080static unsigned long samsung_pll2650x_recalc_rate(struct clk_hw *hw,
1081                                unsigned long parent_rate)
1082{
1083        struct samsung_clk_pll *pll = to_clk_pll(hw);
1084        u64 fout = parent_rate;
1085        u32 mdiv, pdiv, sdiv, pll_con0, pll_con1;
1086        s16 kdiv;
1087
1088        pll_con0 = readl_relaxed(pll->con_reg);
1089        mdiv = (pll_con0 >> PLL2650X_M_SHIFT) & PLL2650X_M_MASK;
1090        pdiv = (pll_con0 >> PLL2650X_P_SHIFT) & PLL2650X_P_MASK;
1091        sdiv = (pll_con0 >> PLL2650X_S_SHIFT) & PLL2650X_S_MASK;
1092
1093        pll_con1 = readl_relaxed(pll->con_reg + 4);
1094        kdiv = (s16)((pll_con1 >> PLL2650X_K_SHIFT) & PLL2650X_K_MASK);
1095
1096        fout *= (mdiv << 16) + kdiv;
1097        do_div(fout, (pdiv << sdiv));
1098        fout >>= 16;
1099
1100        return (unsigned long)fout;
1101}
1102
1103static int samsung_pll2650x_set_rate(struct clk_hw *hw, unsigned long drate,
1104                                        unsigned long prate)
1105{
1106        struct samsung_clk_pll *pll = to_clk_pll(hw);
1107        const struct samsung_pll_rate_table *rate;
1108        u32 con0, con1;
1109
1110        /* Get required rate settings from table */
1111        rate = samsung_get_pll_settings(pll, drate);
1112        if (!rate) {
1113                pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
1114                        drate, clk_hw_get_name(hw));
1115                return -EINVAL;
1116        }
1117
1118        con0 = readl_relaxed(pll->con_reg);
1119        con1 = readl_relaxed(pll->con_reg + 4);
1120
1121        /* Set PLL lock time. */
1122        writel_relaxed(rate->pdiv * PLL2650X_LOCK_FACTOR, pll->lock_reg);
1123
1124        /* Change PLL PMS values */
1125        con0 &= ~((PLL2650X_M_MASK << PLL2650X_M_SHIFT) |
1126                        (PLL2650X_P_MASK << PLL2650X_P_SHIFT) |
1127                        (PLL2650X_S_MASK << PLL2650X_S_SHIFT));
1128        con0 |= (rate->mdiv << PLL2650X_M_SHIFT) |
1129                        (rate->pdiv << PLL2650X_P_SHIFT) |
1130                        (rate->sdiv << PLL2650X_S_SHIFT);
1131        con0 |= (1 << PLL2650X_PLL_ENABLE_SHIFT);
1132        writel_relaxed(con0, pll->con_reg);
1133
1134        con1 &= ~(PLL2650X_K_MASK << PLL2650X_K_SHIFT);
1135        con1 |= ((rate->kdiv & PLL2650X_K_MASK) << PLL2650X_K_SHIFT);
1136        writel_relaxed(con1, pll->con_reg + 4);
1137
1138        /* Wait for PLL lock */
1139        return samsung_pll_lock_wait(pll,
1140                        PLL2650X_LOCK_STAT_MASK << PLL2650X_LOCK_STAT_SHIFT);
1141}
1142
1143static const struct clk_ops samsung_pll2650x_clk_ops = {
1144        .recalc_rate = samsung_pll2650x_recalc_rate,
1145        .round_rate = samsung_pll_round_rate,
1146        .set_rate = samsung_pll2650x_set_rate,
1147};
1148
1149static const struct clk_ops samsung_pll2650x_clk_min_ops = {
1150        .recalc_rate = samsung_pll2650x_recalc_rate,
1151};
1152
1153/*
1154 * PLL2650XX Clock Type
1155 */
1156
1157/* Maximum lock time can be 3000 * PDIV cycles */
1158#define PLL2650XX_LOCK_FACTOR 3000
1159
1160#define PLL2650XX_MDIV_SHIFT            9
1161#define PLL2650XX_PDIV_SHIFT            3
1162#define PLL2650XX_SDIV_SHIFT            0
1163#define PLL2650XX_KDIV_SHIFT            0
1164#define PLL2650XX_MDIV_MASK             0x1ff
1165#define PLL2650XX_PDIV_MASK             0x3f
1166#define PLL2650XX_SDIV_MASK             0x7
1167#define PLL2650XX_KDIV_MASK             0xffff
1168#define PLL2650XX_PLL_ENABLE_SHIFT      23
1169#define PLL2650XX_PLL_LOCKTIME_SHIFT    21
1170#define PLL2650XX_PLL_FOUTMASK_SHIFT    31
1171
1172static unsigned long samsung_pll2650xx_recalc_rate(struct clk_hw *hw,
1173                                unsigned long parent_rate)
1174{
1175        struct samsung_clk_pll *pll = to_clk_pll(hw);
1176        u32 mdiv, pdiv, sdiv, pll_con0, pll_con2;
1177        s16 kdiv;
1178        u64 fvco = parent_rate;
1179
1180        pll_con0 = readl_relaxed(pll->con_reg);
1181        pll_con2 = readl_relaxed(pll->con_reg + 8);
1182        mdiv = (pll_con0 >> PLL2650XX_MDIV_SHIFT) & PLL2650XX_MDIV_MASK;
1183        pdiv = (pll_con0 >> PLL2650XX_PDIV_SHIFT) & PLL2650XX_PDIV_MASK;
1184        sdiv = (pll_con0 >> PLL2650XX_SDIV_SHIFT) & PLL2650XX_SDIV_MASK;
1185        kdiv = (s16)(pll_con2 & PLL2650XX_KDIV_MASK);
1186
1187        fvco *= (mdiv << 16) + kdiv;
1188        do_div(fvco, (pdiv << sdiv));
1189        fvco >>= 16;
1190
1191        return (unsigned long)fvco;
1192}
1193
1194static int samsung_pll2650xx_set_rate(struct clk_hw *hw, unsigned long drate,
1195                                        unsigned long parent_rate)
1196{
1197        struct samsung_clk_pll *pll = to_clk_pll(hw);
1198        u32 pll_con0, pll_con2;
1199        const struct samsung_pll_rate_table *rate;
1200
1201        rate = samsung_get_pll_settings(pll, drate);
1202        if (!rate) {
1203                pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
1204                        drate, clk_hw_get_name(hw));
1205                return -EINVAL;
1206        }
1207
1208        pll_con0 = readl_relaxed(pll->con_reg);
1209        pll_con2 = readl_relaxed(pll->con_reg + 8);
1210
1211         /* Change PLL PMS values */
1212        pll_con0 &= ~(PLL2650XX_MDIV_MASK << PLL2650XX_MDIV_SHIFT |
1213                        PLL2650XX_PDIV_MASK << PLL2650XX_PDIV_SHIFT |
1214                        PLL2650XX_SDIV_MASK << PLL2650XX_SDIV_SHIFT);
1215        pll_con0 |= rate->mdiv << PLL2650XX_MDIV_SHIFT;
1216        pll_con0 |= rate->pdiv << PLL2650XX_PDIV_SHIFT;
1217        pll_con0 |= rate->sdiv << PLL2650XX_SDIV_SHIFT;
1218        pll_con0 |= 1 << PLL2650XX_PLL_ENABLE_SHIFT;
1219        pll_con0 |= 1 << PLL2650XX_PLL_FOUTMASK_SHIFT;
1220
1221        pll_con2 &= ~(PLL2650XX_KDIV_MASK << PLL2650XX_KDIV_SHIFT);
1222        pll_con2 |= ((~(rate->kdiv) + 1) & PLL2650XX_KDIV_MASK)
1223                        << PLL2650XX_KDIV_SHIFT;
1224
1225        /* Set PLL lock time. */
1226        writel_relaxed(PLL2650XX_LOCK_FACTOR * rate->pdiv, pll->lock_reg);
1227
1228        writel_relaxed(pll_con0, pll->con_reg);
1229        writel_relaxed(pll_con2, pll->con_reg + 8);
1230
1231        return samsung_pll_lock_wait(pll, 0x1 << PLL2650XX_PLL_LOCKTIME_SHIFT);
1232}
1233
1234static const struct clk_ops samsung_pll2650xx_clk_ops = {
1235        .recalc_rate = samsung_pll2650xx_recalc_rate,
1236        .set_rate = samsung_pll2650xx_set_rate,
1237        .round_rate = samsung_pll_round_rate,
1238};
1239
1240static const struct clk_ops samsung_pll2650xx_clk_min_ops = {
1241        .recalc_rate = samsung_pll2650xx_recalc_rate,
1242};
1243
1244static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
1245                                const struct samsung_pll_clock *pll_clk,
1246                                void __iomem *base)
1247{
1248        struct samsung_clk_pll *pll;
1249        struct clk_init_data init;
1250        int ret, len;
1251
1252        pll = kzalloc(sizeof(*pll), GFP_KERNEL);
1253        if (!pll) {
1254                pr_err("%s: could not allocate pll clk %s\n",
1255                        __func__, pll_clk->name);
1256                return;
1257        }
1258
1259        init.name = pll_clk->name;
1260        init.flags = pll_clk->flags;
1261        init.parent_names = &pll_clk->parent_name;
1262        init.num_parents = 1;
1263
1264        if (pll_clk->rate_table) {
1265                /* find count of rates in rate_table */
1266                for (len = 0; pll_clk->rate_table[len].rate != 0; )
1267                        len++;
1268
1269                pll->rate_count = len;
1270                pll->rate_table = kmemdup(pll_clk->rate_table,
1271                                        pll->rate_count *
1272                                        sizeof(struct samsung_pll_rate_table),
1273                                        GFP_KERNEL);
1274                WARN(!pll->rate_table,
1275                        "%s: could not allocate rate table for %s\n",
1276                        __func__, pll_clk->name);
1277        }
1278
1279        switch (pll_clk->type) {
1280        case pll_2126:
1281                init.ops = &samsung_pll2126_clk_ops;
1282                break;
1283        case pll_3000:
1284                init.ops = &samsung_pll3000_clk_ops;
1285                break;
1286        /* clk_ops for 35xx and 2550 are similar */
1287        case pll_35xx:
1288        case pll_2550:
1289        case pll_1450x:
1290        case pll_1451x:
1291        case pll_1452x:
1292                pll->enable_offs = PLL35XX_ENABLE_SHIFT;
1293                pll->lock_offs = PLL35XX_LOCK_STAT_SHIFT;
1294                if (!pll->rate_table)
1295                        init.ops = &samsung_pll35xx_clk_min_ops;
1296                else
1297                        init.ops = &samsung_pll35xx_clk_ops;
1298                break;
1299        case pll_4500:
1300                init.ops = &samsung_pll45xx_clk_min_ops;
1301                break;
1302        case pll_4502:
1303        case pll_4508:
1304                if (!pll->rate_table)
1305                        init.ops = &samsung_pll45xx_clk_min_ops;
1306                else
1307                        init.ops = &samsung_pll45xx_clk_ops;
1308                break;
1309        /* clk_ops for 36xx and 2650 are similar */
1310        case pll_36xx:
1311        case pll_2650:
1312                pll->enable_offs = PLL36XX_ENABLE_SHIFT;
1313                pll->lock_offs = PLL36XX_LOCK_STAT_SHIFT;
1314                if (!pll->rate_table)
1315                        init.ops = &samsung_pll36xx_clk_min_ops;
1316                else
1317                        init.ops = &samsung_pll36xx_clk_ops;
1318                break;
1319        case pll_6552:
1320        case pll_6552_s3c2416:
1321                init.ops = &samsung_pll6552_clk_ops;
1322                break;
1323        case pll_6553:
1324                init.ops = &samsung_pll6553_clk_ops;
1325                break;
1326        case pll_4600:
1327        case pll_4650:
1328        case pll_4650c:
1329        case pll_1460x:
1330                if (!pll->rate_table)
1331                        init.ops = &samsung_pll46xx_clk_min_ops;
1332                else
1333                        init.ops = &samsung_pll46xx_clk_ops;
1334                break;
1335        case pll_s3c2410_mpll:
1336                if (!pll->rate_table)
1337                        init.ops = &samsung_s3c2410_mpll_clk_min_ops;
1338                else
1339                        init.ops = &samsung_s3c2410_mpll_clk_ops;
1340                break;
1341        case pll_s3c2410_upll:
1342                if (!pll->rate_table)
1343                        init.ops = &samsung_s3c2410_upll_clk_min_ops;
1344                else
1345                        init.ops = &samsung_s3c2410_upll_clk_ops;
1346                break;
1347        case pll_s3c2440_mpll:
1348                if (!pll->rate_table)
1349                        init.ops = &samsung_s3c2440_mpll_clk_min_ops;
1350                else
1351                        init.ops = &samsung_s3c2440_mpll_clk_ops;
1352                break;
1353        case pll_2550x:
1354                init.ops = &samsung_pll2550x_clk_ops;
1355                break;
1356        case pll_2550xx:
1357                if (!pll->rate_table)
1358                        init.ops = &samsung_pll2550xx_clk_min_ops;
1359                else
1360                        init.ops = &samsung_pll2550xx_clk_ops;
1361                break;
1362        case pll_2650x:
1363                if (!pll->rate_table)
1364                        init.ops = &samsung_pll2650x_clk_min_ops;
1365                else
1366                        init.ops = &samsung_pll2650x_clk_ops;
1367                break;
1368        case pll_2650xx:
1369                if (!pll->rate_table)
1370                        init.ops = &samsung_pll2650xx_clk_min_ops;
1371                else
1372                        init.ops = &samsung_pll2650xx_clk_ops;
1373                break;
1374        default:
1375                pr_warn("%s: Unknown pll type for pll clk %s\n",
1376                        __func__, pll_clk->name);
1377        }
1378
1379        pll->hw.init = &init;
1380        pll->type = pll_clk->type;
1381        pll->lock_reg = base + pll_clk->lock_offset;
1382        pll->con_reg = base + pll_clk->con_offset;
1383
1384        ret = clk_hw_register(ctx->dev, &pll->hw);
1385        if (ret) {
1386                pr_err("%s: failed to register pll clock %s : %d\n",
1387                        __func__, pll_clk->name, ret);
1388                kfree(pll);
1389                return;
1390        }
1391
1392        samsung_clk_add_lookup(ctx, &pll->hw, pll_clk->id);
1393}
1394
1395void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx,
1396                        const struct samsung_pll_clock *pll_list,
1397                        unsigned int nr_pll, void __iomem *base)
1398{
1399        int cnt;
1400
1401        for (cnt = 0; cnt < nr_pll; cnt++)
1402                _samsung_clk_register_pll(ctx, &pll_list[cnt], base);
1403}
1404