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 * __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 *clk = NULL;
 139        struct clk_init_data init;
 140
 141        if (!name || !parent_name)
 142                return ERR_PTR(-EINVAL);
 143
 144        osc = kzalloc(sizeof(*osc), GFP_KERNEL);
 145        if (!osc)
 146                return ERR_PTR(-ENOMEM);
 147
 148        init.name = name;
 149        init.ops = &main_osc_ops;
 150        init.parent_names = &parent_name;
 151        init.num_parents = 1;
 152        init.flags = CLK_IGNORE_UNUSED;
 153
 154        osc->hw.init = &init;
 155        osc->regmap = regmap;
 156
 157        if (bypass)
 158                regmap_update_bits(regmap,
 159                                   AT91_CKGR_MOR, MOR_KEY_MASK |
 160                                   AT91_PMC_MOSCEN,
 161                                   AT91_PMC_OSCBYPASS | AT91_PMC_KEY);
 162
 163        clk = clk_register(NULL, &osc->hw);
 164        if (IS_ERR(clk))
 165                kfree(osc);
 166
 167        return clk;
 168}
 169
 170static void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np)
 171{
 172        struct clk *clk;
 173        const char *name = np->name;
 174        const char *parent_name;
 175        struct regmap *regmap;
 176        bool bypass;
 177
 178        of_property_read_string(np, "clock-output-names", &name);
 179        bypass = of_property_read_bool(np, "atmel,osc-bypass");
 180        parent_name = of_clk_get_parent_name(np, 0);
 181
 182        regmap = syscon_node_to_regmap(of_get_parent(np));
 183        if (IS_ERR(regmap))
 184                return;
 185
 186        clk = at91_clk_register_main_osc(regmap, name, parent_name, bypass);
 187        if (IS_ERR(clk))
 188                return;
 189
 190        of_clk_add_provider(np, of_clk_src_simple_get, clk);
 191}
 192CLK_OF_DECLARE(at91rm9200_clk_main_osc, "atmel,at91rm9200-clk-main-osc",
 193               of_at91rm9200_clk_main_osc_setup);
 194
 195static bool clk_main_rc_osc_ready(struct regmap *regmap)
 196{
 197        unsigned int status;
 198
 199        regmap_read(regmap, AT91_PMC_SR, &status);
 200
 201        return status & AT91_PMC_MOSCRCS;
 202}
 203
 204static int clk_main_rc_osc_prepare(struct clk_hw *hw)
 205{
 206        struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
 207        struct regmap *regmap = osc->regmap;
 208        unsigned int mor;
 209
 210        regmap_read(regmap, AT91_CKGR_MOR, &mor);
 211
 212        if (!(mor & AT91_PMC_MOSCRCEN))
 213                regmap_update_bits(regmap, AT91_CKGR_MOR,
 214                                   MOR_KEY_MASK | AT91_PMC_MOSCRCEN,
 215                                   AT91_PMC_MOSCRCEN | AT91_PMC_KEY);
 216
 217        while (!clk_main_rc_osc_ready(regmap))
 218                cpu_relax();
 219
 220        return 0;
 221}
 222
 223static void clk_main_rc_osc_unprepare(struct clk_hw *hw)
 224{
 225        struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
 226        struct regmap *regmap = osc->regmap;
 227        unsigned int mor;
 228
 229        regmap_read(regmap, AT91_CKGR_MOR, &mor);
 230
 231        if (!(mor & AT91_PMC_MOSCRCEN))
 232                return;
 233
 234        regmap_update_bits(regmap, AT91_CKGR_MOR,
 235                           MOR_KEY_MASK | AT91_PMC_MOSCRCEN, AT91_PMC_KEY);
 236}
 237
 238static int clk_main_rc_osc_is_prepared(struct clk_hw *hw)
 239{
 240        struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
 241        struct regmap *regmap = osc->regmap;
 242        unsigned int mor, status;
 243
 244        regmap_read(regmap, AT91_CKGR_MOR, &mor);
 245        regmap_read(regmap, AT91_PMC_SR, &status);
 246
 247        return (mor & AT91_PMC_MOSCRCEN) && (status & AT91_PMC_MOSCRCS);
 248}
 249
 250static unsigned long clk_main_rc_osc_recalc_rate(struct clk_hw *hw,
 251                                                 unsigned long parent_rate)
 252{
 253        struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
 254
 255        return osc->frequency;
 256}
 257
 258static unsigned long clk_main_rc_osc_recalc_accuracy(struct clk_hw *hw,
 259                                                     unsigned long parent_acc)
 260{
 261        struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
 262
 263        return osc->accuracy;
 264}
 265
 266static const struct clk_ops main_rc_osc_ops = {
 267        .prepare = clk_main_rc_osc_prepare,
 268        .unprepare = clk_main_rc_osc_unprepare,
 269        .is_prepared = clk_main_rc_osc_is_prepared,
 270        .recalc_rate = clk_main_rc_osc_recalc_rate,
 271        .recalc_accuracy = clk_main_rc_osc_recalc_accuracy,
 272};
 273
 274static struct clk * __init
 275at91_clk_register_main_rc_osc(struct regmap *regmap,
 276                              const char *name,
 277                              u32 frequency, u32 accuracy)
 278{
 279        struct clk_main_rc_osc *osc;
 280        struct clk *clk = NULL;
 281        struct clk_init_data init;
 282
 283        if (!name || !frequency)
 284                return ERR_PTR(-EINVAL);
 285
 286        osc = kzalloc(sizeof(*osc), GFP_KERNEL);
 287        if (!osc)
 288                return ERR_PTR(-ENOMEM);
 289
 290        init.name = name;
 291        init.ops = &main_rc_osc_ops;
 292        init.parent_names = NULL;
 293        init.num_parents = 0;
 294        init.flags = CLK_IGNORE_UNUSED;
 295
 296        osc->hw.init = &init;
 297        osc->regmap = regmap;
 298        osc->frequency = frequency;
 299        osc->accuracy = accuracy;
 300
 301        clk = clk_register(NULL, &osc->hw);
 302        if (IS_ERR(clk))
 303                kfree(osc);
 304
 305        return clk;
 306}
 307
 308static void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np)
 309{
 310        struct clk *clk;
 311        u32 frequency = 0;
 312        u32 accuracy = 0;
 313        const char *name = np->name;
 314        struct regmap *regmap;
 315
 316        of_property_read_string(np, "clock-output-names", &name);
 317        of_property_read_u32(np, "clock-frequency", &frequency);
 318        of_property_read_u32(np, "clock-accuracy", &accuracy);
 319
 320        regmap = syscon_node_to_regmap(of_get_parent(np));
 321        if (IS_ERR(regmap))
 322                return;
 323
 324        clk = at91_clk_register_main_rc_osc(regmap, name, frequency, accuracy);
 325        if (IS_ERR(clk))
 326                return;
 327
 328        of_clk_add_provider(np, of_clk_src_simple_get, clk);
 329}
 330CLK_OF_DECLARE(at91sam9x5_clk_main_rc_osc, "atmel,at91sam9x5-clk-main-rc-osc",
 331               of_at91sam9x5_clk_main_rc_osc_setup);
 332
 333
 334static int clk_main_probe_frequency(struct regmap *regmap)
 335{
 336        unsigned long prep_time, timeout;
 337        unsigned int mcfr;
 338
 339        timeout = jiffies + usecs_to_jiffies(MAINFRDY_TIMEOUT);
 340        do {
 341                prep_time = jiffies;
 342                regmap_read(regmap, AT91_CKGR_MCFR, &mcfr);
 343                if (mcfr & AT91_PMC_MAINRDY)
 344                        return 0;
 345                usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT);
 346        } while (time_before(prep_time, timeout));
 347
 348        return -ETIMEDOUT;
 349}
 350
 351static unsigned long clk_main_recalc_rate(struct regmap *regmap,
 352                                          unsigned long parent_rate)
 353{
 354        unsigned int mcfr;
 355
 356        if (parent_rate)
 357                return parent_rate;
 358
 359        pr_warn("Main crystal frequency not set, using approximate value\n");
 360        regmap_read(regmap, AT91_CKGR_MCFR, &mcfr);
 361        if (!(mcfr & AT91_PMC_MAINRDY))
 362                return 0;
 363
 364        return ((mcfr & AT91_PMC_MAINF) * SLOW_CLOCK_FREQ) / MAINF_DIV;
 365}
 366
 367static int clk_rm9200_main_prepare(struct clk_hw *hw)
 368{
 369        struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
 370
 371        return clk_main_probe_frequency(clkmain->regmap);
 372}
 373
 374static int clk_rm9200_main_is_prepared(struct clk_hw *hw)
 375{
 376        struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
 377        unsigned int status;
 378
 379        regmap_read(clkmain->regmap, AT91_CKGR_MCFR, &status);
 380
 381        return status & AT91_PMC_MAINRDY ? 1 : 0;
 382}
 383
 384static unsigned long clk_rm9200_main_recalc_rate(struct clk_hw *hw,
 385                                                 unsigned long parent_rate)
 386{
 387        struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
 388
 389        return clk_main_recalc_rate(clkmain->regmap, parent_rate);
 390}
 391
 392static const struct clk_ops rm9200_main_ops = {
 393        .prepare = clk_rm9200_main_prepare,
 394        .is_prepared = clk_rm9200_main_is_prepared,
 395        .recalc_rate = clk_rm9200_main_recalc_rate,
 396};
 397
 398static struct clk * __init
 399at91_clk_register_rm9200_main(struct regmap *regmap,
 400                              const char *name,
 401                              const char *parent_name)
 402{
 403        struct clk_rm9200_main *clkmain;
 404        struct clk *clk = NULL;
 405        struct clk_init_data init;
 406
 407        if (!name)
 408                return ERR_PTR(-EINVAL);
 409
 410        if (!parent_name)
 411                return ERR_PTR(-EINVAL);
 412
 413        clkmain = kzalloc(sizeof(*clkmain), GFP_KERNEL);
 414        if (!clkmain)
 415                return ERR_PTR(-ENOMEM);
 416
 417        init.name = name;
 418        init.ops = &rm9200_main_ops;
 419        init.parent_names = &parent_name;
 420        init.num_parents = 1;
 421        init.flags = 0;
 422
 423        clkmain->hw.init = &init;
 424        clkmain->regmap = regmap;
 425
 426        clk = clk_register(NULL, &clkmain->hw);
 427        if (IS_ERR(clk))
 428                kfree(clkmain);
 429
 430        return clk;
 431}
 432
 433static void __init of_at91rm9200_clk_main_setup(struct device_node *np)
 434{
 435        struct clk *clk;
 436        const char *parent_name;
 437        const char *name = np->name;
 438        struct regmap *regmap;
 439
 440        parent_name = of_clk_get_parent_name(np, 0);
 441        of_property_read_string(np, "clock-output-names", &name);
 442
 443        regmap = syscon_node_to_regmap(of_get_parent(np));
 444        if (IS_ERR(regmap))
 445                return;
 446
 447        clk = at91_clk_register_rm9200_main(regmap, name, parent_name);
 448        if (IS_ERR(clk))
 449                return;
 450
 451        of_clk_add_provider(np, of_clk_src_simple_get, clk);
 452}
 453CLK_OF_DECLARE(at91rm9200_clk_main, "atmel,at91rm9200-clk-main",
 454               of_at91rm9200_clk_main_setup);
 455
 456static inline bool clk_sam9x5_main_ready(struct regmap *regmap)
 457{
 458        unsigned int status;
 459
 460        regmap_read(regmap, AT91_PMC_SR, &status);
 461
 462        return status & AT91_PMC_MOSCSELS ? 1 : 0;
 463}
 464
 465static int clk_sam9x5_main_prepare(struct clk_hw *hw)
 466{
 467        struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
 468        struct regmap *regmap = clkmain->regmap;
 469
 470        while (!clk_sam9x5_main_ready(regmap))
 471                cpu_relax();
 472
 473        return clk_main_probe_frequency(regmap);
 474}
 475
 476static int clk_sam9x5_main_is_prepared(struct clk_hw *hw)
 477{
 478        struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
 479
 480        return clk_sam9x5_main_ready(clkmain->regmap);
 481}
 482
 483static unsigned long clk_sam9x5_main_recalc_rate(struct clk_hw *hw,
 484                                                 unsigned long parent_rate)
 485{
 486        struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
 487
 488        return clk_main_recalc_rate(clkmain->regmap, parent_rate);
 489}
 490
 491static int clk_sam9x5_main_set_parent(struct clk_hw *hw, u8 index)
 492{
 493        struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
 494        struct regmap *regmap = clkmain->regmap;
 495        unsigned int tmp;
 496
 497        if (index > 1)
 498                return -EINVAL;
 499
 500        regmap_read(regmap, AT91_CKGR_MOR, &tmp);
 501        tmp &= ~MOR_KEY_MASK;
 502
 503        if (index && !(tmp & AT91_PMC_MOSCSEL))
 504                regmap_write(regmap, AT91_CKGR_MOR, tmp | AT91_PMC_MOSCSEL);
 505        else if (!index && (tmp & AT91_PMC_MOSCSEL))
 506                regmap_write(regmap, AT91_CKGR_MOR, tmp & ~AT91_PMC_MOSCSEL);
 507
 508        while (!clk_sam9x5_main_ready(regmap))
 509                cpu_relax();
 510
 511        return 0;
 512}
 513
 514static u8 clk_sam9x5_main_get_parent(struct clk_hw *hw)
 515{
 516        struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
 517        unsigned int status;
 518
 519        regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status);
 520
 521        return status & AT91_PMC_MOSCEN ? 1 : 0;
 522}
 523
 524static const struct clk_ops sam9x5_main_ops = {
 525        .prepare = clk_sam9x5_main_prepare,
 526        .is_prepared = clk_sam9x5_main_is_prepared,
 527        .recalc_rate = clk_sam9x5_main_recalc_rate,
 528        .set_parent = clk_sam9x5_main_set_parent,
 529        .get_parent = clk_sam9x5_main_get_parent,
 530};
 531
 532static struct clk * __init
 533at91_clk_register_sam9x5_main(struct regmap *regmap,
 534                              const char *name,
 535                              const char **parent_names,
 536                              int num_parents)
 537{
 538        struct clk_sam9x5_main *clkmain;
 539        struct clk *clk = NULL;
 540        struct clk_init_data init;
 541        unsigned int status;
 542
 543        if (!name)
 544                return ERR_PTR(-EINVAL);
 545
 546        if (!parent_names || !num_parents)
 547                return ERR_PTR(-EINVAL);
 548
 549        clkmain = kzalloc(sizeof(*clkmain), GFP_KERNEL);
 550        if (!clkmain)
 551                return ERR_PTR(-ENOMEM);
 552
 553        init.name = name;
 554        init.ops = &sam9x5_main_ops;
 555        init.parent_names = parent_names;
 556        init.num_parents = num_parents;
 557        init.flags = CLK_SET_PARENT_GATE;
 558
 559        clkmain->hw.init = &init;
 560        clkmain->regmap = regmap;
 561        regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status);
 562        clkmain->parent = status & AT91_PMC_MOSCEN ? 1 : 0;
 563
 564        clk = clk_register(NULL, &clkmain->hw);
 565        if (IS_ERR(clk))
 566                kfree(clkmain);
 567
 568        return clk;
 569}
 570
 571static void __init of_at91sam9x5_clk_main_setup(struct device_node *np)
 572{
 573        struct clk *clk;
 574        const char *parent_names[2];
 575        unsigned int num_parents;
 576        const char *name = np->name;
 577        struct regmap *regmap;
 578
 579        num_parents = of_clk_get_parent_count(np);
 580        if (num_parents == 0 || num_parents > 2)
 581                return;
 582
 583        of_clk_parent_fill(np, parent_names, num_parents);
 584        regmap = syscon_node_to_regmap(of_get_parent(np));
 585        if (IS_ERR(regmap))
 586                return;
 587
 588        of_property_read_string(np, "clock-output-names", &name);
 589
 590        clk = at91_clk_register_sam9x5_main(regmap, name, parent_names,
 591                                            num_parents);
 592        if (IS_ERR(clk))
 593                return;
 594
 595        of_clk_add_provider(np, of_clk_src_simple_get, clk);
 596}
 597CLK_OF_DECLARE(at91sam9x5_clk_main, "atmel,at91sam9x5-clk-main",
 598               of_at91sam9x5_clk_main_setup);
 599