1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2015 Altera Corporation. All rights reserved 4 */ 5 #include <linux/slab.h> 6 #include <linux/clk-provider.h> 7 #include <linux/io.h> 8 #include <linux/mfd/syscon.h> 9 #include <linux/of.h> 10 #include <linux/regmap.h> 11 12 #include "clk.h" 13 14 #define streq(a, b) (strcmp((a), (b)) == 0) 15 16 #define to_socfpga_gate_clk(p) container_of(p, struct socfpga_gate_clk, hw.hw) 17 18 /* SDMMC Group for System Manager defines */ 19 #define SYSMGR_SDMMCGRP_CTRL_OFFSET 0x28 20 21 static unsigned long socfpga_gate_clk_recalc_rate(struct clk_hw *hwclk, 22 unsigned long parent_rate) 23 { 24 struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hwclk); 25 u32 div = 1, val; 26 27 if (socfpgaclk->fixed_div) 28 div = socfpgaclk->fixed_div; 29 else if (socfpgaclk->div_reg) { 30 val = readl(socfpgaclk->div_reg) >> socfpgaclk->shift; 31 val &= GENMASK(socfpgaclk->width - 1, 0); 32 div = (1 << val); 33 } 34 35 return parent_rate / div; 36 } 37 38 static int socfpga_clk_prepare(struct clk_hw *hwclk) 39 { 40 struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hwclk); 41 int i; 42 u32 hs_timing; 43 u32 clk_phase[2]; 44 45 if (socfpgaclk->clk_phase[0] || socfpgaclk->clk_phase[1]) { 46 for (i = 0; i < ARRAY_SIZE(clk_phase); i++) { 47 switch (socfpgaclk->clk_phase[i]) { 48 case 0: 49 clk_phase[i] = 0; 50 break; 51 case 45: 52 clk_phase[i] = 1; 53 break; 54 case 90: 55 clk_phase[i] = 2; 56 break; 57 case 135: 58 clk_phase[i] = 3; 59 break; 60 case 180: 61 clk_phase[i] = 4; 62 break; 63 case 225: 64 clk_phase[i] = 5; 65 break; 66 case 270: 67 clk_phase[i] = 6; 68 break; 69 case 315: 70 clk_phase[i] = 7; 71 break; 72 default: 73 clk_phase[i] = 0; 74 break; 75 } 76 } 77 78 hs_timing = SYSMGR_SDMMC_CTRL_SET_AS10(clk_phase[0], clk_phase[1]); 79 if (!IS_ERR(socfpgaclk->sys_mgr_base_addr)) 80 regmap_write(socfpgaclk->sys_mgr_base_addr, 81 SYSMGR_SDMMCGRP_CTRL_OFFSET, hs_timing); 82 else 83 pr_err("%s: cannot set clk_phase because sys_mgr_base_addr is not available!\n", 84 __func__); 85 } 86 return 0; 87 } 88 89 static struct clk_ops gateclk_ops = { 90 .prepare = socfpga_clk_prepare, 91 .recalc_rate = socfpga_gate_clk_recalc_rate, 92 }; 93 94 static void __init __socfpga_gate_init(struct device_node *node, 95 const struct clk_ops *ops) 96 { 97 u32 clk_gate[2]; 98 u32 div_reg[3]; 99 u32 clk_phase[2]; 100 u32 fixed_div; 101 struct clk_hw *hw_clk; 102 struct socfpga_gate_clk *socfpga_clk; 103 const char *clk_name = node->name; 104 const char *parent_name[SOCFPGA_MAX_PARENTS]; 105 struct clk_init_data init; 106 int rc; 107 108 socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL); 109 if (WARN_ON(!socfpga_clk)) 110 return; 111 112 rc = of_property_read_u32_array(node, "clk-gate", clk_gate, 2); 113 if (rc) 114 clk_gate[0] = 0; 115 116 if (clk_gate[0]) { 117 socfpga_clk->hw.reg = clk_mgr_a10_base_addr + clk_gate[0]; 118 socfpga_clk->hw.bit_idx = clk_gate[1]; 119 120 gateclk_ops.enable = clk_gate_ops.enable; 121 gateclk_ops.disable = clk_gate_ops.disable; 122 } 123 124 rc = of_property_read_u32(node, "fixed-divider", &fixed_div); 125 if (rc) 126 socfpga_clk->fixed_div = 0; 127 else 128 socfpga_clk->fixed_div = fixed_div; 129 130 rc = of_property_read_u32_array(node, "div-reg", div_reg, 3); 131 if (!rc) { 132 socfpga_clk->div_reg = clk_mgr_a10_base_addr + div_reg[0]; 133 socfpga_clk->shift = div_reg[1]; 134 socfpga_clk->width = div_reg[2]; 135 } else { 136 socfpga_clk->div_reg = NULL; 137 } 138 139 rc = of_property_read_u32_array(node, "clk-phase", clk_phase, 2); 140 if (!rc) { 141 socfpga_clk->clk_phase[0] = clk_phase[0]; 142 socfpga_clk->clk_phase[1] = clk_phase[1]; 143 144 socfpga_clk->sys_mgr_base_addr = 145 syscon_regmap_lookup_by_compatible("altr,sys-mgr"); 146 if (IS_ERR(socfpga_clk->sys_mgr_base_addr)) { 147 pr_err("%s: failed to find altr,sys-mgr regmap!\n", 148 __func__); 149 kfree(socfpga_clk); 150 return; 151 } 152 } 153 154 of_property_read_string(node, "clock-output-names", &clk_name); 155 156 init.name = clk_name; 157 init.ops = ops; 158 init.flags = 0; 159 160 init.num_parents = of_clk_parent_fill(node, parent_name, SOCFPGA_MAX_PARENTS); 161 init.parent_names = parent_name; 162 socfpga_clk->hw.hw.init = &init; 163 hw_clk = &socfpga_clk->hw.hw; 164 165 if (clk_hw_register(NULL, hw_clk)) { 166 kfree(socfpga_clk); 167 return; 168 } 169 rc = of_clk_add_provider(node, of_clk_src_simple_get, hw_clk); 170 if (WARN_ON(rc)) 171 return; 172 } 173 174 void __init socfpga_a10_gate_init(struct device_node *node) 175 { 176 __socfpga_gate_init(node, &gateclk_ops); 177 } 178