1 /* 2 * Copyright (C) 2013 Emilio López <emilio@elopez.com.ar> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 * 8 * Adjustable factor-based clock implementation 9 */ 10 11 #include <linux/clk-provider.h> 12 #include <linux/module.h> 13 #include <linux/slab.h> 14 #include <linux/io.h> 15 #include <linux/err.h> 16 #include <linux/string.h> 17 18 #include <linux/delay.h> 19 20 #include "clk-factors.h" 21 22 /* 23 * DOC: basic adjustable factor-based clock that cannot gate 24 * 25 * Traits of this clock: 26 * prepare - clk_prepare only ensures that parents are prepared 27 * enable - clk_enable only ensures that parents are enabled 28 * rate - rate is adjustable. 29 * clk->rate = (parent->rate * N * (K + 1) >> P) / (M + 1) 30 * parent - fixed parent. No clk_set_parent support 31 */ 32 33 struct clk_factors { 34 struct clk_hw hw; 35 void __iomem *reg; 36 struct clk_factors_config *config; 37 void (*get_factors) (u32 *rate, u32 parent, u8 *n, u8 *k, u8 *m, u8 *p); 38 spinlock_t *lock; 39 }; 40 41 #define to_clk_factors(_hw) container_of(_hw, struct clk_factors, hw) 42 43 #define SETMASK(len, pos) (((-1U) >> (31-len)) << (pos)) 44 #define CLRMASK(len, pos) (~(SETMASK(len, pos))) 45 #define FACTOR_GET(bit, len, reg) (((reg) & SETMASK(len, bit)) >> (bit)) 46 47 #define FACTOR_SET(bit, len, reg, val) \ 48 (((reg) & CLRMASK(len, bit)) | (val << (bit))) 49 50 static unsigned long clk_factors_recalc_rate(struct clk_hw *hw, 51 unsigned long parent_rate) 52 { 53 u8 n = 1, k = 0, p = 0, m = 0; 54 u32 reg; 55 unsigned long rate; 56 struct clk_factors *factors = to_clk_factors(hw); 57 struct clk_factors_config *config = factors->config; 58 59 /* Fetch the register value */ 60 reg = readl(factors->reg); 61 62 /* Get each individual factor if applicable */ 63 if (config->nwidth != SUNXI_FACTORS_NOT_APPLICABLE) 64 n = FACTOR_GET(config->nshift, config->nwidth, reg); 65 if (config->kwidth != SUNXI_FACTORS_NOT_APPLICABLE) 66 k = FACTOR_GET(config->kshift, config->kwidth, reg); 67 if (config->mwidth != SUNXI_FACTORS_NOT_APPLICABLE) 68 m = FACTOR_GET(config->mshift, config->mwidth, reg); 69 if (config->pwidth != SUNXI_FACTORS_NOT_APPLICABLE) 70 p = FACTOR_GET(config->pshift, config->pwidth, reg); 71 72 /* Calculate the rate */ 73 rate = (parent_rate * n * (k + 1) >> p) / (m + 1); 74 75 return rate; 76 } 77 78 static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate, 79 unsigned long *parent_rate) 80 { 81 struct clk_factors *factors = to_clk_factors(hw); 82 factors->get_factors((u32 *)&rate, (u32)*parent_rate, 83 NULL, NULL, NULL, NULL); 84 85 return rate; 86 } 87 88 static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate, 89 unsigned long parent_rate) 90 { 91 u8 n, k, m, p; 92 u32 reg; 93 struct clk_factors *factors = to_clk_factors(hw); 94 struct clk_factors_config *config = factors->config; 95 unsigned long flags = 0; 96 97 factors->get_factors((u32 *)&rate, (u32)parent_rate, &n, &k, &m, &p); 98 99 if (factors->lock) 100 spin_lock_irqsave(factors->lock, flags); 101 102 /* Fetch the register value */ 103 reg = readl(factors->reg); 104 105 /* Set up the new factors - macros do not do anything if width is 0 */ 106 reg = FACTOR_SET(config->nshift, config->nwidth, reg, n); 107 reg = FACTOR_SET(config->kshift, config->kwidth, reg, k); 108 reg = FACTOR_SET(config->mshift, config->mwidth, reg, m); 109 reg = FACTOR_SET(config->pshift, config->pwidth, reg, p); 110 111 /* Apply them now */ 112 writel(reg, factors->reg); 113 114 /* delay 500us so pll stabilizes */ 115 __delay((rate >> 20) * 500 / 2); 116 117 if (factors->lock) 118 spin_unlock_irqrestore(factors->lock, flags); 119 120 return 0; 121 } 122 123 static const struct clk_ops clk_factors_ops = { 124 .recalc_rate = clk_factors_recalc_rate, 125 .round_rate = clk_factors_round_rate, 126 .set_rate = clk_factors_set_rate, 127 }; 128 129 /** 130 * clk_register_factors - register a factors clock with 131 * the clock framework 132 * @dev: device registering this clock 133 * @name: name of this clock 134 * @parent_name: name of clock's parent 135 * @flags: framework-specific flags 136 * @reg: register address to adjust factors 137 * @config: shift and width of factors n, k, m and p 138 * @get_factors: function to calculate the factors for a given frequency 139 * @lock: shared register lock for this clock 140 */ 141 struct clk *clk_register_factors(struct device *dev, const char *name, 142 const char *parent_name, 143 unsigned long flags, void __iomem *reg, 144 struct clk_factors_config *config, 145 void (*get_factors)(u32 *rate, u32 parent, 146 u8 *n, u8 *k, u8 *m, u8 *p), 147 spinlock_t *lock) 148 { 149 struct clk_factors *factors; 150 struct clk *clk; 151 struct clk_init_data init; 152 153 /* allocate the factors */ 154 factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL); 155 if (!factors) { 156 pr_err("%s: could not allocate factors clk\n", __func__); 157 return ERR_PTR(-ENOMEM); 158 } 159 160 init.name = name; 161 init.ops = &clk_factors_ops; 162 init.flags = flags; 163 init.parent_names = (parent_name ? &parent_name : NULL); 164 init.num_parents = (parent_name ? 1 : 0); 165 166 /* struct clk_factors assignments */ 167 factors->reg = reg; 168 factors->config = config; 169 factors->lock = lock; 170 factors->hw.init = &init; 171 factors->get_factors = get_factors; 172 173 /* register the clock */ 174 clk = clk_register(dev, &factors->hw); 175 176 if (IS_ERR(clk)) 177 kfree(factors); 178 179 return clk; 180 } 181