^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/clkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/clk/at91_pmc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/mfd/syscon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "pmc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define SLOW_CLOCK_FREQ 32768
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define MAINF_DIV 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define MAINFRDY_TIMEOUT (((MAINF_DIV + 1) * USEC_PER_SEC) / \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) SLOW_CLOCK_FREQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define MAINF_LOOP_MIN_WAIT (USEC_PER_SEC / SLOW_CLOCK_FREQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define MAINF_LOOP_MAX_WAIT MAINFRDY_TIMEOUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define MOR_KEY_MASK (0xff << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define clk_main_parent_select(s) (((s) & \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) (AT91_PMC_MOSCEN | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) AT91_PMC_OSCBYPASS)) ? 1 : 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct clk_main_osc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct clk_hw hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define to_clk_main_osc(hw) container_of(hw, struct clk_main_osc, hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct clk_main_rc_osc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct clk_hw hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) unsigned long frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) unsigned long accuracy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define to_clk_main_rc_osc(hw) container_of(hw, struct clk_main_rc_osc, hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct clk_rm9200_main {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct clk_hw hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define to_clk_rm9200_main(hw) container_of(hw, struct clk_rm9200_main, hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct clk_sam9x5_main {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct clk_hw hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) u8 parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define to_clk_sam9x5_main(hw) container_of(hw, struct clk_sam9x5_main, hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static inline bool clk_main_osc_ready(struct regmap *regmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) unsigned int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) regmap_read(regmap, AT91_PMC_SR, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return status & AT91_PMC_MOSCS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static int clk_main_osc_prepare(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct clk_main_osc *osc = to_clk_main_osc(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct regmap *regmap = osc->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) regmap_read(regmap, AT91_CKGR_MOR, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) tmp &= ~MOR_KEY_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (tmp & AT91_PMC_OSCBYPASS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if (!(tmp & AT91_PMC_MOSCEN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) tmp |= AT91_PMC_MOSCEN | AT91_PMC_KEY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) regmap_write(regmap, AT91_CKGR_MOR, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) while (!clk_main_osc_ready(regmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static void clk_main_osc_unprepare(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct clk_main_osc *osc = to_clk_main_osc(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct regmap *regmap = osc->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) regmap_read(regmap, AT91_CKGR_MOR, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (tmp & AT91_PMC_OSCBYPASS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (!(tmp & AT91_PMC_MOSCEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) tmp &= ~(AT91_PMC_KEY | AT91_PMC_MOSCEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) regmap_write(regmap, AT91_CKGR_MOR, tmp | AT91_PMC_KEY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static int clk_main_osc_is_prepared(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct clk_main_osc *osc = to_clk_main_osc(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct regmap *regmap = osc->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) u32 tmp, status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) regmap_read(regmap, AT91_CKGR_MOR, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (tmp & AT91_PMC_OSCBYPASS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) regmap_read(regmap, AT91_PMC_SR, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return (status & AT91_PMC_MOSCS) && clk_main_parent_select(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static const struct clk_ops main_osc_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) .prepare = clk_main_osc_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) .unprepare = clk_main_osc_unprepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) .is_prepared = clk_main_osc_is_prepared,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct clk_hw * __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) at91_clk_register_main_osc(struct regmap *regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) const char *parent_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) bool bypass)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct clk_main_osc *osc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct clk_init_data init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct clk_hw *hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (!name || !parent_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) osc = kzalloc(sizeof(*osc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (!osc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) init.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) init.ops = &main_osc_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) init.parent_names = &parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) init.num_parents = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) init.flags = CLK_IGNORE_UNUSED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) osc->hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) osc->regmap = regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (bypass)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) regmap_update_bits(regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) AT91_CKGR_MOR, MOR_KEY_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) AT91_PMC_OSCBYPASS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) AT91_PMC_OSCBYPASS | AT91_PMC_KEY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) hw = &osc->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) ret = clk_hw_register(NULL, &osc->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) kfree(osc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) hw = ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static bool clk_main_rc_osc_ready(struct regmap *regmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) unsigned int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) regmap_read(regmap, AT91_PMC_SR, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return !!(status & AT91_PMC_MOSCRCS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static int clk_main_rc_osc_prepare(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct regmap *regmap = osc->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) unsigned int mor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) regmap_read(regmap, AT91_CKGR_MOR, &mor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (!(mor & AT91_PMC_MOSCRCEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) regmap_update_bits(regmap, AT91_CKGR_MOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) MOR_KEY_MASK | AT91_PMC_MOSCRCEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) AT91_PMC_MOSCRCEN | AT91_PMC_KEY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) while (!clk_main_rc_osc_ready(regmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static void clk_main_rc_osc_unprepare(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) struct regmap *regmap = osc->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) unsigned int mor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) regmap_read(regmap, AT91_CKGR_MOR, &mor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (!(mor & AT91_PMC_MOSCRCEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) regmap_update_bits(regmap, AT91_CKGR_MOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) MOR_KEY_MASK | AT91_PMC_MOSCRCEN, AT91_PMC_KEY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) static int clk_main_rc_osc_is_prepared(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) struct regmap *regmap = osc->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) unsigned int mor, status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) regmap_read(regmap, AT91_CKGR_MOR, &mor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) regmap_read(regmap, AT91_PMC_SR, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return (mor & AT91_PMC_MOSCRCEN) && (status & AT91_PMC_MOSCRCS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) static unsigned long clk_main_rc_osc_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) return osc->frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) static unsigned long clk_main_rc_osc_recalc_accuracy(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) unsigned long parent_acc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return osc->accuracy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static const struct clk_ops main_rc_osc_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) .prepare = clk_main_rc_osc_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) .unprepare = clk_main_rc_osc_unprepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) .is_prepared = clk_main_rc_osc_is_prepared,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) .recalc_rate = clk_main_rc_osc_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) .recalc_accuracy = clk_main_rc_osc_recalc_accuracy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct clk_hw * __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) at91_clk_register_main_rc_osc(struct regmap *regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) u32 frequency, u32 accuracy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) struct clk_main_rc_osc *osc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) struct clk_init_data init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) struct clk_hw *hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (!name || !frequency)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) osc = kzalloc(sizeof(*osc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (!osc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) init.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) init.ops = &main_rc_osc_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) init.parent_names = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) init.num_parents = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) init.flags = CLK_IGNORE_UNUSED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) osc->hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) osc->regmap = regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) osc->frequency = frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) osc->accuracy = accuracy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) hw = &osc->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) ret = clk_hw_register(NULL, hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) kfree(osc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) hw = ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) static int clk_main_probe_frequency(struct regmap *regmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) unsigned long prep_time, timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) unsigned int mcfr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) timeout = jiffies + usecs_to_jiffies(MAINFRDY_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) prep_time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) regmap_read(regmap, AT91_CKGR_MCFR, &mcfr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (mcfr & AT91_PMC_MAINRDY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (system_state < SYSTEM_RUNNING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) udelay(MAINF_LOOP_MIN_WAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) } while (time_before(prep_time, timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) static unsigned long clk_main_recalc_rate(struct regmap *regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) unsigned int mcfr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) pr_warn("Main crystal frequency not set, using approximate value\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) regmap_read(regmap, AT91_CKGR_MCFR, &mcfr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (!(mcfr & AT91_PMC_MAINRDY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return ((mcfr & AT91_PMC_MAINF) * SLOW_CLOCK_FREQ) / MAINF_DIV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) static int clk_rm9200_main_prepare(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return clk_main_probe_frequency(clkmain->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static int clk_rm9200_main_is_prepared(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) unsigned int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) regmap_read(clkmain->regmap, AT91_CKGR_MCFR, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return !!(status & AT91_PMC_MAINRDY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) static unsigned long clk_rm9200_main_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) return clk_main_recalc_rate(clkmain->regmap, parent_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) static const struct clk_ops rm9200_main_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) .prepare = clk_rm9200_main_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) .is_prepared = clk_rm9200_main_is_prepared,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) .recalc_rate = clk_rm9200_main_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) struct clk_hw * __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) at91_clk_register_rm9200_main(struct regmap *regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) const char *parent_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) struct clk_rm9200_main *clkmain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) struct clk_init_data init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) struct clk_hw *hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (!parent_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) clkmain = kzalloc(sizeof(*clkmain), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (!clkmain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) init.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) init.ops = &rm9200_main_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) init.parent_names = &parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) init.num_parents = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) init.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) clkmain->hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) clkmain->regmap = regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) hw = &clkmain->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) ret = clk_hw_register(NULL, &clkmain->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) kfree(clkmain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) hw = ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) return hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) static inline bool clk_sam9x5_main_ready(struct regmap *regmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) unsigned int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) regmap_read(regmap, AT91_PMC_SR, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return !!(status & AT91_PMC_MOSCSELS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) static int clk_sam9x5_main_prepare(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) struct regmap *regmap = clkmain->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) while (!clk_sam9x5_main_ready(regmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return clk_main_probe_frequency(regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) static int clk_sam9x5_main_is_prepared(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) return clk_sam9x5_main_ready(clkmain->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) static unsigned long clk_sam9x5_main_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return clk_main_recalc_rate(clkmain->regmap, parent_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) static int clk_sam9x5_main_set_parent(struct clk_hw *hw, u8 index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) struct regmap *regmap = clkmain->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (index > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) regmap_read(regmap, AT91_CKGR_MOR, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (index && !(tmp & AT91_PMC_MOSCSEL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) tmp = AT91_PMC_MOSCSEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) else if (!index && (tmp & AT91_PMC_MOSCSEL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) regmap_update_bits(regmap, AT91_CKGR_MOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) AT91_PMC_MOSCSEL | MOR_KEY_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) tmp | AT91_PMC_KEY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) while (!clk_sam9x5_main_ready(regmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) static u8 clk_sam9x5_main_get_parent(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) unsigned int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) return clk_main_parent_select(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) static const struct clk_ops sam9x5_main_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) .prepare = clk_sam9x5_main_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) .is_prepared = clk_sam9x5_main_is_prepared,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) .recalc_rate = clk_sam9x5_main_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) .set_parent = clk_sam9x5_main_set_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) .get_parent = clk_sam9x5_main_get_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) struct clk_hw * __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) at91_clk_register_sam9x5_main(struct regmap *regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) const char **parent_names,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) int num_parents)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) struct clk_sam9x5_main *clkmain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct clk_init_data init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) unsigned int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) struct clk_hw *hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (!parent_names || !num_parents)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) clkmain = kzalloc(sizeof(*clkmain), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (!clkmain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) init.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) init.ops = &sam9x5_main_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) init.parent_names = parent_names;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) init.num_parents = num_parents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) init.flags = CLK_SET_PARENT_GATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) clkmain->hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) clkmain->regmap = regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) clkmain->parent = clk_main_parent_select(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) hw = &clkmain->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) ret = clk_hw_register(NULL, &clkmain->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) kfree(clkmain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) hw = ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }