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