Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Clock driver for Keystone 2 based devices
0004  *
0005  * Copyright (C) 2013 Texas Instruments.
0006  *  Murali Karicheri <m-karicheri2@ti.com>
0007  *  Santosh Shilimkar <santosh.shilimkar@ti.com>
0008  */
0009 #include <linux/clk-provider.h>
0010 #include <linux/err.h>
0011 #include <linux/io.h>
0012 #include <linux/slab.h>
0013 #include <linux/of_address.h>
0014 #include <linux/of.h>
0015 #include <linux/module.h>
0016 
0017 /* PSC register offsets */
0018 #define PTCMD           0x120
0019 #define PTSTAT          0x128
0020 #define PDSTAT          0x200
0021 #define PDCTL           0x300
0022 #define MDSTAT          0x800
0023 #define MDCTL           0xa00
0024 
0025 /* PSC module states */
0026 #define PSC_STATE_SWRSTDISABLE  0
0027 #define PSC_STATE_SYNCRST   1
0028 #define PSC_STATE_DISABLE   2
0029 #define PSC_STATE_ENABLE    3
0030 
0031 #define MDSTAT_STATE_MASK   0x3f
0032 #define MDSTAT_MCKOUT       BIT(12)
0033 #define PDSTAT_STATE_MASK   0x1f
0034 #define MDCTL_FORCE     BIT(31)
0035 #define MDCTL_LRESET        BIT(8)
0036 #define PDCTL_NEXT      BIT(0)
0037 
0038 /* Maximum timeout to bail out state transition for module */
0039 #define STATE_TRANS_MAX_COUNT   0xffff
0040 
0041 static void __iomem *domain_transition_base;
0042 
0043 /**
0044  * struct clk_psc_data - PSC data
0045  * @control_base: Base address for a PSC control
0046  * @domain_base: Base address for a PSC domain
0047  * @domain_id: PSC domain id number
0048  */
0049 struct clk_psc_data {
0050     void __iomem *control_base;
0051     void __iomem *domain_base;
0052     u32 domain_id;
0053 };
0054 
0055 /**
0056  * struct clk_psc - PSC clock structure
0057  * @hw: clk_hw for the psc
0058  * @psc_data: PSC driver specific data
0059  * @lock: Spinlock used by the driver
0060  */
0061 struct clk_psc {
0062     struct clk_hw hw;
0063     struct clk_psc_data *psc_data;
0064     spinlock_t *lock;
0065 };
0066 
0067 static DEFINE_SPINLOCK(psc_lock);
0068 
0069 #define to_clk_psc(_hw) container_of(_hw, struct clk_psc, hw)
0070 
0071 static void psc_config(void __iomem *control_base, void __iomem *domain_base,
0072                         u32 next_state, u32 domain_id)
0073 {
0074     u32 ptcmd, pdstat, pdctl, mdstat, mdctl, ptstat;
0075     u32 count = STATE_TRANS_MAX_COUNT;
0076 
0077     mdctl = readl(control_base + MDCTL);
0078     mdctl &= ~MDSTAT_STATE_MASK;
0079     mdctl |= next_state;
0080     /* For disable, we always put the module in local reset */
0081     if (next_state == PSC_STATE_DISABLE)
0082         mdctl &= ~MDCTL_LRESET;
0083     writel(mdctl, control_base + MDCTL);
0084 
0085     pdstat = readl(domain_base + PDSTAT);
0086     if (!(pdstat & PDSTAT_STATE_MASK)) {
0087         pdctl = readl(domain_base + PDCTL);
0088         pdctl |= PDCTL_NEXT;
0089         writel(pdctl, domain_base + PDCTL);
0090     }
0091 
0092     ptcmd = 1 << domain_id;
0093     writel(ptcmd, domain_transition_base + PTCMD);
0094     do {
0095         ptstat = readl(domain_transition_base + PTSTAT);
0096     } while (((ptstat >> domain_id) & 1) && count--);
0097 
0098     count = STATE_TRANS_MAX_COUNT;
0099     do {
0100         mdstat = readl(control_base + MDSTAT);
0101     } while (!((mdstat & MDSTAT_STATE_MASK) == next_state) && count--);
0102 }
0103 
0104 static int keystone_clk_is_enabled(struct clk_hw *hw)
0105 {
0106     struct clk_psc *psc = to_clk_psc(hw);
0107     struct clk_psc_data *data = psc->psc_data;
0108     u32 mdstat = readl(data->control_base + MDSTAT);
0109 
0110     return (mdstat & MDSTAT_MCKOUT) ? 1 : 0;
0111 }
0112 
0113 static int keystone_clk_enable(struct clk_hw *hw)
0114 {
0115     struct clk_psc *psc = to_clk_psc(hw);
0116     struct clk_psc_data *data = psc->psc_data;
0117     unsigned long flags = 0;
0118 
0119     if (psc->lock)
0120         spin_lock_irqsave(psc->lock, flags);
0121 
0122     psc_config(data->control_base, data->domain_base,
0123                 PSC_STATE_ENABLE, data->domain_id);
0124 
0125     if (psc->lock)
0126         spin_unlock_irqrestore(psc->lock, flags);
0127 
0128     return 0;
0129 }
0130 
0131 static void keystone_clk_disable(struct clk_hw *hw)
0132 {
0133     struct clk_psc *psc = to_clk_psc(hw);
0134     struct clk_psc_data *data = psc->psc_data;
0135     unsigned long flags = 0;
0136 
0137     if (psc->lock)
0138         spin_lock_irqsave(psc->lock, flags);
0139 
0140     psc_config(data->control_base, data->domain_base,
0141                 PSC_STATE_DISABLE, data->domain_id);
0142 
0143     if (psc->lock)
0144         spin_unlock_irqrestore(psc->lock, flags);
0145 }
0146 
0147 static const struct clk_ops clk_psc_ops = {
0148     .enable = keystone_clk_enable,
0149     .disable = keystone_clk_disable,
0150     .is_enabled = keystone_clk_is_enabled,
0151 };
0152 
0153 /**
0154  * clk_register_psc - register psc clock
0155  * @dev: device that is registering this clock
0156  * @name: name of this clock
0157  * @parent_name: name of clock's parent
0158  * @psc_data: platform data to configure this clock
0159  * @lock: spinlock used by this clock
0160  */
0161 static struct clk *clk_register_psc(struct device *dev,
0162             const char *name,
0163             const char *parent_name,
0164             struct clk_psc_data *psc_data,
0165             spinlock_t *lock)
0166 {
0167     struct clk_init_data init;
0168     struct clk_psc *psc;
0169     struct clk *clk;
0170 
0171     psc = kzalloc(sizeof(*psc), GFP_KERNEL);
0172     if (!psc)
0173         return ERR_PTR(-ENOMEM);
0174 
0175     init.name = name;
0176     init.ops = &clk_psc_ops;
0177     init.flags = 0;
0178     init.parent_names = (parent_name ? &parent_name : NULL);
0179     init.num_parents = (parent_name ? 1 : 0);
0180 
0181     psc->psc_data = psc_data;
0182     psc->lock = lock;
0183     psc->hw.init = &init;
0184 
0185     clk = clk_register(NULL, &psc->hw);
0186     if (IS_ERR(clk))
0187         kfree(psc);
0188 
0189     return clk;
0190 }
0191 
0192 /**
0193  * of_psc_clk_init - initialize psc clock through DT
0194  * @node: device tree node for this clock
0195  * @lock: spinlock used by this clock
0196  */
0197 static void __init of_psc_clk_init(struct device_node *node, spinlock_t *lock)
0198 {
0199     const char *clk_name = node->name;
0200     const char *parent_name;
0201     struct clk_psc_data *data;
0202     struct clk *clk;
0203     int i;
0204 
0205     data = kzalloc(sizeof(*data), GFP_KERNEL);
0206     if (!data) {
0207         pr_err("%s: Out of memory\n", __func__);
0208         return;
0209     }
0210 
0211     i = of_property_match_string(node, "reg-names", "control");
0212     data->control_base = of_iomap(node, i);
0213     if (!data->control_base) {
0214         pr_err("%s: control ioremap failed\n", __func__);
0215         goto out;
0216     }
0217 
0218     i = of_property_match_string(node, "reg-names", "domain");
0219     data->domain_base = of_iomap(node, i);
0220     if (!data->domain_base) {
0221         pr_err("%s: domain ioremap failed\n", __func__);
0222         goto unmap_ctrl;
0223     }
0224 
0225     of_property_read_u32(node, "domain-id", &data->domain_id);
0226 
0227     /* Domain transition registers at fixed address space of domain_id 0 */
0228     if (!domain_transition_base && !data->domain_id)
0229         domain_transition_base = data->domain_base;
0230 
0231     of_property_read_string(node, "clock-output-names", &clk_name);
0232     parent_name = of_clk_get_parent_name(node, 0);
0233     if (!parent_name) {
0234         pr_err("%s: Parent clock not found\n", __func__);
0235         goto unmap_domain;
0236     }
0237 
0238     clk = clk_register_psc(NULL, clk_name, parent_name, data, lock);
0239     if (!IS_ERR(clk)) {
0240         of_clk_add_provider(node, of_clk_src_simple_get, clk);
0241         return;
0242     }
0243 
0244     pr_err("%s: error registering clk %pOFn\n", __func__, node);
0245 
0246 unmap_domain:
0247     iounmap(data->domain_base);
0248 unmap_ctrl:
0249     iounmap(data->control_base);
0250 out:
0251     kfree(data);
0252     return;
0253 }
0254 
0255 /**
0256  * of_keystone_psc_clk_init - initialize psc clock through DT
0257  * @node: device tree node for this clock
0258  */
0259 static void __init of_keystone_psc_clk_init(struct device_node *node)
0260 {
0261     of_psc_clk_init(node, &psc_lock);
0262 }
0263 CLK_OF_DECLARE(keystone_gate_clk, "ti,keystone,psc-clock",
0264                     of_keystone_psc_clk_init);
0265 
0266 MODULE_LICENSE("GPL");
0267 MODULE_DESCRIPTION("Clock driver for Keystone 2 based devices");
0268 MODULE_AUTHOR("Murali Karicheri <m-karicheri2@ti.com>");
0269 MODULE_AUTHOR("Santosh Shilimkar <santosh.shilimkar@ti.com>");