uboot/drivers/clk/at91/pmc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2016 Atmel Corporation
   4 *               Wenyou.Yang <wenyou.yang@atmel.com>
   5 */
   6
   7#include <common.h>
   8#include <asm/io.h>
   9#include <clk-uclass.h>
  10#include "pmc.h"
  11
  12static int at91_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
  13{
  14        if (args->args_count != 2) {
  15                debug("AT91: clk: Invalid args_count: %d\n", args->args_count);
  16                return -EINVAL;
  17        }
  18
  19        clk->id = AT91_TO_CLK_ID(args->args[0], args->args[1]);
  20
  21        return 0;
  22}
  23
  24static ulong at91_clk_get_rate(struct clk *clk)
  25{
  26        struct clk *c;
  27        int ret;
  28
  29        ret = clk_get_by_id(clk->id, &c);
  30        if (ret)
  31                return ret;
  32
  33        return clk_get_rate(c);
  34}
  35
  36static ulong at91_clk_set_rate(struct clk *clk, ulong rate)
  37{
  38        struct clk *c;
  39        int ret;
  40
  41        ret = clk_get_by_id(clk->id, &c);
  42        if (ret)
  43                return ret;
  44
  45        return clk_set_rate(c, rate);
  46}
  47
  48static int at91_clk_enable(struct clk *clk)
  49{
  50        struct clk *c;
  51        int ret;
  52
  53        ret = clk_get_by_id(clk->id, &c);
  54        if (ret)
  55                return ret;
  56
  57        return clk_enable(c);
  58}
  59
  60static int at91_clk_disable(struct clk *clk)
  61{
  62        struct clk *c;
  63        int ret;
  64
  65        ret = clk_get_by_id(clk->id, &c);
  66        if (ret)
  67                return ret;
  68
  69        return clk_disable(c);
  70}
  71
  72const struct clk_ops at91_clk_ops = {
  73        .of_xlate       = at91_clk_of_xlate,
  74        .set_rate       = at91_clk_set_rate,
  75        .get_rate       = at91_clk_get_rate,
  76        .enable         = at91_clk_enable,
  77        .disable        = at91_clk_disable,
  78};
  79
  80/**
  81 * pmc_read() - read content at address base + off into val
  82 *
  83 * @base: base address
  84 * @off: offset to read from
  85 * @val: where the content of base + off is stored
  86 *
  87 * @return: void
  88 */
  89void pmc_read(void __iomem *base, unsigned int off, unsigned int *val)
  90{
  91        *val = readl(base + off);
  92}
  93
  94/**
  95 * pmc_write() - write content of val at address base + off
  96 *
  97 * @base: base address
  98 * @off: offset to write to
  99 * @val: content to be written at base + off
 100 *
 101 * @return: void
 102 */
 103void pmc_write(void __iomem *base, unsigned int off, unsigned int val)
 104{
 105        writel(val, base + off);
 106}
 107
 108/**
 109 * pmc_update_bits() - update a set of bits at address base + off
 110 *
 111 * @base: base address
 112 * @off: offset to be updated
 113 * @mask: mask of bits to be updated
 114 * @bits: the new value to be updated
 115 *
 116 * @return: void
 117 */
 118void pmc_update_bits(void __iomem *base, unsigned int off,
 119                     unsigned int mask, unsigned int bits)
 120{
 121        unsigned int tmp;
 122
 123        tmp = readl(base + off);
 124        tmp &= ~mask;
 125        writel(tmp | (bits & mask), base + off);
 126}
 127
 128/**
 129 * at91_clk_mux_val_to_index() - get parent index in mux table
 130 *
 131 * @table: clock mux table
 132 * @num_parents: clock number of parents
 133 * @val: clock id who's mux index should be retrieved
 134 *
 135 * @return: clock index in mux table or a negative error number in case of
 136 *              failure
 137 */
 138int at91_clk_mux_val_to_index(const u32 *table, u32 num_parents, u32 val)
 139{
 140        int i;
 141
 142        if (!table || !num_parents)
 143                return -EINVAL;
 144
 145        for (i = 0; i < num_parents; i++) {
 146                if (table[i] == val)
 147                        return i;
 148        }
 149
 150        return -EINVAL;
 151}
 152
 153/**
 154 * at91_clk_mux_index_to_val() - get parent ID corresponding to an entry in
 155 *      clock's mux table
 156 *
 157 * @table: clock's mux table
 158 * @num_parents: clock's number of parents
 159 * @index: index in mux table which clock's ID should be retrieved
 160 *
 161 * @return: clock ID or a negative error number in case of failure
 162 */
 163int at91_clk_mux_index_to_val(const u32 *table, u32 num_parents, u32 index)
 164{
 165        if (!table || !num_parents || index < 0 || index > num_parents)
 166                return -EINVAL;
 167
 168        return table[index];
 169}
 170