1 /* 2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms and conditions of the GNU General Public License, 6 * version 2, as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 * more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 */ 16 17 #include <linux/clk.h> 18 #include <linux/clk-provider.h> 19 #include <linux/of.h> 20 #include <linux/clk/tegra.h> 21 #include <linux/reset-controller.h> 22 23 #include <soc/tegra/fuse.h> 24 25 #include "clk.h" 26 27 #define CLK_OUT_ENB_L 0x010 28 #define CLK_OUT_ENB_H 0x014 29 #define CLK_OUT_ENB_U 0x018 30 #define CLK_OUT_ENB_V 0x360 31 #define CLK_OUT_ENB_W 0x364 32 #define CLK_OUT_ENB_X 0x280 33 #define CLK_OUT_ENB_SET_L 0x320 34 #define CLK_OUT_ENB_CLR_L 0x324 35 #define CLK_OUT_ENB_SET_H 0x328 36 #define CLK_OUT_ENB_CLR_H 0x32c 37 #define CLK_OUT_ENB_SET_U 0x330 38 #define CLK_OUT_ENB_CLR_U 0x334 39 #define CLK_OUT_ENB_SET_V 0x440 40 #define CLK_OUT_ENB_CLR_V 0x444 41 #define CLK_OUT_ENB_SET_W 0x448 42 #define CLK_OUT_ENB_CLR_W 0x44c 43 #define CLK_OUT_ENB_SET_X 0x284 44 #define CLK_OUT_ENB_CLR_X 0x288 45 46 #define RST_DEVICES_L 0x004 47 #define RST_DEVICES_H 0x008 48 #define RST_DEVICES_U 0x00C 49 #define RST_DFLL_DVCO 0x2F4 50 #define RST_DEVICES_V 0x358 51 #define RST_DEVICES_W 0x35C 52 #define RST_DEVICES_X 0x28C 53 #define RST_DEVICES_SET_L 0x300 54 #define RST_DEVICES_CLR_L 0x304 55 #define RST_DEVICES_SET_H 0x308 56 #define RST_DEVICES_CLR_H 0x30c 57 #define RST_DEVICES_SET_U 0x310 58 #define RST_DEVICES_CLR_U 0x314 59 #define RST_DEVICES_SET_V 0x430 60 #define RST_DEVICES_CLR_V 0x434 61 #define RST_DEVICES_SET_W 0x438 62 #define RST_DEVICES_CLR_W 0x43c 63 #define RST_DEVICES_SET_X 0x290 64 #define RST_DEVICES_CLR_X 0x294 65 66 /* Global data of Tegra CPU CAR ops */ 67 static struct tegra_cpu_car_ops dummy_car_ops; 68 struct tegra_cpu_car_ops *tegra_cpu_car_ops = &dummy_car_ops; 69 70 int *periph_clk_enb_refcnt; 71 static int periph_banks; 72 static struct clk **clks; 73 static int clk_num; 74 static struct clk_onecell_data clk_data; 75 76 static struct tegra_clk_periph_regs periph_regs[] = { 77 [0] = { 78 .enb_reg = CLK_OUT_ENB_L, 79 .enb_set_reg = CLK_OUT_ENB_SET_L, 80 .enb_clr_reg = CLK_OUT_ENB_CLR_L, 81 .rst_reg = RST_DEVICES_L, 82 .rst_set_reg = RST_DEVICES_SET_L, 83 .rst_clr_reg = RST_DEVICES_CLR_L, 84 }, 85 [1] = { 86 .enb_reg = CLK_OUT_ENB_H, 87 .enb_set_reg = CLK_OUT_ENB_SET_H, 88 .enb_clr_reg = CLK_OUT_ENB_CLR_H, 89 .rst_reg = RST_DEVICES_H, 90 .rst_set_reg = RST_DEVICES_SET_H, 91 .rst_clr_reg = RST_DEVICES_CLR_H, 92 }, 93 [2] = { 94 .enb_reg = CLK_OUT_ENB_U, 95 .enb_set_reg = CLK_OUT_ENB_SET_U, 96 .enb_clr_reg = CLK_OUT_ENB_CLR_U, 97 .rst_reg = RST_DEVICES_U, 98 .rst_set_reg = RST_DEVICES_SET_U, 99 .rst_clr_reg = RST_DEVICES_CLR_U, 100 }, 101 [3] = { 102 .enb_reg = CLK_OUT_ENB_V, 103 .enb_set_reg = CLK_OUT_ENB_SET_V, 104 .enb_clr_reg = CLK_OUT_ENB_CLR_V, 105 .rst_reg = RST_DEVICES_V, 106 .rst_set_reg = RST_DEVICES_SET_V, 107 .rst_clr_reg = RST_DEVICES_CLR_V, 108 }, 109 [4] = { 110 .enb_reg = CLK_OUT_ENB_W, 111 .enb_set_reg = CLK_OUT_ENB_SET_W, 112 .enb_clr_reg = CLK_OUT_ENB_CLR_W, 113 .rst_reg = RST_DEVICES_W, 114 .rst_set_reg = RST_DEVICES_SET_W, 115 .rst_clr_reg = RST_DEVICES_CLR_W, 116 }, 117 [5] = { 118 .enb_reg = CLK_OUT_ENB_X, 119 .enb_set_reg = CLK_OUT_ENB_SET_X, 120 .enb_clr_reg = CLK_OUT_ENB_CLR_X, 121 .rst_reg = RST_DEVICES_X, 122 .rst_set_reg = RST_DEVICES_SET_X, 123 .rst_clr_reg = RST_DEVICES_CLR_X, 124 }, 125 }; 126 127 static void __iomem *clk_base; 128 129 static int tegra_clk_rst_assert(struct reset_controller_dev *rcdev, 130 unsigned long id) 131 { 132 /* 133 * If peripheral is on the APB bus then we must read the APB bus to 134 * flush the write operation in apb bus. This will avoid peripheral 135 * access after disabling clock. Since the reset driver has no 136 * knowledge of which reset IDs represent which devices, simply do 137 * this all the time. 138 */ 139 tegra_read_chipid(); 140 141 writel_relaxed(BIT(id % 32), 142 clk_base + periph_regs[id / 32].rst_set_reg); 143 144 return 0; 145 } 146 147 static int tegra_clk_rst_deassert(struct reset_controller_dev *rcdev, 148 unsigned long id) 149 { 150 writel_relaxed(BIT(id % 32), 151 clk_base + periph_regs[id / 32].rst_clr_reg); 152 153 return 0; 154 } 155 156 struct tegra_clk_periph_regs *get_reg_bank(int clkid) 157 { 158 int reg_bank = clkid / 32; 159 160 if (reg_bank < periph_banks) 161 return &periph_regs[reg_bank]; 162 else { 163 WARN_ON(1); 164 return NULL; 165 } 166 } 167 168 struct clk ** __init tegra_clk_init(void __iomem *regs, int num, int banks) 169 { 170 clk_base = regs; 171 172 if (WARN_ON(banks > ARRAY_SIZE(periph_regs))) 173 return NULL; 174 175 periph_clk_enb_refcnt = kzalloc(32 * banks * 176 sizeof(*periph_clk_enb_refcnt), GFP_KERNEL); 177 if (!periph_clk_enb_refcnt) 178 return NULL; 179 180 periph_banks = banks; 181 182 clks = kzalloc(num * sizeof(struct clk *), GFP_KERNEL); 183 if (!clks) 184 kfree(periph_clk_enb_refcnt); 185 186 clk_num = num; 187 188 return clks; 189 } 190 191 void __init tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list, 192 struct clk *clks[], int clk_max) 193 { 194 struct clk *clk; 195 196 for (; dup_list->clk_id < clk_max; dup_list++) { 197 clk = clks[dup_list->clk_id]; 198 dup_list->lookup.clk = clk; 199 clkdev_add(&dup_list->lookup); 200 } 201 } 202 203 void __init tegra_init_from_table(struct tegra_clk_init_table *tbl, 204 struct clk *clks[], int clk_max) 205 { 206 struct clk *clk; 207 208 for (; tbl->clk_id < clk_max; tbl++) { 209 clk = clks[tbl->clk_id]; 210 if (IS_ERR_OR_NULL(clk)) { 211 pr_err("%s: invalid entry %ld in clks array for id %d\n", 212 __func__, PTR_ERR(clk), tbl->clk_id); 213 WARN_ON(1); 214 215 continue; 216 } 217 218 if (tbl->parent_id < clk_max) { 219 struct clk *parent = clks[tbl->parent_id]; 220 if (clk_set_parent(clk, parent)) { 221 pr_err("%s: Failed to set parent %s of %s\n", 222 __func__, __clk_get_name(parent), 223 __clk_get_name(clk)); 224 WARN_ON(1); 225 } 226 } 227 228 if (tbl->rate) 229 if (clk_set_rate(clk, tbl->rate)) { 230 pr_err("%s: Failed to set rate %lu of %s\n", 231 __func__, tbl->rate, 232 __clk_get_name(clk)); 233 WARN_ON(1); 234 } 235 236 if (tbl->state) 237 if (clk_prepare_enable(clk)) { 238 pr_err("%s: Failed to enable %s\n", __func__, 239 __clk_get_name(clk)); 240 WARN_ON(1); 241 } 242 } 243 } 244 245 static struct reset_control_ops rst_ops = { 246 .assert = tegra_clk_rst_assert, 247 .deassert = tegra_clk_rst_deassert, 248 }; 249 250 static struct reset_controller_dev rst_ctlr = { 251 .ops = &rst_ops, 252 .owner = THIS_MODULE, 253 .of_reset_n_cells = 1, 254 }; 255 256 void __init tegra_add_of_provider(struct device_node *np) 257 { 258 int i; 259 260 for (i = 0; i < clk_num; i++) { 261 if (IS_ERR(clks[i])) { 262 pr_err 263 ("Tegra clk %d: register failed with %ld\n", 264 i, PTR_ERR(clks[i])); 265 } 266 if (!clks[i]) 267 clks[i] = ERR_PTR(-EINVAL); 268 } 269 270 clk_data.clks = clks; 271 clk_data.clk_num = clk_num; 272 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); 273 274 rst_ctlr.of_node = np; 275 rst_ctlr.nr_resets = clk_num * 32; 276 reset_controller_register(&rst_ctlr); 277 } 278 279 void __init tegra_register_devclks(struct tegra_devclk *dev_clks, int num) 280 { 281 int i; 282 283 for (i = 0; i < num; i++, dev_clks++) 284 clk_register_clkdev(clks[dev_clks->dt_id], dev_clks->con_id, 285 dev_clks->dev_id); 286 287 for (i = 0; i < clk_num; i++) { 288 if (!IS_ERR_OR_NULL(clks[i])) 289 clk_register_clkdev(clks[i], __clk_get_name(clks[i]), 290 "tegra-clk-debug"); 291 } 292 } 293 294 struct clk ** __init tegra_lookup_dt_id(int clk_id, 295 struct tegra_clk *tegra_clk) 296 { 297 if (tegra_clk[clk_id].present) 298 return &clks[tegra_clk[clk_id].dt_id]; 299 else 300 return NULL; 301 } 302 303 tegra_clk_apply_init_table_func tegra_clk_apply_init_table; 304 305 void __init tegra_clocks_apply_init_table(void) 306 { 307 if (!tegra_clk_apply_init_table) 308 return; 309 310 tegra_clk_apply_init_table(); 311 } 312