linux/drivers/clk/clk-versaclock5.c
<<
>>
Prefs
   1/*
   2 * Driver for IDT Versaclock 5
   3 *
   4 * Copyright (C) 2017 Marek Vasut <marek.vasut@gmail.com>
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2 of the License, or
   9 * (at your option) any later version.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 */
  16
  17/*
  18 * Possible optimizations:
  19 * - Use spread spectrum
  20 * - Use integer divider in FOD if applicable
  21 */
  22
  23#include <linux/clk.h>
  24#include <linux/clk-provider.h>
  25#include <linux/delay.h>
  26#include <linux/i2c.h>
  27#include <linux/interrupt.h>
  28#include <linux/mod_devicetable.h>
  29#include <linux/module.h>
  30#include <linux/of.h>
  31#include <linux/of_platform.h>
  32#include <linux/rational.h>
  33#include <linux/regmap.h>
  34#include <linux/slab.h>
  35
  36/* VersaClock5 registers */
  37#define VC5_OTP_CONTROL                         0x00
  38
  39/* Factory-reserved register block */
  40#define VC5_RSVD_DEVICE_ID                      0x01
  41#define VC5_RSVD_ADC_GAIN_7_0                   0x02
  42#define VC5_RSVD_ADC_GAIN_15_8                  0x03
  43#define VC5_RSVD_ADC_OFFSET_7_0                 0x04
  44#define VC5_RSVD_ADC_OFFSET_15_8                0x05
  45#define VC5_RSVD_TEMPY                          0x06
  46#define VC5_RSVD_OFFSET_TBIN                    0x07
  47#define VC5_RSVD_GAIN                           0x08
  48#define VC5_RSVD_TEST_NP                        0x09
  49#define VC5_RSVD_UNUSED                         0x0a
  50#define VC5_RSVD_BANDGAP_TRIM_UP                0x0b
  51#define VC5_RSVD_BANDGAP_TRIM_DN                0x0c
  52#define VC5_RSVD_CLK_R_12_CLK_AMP_4             0x0d
  53#define VC5_RSVD_CLK_R_34_CLK_AMP_4             0x0e
  54#define VC5_RSVD_CLK_AMP_123                    0x0f
  55
  56/* Configuration register block */
  57#define VC5_PRIM_SRC_SHDN                       0x10
  58#define VC5_PRIM_SRC_SHDN_EN_XTAL               BIT(7)
  59#define VC5_PRIM_SRC_SHDN_EN_CLKIN              BIT(6)
  60#define VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ   BIT(3)
  61#define VC5_PRIM_SRC_SHDN_SP                    BIT(1)
  62#define VC5_PRIM_SRC_SHDN_EN_GBL_SHDN           BIT(0)
  63
  64#define VC5_VCO_BAND                            0x11
  65#define VC5_XTAL_X1_LOAD_CAP                    0x12
  66#define VC5_XTAL_X2_LOAD_CAP                    0x13
  67#define VC5_REF_DIVIDER                         0x15
  68#define VC5_REF_DIVIDER_SEL_PREDIV2             BIT(7)
  69#define VC5_REF_DIVIDER_REF_DIV(n)              ((n) & 0x3f)
  70
  71#define VC5_VCO_CTRL_AND_PREDIV                 0x16
  72#define VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV   BIT(7)
  73
  74#define VC5_FEEDBACK_INT_DIV                    0x17
  75#define VC5_FEEDBACK_INT_DIV_BITS               0x18
  76#define VC5_FEEDBACK_FRAC_DIV(n)                (0x19 + (n))
  77#define VC5_RC_CONTROL0                         0x1e
  78#define VC5_RC_CONTROL1                         0x1f
  79/* Register 0x20 is factory reserved */
  80
  81/* Output divider control for divider 1,2,3,4 */
  82#define VC5_OUT_DIV_CONTROL(idx)        (0x21 + ((idx) * 0x10))
  83#define VC5_OUT_DIV_CONTROL_RESET       BIT(7)
  84#define VC5_OUT_DIV_CONTROL_SELB_NORM   BIT(3)
  85#define VC5_OUT_DIV_CONTROL_SEL_EXT     BIT(2)
  86#define VC5_OUT_DIV_CONTROL_INT_MODE    BIT(1)
  87#define VC5_OUT_DIV_CONTROL_EN_FOD      BIT(0)
  88
  89#define VC5_OUT_DIV_FRAC(idx, n)        (0x22 + ((idx) * 0x10) + (n))
  90#define VC5_OUT_DIV_FRAC4_OD_SCEE       BIT(1)
  91
  92#define VC5_OUT_DIV_STEP_SPREAD(idx, n) (0x26 + ((idx) * 0x10) + (n))
  93#define VC5_OUT_DIV_SPREAD_MOD(idx, n)  (0x29 + ((idx) * 0x10) + (n))
  94#define VC5_OUT_DIV_SKEW_INT(idx, n)    (0x2b + ((idx) * 0x10) + (n))
  95#define VC5_OUT_DIV_INT(idx, n)         (0x2d + ((idx) * 0x10) + (n))
  96#define VC5_OUT_DIV_SKEW_FRAC(idx)      (0x2f + ((idx) * 0x10))
  97/* Registers 0x30, 0x40, 0x50 are factory reserved */
  98
  99/* Clock control register for clock 1,2 */
 100#define VC5_CLK_OUTPUT_CFG(idx, n)      (0x60 + ((idx) * 0x2) + (n))
 101#define VC5_CLK_OUTPUT_CFG1_EN_CLKBUF   BIT(0)
 102
 103#define VC5_CLK_OE_SHDN                         0x68
 104#define VC5_CLK_OS_SHDN                         0x69
 105
 106#define VC5_GLOBAL_REGISTER                     0x76
 107#define VC5_GLOBAL_REGISTER_GLOBAL_RESET        BIT(5)
 108
 109/* PLL/VCO runs between 2.5 GHz and 3.0 GHz */
 110#define VC5_PLL_VCO_MIN                         2500000000UL
 111#define VC5_PLL_VCO_MAX                         3000000000UL
 112
 113/* VC5 Input mux settings */
 114#define VC5_MUX_IN_XIN          BIT(0)
 115#define VC5_MUX_IN_CLKIN        BIT(1)
 116
 117/* Maximum number of clk_out supported by this driver */
 118#define VC5_MAX_CLK_OUT_NUM     5
 119
 120/* Maximum number of FODs supported by this driver */
 121#define VC5_MAX_FOD_NUM 4
 122
 123/* flags to describe chip features */
 124/* chip has built-in oscilator */
 125#define VC5_HAS_INTERNAL_XTAL   BIT(0)
 126/* chip has PFD requency doubler */
 127#define VC5_HAS_PFD_FREQ_DBL    BIT(1)
 128
 129/* Supported IDT VC5 models. */
 130enum vc5_model {
 131        IDT_VC5_5P49V5923,
 132        IDT_VC5_5P49V5925,
 133        IDT_VC5_5P49V5933,
 134        IDT_VC5_5P49V5935,
 135        IDT_VC6_5P49V6901,
 136};
 137
 138/* Structure to describe features of a particular VC5 model */
 139struct vc5_chip_info {
 140        const enum vc5_model    model;
 141        const unsigned int      clk_fod_cnt;
 142        const unsigned int      clk_out_cnt;
 143        const u32               flags;
 144};
 145
 146struct vc5_driver_data;
 147
 148struct vc5_hw_data {
 149        struct clk_hw           hw;
 150        struct vc5_driver_data  *vc5;
 151        u32                     div_int;
 152        u32                     div_frc;
 153        unsigned int            num;
 154};
 155
 156struct vc5_driver_data {
 157        struct i2c_client       *client;
 158        struct regmap           *regmap;
 159        const struct vc5_chip_info      *chip_info;
 160
 161        struct clk              *pin_xin;
 162        struct clk              *pin_clkin;
 163        unsigned char           clk_mux_ins;
 164        struct clk_hw           clk_mux;
 165        struct clk_hw           clk_mul;
 166        struct clk_hw           clk_pfd;
 167        struct vc5_hw_data      clk_pll;
 168        struct vc5_hw_data      clk_fod[VC5_MAX_FOD_NUM];
 169        struct vc5_hw_data      clk_out[VC5_MAX_CLK_OUT_NUM];
 170};
 171
 172static const char * const vc5_mux_names[] = {
 173        "mux"
 174};
 175
 176static const char * const vc5_dbl_names[] = {
 177        "dbl"
 178};
 179
 180static const char * const vc5_pfd_names[] = {
 181        "pfd"
 182};
 183
 184static const char * const vc5_pll_names[] = {
 185        "pll"
 186};
 187
 188static const char * const vc5_fod_names[] = {
 189        "fod0", "fod1", "fod2", "fod3",
 190};
 191
 192static const char * const vc5_clk_out_names[] = {
 193        "out0_sel_i2cb", "out1", "out2", "out3", "out4",
 194};
 195
 196/*
 197 * VersaClock5 i2c regmap
 198 */
 199static bool vc5_regmap_is_writeable(struct device *dev, unsigned int reg)
 200{
 201        /* Factory reserved regs, make them read-only */
 202        if (reg <= 0xf)
 203                return false;
 204
 205        /* Factory reserved regs, make them read-only */
 206        if (reg == 0x14 || reg == 0x1c || reg == 0x1d)
 207                return false;
 208
 209        return true;
 210}
 211
 212static const struct regmap_config vc5_regmap_config = {
 213        .reg_bits = 8,
 214        .val_bits = 8,
 215        .cache_type = REGCACHE_RBTREE,
 216        .max_register = 0x76,
 217        .writeable_reg = vc5_regmap_is_writeable,
 218};
 219
 220/*
 221 * VersaClock5 input multiplexer between XTAL and CLKIN divider
 222 */
 223static unsigned char vc5_mux_get_parent(struct clk_hw *hw)
 224{
 225        struct vc5_driver_data *vc5 =
 226                container_of(hw, struct vc5_driver_data, clk_mux);
 227        const u8 mask = VC5_PRIM_SRC_SHDN_EN_XTAL | VC5_PRIM_SRC_SHDN_EN_CLKIN;
 228        unsigned int src;
 229
 230        regmap_read(vc5->regmap, VC5_PRIM_SRC_SHDN, &src);
 231        src &= mask;
 232
 233        if (src == VC5_PRIM_SRC_SHDN_EN_XTAL)
 234                return 0;
 235
 236        if (src == VC5_PRIM_SRC_SHDN_EN_CLKIN)
 237                return 1;
 238
 239        dev_warn(&vc5->client->dev,
 240                 "Invalid clock input configuration (%02x)\n", src);
 241        return 0;
 242}
 243
 244static int vc5_mux_set_parent(struct clk_hw *hw, u8 index)
 245{
 246        struct vc5_driver_data *vc5 =
 247                container_of(hw, struct vc5_driver_data, clk_mux);
 248        const u8 mask = VC5_PRIM_SRC_SHDN_EN_XTAL | VC5_PRIM_SRC_SHDN_EN_CLKIN;
 249        u8 src;
 250
 251        if ((index > 1) || !vc5->clk_mux_ins)
 252                return -EINVAL;
 253
 254        if (vc5->clk_mux_ins == (VC5_MUX_IN_CLKIN | VC5_MUX_IN_XIN)) {
 255                if (index == 0)
 256                        src = VC5_PRIM_SRC_SHDN_EN_XTAL;
 257                if (index == 1)
 258                        src = VC5_PRIM_SRC_SHDN_EN_CLKIN;
 259        } else {
 260                if (index != 0)
 261                        return -EINVAL;
 262
 263                if (vc5->clk_mux_ins == VC5_MUX_IN_XIN)
 264                        src = VC5_PRIM_SRC_SHDN_EN_XTAL;
 265                if (vc5->clk_mux_ins == VC5_MUX_IN_CLKIN)
 266                        src = VC5_PRIM_SRC_SHDN_EN_CLKIN;
 267        }
 268
 269        return regmap_update_bits(vc5->regmap, VC5_PRIM_SRC_SHDN, mask, src);
 270}
 271
 272static const struct clk_ops vc5_mux_ops = {
 273        .set_parent     = vc5_mux_set_parent,
 274        .get_parent     = vc5_mux_get_parent,
 275};
 276
 277static unsigned long vc5_dbl_recalc_rate(struct clk_hw *hw,
 278                                         unsigned long parent_rate)
 279{
 280        struct vc5_driver_data *vc5 =
 281                container_of(hw, struct vc5_driver_data, clk_mul);
 282        unsigned int premul;
 283
 284        regmap_read(vc5->regmap, VC5_PRIM_SRC_SHDN, &premul);
 285        if (premul & VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ)
 286                parent_rate *= 2;
 287
 288        return parent_rate;
 289}
 290
 291static long vc5_dbl_round_rate(struct clk_hw *hw, unsigned long rate,
 292                               unsigned long *parent_rate)
 293{
 294        if ((*parent_rate == rate) || ((*parent_rate * 2) == rate))
 295                return rate;
 296        else
 297                return -EINVAL;
 298}
 299
 300static int vc5_dbl_set_rate(struct clk_hw *hw, unsigned long rate,
 301                            unsigned long parent_rate)
 302{
 303        struct vc5_driver_data *vc5 =
 304                container_of(hw, struct vc5_driver_data, clk_mul);
 305        u32 mask;
 306
 307        if ((parent_rate * 2) == rate)
 308                mask = VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ;
 309        else
 310                mask = 0;
 311
 312        regmap_update_bits(vc5->regmap, VC5_PRIM_SRC_SHDN,
 313                           VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ,
 314                           mask);
 315
 316        return 0;
 317}
 318
 319static const struct clk_ops vc5_dbl_ops = {
 320        .recalc_rate    = vc5_dbl_recalc_rate,
 321        .round_rate     = vc5_dbl_round_rate,
 322        .set_rate       = vc5_dbl_set_rate,
 323};
 324
 325static unsigned long vc5_pfd_recalc_rate(struct clk_hw *hw,
 326                                         unsigned long parent_rate)
 327{
 328        struct vc5_driver_data *vc5 =
 329                container_of(hw, struct vc5_driver_data, clk_pfd);
 330        unsigned int prediv, div;
 331
 332        regmap_read(vc5->regmap, VC5_VCO_CTRL_AND_PREDIV, &prediv);
 333
 334        /* The bypass_prediv is set, PLL fed from Ref_in directly. */
 335        if (prediv & VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV)
 336                return parent_rate;
 337
 338        regmap_read(vc5->regmap, VC5_REF_DIVIDER, &div);
 339
 340        /* The Sel_prediv2 is set, PLL fed from prediv2 (Ref_in / 2) */
 341        if (div & VC5_REF_DIVIDER_SEL_PREDIV2)
 342                return parent_rate / 2;
 343        else
 344                return parent_rate / VC5_REF_DIVIDER_REF_DIV(div);
 345}
 346
 347static long vc5_pfd_round_rate(struct clk_hw *hw, unsigned long rate,
 348                               unsigned long *parent_rate)
 349{
 350        unsigned long idiv;
 351
 352        /* PLL cannot operate with input clock above 50 MHz. */
 353        if (rate > 50000000)
 354                return -EINVAL;
 355
 356        /* CLKIN within range of PLL input, feed directly to PLL. */
 357        if (*parent_rate <= 50000000)
 358                return *parent_rate;
 359
 360        idiv = DIV_ROUND_UP(*parent_rate, rate);
 361        if (idiv > 127)
 362                return -EINVAL;
 363
 364        return *parent_rate / idiv;
 365}
 366
 367static int vc5_pfd_set_rate(struct clk_hw *hw, unsigned long rate,
 368                            unsigned long parent_rate)
 369{
 370        struct vc5_driver_data *vc5 =
 371                container_of(hw, struct vc5_driver_data, clk_pfd);
 372        unsigned long idiv;
 373        u8 div;
 374
 375        /* CLKIN within range of PLL input, feed directly to PLL. */
 376        if (parent_rate <= 50000000) {
 377                regmap_update_bits(vc5->regmap, VC5_VCO_CTRL_AND_PREDIV,
 378                                   VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV,
 379                                   VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV);
 380                regmap_update_bits(vc5->regmap, VC5_REF_DIVIDER, 0xff, 0x00);
 381                return 0;
 382        }
 383
 384        idiv = DIV_ROUND_UP(parent_rate, rate);
 385
 386        /* We have dedicated div-2 predivider. */
 387        if (idiv == 2)
 388                div = VC5_REF_DIVIDER_SEL_PREDIV2;
 389        else
 390                div = VC5_REF_DIVIDER_REF_DIV(idiv);
 391
 392        regmap_update_bits(vc5->regmap, VC5_REF_DIVIDER, 0xff, div);
 393        regmap_update_bits(vc5->regmap, VC5_VCO_CTRL_AND_PREDIV,
 394                           VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV, 0);
 395
 396        return 0;
 397}
 398
 399static const struct clk_ops vc5_pfd_ops = {
 400        .recalc_rate    = vc5_pfd_recalc_rate,
 401        .round_rate     = vc5_pfd_round_rate,
 402        .set_rate       = vc5_pfd_set_rate,
 403};
 404
 405/*
 406 * VersaClock5 PLL/VCO
 407 */
 408static unsigned long vc5_pll_recalc_rate(struct clk_hw *hw,
 409                                         unsigned long parent_rate)
 410{
 411        struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
 412        struct vc5_driver_data *vc5 = hwdata->vc5;
 413        u32 div_int, div_frc;
 414        u8 fb[5];
 415
 416        regmap_bulk_read(vc5->regmap, VC5_FEEDBACK_INT_DIV, fb, 5);
 417
 418        div_int = (fb[0] << 4) | (fb[1] >> 4);
 419        div_frc = (fb[2] << 16) | (fb[3] << 8) | fb[4];
 420
 421        /* The PLL divider has 12 integer bits and 24 fractional bits */
 422        return (parent_rate * div_int) + ((parent_rate * div_frc) >> 24);
 423}
 424
 425static long vc5_pll_round_rate(struct clk_hw *hw, unsigned long rate,
 426                               unsigned long *parent_rate)
 427{
 428        struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
 429        u32 div_int;
 430        u64 div_frc;
 431
 432        if (rate < VC5_PLL_VCO_MIN)
 433                rate = VC5_PLL_VCO_MIN;
 434        if (rate > VC5_PLL_VCO_MAX)
 435                rate = VC5_PLL_VCO_MAX;
 436
 437        /* Determine integer part, which is 12 bit wide */
 438        div_int = rate / *parent_rate;
 439        if (div_int > 0xfff)
 440                rate = *parent_rate * 0xfff;
 441
 442        /* Determine best fractional part, which is 24 bit wide */
 443        div_frc = rate % *parent_rate;
 444        div_frc *= BIT(24) - 1;
 445        do_div(div_frc, *parent_rate);
 446
 447        hwdata->div_int = div_int;
 448        hwdata->div_frc = (u32)div_frc;
 449
 450        return (*parent_rate * div_int) + ((*parent_rate * div_frc) >> 24);
 451}
 452
 453static int vc5_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 454                            unsigned long parent_rate)
 455{
 456        struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
 457        struct vc5_driver_data *vc5 = hwdata->vc5;
 458        u8 fb[5];
 459
 460        fb[0] = hwdata->div_int >> 4;
 461        fb[1] = hwdata->div_int << 4;
 462        fb[2] = hwdata->div_frc >> 16;
 463        fb[3] = hwdata->div_frc >> 8;
 464        fb[4] = hwdata->div_frc;
 465
 466        return regmap_bulk_write(vc5->regmap, VC5_FEEDBACK_INT_DIV, fb, 5);
 467}
 468
 469static const struct clk_ops vc5_pll_ops = {
 470        .recalc_rate    = vc5_pll_recalc_rate,
 471        .round_rate     = vc5_pll_round_rate,
 472        .set_rate       = vc5_pll_set_rate,
 473};
 474
 475static unsigned long vc5_fod_recalc_rate(struct clk_hw *hw,
 476                                         unsigned long parent_rate)
 477{
 478        struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
 479        struct vc5_driver_data *vc5 = hwdata->vc5;
 480        /* VCO frequency is divided by two before entering FOD */
 481        u32 f_in = parent_rate / 2;
 482        u32 div_int, div_frc;
 483        u8 od_int[2];
 484        u8 od_frc[4];
 485
 486        regmap_bulk_read(vc5->regmap, VC5_OUT_DIV_INT(hwdata->num, 0),
 487                         od_int, 2);
 488        regmap_bulk_read(vc5->regmap, VC5_OUT_DIV_FRAC(hwdata->num, 0),
 489                         od_frc, 4);
 490
 491        div_int = (od_int[0] << 4) | (od_int[1] >> 4);
 492        div_frc = (od_frc[0] << 22) | (od_frc[1] << 14) |
 493                  (od_frc[2] << 6) | (od_frc[3] >> 2);
 494
 495        /* Avoid division by zero if the output is not configured. */
 496        if (div_int == 0 && div_frc == 0)
 497                return 0;
 498
 499        /* The PLL divider has 12 integer bits and 30 fractional bits */
 500        return div64_u64((u64)f_in << 24ULL, ((u64)div_int << 24ULL) + div_frc);
 501}
 502
 503static long vc5_fod_round_rate(struct clk_hw *hw, unsigned long rate,
 504                               unsigned long *parent_rate)
 505{
 506        struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
 507        /* VCO frequency is divided by two before entering FOD */
 508        u32 f_in = *parent_rate / 2;
 509        u32 div_int;
 510        u64 div_frc;
 511
 512        /* Determine integer part, which is 12 bit wide */
 513        div_int = f_in / rate;
 514        /*
 515         * WARNING: The clock chip does not output signal if the integer part
 516         *          of the divider is 0xfff and fractional part is non-zero.
 517         *          Clamp the divider at 0xffe to keep the code simple.
 518         */
 519        if (div_int > 0xffe) {
 520                div_int = 0xffe;
 521                rate = f_in / div_int;
 522        }
 523
 524        /* Determine best fractional part, which is 30 bit wide */
 525        div_frc = f_in % rate;
 526        div_frc <<= 24;
 527        do_div(div_frc, rate);
 528
 529        hwdata->div_int = div_int;
 530        hwdata->div_frc = (u32)div_frc;
 531
 532        return div64_u64((u64)f_in << 24ULL, ((u64)div_int << 24ULL) + div_frc);
 533}
 534
 535static int vc5_fod_set_rate(struct clk_hw *hw, unsigned long rate,
 536                            unsigned long parent_rate)
 537{
 538        struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
 539        struct vc5_driver_data *vc5 = hwdata->vc5;
 540        u8 data[14] = {
 541                hwdata->div_frc >> 22, hwdata->div_frc >> 14,
 542                hwdata->div_frc >> 6, hwdata->div_frc << 2,
 543                0, 0, 0, 0, 0,
 544                0, 0,
 545                hwdata->div_int >> 4, hwdata->div_int << 4,
 546                0
 547        };
 548
 549        regmap_bulk_write(vc5->regmap, VC5_OUT_DIV_FRAC(hwdata->num, 0),
 550                          data, 14);
 551
 552        /*
 553         * Toggle magic bit in undocumented register for unknown reason.
 554         * This is what the IDT timing commander tool does and the chip
 555         * datasheet somewhat implies this is needed, but the register
 556         * and the bit is not documented.
 557         */
 558        regmap_update_bits(vc5->regmap, VC5_GLOBAL_REGISTER,
 559                           VC5_GLOBAL_REGISTER_GLOBAL_RESET, 0);
 560        regmap_update_bits(vc5->regmap, VC5_GLOBAL_REGISTER,
 561                           VC5_GLOBAL_REGISTER_GLOBAL_RESET,
 562                           VC5_GLOBAL_REGISTER_GLOBAL_RESET);
 563        return 0;
 564}
 565
 566static const struct clk_ops vc5_fod_ops = {
 567        .recalc_rate    = vc5_fod_recalc_rate,
 568        .round_rate     = vc5_fod_round_rate,
 569        .set_rate       = vc5_fod_set_rate,
 570};
 571
 572static int vc5_clk_out_prepare(struct clk_hw *hw)
 573{
 574        struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
 575        struct vc5_driver_data *vc5 = hwdata->vc5;
 576        const u8 mask = VC5_OUT_DIV_CONTROL_SELB_NORM |
 577                        VC5_OUT_DIV_CONTROL_SEL_EXT |
 578                        VC5_OUT_DIV_CONTROL_EN_FOD;
 579        unsigned int src;
 580        int ret;
 581
 582        /*
 583         * If the input mux is disabled, enable it first and
 584         * select source from matching FOD.
 585         */
 586        regmap_read(vc5->regmap, VC5_OUT_DIV_CONTROL(hwdata->num), &src);
 587        if ((src & mask) == 0) {
 588                src = VC5_OUT_DIV_CONTROL_RESET | VC5_OUT_DIV_CONTROL_EN_FOD;
 589                ret = regmap_update_bits(vc5->regmap,
 590                                         VC5_OUT_DIV_CONTROL(hwdata->num),
 591                                         mask | VC5_OUT_DIV_CONTROL_RESET, src);
 592                if (ret)
 593                        return ret;
 594        }
 595
 596        /* Enable the clock buffer */
 597        regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1),
 598                           VC5_CLK_OUTPUT_CFG1_EN_CLKBUF,
 599                           VC5_CLK_OUTPUT_CFG1_EN_CLKBUF);
 600        return 0;
 601}
 602
 603static void vc5_clk_out_unprepare(struct clk_hw *hw)
 604{
 605        struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
 606        struct vc5_driver_data *vc5 = hwdata->vc5;
 607
 608        /* Disable the clock buffer */
 609        regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1),
 610                           VC5_CLK_OUTPUT_CFG1_EN_CLKBUF, 0);
 611}
 612
 613static unsigned char vc5_clk_out_get_parent(struct clk_hw *hw)
 614{
 615        struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
 616        struct vc5_driver_data *vc5 = hwdata->vc5;
 617        const u8 mask = VC5_OUT_DIV_CONTROL_SELB_NORM |
 618                        VC5_OUT_DIV_CONTROL_SEL_EXT |
 619                        VC5_OUT_DIV_CONTROL_EN_FOD;
 620        const u8 fodclkmask = VC5_OUT_DIV_CONTROL_SELB_NORM |
 621                              VC5_OUT_DIV_CONTROL_EN_FOD;
 622        const u8 extclk = VC5_OUT_DIV_CONTROL_SELB_NORM |
 623                          VC5_OUT_DIV_CONTROL_SEL_EXT;
 624        unsigned int src;
 625
 626        regmap_read(vc5->regmap, VC5_OUT_DIV_CONTROL(hwdata->num), &src);
 627        src &= mask;
 628
 629        if (src == 0)   /* Input mux set to DISABLED */
 630                return 0;
 631
 632        if ((src & fodclkmask) == VC5_OUT_DIV_CONTROL_EN_FOD)
 633                return 0;
 634
 635        if (src == extclk)
 636                return 1;
 637
 638        dev_warn(&vc5->client->dev,
 639                 "Invalid clock output configuration (%02x)\n", src);
 640        return 0;
 641}
 642
 643static int vc5_clk_out_set_parent(struct clk_hw *hw, u8 index)
 644{
 645        struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
 646        struct vc5_driver_data *vc5 = hwdata->vc5;
 647        const u8 mask = VC5_OUT_DIV_CONTROL_RESET |
 648                        VC5_OUT_DIV_CONTROL_SELB_NORM |
 649                        VC5_OUT_DIV_CONTROL_SEL_EXT |
 650                        VC5_OUT_DIV_CONTROL_EN_FOD;
 651        const u8 extclk = VC5_OUT_DIV_CONTROL_SELB_NORM |
 652                          VC5_OUT_DIV_CONTROL_SEL_EXT;
 653        u8 src = VC5_OUT_DIV_CONTROL_RESET;
 654
 655        if (index == 0)
 656                src |= VC5_OUT_DIV_CONTROL_EN_FOD;
 657        else
 658                src |= extclk;
 659
 660        return regmap_update_bits(vc5->regmap, VC5_OUT_DIV_CONTROL(hwdata->num),
 661                                  mask, src);
 662}
 663
 664static const struct clk_ops vc5_clk_out_ops = {
 665        .prepare        = vc5_clk_out_prepare,
 666        .unprepare      = vc5_clk_out_unprepare,
 667        .set_parent     = vc5_clk_out_set_parent,
 668        .get_parent     = vc5_clk_out_get_parent,
 669};
 670
 671static struct clk_hw *vc5_of_clk_get(struct of_phandle_args *clkspec,
 672                                     void *data)
 673{
 674        struct vc5_driver_data *vc5 = data;
 675        unsigned int idx = clkspec->args[0];
 676
 677        if (idx >= vc5->chip_info->clk_out_cnt)
 678                return ERR_PTR(-EINVAL);
 679
 680        return &vc5->clk_out[idx].hw;
 681}
 682
 683static int vc5_map_index_to_output(const enum vc5_model model,
 684                                   const unsigned int n)
 685{
 686        switch (model) {
 687        case IDT_VC5_5P49V5933:
 688                return (n == 0) ? 0 : 3;
 689        case IDT_VC5_5P49V5923:
 690        case IDT_VC5_5P49V5925:
 691        case IDT_VC5_5P49V5935:
 692        case IDT_VC6_5P49V6901:
 693        default:
 694                return n;
 695        }
 696}
 697
 698static const struct of_device_id clk_vc5_of_match[];
 699
 700static int vc5_probe(struct i2c_client *client,
 701                     const struct i2c_device_id *id)
 702{
 703        struct vc5_driver_data *vc5;
 704        struct clk_init_data init;
 705        const char *parent_names[2];
 706        unsigned int n, idx = 0;
 707        int ret;
 708
 709        vc5 = devm_kzalloc(&client->dev, sizeof(*vc5), GFP_KERNEL);
 710        if (vc5 == NULL)
 711                return -ENOMEM;
 712
 713        i2c_set_clientdata(client, vc5);
 714        vc5->client = client;
 715        vc5->chip_info = of_device_get_match_data(&client->dev);
 716
 717        vc5->pin_xin = devm_clk_get(&client->dev, "xin");
 718        if (PTR_ERR(vc5->pin_xin) == -EPROBE_DEFER)
 719                return -EPROBE_DEFER;
 720
 721        vc5->pin_clkin = devm_clk_get(&client->dev, "clkin");
 722        if (PTR_ERR(vc5->pin_clkin) == -EPROBE_DEFER)
 723                return -EPROBE_DEFER;
 724
 725        vc5->regmap = devm_regmap_init_i2c(client, &vc5_regmap_config);
 726        if (IS_ERR(vc5->regmap)) {
 727                dev_err(&client->dev, "failed to allocate register map\n");
 728                return PTR_ERR(vc5->regmap);
 729        }
 730
 731        /* Register clock input mux */
 732        memset(&init, 0, sizeof(init));
 733
 734        if (!IS_ERR(vc5->pin_xin)) {
 735                vc5->clk_mux_ins |= VC5_MUX_IN_XIN;
 736                parent_names[init.num_parents++] = __clk_get_name(vc5->pin_xin);
 737        } else if (vc5->chip_info->flags & VC5_HAS_INTERNAL_XTAL) {
 738                vc5->pin_xin = clk_register_fixed_rate(&client->dev,
 739                                                       "internal-xtal", NULL,
 740                                                       0, 25000000);
 741                if (IS_ERR(vc5->pin_xin))
 742                        return PTR_ERR(vc5->pin_xin);
 743                vc5->clk_mux_ins |= VC5_MUX_IN_XIN;
 744                parent_names[init.num_parents++] = __clk_get_name(vc5->pin_xin);
 745        }
 746
 747        if (!IS_ERR(vc5->pin_clkin)) {
 748                vc5->clk_mux_ins |= VC5_MUX_IN_CLKIN;
 749                parent_names[init.num_parents++] =
 750                        __clk_get_name(vc5->pin_clkin);
 751        }
 752
 753        if (!init.num_parents) {
 754                dev_err(&client->dev, "no input clock specified!\n");
 755                return -EINVAL;
 756        }
 757
 758        init.name = vc5_mux_names[0];
 759        init.ops = &vc5_mux_ops;
 760        init.flags = 0;
 761        init.parent_names = parent_names;
 762        vc5->clk_mux.init = &init;
 763        ret = devm_clk_hw_register(&client->dev, &vc5->clk_mux);
 764        if (ret) {
 765                dev_err(&client->dev, "unable to register %s\n", init.name);
 766                goto err_clk;
 767        }
 768
 769        if (vc5->chip_info->flags & VC5_HAS_PFD_FREQ_DBL) {
 770                /* Register frequency doubler */
 771                memset(&init, 0, sizeof(init));
 772                init.name = vc5_dbl_names[0];
 773                init.ops = &vc5_dbl_ops;
 774                init.flags = CLK_SET_RATE_PARENT;
 775                init.parent_names = vc5_mux_names;
 776                init.num_parents = 1;
 777                vc5->clk_mul.init = &init;
 778                ret = devm_clk_hw_register(&client->dev, &vc5->clk_mul);
 779                if (ret) {
 780                        dev_err(&client->dev, "unable to register %s\n",
 781                                init.name);
 782                        goto err_clk;
 783                }
 784        }
 785
 786        /* Register PFD */
 787        memset(&init, 0, sizeof(init));
 788        init.name = vc5_pfd_names[0];
 789        init.ops = &vc5_pfd_ops;
 790        init.flags = CLK_SET_RATE_PARENT;
 791        if (vc5->chip_info->flags & VC5_HAS_PFD_FREQ_DBL)
 792                init.parent_names = vc5_dbl_names;
 793        else
 794                init.parent_names = vc5_mux_names;
 795        init.num_parents = 1;
 796        vc5->clk_pfd.init = &init;
 797        ret = devm_clk_hw_register(&client->dev, &vc5->clk_pfd);
 798        if (ret) {
 799                dev_err(&client->dev, "unable to register %s\n", init.name);
 800                goto err_clk;
 801        }
 802
 803        /* Register PLL */
 804        memset(&init, 0, sizeof(init));
 805        init.name = vc5_pll_names[0];
 806        init.ops = &vc5_pll_ops;
 807        init.flags = CLK_SET_RATE_PARENT;
 808        init.parent_names = vc5_pfd_names;
 809        init.num_parents = 1;
 810        vc5->clk_pll.num = 0;
 811        vc5->clk_pll.vc5 = vc5;
 812        vc5->clk_pll.hw.init = &init;
 813        ret = devm_clk_hw_register(&client->dev, &vc5->clk_pll.hw);
 814        if (ret) {
 815                dev_err(&client->dev, "unable to register %s\n", init.name);
 816                goto err_clk;
 817        }
 818
 819        /* Register FODs */
 820        for (n = 0; n < vc5->chip_info->clk_fod_cnt; n++) {
 821                idx = vc5_map_index_to_output(vc5->chip_info->model, n);
 822                memset(&init, 0, sizeof(init));
 823                init.name = vc5_fod_names[idx];
 824                init.ops = &vc5_fod_ops;
 825                init.flags = CLK_SET_RATE_PARENT;
 826                init.parent_names = vc5_pll_names;
 827                init.num_parents = 1;
 828                vc5->clk_fod[n].num = idx;
 829                vc5->clk_fod[n].vc5 = vc5;
 830                vc5->clk_fod[n].hw.init = &init;
 831                ret = devm_clk_hw_register(&client->dev, &vc5->clk_fod[n].hw);
 832                if (ret) {
 833                        dev_err(&client->dev, "unable to register %s\n",
 834                                init.name);
 835                        goto err_clk;
 836                }
 837        }
 838
 839        /* Register MUX-connected OUT0_I2C_SELB output */
 840        memset(&init, 0, sizeof(init));
 841        init.name = vc5_clk_out_names[0];
 842        init.ops = &vc5_clk_out_ops;
 843        init.flags = CLK_SET_RATE_PARENT;
 844        init.parent_names = vc5_mux_names;
 845        init.num_parents = 1;
 846        vc5->clk_out[0].num = idx;
 847        vc5->clk_out[0].vc5 = vc5;
 848        vc5->clk_out[0].hw.init = &init;
 849        ret = devm_clk_hw_register(&client->dev, &vc5->clk_out[0].hw);
 850        if (ret) {
 851                dev_err(&client->dev, "unable to register %s\n",
 852                        init.name);
 853                goto err_clk;
 854        }
 855
 856        /* Register FOD-connected OUTx outputs */
 857        for (n = 1; n < vc5->chip_info->clk_out_cnt; n++) {
 858                idx = vc5_map_index_to_output(vc5->chip_info->model, n - 1);
 859                parent_names[0] = vc5_fod_names[idx];
 860                if (n == 1)
 861                        parent_names[1] = vc5_mux_names[0];
 862                else
 863                        parent_names[1] = vc5_clk_out_names[n - 1];
 864
 865                memset(&init, 0, sizeof(init));
 866                init.name = vc5_clk_out_names[idx + 1];
 867                init.ops = &vc5_clk_out_ops;
 868                init.flags = CLK_SET_RATE_PARENT;
 869                init.parent_names = parent_names;
 870                init.num_parents = 2;
 871                vc5->clk_out[n].num = idx;
 872                vc5->clk_out[n].vc5 = vc5;
 873                vc5->clk_out[n].hw.init = &init;
 874                ret = devm_clk_hw_register(&client->dev,
 875                                           &vc5->clk_out[n].hw);
 876                if (ret) {
 877                        dev_err(&client->dev, "unable to register %s\n",
 878                                init.name);
 879                        goto err_clk;
 880                }
 881        }
 882
 883        ret = of_clk_add_hw_provider(client->dev.of_node, vc5_of_clk_get, vc5);
 884        if (ret) {
 885                dev_err(&client->dev, "unable to add clk provider\n");
 886                goto err_clk;
 887        }
 888
 889        return 0;
 890
 891err_clk:
 892        if (vc5->chip_info->flags & VC5_HAS_INTERNAL_XTAL)
 893                clk_unregister_fixed_rate(vc5->pin_xin);
 894        return ret;
 895}
 896
 897static int vc5_remove(struct i2c_client *client)
 898{
 899        struct vc5_driver_data *vc5 = i2c_get_clientdata(client);
 900
 901        of_clk_del_provider(client->dev.of_node);
 902
 903        if (vc5->chip_info->flags & VC5_HAS_INTERNAL_XTAL)
 904                clk_unregister_fixed_rate(vc5->pin_xin);
 905
 906        return 0;
 907}
 908
 909static const struct vc5_chip_info idt_5p49v5923_info = {
 910        .model = IDT_VC5_5P49V5923,
 911        .clk_fod_cnt = 2,
 912        .clk_out_cnt = 3,
 913        .flags = 0,
 914};
 915
 916static const struct vc5_chip_info idt_5p49v5925_info = {
 917        .model = IDT_VC5_5P49V5925,
 918        .clk_fod_cnt = 4,
 919        .clk_out_cnt = 5,
 920        .flags = 0,
 921};
 922
 923static const struct vc5_chip_info idt_5p49v5933_info = {
 924        .model = IDT_VC5_5P49V5933,
 925        .clk_fod_cnt = 2,
 926        .clk_out_cnt = 3,
 927        .flags = VC5_HAS_INTERNAL_XTAL,
 928};
 929
 930static const struct vc5_chip_info idt_5p49v5935_info = {
 931        .model = IDT_VC5_5P49V5935,
 932        .clk_fod_cnt = 4,
 933        .clk_out_cnt = 5,
 934        .flags = VC5_HAS_INTERNAL_XTAL,
 935};
 936
 937static const struct vc5_chip_info idt_5p49v6901_info = {
 938        .model = IDT_VC6_5P49V6901,
 939        .clk_fod_cnt = 4,
 940        .clk_out_cnt = 5,
 941        .flags = VC5_HAS_PFD_FREQ_DBL,
 942};
 943
 944static const struct i2c_device_id vc5_id[] = {
 945        { "5p49v5923", .driver_data = IDT_VC5_5P49V5923 },
 946        { "5p49v5925", .driver_data = IDT_VC5_5P49V5925 },
 947        { "5p49v5933", .driver_data = IDT_VC5_5P49V5933 },
 948        { "5p49v5935", .driver_data = IDT_VC5_5P49V5935 },
 949        { "5p49v6901", .driver_data = IDT_VC6_5P49V6901 },
 950        { }
 951};
 952MODULE_DEVICE_TABLE(i2c, vc5_id);
 953
 954static const struct of_device_id clk_vc5_of_match[] = {
 955        { .compatible = "idt,5p49v5923", .data = &idt_5p49v5923_info },
 956        { .compatible = "idt,5p49v5925", .data = &idt_5p49v5925_info },
 957        { .compatible = "idt,5p49v5933", .data = &idt_5p49v5933_info },
 958        { .compatible = "idt,5p49v5935", .data = &idt_5p49v5935_info },
 959        { .compatible = "idt,5p49v6901", .data = &idt_5p49v6901_info },
 960        { },
 961};
 962MODULE_DEVICE_TABLE(of, clk_vc5_of_match);
 963
 964static struct i2c_driver vc5_driver = {
 965        .driver = {
 966                .name = "vc5",
 967                .of_match_table = clk_vc5_of_match,
 968        },
 969        .probe          = vc5_probe,
 970        .remove         = vc5_remove,
 971        .id_table       = vc5_id,
 972};
 973module_i2c_driver(vc5_driver);
 974
 975MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
 976MODULE_DESCRIPTION("IDT VersaClock 5 driver");
 977MODULE_LICENSE("GPL");
 978