1 /* 2 * Copyright 2011-2012 Calxeda, Inc. 3 * Copyright (C) 2012-2013 Altera Corporation <www.altera.com> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * Based from clk-highbank.c 16 * 17 */ 18 #include <linux/slab.h> 19 #include <linux/clk-provider.h> 20 #include <linux/io.h> 21 #include <linux/mfd/syscon.h> 22 #include <linux/of.h> 23 #include <linux/regmap.h> 24 25 #include "clk.h" 26 27 #define SOCFPGA_L4_MP_CLK "l4_mp_clk" 28 #define SOCFPGA_L4_SP_CLK "l4_sp_clk" 29 #define SOCFPGA_NAND_CLK "nand_clk" 30 #define SOCFPGA_NAND_X_CLK "nand_x_clk" 31 #define SOCFPGA_MMC_CLK "sdmmc_clk" 32 #define SOCFPGA_GPIO_DB_CLK_OFFSET 0xA8 33 34 #define to_socfpga_gate_clk(p) container_of(p, struct socfpga_gate_clk, hw.hw) 35 36 /* SDMMC Group for System Manager defines */ 37 #define SYSMGR_SDMMCGRP_CTRL_OFFSET 0x108 38 39 static u8 socfpga_clk_get_parent(struct clk_hw *hwclk) 40 { 41 u32 l4_src; 42 u32 perpll_src; 43 44 if (streq(hwclk->init->name, SOCFPGA_L4_MP_CLK)) { 45 l4_src = readl(clk_mgr_base_addr + CLKMGR_L4SRC); 46 return l4_src &= 0x1; 47 } 48 if (streq(hwclk->init->name, SOCFPGA_L4_SP_CLK)) { 49 l4_src = readl(clk_mgr_base_addr + CLKMGR_L4SRC); 50 return !!(l4_src & 2); 51 } 52 53 perpll_src = readl(clk_mgr_base_addr + CLKMGR_PERPLL_SRC); 54 if (streq(hwclk->init->name, SOCFPGA_MMC_CLK)) 55 return perpll_src &= 0x3; 56 if (streq(hwclk->init->name, SOCFPGA_NAND_CLK) || 57 streq(hwclk->init->name, SOCFPGA_NAND_X_CLK)) 58 return (perpll_src >> 2) & 3; 59 60 /* QSPI clock */ 61 return (perpll_src >> 4) & 3; 62 63 } 64 65 static int socfpga_clk_set_parent(struct clk_hw *hwclk, u8 parent) 66 { 67 u32 src_reg; 68 69 if (streq(hwclk->init->name, SOCFPGA_L4_MP_CLK)) { 70 src_reg = readl(clk_mgr_base_addr + CLKMGR_L4SRC); 71 src_reg &= ~0x1; 72 src_reg |= parent; 73 writel(src_reg, clk_mgr_base_addr + CLKMGR_L4SRC); 74 } else if (streq(hwclk->init->name, SOCFPGA_L4_SP_CLK)) { 75 src_reg = readl(clk_mgr_base_addr + CLKMGR_L4SRC); 76 src_reg &= ~0x2; 77 src_reg |= (parent << 1); 78 writel(src_reg, clk_mgr_base_addr + CLKMGR_L4SRC); 79 } else { 80 src_reg = readl(clk_mgr_base_addr + CLKMGR_PERPLL_SRC); 81 if (streq(hwclk->init->name, SOCFPGA_MMC_CLK)) { 82 src_reg &= ~0x3; 83 src_reg |= parent; 84 } else if (streq(hwclk->init->name, SOCFPGA_NAND_CLK) || 85 streq(hwclk->init->name, SOCFPGA_NAND_X_CLK)) { 86 src_reg &= ~0xC; 87 src_reg |= (parent << 2); 88 } else {/* QSPI clock */ 89 src_reg &= ~0x30; 90 src_reg |= (parent << 4); 91 } 92 writel(src_reg, clk_mgr_base_addr + CLKMGR_PERPLL_SRC); 93 } 94 95 return 0; 96 } 97 98 static unsigned long socfpga_clk_recalc_rate(struct clk_hw *hwclk, 99 unsigned long parent_rate) 100 { 101 struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hwclk); 102 u32 div = 1, val; 103 104 if (socfpgaclk->fixed_div) 105 div = socfpgaclk->fixed_div; 106 else if (socfpgaclk->div_reg) { 107 val = readl(socfpgaclk->div_reg) >> socfpgaclk->shift; 108 val &= GENMASK(socfpgaclk->width - 1, 0); 109 /* Check for GPIO_DB_CLK by its offset */ 110 if ((int) socfpgaclk->div_reg & SOCFPGA_GPIO_DB_CLK_OFFSET) 111 div = val + 1; 112 else 113 div = (1 << val); 114 } 115 116 return parent_rate / div; 117 } 118 119 static int socfpga_clk_prepare(struct clk_hw *hwclk) 120 { 121 struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hwclk); 122 struct regmap *sys_mgr_base_addr; 123 int i; 124 u32 hs_timing; 125 u32 clk_phase[2]; 126 127 if (socfpgaclk->clk_phase[0] || socfpgaclk->clk_phase[1]) { 128 sys_mgr_base_addr = syscon_regmap_lookup_by_compatible("altr,sys-mgr"); 129 if (IS_ERR(sys_mgr_base_addr)) { 130 pr_err("%s: failed to find altr,sys-mgr regmap!\n", __func__); 131 return -EINVAL; 132 } 133 134 for (i = 0; i < 2; i++) { 135 switch (socfpgaclk->clk_phase[i]) { 136 case 0: 137 clk_phase[i] = 0; 138 break; 139 case 45: 140 clk_phase[i] = 1; 141 break; 142 case 90: 143 clk_phase[i] = 2; 144 break; 145 case 135: 146 clk_phase[i] = 3; 147 break; 148 case 180: 149 clk_phase[i] = 4; 150 break; 151 case 225: 152 clk_phase[i] = 5; 153 break; 154 case 270: 155 clk_phase[i] = 6; 156 break; 157 case 315: 158 clk_phase[i] = 7; 159 break; 160 default: 161 clk_phase[i] = 0; 162 break; 163 } 164 } 165 hs_timing = SYSMGR_SDMMC_CTRL_SET(clk_phase[0], clk_phase[1]); 166 regmap_write(sys_mgr_base_addr, SYSMGR_SDMMCGRP_CTRL_OFFSET, 167 hs_timing); 168 } 169 return 0; 170 } 171 172 static struct clk_ops gateclk_ops = { 173 .prepare = socfpga_clk_prepare, 174 .recalc_rate = socfpga_clk_recalc_rate, 175 .get_parent = socfpga_clk_get_parent, 176 .set_parent = socfpga_clk_set_parent, 177 }; 178 179 void __init socfpga_gate_init(struct device_node *node) 180 { 181 u32 clk_gate[2]; 182 u32 div_reg[3]; 183 u32 clk_phase[2]; 184 u32 fixed_div; 185 struct clk *clk; 186 struct socfpga_gate_clk *socfpga_clk; 187 const char *clk_name = node->name; 188 const char *parent_name[SOCFPGA_MAX_PARENTS]; 189 struct clk_init_data init; 190 struct clk_ops *ops; 191 int rc; 192 193 socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL); 194 if (WARN_ON(!socfpga_clk)) 195 return; 196 197 ops = kmemdup(&gateclk_ops, sizeof(gateclk_ops), GFP_KERNEL); 198 if (WARN_ON(!ops)) 199 return; 200 201 rc = of_property_read_u32_array(node, "clk-gate", clk_gate, 2); 202 if (rc) 203 clk_gate[0] = 0; 204 205 if (clk_gate[0]) { 206 socfpga_clk->hw.reg = clk_mgr_base_addr + clk_gate[0]; 207 socfpga_clk->hw.bit_idx = clk_gate[1]; 208 209 ops->enable = clk_gate_ops.enable; 210 ops->disable = clk_gate_ops.disable; 211 } 212 213 rc = of_property_read_u32(node, "fixed-divider", &fixed_div); 214 if (rc) 215 socfpga_clk->fixed_div = 0; 216 else 217 socfpga_clk->fixed_div = fixed_div; 218 219 rc = of_property_read_u32_array(node, "div-reg", div_reg, 3); 220 if (!rc) { 221 socfpga_clk->div_reg = clk_mgr_base_addr + div_reg[0]; 222 socfpga_clk->shift = div_reg[1]; 223 socfpga_clk->width = div_reg[2]; 224 } else { 225 socfpga_clk->div_reg = NULL; 226 } 227 228 rc = of_property_read_u32_array(node, "clk-phase", clk_phase, 2); 229 if (!rc) { 230 socfpga_clk->clk_phase[0] = clk_phase[0]; 231 socfpga_clk->clk_phase[1] = clk_phase[1]; 232 } 233 234 of_property_read_string(node, "clock-output-names", &clk_name); 235 236 init.name = clk_name; 237 init.ops = ops; 238 init.flags = 0; 239 240 init.num_parents = of_clk_parent_fill(node, parent_name, SOCFPGA_MAX_PARENTS); 241 if (init.num_parents < 2) { 242 ops->get_parent = NULL; 243 ops->set_parent = NULL; 244 } 245 246 init.parent_names = parent_name; 247 socfpga_clk->hw.hw.init = &init; 248 249 clk = clk_register(NULL, &socfpga_clk->hw.hw); 250 if (WARN_ON(IS_ERR(clk))) { 251 kfree(socfpga_clk); 252 return; 253 } 254 rc = of_clk_add_provider(node, of_clk_src_simple_get, clk); 255 if (WARN_ON(rc)) 256 return; 257 } 258