linux/drivers/clk/mmp/clk.c
<<
>>
Prefs
   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}
 193