linux/drivers/clk/at91/clk-main.c
<<
>>
Prefs
   1/*
   2 *  Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License as published by
   6 * the Free Software Foundation; either version 2 of the License, or
   7 * (at your option) any later version.
   8 *
   9 */
  10
  11#include <linux/clk-provider.h>
  12#include <linux/clkdev.h>
  13#include <linux/clk/at91_pmc.h>
  14#include <linux/delay.h>
  15#include <linux/of.h>
  16#include <linux/mfd/syscon.h>
  17#include <linux/regmap.h>
  18
  19#include "pmc.h"
  20
  21#define SLOW_CLOCK_FREQ         32768
  22#define MAINF_DIV               16
  23#define MAINFRDY_TIMEOUT        (((MAINF_DIV + 1) * USEC_PER_SEC) / \
  24                                 SLOW_CLOCK_FREQ)
  25#define MAINF_LOOP_MIN_WAIT     (USEC_PER_SEC / SLOW_CLOCK_FREQ)
  26#define MAINF_LOOP_MAX_WAIT     MAINFRDY_TIMEOUT
  27
  28#define MOR_KEY_MASK            (0xff << 16)
  29
  30struct clk_main_osc {
  31        struct clk_hw hw;
  32        struct regmap *regmap;
  33};
  34
  35#define to_clk_main_osc(hw) container_of(hw, struct clk_main_osc, hw)
  36
  37struct clk_main_rc_osc {
  38        struct clk_hw hw;
  39        struct regmap *regmap;
  40        unsigned long frequency;
  41        unsigned long accuracy;
  42};
  43
  44#define to_clk_main_rc_osc(hw) container_of(hw, struct clk_main_rc_osc, hw)
  45
  46struct clk_rm9200_main {
  47        struct clk_hw hw;
  48        struct regmap *regmap;
  49};
  50
  51#define to_clk_rm9200_main(hw) container_of(hw, struct clk_rm9200_main, hw)
  52
  53struct clk_sam9x5_main {
  54        struct clk_hw hw;
  55        struct regmap *regmap;
  56        u8 parent;
  57};
  58
  59#define to_clk_sam9x5_main(hw) container_of(hw, struct clk_sam9x5_main, hw)
  60
  61static inline bool clk_main_osc_ready(struct regmap *regmap)
  62{
  63        unsigned int status;
  64
  65        regmap_read(regmap, AT91_PMC_SR, &status);
  66
  67        return status & AT91_PMC_MOSCS;
  68}
  69
  70static int clk_main_osc_prepare(struct clk_hw *hw)
  71{
  72        struct clk_main_osc *osc = to_clk_main_osc(hw);
  73        struct regmap *regmap = osc->regmap;
  74        u32 tmp;
  75
  76        regmap_read(regmap, AT91_CKGR_MOR, &tmp);
  77        tmp &= ~MOR_KEY_MASK;
  78
  79        if (tmp & AT91_PMC_OSCBYPASS)
  80                return 0;
  81
  82        if (!(tmp & AT91_PMC_MOSCEN)) {
  83                tmp |= AT91_PMC_MOSCEN | AT91_PMC_KEY;
  84                regmap_write(regmap, AT91_CKGR_MOR, tmp);
  85        }
  86
  87        while (!clk_main_osc_ready(regmap))
  88                cpu_relax();
  89
  90        return 0;
  91}
  92
  93static void clk_main_osc_unprepare(struct clk_hw *hw)
  94{
  95        struct clk_main_osc *osc = to_clk_main_osc(hw);
  96        struct regmap *regmap = osc->regmap;
  97        u32 tmp;
  98
  99        regmap_read(regmap, AT91_CKGR_MOR, &tmp);
 100        if (tmp & AT91_PMC_OSCBYPASS)
 101                return;
 102
 103        if (!(tmp & AT91_PMC_MOSCEN))
 104                return;
 105
 106        tmp &= ~(AT91_PMC_KEY | AT91_PMC_MOSCEN);
 107        regmap_write(regmap, AT91_CKGR_MOR, tmp | AT91_PMC_KEY);
 108}
 109
 110static int clk_main_osc_is_prepared(struct clk_hw *hw)
 111{
 112        struct clk_main_osc *osc = to_clk_main_osc(hw);
 113        struct regmap *regmap = osc->regmap;
 114        u32 tmp, status;
 115
 116        regmap_read(regmap, AT91_CKGR_MOR, &tmp);
 117        if (tmp & AT91_PMC_OSCBYPASS)
 118                return 1;
 119
 120        regmap_read(regmap, AT91_PMC_SR, &status);
 121
 122        return (status & AT91_PMC_MOSCS) && (tmp & AT91_PMC_MOSCEN);
 123}
 124
 125static const struct clk_ops main_osc_ops = {
 126        .prepare = clk_main_osc_prepare,
 127        .unprepare = clk_main_osc_unprepare,
 128        .is_prepared = clk_main_osc_is_prepared,
 129};
 130
 131static struct clk_hw * __init
 132at91_clk_register_main_osc(struct regmap *regmap,
 133                           const char *name,
 134                           const char *parent_name,
 135                           bool bypass)
 136{
 137        struct clk_main_osc *osc;
 138        struct clk_init_data init;
 139        struct clk_hw *hw;
 140        int ret;
 141
 142        if (!name || !parent_name)
 143                return ERR_PTR(-EINVAL);
 144
 145        osc = kzalloc(sizeof(*osc), GFP_KERNEL);
 146        if (!osc)
 147                return ERR_PTR(-ENOMEM);
 148
 149        init.name = name;
 150        init.ops = &main_osc_ops;
 151        init.parent_names = &parent_name;
 152        init.num_parents = 1;
 153        init.flags = CLK_IGNORE_UNUSED;
 154
 155        osc->hw.init = &init;
 156        osc->regmap = regmap;
 157
 158        if (bypass)
 159                regmap_update_bits(regmap,
 160                                   AT91_CKGR_MOR, MOR_KEY_MASK |
 161                                   AT91_PMC_MOSCEN,
 162                                   AT91_PMC_OSCBYPASS | AT91_PMC_KEY);
 163
 164        hw = &osc->hw;
 165        ret = clk_hw_register(NULL, &osc->hw);
 166        if (ret) {
 167                kfree(osc);
 168                hw = ERR_PTR(ret);
 169        }
 170
 171        return hw;
 172}
 173
 174static void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np)
 175{
 176        struct clk_hw *hw;
 177        const char *name = np->name;
 178        const char *parent_name;
 179        struct regmap *regmap;
 180        bool bypass;
 181
 182        of_property_read_string(np, "clock-output-names", &name);
 183        bypass = of_property_read_bool(np, "atmel,osc-bypass");
 184        parent_name = of_clk_get_parent_name(np, 0);
 185
 186        regmap = syscon_node_to_regmap(of_get_parent(np));
 187        if (IS_ERR(regmap))
 188                return;
 189
 190        hw = at91_clk_register_main_osc(regmap, name, parent_name, bypass);
 191        if (IS_ERR(hw))
 192                return;
 193
 194        of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 195}
 196CLK_OF_DECLARE(at91rm9200_clk_main_osc, "atmel,at91rm9200-clk-main-osc",
 197               of_at91rm9200_clk_main_osc_setup);
 198
 199static bool clk_main_rc_osc_ready(struct regmap *regmap)
 200{
 201        unsigned int status;
 202
 203        regmap_read(regmap, AT91_PMC_SR, &status);
 204
 205        return status & AT91_PMC_MOSCRCS;
 206}
 207
 208static int clk_main_rc_osc_prepare(struct clk_hw *hw)
 209{
 210        struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
 211        struct regmap *regmap = osc->regmap;
 212        unsigned int mor;
 213
 214        regmap_read(regmap, AT91_CKGR_MOR, &mor);
 215
 216        if (!(mor & AT91_PMC_MOSCRCEN))
 217                regmap_update_bits(regmap, AT91_CKGR_MOR,
 218                                   MOR_KEY_MASK | AT91_PMC_MOSCRCEN,
 219                                   AT91_PMC_MOSCRCEN | AT91_PMC_KEY);
 220
 221        while (!clk_main_rc_osc_ready(regmap))
 222                cpu_relax();
 223
 224        return 0;
 225}
 226
 227static void clk_main_rc_osc_unprepare(struct clk_hw *hw)
 228{
 229        struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
 230        struct regmap *regmap = osc->regmap;
 231        unsigned int mor;
 232
 233        regmap_read(regmap, AT91_CKGR_MOR, &mor);
 234
 235        if (!(mor & AT91_PMC_MOSCRCEN))
 236                return;
 237
 238        regmap_update_bits(regmap, AT91_CKGR_MOR,
 239                           MOR_KEY_MASK | AT91_PMC_MOSCRCEN, AT91_PMC_KEY);
 240}
 241
 242static int clk_main_rc_osc_is_prepared(struct clk_hw *hw)
 243{
 244        struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
 245        struct regmap *regmap = osc->regmap;
 246        unsigned int mor, status;
 247
 248        regmap_read(regmap, AT91_CKGR_MOR, &mor);
 249        regmap_read(regmap, AT91_PMC_SR, &status);
 250
 251        return (mor & AT91_PMC_MOSCRCEN) && (status & AT91_PMC_MOSCRCS);
 252}
 253
 254static unsigned long clk_main_rc_osc_recalc_rate(struct clk_hw *hw,
 255                                                 unsigned long parent_rate)
 256{
 257        struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
 258
 259        return osc->frequency;
 260}
 261
 262static unsigned long clk_main_rc_osc_recalc_accuracy(struct clk_hw *hw,
 263                                                     unsigned long parent_acc)
 264{
 265        struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
 266
 267        return osc->accuracy;
 268}
 269
 270static const struct clk_ops main_rc_osc_ops = {
 271        .prepare = clk_main_rc_osc_prepare,
 272        .unprepare = clk_main_rc_osc_unprepare,
 273        .is_prepared = clk_main_rc_osc_is_prepared,
 274        .recalc_rate = clk_main_rc_osc_recalc_rate,
 275        .recalc_accuracy = clk_main_rc_osc_recalc_accuracy,
 276};
 277
 278static struct clk_hw * __init
 279at91_clk_register_main_rc_osc(struct regmap *regmap,
 280                              const char *name,
 281                              u32 frequency, u32 accuracy)
 282{
 283        struct clk_main_rc_osc *osc;
 284        struct clk_init_data init;
 285        struct clk_hw *hw;
 286        int ret;
 287
 288        if (!name || !frequency)
 289                return ERR_PTR(-EINVAL);
 290
 291        osc = kzalloc(sizeof(*osc), GFP_KERNEL);
 292        if (!osc)
 293                return ERR_PTR(-ENOMEM);
 294
 295        init.name = name;
 296        init.ops = &main_rc_osc_ops;
 297        init.parent_names = NULL;
 298        init.num_parents = 0;
 299        init.flags = CLK_IGNORE_UNUSED;
 300
 301        osc->hw.init = &init;
 302        osc->regmap = regmap;
 303        osc->frequency = frequency;
 304        osc->accuracy = accuracy;
 305
 306        hw = &osc->hw;
 307        ret = clk_hw_register(NULL, hw);
 308        if (ret) {
 309                kfree(osc);
 310                hw = ERR_PTR(ret);
 311        }
 312
 313        return hw;
 314}
 315
 316static void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np)
 317{
 318        struct clk_hw *hw;
 319        u32 frequency = 0;
 320        u32 accuracy = 0;
 321        const char *name = np->name;
 322        struct regmap *regmap;
 323
 324        of_property_read_string(np, "clock-output-names", &name);
 325        of_property_read_u32(np, "clock-frequency", &frequency);
 326        of_property_read_u32(np, "clock-accuracy", &accuracy);
 327
 328        regmap = syscon_node_to_regmap(of_get_parent(np));
 329        if (IS_ERR(regmap))
 330                return;
 331
 332        hw = at91_clk_register_main_rc_osc(regmap, name, frequency, accuracy);
 333        if (IS_ERR(hw))
 334                return;
 335
 336        of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 337}
 338CLK_OF_DECLARE(at91sam9x5_clk_main_rc_osc, "atmel,at91sam9x5-clk-main-rc-osc",
 339               of_at91sam9x5_clk_main_rc_osc_setup);
 340
 341
 342static int clk_main_probe_frequency(struct regmap *regmap)
 343{
 344        unsigned long prep_time, timeout;
 345        unsigned int mcfr;
 346
 347        timeout = jiffies + usecs_to_jiffies(MAINFRDY_TIMEOUT);
 348        do {
 349                prep_time = jiffies;
 350                regmap_read(regmap, AT91_CKGR_MCFR, &mcfr);
 351                if (mcfr & AT91_PMC_MAINRDY)
 352                        return 0;
 353                usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT);
 354        } while (time_before(prep_time, timeout));
 355
 356        return -ETIMEDOUT;
 357}
 358
 359static unsigned long clk_main_recalc_rate(struct regmap *regmap,
 360                                          unsigned long parent_rate)
 361{
 362        unsigned int mcfr;
 363
 364        if (parent_rate)
 365                return parent_rate;
 366
 367        pr_warn("Main crystal frequency not set, using approximate value\n");
 368        regmap_read(regmap, AT91_CKGR_MCFR, &mcfr);
 369        if (!(mcfr & AT91_PMC_MAINRDY))
 370                return 0;
 371
 372        return ((mcfr & AT91_PMC_MAINF) * SLOW_CLOCK_FREQ) / MAINF_DIV;
 373}
 374
 375static int clk_rm9200_main_prepare(struct clk_hw *hw)
 376{
 377        struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
 378
 379        return clk_main_probe_frequency(clkmain->regmap);
 380}
 381
 382static int clk_rm9200_main_is_prepared(struct clk_hw *hw)
 383{
 384        struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
 385        unsigned int status;
 386
 387        regmap_read(clkmain->regmap, AT91_CKGR_MCFR, &status);
 388
 389        return status & AT91_PMC_MAINRDY ? 1 : 0;
 390}
 391
 392static unsigned long clk_rm9200_main_recalc_rate(struct clk_hw *hw,
 393                                                 unsigned long parent_rate)
 394{
 395        struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
 396
 397        return clk_main_recalc_rate(clkmain->regmap, parent_rate);
 398}
 399
 400static const struct clk_ops rm9200_main_ops = {
 401        .prepare = clk_rm9200_main_prepare,
 402        .is_prepared = clk_rm9200_main_is_prepared,
 403        .recalc_rate = clk_rm9200_main_recalc_rate,
 404};
 405
 406static struct clk_hw * __init
 407at91_clk_register_rm9200_main(struct regmap *regmap,
 408                              const char *name,
 409                              const char *parent_name)
 410{
 411        struct clk_rm9200_main *clkmain;
 412        struct clk_init_data init;
 413        struct clk_hw *hw;
 414        int ret;
 415
 416        if (!name)
 417                return ERR_PTR(-EINVAL);
 418
 419        if (!parent_name)
 420                return ERR_PTR(-EINVAL);
 421
 422        clkmain = kzalloc(sizeof(*clkmain), GFP_KERNEL);
 423        if (!clkmain)
 424                return ERR_PTR(-ENOMEM);
 425
 426        init.name = name;
 427        init.ops = &rm9200_main_ops;
 428        init.parent_names = &parent_name;
 429        init.num_parents = 1;
 430        init.flags = 0;
 431
 432        clkmain->hw.init = &init;
 433        clkmain->regmap = regmap;
 434
 435        hw = &clkmain->hw;
 436        ret = clk_hw_register(NULL, &clkmain->hw);
 437        if (ret) {
 438                kfree(clkmain);
 439                hw = ERR_PTR(ret);
 440        }
 441
 442        return hw;
 443}
 444
 445static void __init of_at91rm9200_clk_main_setup(struct device_node *np)
 446{
 447        struct clk_hw *hw;
 448        const char *parent_name;
 449        const char *name = np->name;
 450        struct regmap *regmap;
 451
 452        parent_name = of_clk_get_parent_name(np, 0);
 453        of_property_read_string(np, "clock-output-names", &name);
 454
 455        regmap = syscon_node_to_regmap(of_get_parent(np));
 456        if (IS_ERR(regmap))
 457                return;
 458
 459        hw = at91_clk_register_rm9200_main(regmap, name, parent_name);
 460        if (IS_ERR(hw))
 461                return;
 462
 463        of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 464}
 465CLK_OF_DECLARE(at91rm9200_clk_main, "atmel,at91rm9200-clk-main",
 466               of_at91rm9200_clk_main_setup);
 467
 468static inline bool clk_sam9x5_main_ready(struct regmap *regmap)
 469{
 470        unsigned int status;
 471
 472        regmap_read(regmap, AT91_PMC_SR, &status);
 473
 474        return status & AT91_PMC_MOSCSELS ? 1 : 0;
 475}
 476
 477static int clk_sam9x5_main_prepare(struct clk_hw *hw)
 478{
 479        struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
 480        struct regmap *regmap = clkmain->regmap;
 481
 482        while (!clk_sam9x5_main_ready(regmap))
 483                cpu_relax();
 484
 485        return clk_main_probe_frequency(regmap);
 486}
 487
 488static int clk_sam9x5_main_is_prepared(struct clk_hw *hw)
 489{
 490        struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
 491
 492        return clk_sam9x5_main_ready(clkmain->regmap);
 493}
 494
 495static unsigned long clk_sam9x5_main_recalc_rate(struct clk_hw *hw,
 496                                                 unsigned long parent_rate)
 497{
 498        struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
 499
 500        return clk_main_recalc_rate(clkmain->regmap, parent_rate);
 501}
 502
 503static int clk_sam9x5_main_set_parent(struct clk_hw *hw, u8 index)
 504{
 505        struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
 506        struct regmap *regmap = clkmain->regmap;
 507        unsigned int tmp;
 508
 509        if (index > 1)
 510                return -EINVAL;
 511
 512        regmap_read(regmap, AT91_CKGR_MOR, &tmp);
 513        tmp &= ~MOR_KEY_MASK;
 514
 515        if (index && !(tmp & AT91_PMC_MOSCSEL))
 516                regmap_write(regmap, AT91_CKGR_MOR, tmp | AT91_PMC_MOSCSEL);
 517        else if (!index && (tmp & AT91_PMC_MOSCSEL))
 518                regmap_write(regmap, AT91_CKGR_MOR, tmp & ~AT91_PMC_MOSCSEL);
 519
 520        while (!clk_sam9x5_main_ready(regmap))
 521                cpu_relax();
 522
 523        return 0;
 524}
 525
 526static u8 clk_sam9x5_main_get_parent(struct clk_hw *hw)
 527{
 528        struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
 529        unsigned int status;
 530
 531        regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status);
 532
 533        return status & AT91_PMC_MOSCEN ? 1 : 0;
 534}
 535
 536static const struct clk_ops sam9x5_main_ops = {
 537        .prepare = clk_sam9x5_main_prepare,
 538        .is_prepared = clk_sam9x5_main_is_prepared,
 539        .recalc_rate = clk_sam9x5_main_recalc_rate,
 540        .set_parent = clk_sam9x5_main_set_parent,
 541        .get_parent = clk_sam9x5_main_get_parent,
 542};
 543
 544static struct clk_hw * __init
 545at91_clk_register_sam9x5_main(struct regmap *regmap,
 546                              const char *name,
 547                              const char **parent_names,
 548                              int num_parents)
 549{
 550        struct clk_sam9x5_main *clkmain;
 551        struct clk_init_data init;
 552        unsigned int status;
 553        struct clk_hw *hw;
 554        int ret;
 555
 556        if (!name)
 557                return ERR_PTR(-EINVAL);
 558
 559        if (!parent_names || !num_parents)
 560                return ERR_PTR(-EINVAL);
 561
 562        clkmain = kzalloc(sizeof(*clkmain), GFP_KERNEL);
 563        if (!clkmain)
 564                return ERR_PTR(-ENOMEM);
 565
 566        init.name = name;
 567        init.ops = &sam9x5_main_ops;
 568        init.parent_names = parent_names;
 569        init.num_parents = num_parents;
 570        init.flags = CLK_SET_PARENT_GATE;
 571
 572        clkmain->hw.init = &init;
 573        clkmain->regmap = regmap;
 574        regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status);
 575        clkmain->parent = status & AT91_PMC_MOSCEN ? 1 : 0;
 576
 577        hw = &clkmain->hw;
 578        ret = clk_hw_register(NULL, &clkmain->hw);
 579        if (ret) {
 580                kfree(clkmain);
 581                hw = ERR_PTR(ret);
 582        }
 583
 584        return hw;
 585}
 586
 587static void __init of_at91sam9x5_clk_main_setup(struct device_node *np)
 588{
 589        struct clk_hw *hw;
 590        const char *parent_names[2];
 591        unsigned int num_parents;
 592        const char *name = np->name;
 593        struct regmap *regmap;
 594
 595        num_parents = of_clk_get_parent_count(np);
 596        if (num_parents == 0 || num_parents > 2)
 597                return;
 598
 599        of_clk_parent_fill(np, parent_names, num_parents);
 600        regmap = syscon_node_to_regmap(of_get_parent(np));
 601        if (IS_ERR(regmap))
 602                return;
 603
 604        of_property_read_string(np, "clock-output-names", &name);
 605
 606        hw = at91_clk_register_sam9x5_main(regmap, name, parent_names,
 607                                            num_parents);
 608        if (IS_ERR(hw))
 609                return;
 610
 611        of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 612}
 613CLK_OF_DECLARE(at91sam9x5_clk_main, "atmel,at91sam9x5-clk-main",
 614               of_at91sam9x5_clk_main_setup);
 615