clk.c (4194B)
1// SPDX-License-Identifier: GPL-2.0 2#include <linux/io.h> 3#include <linux/clk-provider.h> 4#include <linux/slab.h> 5#include <linux/of.h> 6#include <linux/of_address.h> 7 8#include "clk.h" 9 10void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit, 11 int nr_clks) 12{ 13 struct clk **clk_table; 14 15 clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL); 16 if (!clk_table) 17 return; 18 19 unit->clk_table = clk_table; 20 unit->nr_clks = nr_clks; 21 unit->clk_data.clks = clk_table; 22 unit->clk_data.clk_num = nr_clks; 23 of_clk_add_provider(np, of_clk_src_onecell_get, &unit->clk_data); 24} 25 26void mmp_register_fixed_rate_clks(struct mmp_clk_unit *unit, 27 struct mmp_param_fixed_rate_clk *clks, 28 int size) 29{ 30 int i; 31 struct clk *clk; 32 33 for (i = 0; i < size; i++) { 34 clk = clk_register_fixed_rate(NULL, clks[i].name, 35 clks[i].parent_name, 36 clks[i].flags, 37 clks[i].fixed_rate); 38 if (IS_ERR(clk)) { 39 pr_err("%s: failed to register clock %s\n", 40 __func__, clks[i].name); 41 continue; 42 } 43 if (clks[i].id) 44 unit->clk_table[clks[i].id] = clk; 45 } 46} 47 48void mmp_register_fixed_factor_clks(struct mmp_clk_unit *unit, 49 struct mmp_param_fixed_factor_clk *clks, 50 int size) 51{ 52 struct clk *clk; 53 int i; 54 55 for (i = 0; i < size; i++) { 56 clk = clk_register_fixed_factor(NULL, clks[i].name, 57 clks[i].parent_name, 58 clks[i].flags, clks[i].mult, 59 clks[i].div); 60 if (IS_ERR(clk)) { 61 pr_err("%s: failed to register clock %s\n", 62 __func__, clks[i].name); 63 continue; 64 } 65 if (clks[i].id) 66 unit->clk_table[clks[i].id] = clk; 67 } 68} 69 70void mmp_register_general_gate_clks(struct mmp_clk_unit *unit, 71 struct mmp_param_general_gate_clk *clks, 72 void __iomem *base, int size) 73{ 74 struct clk *clk; 75 int i; 76 77 for (i = 0; i < size; i++) { 78 clk = clk_register_gate(NULL, clks[i].name, 79 clks[i].parent_name, 80 clks[i].flags, 81 base + clks[i].offset, 82 clks[i].bit_idx, 83 clks[i].gate_flags, 84 clks[i].lock); 85 86 if (IS_ERR(clk)) { 87 pr_err("%s: failed to register clock %s\n", 88 __func__, clks[i].name); 89 continue; 90 } 91 if (clks[i].id) 92 unit->clk_table[clks[i].id] = clk; 93 } 94} 95 96void mmp_register_gate_clks(struct mmp_clk_unit *unit, 97 struct mmp_param_gate_clk *clks, 98 void __iomem *base, int size) 99{ 100 struct clk *clk; 101 int i; 102 103 for (i = 0; i < size; i++) { 104 clk = mmp_clk_register_gate(NULL, clks[i].name, 105 clks[i].parent_name, 106 clks[i].flags, 107 base + clks[i].offset, 108 clks[i].mask, 109 clks[i].val_enable, 110 clks[i].val_disable, 111 clks[i].gate_flags, 112 clks[i].lock); 113 114 if (IS_ERR(clk)) { 115 pr_err("%s: failed to register clock %s\n", 116 __func__, clks[i].name); 117 continue; 118 } 119 if (clks[i].id) 120 unit->clk_table[clks[i].id] = clk; 121 } 122} 123 124void mmp_register_mux_clks(struct mmp_clk_unit *unit, 125 struct mmp_param_mux_clk *clks, 126 void __iomem *base, int size) 127{ 128 struct clk *clk; 129 int i; 130 131 for (i = 0; i < size; i++) { 132 clk = clk_register_mux(NULL, clks[i].name, 133 clks[i].parent_name, 134 clks[i].num_parents, 135 clks[i].flags, 136 base + clks[i].offset, 137 clks[i].shift, 138 clks[i].width, 139 clks[i].mux_flags, 140 clks[i].lock); 141 142 if (IS_ERR(clk)) { 143 pr_err("%s: failed to register clock %s\n", 144 __func__, clks[i].name); 145 continue; 146 } 147 if (clks[i].id) 148 unit->clk_table[clks[i].id] = clk; 149 } 150} 151 152void mmp_register_div_clks(struct mmp_clk_unit *unit, 153 struct mmp_param_div_clk *clks, 154 void __iomem *base, int size) 155{ 156 struct clk *clk; 157 int i; 158 159 for (i = 0; i < size; i++) { 160 clk = clk_register_divider(NULL, clks[i].name, 161 clks[i].parent_name, 162 clks[i].flags, 163 base + clks[i].offset, 164 clks[i].shift, 165 clks[i].width, 166 clks[i].div_flags, 167 clks[i].lock); 168 169 if (IS_ERR(clk)) { 170 pr_err("%s: failed to register clock %s\n", 171 __func__, clks[i].name); 172 continue; 173 } 174 if (clks[i].id) 175 unit->clk_table[clks[i].id] = clk; 176 } 177} 178 179void mmp_clk_add(struct mmp_clk_unit *unit, unsigned int id, 180 struct clk *clk) 181{ 182 if (IS_ERR_OR_NULL(clk)) { 183 pr_err("CLK %d has invalid pointer %p\n", id, clk); 184 return; 185 } 186 if (id >= unit->nr_clks) { 187 pr_err("CLK %d is invalid\n", id); 188 return; 189 } 190 191 unit->clk_table[id] = clk; 192}