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