root/drivers/clk/ux500/clk-prcc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. clk_prcc_pclk_enable
  2. clk_prcc_pclk_disable
  3. clk_prcc_kclk_enable
  4. clk_prcc_kclk_disable
  5. clk_prcc_is_enabled
  6. clk_reg_prcc
  7. clk_reg_prcc_pclk
  8. clk_reg_prcc_kclk

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * PRCC clock implementation for ux500 platform.
   4  *
   5  * Copyright (C) 2012 ST-Ericsson SA
   6  * Author: Ulf Hansson <ulf.hansson@linaro.org>
   7  */
   8 
   9 #include <linux/clk-provider.h>
  10 #include <linux/slab.h>
  11 #include <linux/io.h>
  12 #include <linux/err.h>
  13 #include <linux/types.h>
  14 
  15 #include "clk.h"
  16 
  17 #define PRCC_PCKEN                      0x000
  18 #define PRCC_PCKDIS                     0x004
  19 #define PRCC_KCKEN                      0x008
  20 #define PRCC_KCKDIS                     0x00C
  21 #define PRCC_PCKSR                      0x010
  22 #define PRCC_KCKSR                      0x014
  23 
  24 #define to_clk_prcc(_hw) container_of(_hw, struct clk_prcc, hw)
  25 
  26 struct clk_prcc {
  27         struct clk_hw hw;
  28         void __iomem *base;
  29         u32 cg_sel;
  30         int is_enabled;
  31 };
  32 
  33 /* PRCC clock operations. */
  34 
  35 static int clk_prcc_pclk_enable(struct clk_hw *hw)
  36 {
  37         struct clk_prcc *clk = to_clk_prcc(hw);
  38 
  39         writel(clk->cg_sel, (clk->base + PRCC_PCKEN));
  40         while (!(readl(clk->base + PRCC_PCKSR) & clk->cg_sel))
  41                 cpu_relax();
  42 
  43         clk->is_enabled = 1;
  44         return 0;
  45 }
  46 
  47 static void clk_prcc_pclk_disable(struct clk_hw *hw)
  48 {
  49         struct clk_prcc *clk = to_clk_prcc(hw);
  50 
  51         writel(clk->cg_sel, (clk->base + PRCC_PCKDIS));
  52         clk->is_enabled = 0;
  53 }
  54 
  55 static int clk_prcc_kclk_enable(struct clk_hw *hw)
  56 {
  57         struct clk_prcc *clk = to_clk_prcc(hw);
  58 
  59         writel(clk->cg_sel, (clk->base + PRCC_KCKEN));
  60         while (!(readl(clk->base + PRCC_KCKSR) & clk->cg_sel))
  61                 cpu_relax();
  62 
  63         clk->is_enabled = 1;
  64         return 0;
  65 }
  66 
  67 static void clk_prcc_kclk_disable(struct clk_hw *hw)
  68 {
  69         struct clk_prcc *clk = to_clk_prcc(hw);
  70 
  71         writel(clk->cg_sel, (clk->base + PRCC_KCKDIS));
  72         clk->is_enabled = 0;
  73 }
  74 
  75 static int clk_prcc_is_enabled(struct clk_hw *hw)
  76 {
  77         struct clk_prcc *clk = to_clk_prcc(hw);
  78         return clk->is_enabled;
  79 }
  80 
  81 static const struct clk_ops clk_prcc_pclk_ops = {
  82         .enable = clk_prcc_pclk_enable,
  83         .disable = clk_prcc_pclk_disable,
  84         .is_enabled = clk_prcc_is_enabled,
  85 };
  86 
  87 static const struct clk_ops clk_prcc_kclk_ops = {
  88         .enable = clk_prcc_kclk_enable,
  89         .disable = clk_prcc_kclk_disable,
  90         .is_enabled = clk_prcc_is_enabled,
  91 };
  92 
  93 static struct clk *clk_reg_prcc(const char *name,
  94                                 const char *parent_name,
  95                                 resource_size_t phy_base,
  96                                 u32 cg_sel,
  97                                 unsigned long flags,
  98                                 const struct clk_ops *clk_prcc_ops)
  99 {
 100         struct clk_prcc *clk;
 101         struct clk_init_data clk_prcc_init;
 102         struct clk *clk_reg;
 103 
 104         if (!name) {
 105                 pr_err("clk_prcc: %s invalid arguments passed\n", __func__);
 106                 return ERR_PTR(-EINVAL);
 107         }
 108 
 109         clk = kzalloc(sizeof(*clk), GFP_KERNEL);
 110         if (!clk)
 111                 return ERR_PTR(-ENOMEM);
 112 
 113         clk->base = ioremap(phy_base, SZ_4K);
 114         if (!clk->base)
 115                 goto free_clk;
 116 
 117         clk->cg_sel = cg_sel;
 118         clk->is_enabled = 1;
 119 
 120         clk_prcc_init.name = name;
 121         clk_prcc_init.ops = clk_prcc_ops;
 122         clk_prcc_init.flags = flags;
 123         clk_prcc_init.parent_names = (parent_name ? &parent_name : NULL);
 124         clk_prcc_init.num_parents = (parent_name ? 1 : 0);
 125         clk->hw.init = &clk_prcc_init;
 126 
 127         clk_reg = clk_register(NULL, &clk->hw);
 128         if (IS_ERR_OR_NULL(clk_reg))
 129                 goto unmap_clk;
 130 
 131         return clk_reg;
 132 
 133 unmap_clk:
 134         iounmap(clk->base);
 135 free_clk:
 136         kfree(clk);
 137         pr_err("clk_prcc: %s failed to register clk\n", __func__);
 138         return ERR_PTR(-ENOMEM);
 139 }
 140 
 141 struct clk *clk_reg_prcc_pclk(const char *name,
 142                               const char *parent_name,
 143                               resource_size_t phy_base,
 144                               u32 cg_sel,
 145                               unsigned long flags)
 146 {
 147         return clk_reg_prcc(name, parent_name, phy_base, cg_sel, flags,
 148                         &clk_prcc_pclk_ops);
 149 }
 150 
 151 struct clk *clk_reg_prcc_kclk(const char *name,
 152                               const char *parent_name,
 153                               resource_size_t phy_base,
 154                               u32 cg_sel,
 155                               unsigned long flags)
 156 {
 157         return clk_reg_prcc(name, parent_name, phy_base, cg_sel, flags,
 158                         &clk_prcc_kclk_ops);
 159 }

/* [<][>][^][v][top][bottom][index][help] */