linux/drivers/clk/at91/clk-utmi.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 *  Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
   4 */
   5
   6#include <linux/clk-provider.h>
   7#include <linux/clkdev.h>
   8#include <linux/clk/at91_pmc.h>
   9#include <linux/of.h>
  10#include <linux/mfd/syscon.h>
  11#include <linux/regmap.h>
  12#include <soc/at91/atmel-sfr.h>
  13
  14#include "pmc.h"
  15
  16/*
  17 * The purpose of this clock is to generate a 480 MHz signal. A different
  18 * rate can't be configured.
  19 */
  20#define UTMI_RATE       480000000
  21
  22struct clk_utmi {
  23        struct clk_hw hw;
  24        struct regmap *regmap_pmc;
  25        struct regmap *regmap_sfr;
  26};
  27
  28#define to_clk_utmi(hw) container_of(hw, struct clk_utmi, hw)
  29
  30static inline bool clk_utmi_ready(struct regmap *regmap)
  31{
  32        unsigned int status;
  33
  34        regmap_read(regmap, AT91_PMC_SR, &status);
  35
  36        return status & AT91_PMC_LOCKU;
  37}
  38
  39static int clk_utmi_prepare(struct clk_hw *hw)
  40{
  41        struct clk_hw *hw_parent;
  42        struct clk_utmi *utmi = to_clk_utmi(hw);
  43        unsigned int uckr = AT91_PMC_UPLLEN | AT91_PMC_UPLLCOUNT |
  44                            AT91_PMC_BIASEN;
  45        unsigned int utmi_ref_clk_freq;
  46        unsigned long parent_rate;
  47
  48        /*
  49         * If mainck rate is different from 12 MHz, we have to configure the
  50         * FREQ field of the SFR_UTMICKTRIM register to generate properly
  51         * the utmi clock.
  52         */
  53        hw_parent = clk_hw_get_parent(hw);
  54        parent_rate = clk_hw_get_rate(hw_parent);
  55
  56        switch (parent_rate) {
  57        case 12000000:
  58                utmi_ref_clk_freq = 0;
  59                break;
  60        case 16000000:
  61                utmi_ref_clk_freq = 1;
  62                break;
  63        case 24000000:
  64                utmi_ref_clk_freq = 2;
  65                break;
  66        /*
  67         * Not supported on SAMA5D2 but it's not an issue since MAINCK
  68         * maximum value is 24 MHz.
  69         */
  70        case 48000000:
  71                utmi_ref_clk_freq = 3;
  72                break;
  73        default:
  74                pr_err("UTMICK: unsupported mainck rate\n");
  75                return -EINVAL;
  76        }
  77
  78        if (utmi->regmap_sfr) {
  79                regmap_update_bits(utmi->regmap_sfr, AT91_SFR_UTMICKTRIM,
  80                                   AT91_UTMICKTRIM_FREQ, utmi_ref_clk_freq);
  81        } else if (utmi_ref_clk_freq) {
  82                pr_err("UTMICK: sfr node required\n");
  83                return -EINVAL;
  84        }
  85
  86        regmap_update_bits(utmi->regmap_pmc, AT91_CKGR_UCKR, uckr, uckr);
  87
  88        while (!clk_utmi_ready(utmi->regmap_pmc))
  89                cpu_relax();
  90
  91        return 0;
  92}
  93
  94static int clk_utmi_is_prepared(struct clk_hw *hw)
  95{
  96        struct clk_utmi *utmi = to_clk_utmi(hw);
  97
  98        return clk_utmi_ready(utmi->regmap_pmc);
  99}
 100
 101static void clk_utmi_unprepare(struct clk_hw *hw)
 102{
 103        struct clk_utmi *utmi = to_clk_utmi(hw);
 104
 105        regmap_update_bits(utmi->regmap_pmc, AT91_CKGR_UCKR,
 106                           AT91_PMC_UPLLEN, 0);
 107}
 108
 109static unsigned long clk_utmi_recalc_rate(struct clk_hw *hw,
 110                                          unsigned long parent_rate)
 111{
 112        /* UTMI clk rate is fixed. */
 113        return UTMI_RATE;
 114}
 115
 116static const struct clk_ops utmi_ops = {
 117        .prepare = clk_utmi_prepare,
 118        .unprepare = clk_utmi_unprepare,
 119        .is_prepared = clk_utmi_is_prepared,
 120        .recalc_rate = clk_utmi_recalc_rate,
 121};
 122
 123static struct clk_hw * __init
 124at91_clk_register_utmi_internal(struct regmap *regmap_pmc,
 125                                struct regmap *regmap_sfr,
 126                                const char *name, const char *parent_name,
 127                                const struct clk_ops *ops, unsigned long flags)
 128{
 129        struct clk_utmi *utmi;
 130        struct clk_hw *hw;
 131        struct clk_init_data init;
 132        int ret;
 133
 134        utmi = kzalloc(sizeof(*utmi), GFP_KERNEL);
 135        if (!utmi)
 136                return ERR_PTR(-ENOMEM);
 137
 138        init.name = name;
 139        init.ops = ops;
 140        init.parent_names = parent_name ? &parent_name : NULL;
 141        init.num_parents = parent_name ? 1 : 0;
 142        init.flags = flags;
 143
 144        utmi->hw.init = &init;
 145        utmi->regmap_pmc = regmap_pmc;
 146        utmi->regmap_sfr = regmap_sfr;
 147
 148        hw = &utmi->hw;
 149        ret = clk_hw_register(NULL, &utmi->hw);
 150        if (ret) {
 151                kfree(utmi);
 152                hw = ERR_PTR(ret);
 153        }
 154
 155        return hw;
 156}
 157
 158struct clk_hw * __init
 159at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr,
 160                       const char *name, const char *parent_name)
 161{
 162        return at91_clk_register_utmi_internal(regmap_pmc, regmap_sfr, name,
 163                        parent_name, &utmi_ops, CLK_SET_RATE_GATE);
 164}
 165
 166static int clk_utmi_sama7g5_prepare(struct clk_hw *hw)
 167{
 168        struct clk_utmi *utmi = to_clk_utmi(hw);
 169        struct clk_hw *hw_parent;
 170        unsigned long parent_rate;
 171        unsigned int val;
 172
 173        hw_parent = clk_hw_get_parent(hw);
 174        parent_rate = clk_hw_get_rate(hw_parent);
 175
 176        switch (parent_rate) {
 177        case 16000000:
 178                val = 0;
 179                break;
 180        case 20000000:
 181                val = 2;
 182                break;
 183        case 24000000:
 184                val = 3;
 185                break;
 186        case 32000000:
 187                val = 5;
 188                break;
 189        default:
 190                pr_err("UTMICK: unsupported main_xtal rate\n");
 191                return -EINVAL;
 192        }
 193
 194        regmap_write(utmi->regmap_pmc, AT91_PMC_XTALF, val);
 195
 196        return 0;
 197
 198}
 199
 200static int clk_utmi_sama7g5_is_prepared(struct clk_hw *hw)
 201{
 202        struct clk_utmi *utmi = to_clk_utmi(hw);
 203        struct clk_hw *hw_parent;
 204        unsigned long parent_rate;
 205        unsigned int val;
 206
 207        hw_parent = clk_hw_get_parent(hw);
 208        parent_rate = clk_hw_get_rate(hw_parent);
 209
 210        regmap_read(utmi->regmap_pmc, AT91_PMC_XTALF, &val);
 211        switch (val & 0x7) {
 212        case 0:
 213                if (parent_rate == 16000000)
 214                        return 1;
 215                break;
 216        case 2:
 217                if (parent_rate == 20000000)
 218                        return 1;
 219                break;
 220        case 3:
 221                if (parent_rate == 24000000)
 222                        return 1;
 223                break;
 224        case 5:
 225                if (parent_rate == 32000000)
 226                        return 1;
 227                break;
 228        default:
 229                break;
 230        }
 231
 232        return 0;
 233}
 234
 235static const struct clk_ops sama7g5_utmi_ops = {
 236        .prepare = clk_utmi_sama7g5_prepare,
 237        .is_prepared = clk_utmi_sama7g5_is_prepared,
 238        .recalc_rate = clk_utmi_recalc_rate,
 239};
 240
 241struct clk_hw * __init
 242at91_clk_sama7g5_register_utmi(struct regmap *regmap_pmc, const char *name,
 243                               const char *parent_name)
 244{
 245        return at91_clk_register_utmi_internal(regmap_pmc, NULL, name,
 246                        parent_name, &sama7g5_utmi_ops, 0);
 247}
 248