]>
git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/blob - drivers/clk/keystone/gate.c
2 * Clock driver for Keystone 2 based devices
4 * Copyright (C) 2013 Texas Instruments.
5 * Murali Karicheri <m-karicheri2@ti.com>
6 * Santosh Shilimkar <santosh.shilimkar@ti.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 #include <linux/clk-provider.h>
14 #include <linux/err.h>
16 #include <linux/slab.h>
17 #include <linux/of_address.h>
19 #include <linux/module.h>
21 /* PSC register offsets */
29 /* PSC module states */
30 #define PSC_STATE_SWRSTDISABLE 0
31 #define PSC_STATE_SYNCRST 1
32 #define PSC_STATE_DISABLE 2
33 #define PSC_STATE_ENABLE 3
35 #define MDSTAT_STATE_MASK 0x3f
36 #define MDSTAT_MCKOUT BIT(12)
37 #define PDSTAT_STATE_MASK 0x1f
38 #define MDCTL_FORCE BIT(31)
39 #define MDCTL_LRESET BIT(8)
40 #define PDCTL_NEXT BIT(0)
42 /* Maximum timeout to bail out state transition for module */
43 #define STATE_TRANS_MAX_COUNT 0xffff
45 static void __iomem
*domain_transition_base
;
48 * struct clk_psc_data - PSC data
49 * @control_base: Base address for a PSC control
50 * @domain_base: Base address for a PSC domain
51 * @domain_id: PSC domain id number
54 void __iomem
*control_base
;
55 void __iomem
*domain_base
;
60 * struct clk_psc - PSC clock structure
61 * @hw: clk_hw for the psc
62 * @psc_data: PSC driver specific data
63 * @lock: Spinlock used by the driver
67 struct clk_psc_data
*psc_data
;
71 static DEFINE_SPINLOCK(psc_lock
);
73 #define to_clk_psc(_hw) container_of(_hw, struct clk_psc, hw)
75 static void psc_config(void __iomem
*control_base
, void __iomem
*domain_base
,
76 u32 next_state
, u32 domain_id
)
78 u32 ptcmd
, pdstat
, pdctl
, mdstat
, mdctl
, ptstat
;
79 u32 count
= STATE_TRANS_MAX_COUNT
;
81 mdctl
= readl(control_base
+ MDCTL
);
82 mdctl
&= ~MDSTAT_STATE_MASK
;
84 /* For disable, we always put the module in local reset */
85 if (next_state
== PSC_STATE_DISABLE
)
86 mdctl
&= ~MDCTL_LRESET
;
87 writel(mdctl
, control_base
+ MDCTL
);
89 pdstat
= readl(domain_base
+ PDSTAT
);
90 if (!(pdstat
& PDSTAT_STATE_MASK
)) {
91 pdctl
= readl(domain_base
+ PDCTL
);
93 writel(pdctl
, domain_base
+ PDCTL
);
96 ptcmd
= 1 << domain_id
;
97 writel(ptcmd
, domain_transition_base
+ PTCMD
);
99 ptstat
= readl(domain_transition_base
+ PTSTAT
);
100 } while (((ptstat
>> domain_id
) & 1) && count
--);
102 count
= STATE_TRANS_MAX_COUNT
;
104 mdstat
= readl(control_base
+ MDSTAT
);
105 } while (!((mdstat
& MDSTAT_STATE_MASK
) == next_state
) && count
--);
108 static int keystone_clk_is_enabled(struct clk_hw
*hw
)
110 struct clk_psc
*psc
= to_clk_psc(hw
);
111 struct clk_psc_data
*data
= psc
->psc_data
;
112 u32 mdstat
= readl(data
->control_base
+ MDSTAT
);
114 return (mdstat
& MDSTAT_MCKOUT
) ? 1 : 0;
117 static int keystone_clk_enable(struct clk_hw
*hw
)
119 struct clk_psc
*psc
= to_clk_psc(hw
);
120 struct clk_psc_data
*data
= psc
->psc_data
;
121 unsigned long flags
= 0;
124 spin_lock_irqsave(psc
->lock
, flags
);
126 psc_config(data
->control_base
, data
->domain_base
,
127 PSC_STATE_ENABLE
, data
->domain_id
);
130 spin_unlock_irqrestore(psc
->lock
, flags
);
135 static void keystone_clk_disable(struct clk_hw
*hw
)
137 struct clk_psc
*psc
= to_clk_psc(hw
);
138 struct clk_psc_data
*data
= psc
->psc_data
;
139 unsigned long flags
= 0;
142 spin_lock_irqsave(psc
->lock
, flags
);
144 psc_config(data
->control_base
, data
->domain_base
,
145 PSC_STATE_DISABLE
, data
->domain_id
);
148 spin_unlock_irqrestore(psc
->lock
, flags
);
151 static const struct clk_ops clk_psc_ops
= {
152 .enable
= keystone_clk_enable
,
153 .disable
= keystone_clk_disable
,
154 .is_enabled
= keystone_clk_is_enabled
,
158 * clk_register_psc - register psc clock
159 * @dev: device that is registering this clock
160 * @name: name of this clock
161 * @parent_name: name of clock's parent
162 * @psc_data: platform data to configure this clock
163 * @lock: spinlock used by this clock
165 static struct clk
*clk_register_psc(struct device
*dev
,
167 const char *parent_name
,
168 struct clk_psc_data
*psc_data
,
171 struct clk_init_data init
;
175 psc
= kzalloc(sizeof(*psc
), GFP_KERNEL
);
177 return ERR_PTR(-ENOMEM
);
180 init
.ops
= &clk_psc_ops
;
182 init
.parent_names
= (parent_name
? &parent_name
: NULL
);
183 init
.num_parents
= (parent_name
? 1 : 0);
185 psc
->psc_data
= psc_data
;
187 psc
->hw
.init
= &init
;
189 clk
= clk_register(NULL
, &psc
->hw
);
197 * of_psc_clk_init - initialize psc clock through DT
198 * @node: device tree node for this clock
199 * @lock: spinlock used by this clock
201 static void __init
of_psc_clk_init(struct device_node
*node
, spinlock_t
*lock
)
203 const char *clk_name
= node
->name
;
204 const char *parent_name
;
205 struct clk_psc_data
*data
;
209 data
= kzalloc(sizeof(*data
), GFP_KERNEL
);
211 pr_err("%s: Out of memory\n", __func__
);
215 i
= of_property_match_string(node
, "reg-names", "control");
216 data
->control_base
= of_iomap(node
, i
);
217 if (!data
->control_base
) {
218 pr_err("%s: control ioremap failed\n", __func__
);
222 i
= of_property_match_string(node
, "reg-names", "domain");
223 data
->domain_base
= of_iomap(node
, i
);
224 if (!data
->domain_base
) {
225 pr_err("%s: domain ioremap failed\n", __func__
);
229 of_property_read_u32(node
, "domain-id", &data
->domain_id
);
231 /* Domain transition registers at fixed address space of domain_id 0 */
232 if (!domain_transition_base
&& !data
->domain_id
)
233 domain_transition_base
= data
->domain_base
;
235 of_property_read_string(node
, "clock-output-names", &clk_name
);
236 parent_name
= of_clk_get_parent_name(node
, 0);
238 pr_err("%s: Parent clock not found\n", __func__
);
242 clk
= clk_register_psc(NULL
, clk_name
, parent_name
, data
, lock
);
244 of_clk_add_provider(node
, of_clk_src_simple_get
, clk
);
248 pr_err("%s: error registering clk %pOFn\n", __func__
, node
);
251 iounmap(data
->domain_base
);
253 iounmap(data
->control_base
);
260 * of_keystone_psc_clk_init - initialize psc clock through DT
261 * @node: device tree node for this clock
263 static void __init
of_keystone_psc_clk_init(struct device_node
*node
)
265 of_psc_clk_init(node
, &psc_lock
);
267 CLK_OF_DECLARE(keystone_gate_clk
, "ti,keystone,psc-clock",
268 of_keystone_psc_clk_init
);
270 MODULE_LICENSE("GPL");
271 MODULE_DESCRIPTION("Clock driver for Keystone 2 based devices");
272 MODULE_AUTHOR("Murali Karicheri <m-karicheri2@ti.com>");
273 MODULE_AUTHOR("Santosh Shilimkar <santosh.shilimkar@ti.com>");