1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Clock driver for Keystone 2 based devices
5 * Copyright (C) 2013 Texas Instruments.
6 * Murali Karicheri <m-karicheri2@ti.com>
7 * Santosh Shilimkar <santosh.shilimkar@ti.com>
9 #include <linux/clk-provider.h>
10 #include <linux/err.h>
12 #include <linux/slab.h>
13 #include <linux/of_address.h>
15 #include <linux/module.h>
17 /* PSC register offsets */
25 /* PSC module states */
26 #define PSC_STATE_SWRSTDISABLE 0
27 #define PSC_STATE_SYNCRST 1
28 #define PSC_STATE_DISABLE 2
29 #define PSC_STATE_ENABLE 3
31 #define MDSTAT_STATE_MASK 0x3f
32 #define MDSTAT_MCKOUT BIT(12)
33 #define PDSTAT_STATE_MASK 0x1f
34 #define MDCTL_FORCE BIT(31)
35 #define MDCTL_LRESET BIT(8)
36 #define PDCTL_NEXT BIT(0)
38 /* Maximum timeout to bail out state transition for module */
39 #define STATE_TRANS_MAX_COUNT 0xffff
41 static void __iomem
*domain_transition_base
;
44 * struct clk_psc_data - PSC data
45 * @control_base: Base address for a PSC control
46 * @domain_base: Base address for a PSC domain
47 * @domain_id: PSC domain id number
50 void __iomem
*control_base
;
51 void __iomem
*domain_base
;
56 * struct clk_psc - PSC clock structure
57 * @hw: clk_hw for the psc
58 * @psc_data: PSC driver specific data
59 * @lock: Spinlock used by the driver
63 struct clk_psc_data
*psc_data
;
67 static DEFINE_SPINLOCK(psc_lock
);
69 #define to_clk_psc(_hw) container_of(_hw, struct clk_psc, hw)
71 static void psc_config(void __iomem
*control_base
, void __iomem
*domain_base
,
72 u32 next_state
, u32 domain_id
)
74 u32 ptcmd
, pdstat
, pdctl
, mdstat
, mdctl
, ptstat
;
75 u32 count
= STATE_TRANS_MAX_COUNT
;
77 mdctl
= readl(control_base
+ MDCTL
);
78 mdctl
&= ~MDSTAT_STATE_MASK
;
80 /* For disable, we always put the module in local reset */
81 if (next_state
== PSC_STATE_DISABLE
)
82 mdctl
&= ~MDCTL_LRESET
;
83 writel(mdctl
, control_base
+ MDCTL
);
85 pdstat
= readl(domain_base
+ PDSTAT
);
86 if (!(pdstat
& PDSTAT_STATE_MASK
)) {
87 pdctl
= readl(domain_base
+ PDCTL
);
89 writel(pdctl
, domain_base
+ PDCTL
);
92 ptcmd
= 1 << domain_id
;
93 writel(ptcmd
, domain_transition_base
+ PTCMD
);
95 ptstat
= readl(domain_transition_base
+ PTSTAT
);
96 } while (((ptstat
>> domain_id
) & 1) && count
--);
98 count
= STATE_TRANS_MAX_COUNT
;
100 mdstat
= readl(control_base
+ MDSTAT
);
101 } while (!((mdstat
& MDSTAT_STATE_MASK
) == next_state
) && count
--);
104 static int keystone_clk_is_enabled(struct clk_hw
*hw
)
106 struct clk_psc
*psc
= to_clk_psc(hw
);
107 struct clk_psc_data
*data
= psc
->psc_data
;
108 u32 mdstat
= readl(data
->control_base
+ MDSTAT
);
110 return (mdstat
& MDSTAT_MCKOUT
) ? 1 : 0;
113 static int keystone_clk_enable(struct clk_hw
*hw
)
115 struct clk_psc
*psc
= to_clk_psc(hw
);
116 struct clk_psc_data
*data
= psc
->psc_data
;
117 unsigned long flags
= 0;
120 spin_lock_irqsave(psc
->lock
, flags
);
122 psc_config(data
->control_base
, data
->domain_base
,
123 PSC_STATE_ENABLE
, data
->domain_id
);
126 spin_unlock_irqrestore(psc
->lock
, flags
);
131 static void keystone_clk_disable(struct clk_hw
*hw
)
133 struct clk_psc
*psc
= to_clk_psc(hw
);
134 struct clk_psc_data
*data
= psc
->psc_data
;
135 unsigned long flags
= 0;
138 spin_lock_irqsave(psc
->lock
, flags
);
140 psc_config(data
->control_base
, data
->domain_base
,
141 PSC_STATE_DISABLE
, data
->domain_id
);
144 spin_unlock_irqrestore(psc
->lock
, flags
);
147 static const struct clk_ops clk_psc_ops
= {
148 .enable
= keystone_clk_enable
,
149 .disable
= keystone_clk_disable
,
150 .is_enabled
= keystone_clk_is_enabled
,
154 * clk_register_psc - register psc clock
155 * @dev: device that is registering this clock
156 * @name: name of this clock
157 * @parent_name: name of clock's parent
158 * @psc_data: platform data to configure this clock
159 * @lock: spinlock used by this clock
161 static struct clk
*clk_register_psc(struct device
*dev
,
163 const char *parent_name
,
164 struct clk_psc_data
*psc_data
,
167 struct clk_init_data init
;
171 psc
= kzalloc(sizeof(*psc
), GFP_KERNEL
);
173 return ERR_PTR(-ENOMEM
);
176 init
.ops
= &clk_psc_ops
;
178 init
.parent_names
= (parent_name
? &parent_name
: NULL
);
179 init
.num_parents
= (parent_name
? 1 : 0);
181 psc
->psc_data
= psc_data
;
183 psc
->hw
.init
= &init
;
185 clk
= clk_register(NULL
, &psc
->hw
);
193 * of_psc_clk_init - initialize psc clock through DT
194 * @node: device tree node for this clock
195 * @lock: spinlock used by this clock
197 static void __init
of_psc_clk_init(struct device_node
*node
, spinlock_t
*lock
)
199 const char *clk_name
= node
->name
;
200 const char *parent_name
;
201 struct clk_psc_data
*data
;
205 data
= kzalloc(sizeof(*data
), GFP_KERNEL
);
207 pr_err("%s: Out of memory\n", __func__
);
211 i
= of_property_match_string(node
, "reg-names", "control");
212 data
->control_base
= of_iomap(node
, i
);
213 if (!data
->control_base
) {
214 pr_err("%s: control ioremap failed\n", __func__
);
218 i
= of_property_match_string(node
, "reg-names", "domain");
219 data
->domain_base
= of_iomap(node
, i
);
220 if (!data
->domain_base
) {
221 pr_err("%s: domain ioremap failed\n", __func__
);
225 of_property_read_u32(node
, "domain-id", &data
->domain_id
);
227 /* Domain transition registers at fixed address space of domain_id 0 */
228 if (!domain_transition_base
&& !data
->domain_id
)
229 domain_transition_base
= data
->domain_base
;
231 of_property_read_string(node
, "clock-output-names", &clk_name
);
232 parent_name
= of_clk_get_parent_name(node
, 0);
234 pr_err("%s: Parent clock not found\n", __func__
);
238 clk
= clk_register_psc(NULL
, clk_name
, parent_name
, data
, lock
);
240 of_clk_add_provider(node
, of_clk_src_simple_get
, clk
);
244 pr_err("%s: error registering clk %pOFn\n", __func__
, node
);
247 iounmap(data
->domain_base
);
249 iounmap(data
->control_base
);
256 * of_keystone_psc_clk_init - initialize psc clock through DT
257 * @node: device tree node for this clock
259 static void __init
of_keystone_psc_clk_init(struct device_node
*node
)
261 of_psc_clk_init(node
, &psc_lock
);
263 CLK_OF_DECLARE(keystone_gate_clk
, "ti,keystone,psc-clock",
264 of_keystone_psc_clk_init
);
266 MODULE_LICENSE("GPL");
267 MODULE_DESCRIPTION("Clock driver for Keystone 2 based devices");
268 MODULE_AUTHOR("Murali Karicheri <m-karicheri2@ti.com>");
269 MODULE_AUTHOR("Santosh Shilimkar <santosh.shilimkar@ti.com>");