1414#include <linux/of.h>
1515#include <linux/mfd/syscon.h>
1616#include <linux/regmap.h>
17+ #include <soc/at91/atmel-sfr.h>
1718
1819#include "pmc.h"
1920
20- #define UTMI_FIXED_MUL 40
21+ /*
22+ * The purpose of this clock is to generate a 480 MHz signal. A different
23+ * rate can't be configured.
24+ */
25+ #define UTMI_RATE 480000000
2126
2227struct clk_utmi {
2328 struct clk_hw hw ;
24- struct regmap * regmap ;
29+ struct regmap * regmap_pmc ;
30+ struct regmap * regmap_sfr ;
2531};
2632
2733#define to_clk_utmi (hw ) container_of(hw, struct clk_utmi, hw)
@@ -37,13 +43,54 @@ static inline bool clk_utmi_ready(struct regmap *regmap)
3743
3844static int clk_utmi_prepare (struct clk_hw * hw )
3945{
46+ struct clk_hw * hw_parent ;
4047 struct clk_utmi * utmi = to_clk_utmi (hw );
4148 unsigned int uckr = AT91_PMC_UPLLEN | AT91_PMC_UPLLCOUNT |
4249 AT91_PMC_BIASEN ;
50+ unsigned int utmi_ref_clk_freq ;
51+ unsigned long parent_rate ;
52+
53+ /*
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
56+ * the utmi clock.
57+ */
58+ hw_parent = clk_hw_get_parent (hw );
59+ parent_rate = clk_hw_get_rate (hw_parent );
60+
61+ switch (parent_rate ) {
62+ case 12000000 :
63+ utmi_ref_clk_freq = 0 ;
64+ break ;
65+ case 16000000 :
66+ utmi_ref_clk_freq = 1 ;
67+ break ;
68+ case 24000000 :
69+ utmi_ref_clk_freq = 2 ;
70+ break ;
71+ /*
72+ * Not supported on SAMA5D2 but it's not an issue since MAINCK
73+ * maximum value is 24 MHz.
74+ */
75+ case 48000000 :
76+ utmi_ref_clk_freq = 3 ;
77+ break ;
78+ default :
79+ pr_err ("UTMICK: unsupported mainck rate\n" );
80+ return - EINVAL ;
81+ }
4382
44- regmap_update_bits (utmi -> regmap , AT91_CKGR_UCKR , uckr , uckr );
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" );
88+ return - EINVAL ;
89+ }
90+
91+ regmap_update_bits (utmi -> regmap_pmc , AT91_CKGR_UCKR , uckr , uckr );
4592
46- while (!clk_utmi_ready (utmi -> regmap ))
93+ while (!clk_utmi_ready (utmi -> regmap_pmc ))
4794 cpu_relax ();
4895
4996 return 0 ;
@@ -53,21 +100,22 @@ static int clk_utmi_is_prepared(struct clk_hw *hw)
53100{
54101 struct clk_utmi * utmi = to_clk_utmi (hw );
55102
56- return clk_utmi_ready (utmi -> regmap );
103+ return clk_utmi_ready (utmi -> regmap_pmc );
57104}
58105
59106static void clk_utmi_unprepare (struct clk_hw * hw )
60107{
61108 struct clk_utmi * utmi = to_clk_utmi (hw );
62109
63- regmap_update_bits (utmi -> regmap , AT91_CKGR_UCKR , AT91_PMC_UPLLEN , 0 );
110+ regmap_update_bits (utmi -> regmap_pmc , AT91_CKGR_UCKR ,
111+ AT91_PMC_UPLLEN , 0 );
64112}
65113
66114static unsigned long clk_utmi_recalc_rate (struct clk_hw * hw ,
67115 unsigned long parent_rate )
68116{
69- /* UTMI clk is a fixed clk multiplier */
70- return parent_rate * UTMI_FIXED_MUL ;
117+ /* UTMI clk rate is fixed. */
118+ return UTMI_RATE ;
71119}
72120
73121static const struct clk_ops utmi_ops = {
@@ -78,7 +126,7 @@ static const struct clk_ops utmi_ops = {
78126};
79127
80128static struct clk_hw * __init
81- at91_clk_register_utmi (struct regmap * regmap ,
129+ at91_clk_register_utmi (struct regmap * regmap_pmc , struct regmap * regmap_sfr ,
82130 const char * name , const char * parent_name )
83131{
84132 struct clk_utmi * utmi ;
@@ -97,7 +145,8 @@ at91_clk_register_utmi(struct regmap *regmap,
97145 init .flags = CLK_SET_RATE_GATE ;
98146
99147 utmi -> hw .init = & init ;
100- utmi -> regmap = regmap ;
148+ utmi -> regmap_pmc = regmap_pmc ;
149+ utmi -> regmap_sfr = regmap_sfr ;
101150
102151 hw = & utmi -> hw ;
103152 ret = clk_hw_register (NULL , & utmi -> hw );
@@ -114,17 +163,22 @@ static void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np)
114163 struct clk_hw * hw ;
115164 const char * parent_name ;
116165 const char * name = np -> name ;
117- struct regmap * regmap ;
166+ struct regmap * regmap_pmc , * regmap_sfr ;
118167
119168 parent_name = of_clk_get_parent_name (np , 0 );
120169
121170 of_property_read_string (np , "clock-output-names" , & name );
122171
123- regmap = syscon_node_to_regmap (of_get_parent (np ));
124- if (IS_ERR (regmap ))
172+ regmap_pmc = syscon_node_to_regmap (of_get_parent (np ));
173+ if (IS_ERR (regmap_pmc ))
125174 return ;
126175
127- hw = at91_clk_register_utmi (regmap , name , parent_name );
176+ /* SFR node missing is not necessarily an issue. */
177+ regmap_sfr = syscon_regmap_lookup_by_compatible ("atmel,sama5d2-sfr" );
178+ if (IS_ERR (regmap_sfr ))
179+ regmap_sfr = NULL ;
180+
181+ hw = at91_clk_register_utmi (regmap_pmc , regmap_sfr , name , parent_name );
128182 if (IS_ERR (hw ))
129183 return ;
130184
0 commit comments