2 * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
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.
11 #include <linux/clk-provider.h>
12 #include <linux/clkdev.h>
13 #include <linux/clk/at91_pmc.h>
15 #include <linux/mfd/syscon.h>
16 #include <linux/regmap.h>
17 #include <soc/at91/atmel-sfr.h>
22 * The purpose of this clock is to generate a 480 MHz signal. A different
23 * rate can't be configured.
25 #define UTMI_RATE 480000000
29 struct regmap
*regmap_pmc
;
30 struct regmap
*regmap_sfr
;
33 #define to_clk_utmi(hw) container_of(hw, struct clk_utmi, hw)
35 static inline bool clk_utmi_ready(struct regmap
*regmap
)
39 regmap_read(regmap
, AT91_PMC_SR
, &status
);
41 return status
& AT91_PMC_LOCKU
;
44 static int clk_utmi_prepare(struct clk_hw
*hw
)
46 struct clk_hw
*hw_parent
;
47 struct clk_utmi
*utmi
= to_clk_utmi(hw
);
48 unsigned int uckr
= AT91_PMC_UPLLEN
| AT91_PMC_UPLLCOUNT
|
50 unsigned int utmi_ref_clk_freq
;
51 unsigned long parent_rate
;
54 * If mainck rate is different from 12 MHz, we have to configure the
55 * FREQ field of the SFR_UTMICKTRIM register to generate properly
58 hw_parent
= clk_hw_get_parent(hw
);
59 parent_rate
= clk_hw_get_rate(hw_parent
);
61 switch (parent_rate
) {
63 utmi_ref_clk_freq
= 0;
66 utmi_ref_clk_freq
= 1;
69 utmi_ref_clk_freq
= 2;
72 * Not supported on SAMA5D2 but it's not an issue since MAINCK
73 * maximum value is 24 MHz.
76 utmi_ref_clk_freq
= 3;
79 pr_err("UTMICK: unsupported mainck rate\n");
83 if (utmi
->regmap_sfr
) {
84 regmap_update_bits(utmi
->regmap_sfr
, AT91_SFR_UTMICKTRIM
,
85 AT91_UTMICKTRIM_FREQ
, utmi_ref_clk_freq
);
86 } else if (utmi_ref_clk_freq
) {
87 pr_err("UTMICK: sfr node required\n");
91 regmap_update_bits(utmi
->regmap_pmc
, AT91_CKGR_UCKR
, uckr
, uckr
);
93 while (!clk_utmi_ready(utmi
->regmap_pmc
))
99 static int clk_utmi_is_prepared(struct clk_hw
*hw
)
101 struct clk_utmi
*utmi
= to_clk_utmi(hw
);
103 return clk_utmi_ready(utmi
->regmap_pmc
);
106 static void clk_utmi_unprepare(struct clk_hw
*hw
)
108 struct clk_utmi
*utmi
= to_clk_utmi(hw
);
110 regmap_update_bits(utmi
->regmap_pmc
, AT91_CKGR_UCKR
,
114 static unsigned long clk_utmi_recalc_rate(struct clk_hw
*hw
,
115 unsigned long parent_rate
)
117 /* UTMI clk rate is fixed. */
121 static const struct clk_ops utmi_ops
= {
122 .prepare
= clk_utmi_prepare
,
123 .unprepare
= clk_utmi_unprepare
,
124 .is_prepared
= clk_utmi_is_prepared
,
125 .recalc_rate
= clk_utmi_recalc_rate
,
128 static struct clk_hw
* __init
129 at91_clk_register_utmi(struct regmap
*regmap_pmc
, struct regmap
*regmap_sfr
,
130 const char *name
, const char *parent_name
)
132 struct clk_utmi
*utmi
;
134 struct clk_init_data init
;
137 utmi
= kzalloc(sizeof(*utmi
), GFP_KERNEL
);
139 return ERR_PTR(-ENOMEM
);
142 init
.ops
= &utmi_ops
;
143 init
.parent_names
= parent_name
? &parent_name
: NULL
;
144 init
.num_parents
= parent_name
? 1 : 0;
145 init
.flags
= CLK_SET_RATE_GATE
;
147 utmi
->hw
.init
= &init
;
148 utmi
->regmap_pmc
= regmap_pmc
;
149 utmi
->regmap_sfr
= regmap_sfr
;
152 ret
= clk_hw_register(NULL
, &utmi
->hw
);
161 static void __init
of_at91sam9x5_clk_utmi_setup(struct device_node
*np
)
164 const char *parent_name
;
165 const char *name
= np
->name
;
166 struct regmap
*regmap_pmc
, *regmap_sfr
;
168 parent_name
= of_clk_get_parent_name(np
, 0);
170 of_property_read_string(np
, "clock-output-names", &name
);
172 regmap_pmc
= syscon_node_to_regmap(of_get_parent(np
));
173 if (IS_ERR(regmap_pmc
))
177 * If the device supports different mainck rates, this value has to be
178 * set in the UTMI Clock Trimming register.
179 * - 9x5: mainck supports several rates but it is indicated that a
180 * 12 MHz is needed in case of USB.
181 * - sama5d3 and sama5d2: mainck supports several rates. Configuring
182 * the FREQ field of the UTMI Clock Trimming register is mandatory.
183 * - sama5d4: mainck is at 12 MHz.
185 * We only need to retrieve sama5d3 or sama5d2 sfr regmap.
187 regmap_sfr
= syscon_regmap_lookup_by_compatible("atmel,sama5d3-sfr");
188 if (IS_ERR(regmap_sfr
)) {
189 regmap_sfr
= syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr");
190 if (IS_ERR(regmap_sfr
))
194 hw
= at91_clk_register_utmi(regmap_pmc
, regmap_sfr
, name
, parent_name
);
198 of_clk_add_hw_provider(np
, of_clk_hw_simple_get
, hw
);
201 CLK_OF_DECLARE(at91sam9x5_clk_utmi
, "atmel,at91sam9x5-clk-utmi",
202 of_at91sam9x5_clk_utmi_setup
);