^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) 2016 Atmel Corporation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Songjun Wu <songjun.wu@atmel.com>,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Nicolas Ferre <nicolas.ferre@atmel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2017 Free Electrons,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Quentin Schulz <quentin.schulz@free-electrons.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * The Sama5d2 SoC has two audio PLLs (PMC and PAD) that shares the same parent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * (FRAC). FRAC can output between 620 and 700MHz and only multiply the rate of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * its own parent. PMC and PAD can then divide the FRAC rate to best match the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * asked rate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Traits of FRAC clock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * enable - clk_enable writes nd, fracr parameters and enables PLL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * rate - rate is adjustable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * clk->rate = parent->rate * ((nd + 1) + (fracr / 2^22))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * parent - fixed parent. No clk_set_parent support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Traits of PMC clock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * enable - clk_enable writes qdpmc, and enables PMC output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * rate - rate is adjustable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * clk->rate = parent->rate / (qdpmc + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * parent - fixed parent. No clk_set_parent support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * Traits of PAD clock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * enable - clk_enable writes divisors and enables PAD output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * rate - rate is adjustable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * clk->rate = parent->rate / (qdaudio * div))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * parent - fixed parent. No clk_set_parent support
^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) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/clk/at91_pmc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/mfd/syscon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include "pmc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define AUDIO_PLL_DIV_FRAC BIT(22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define AUDIO_PLL_ND_MAX (AT91_PMC_AUDIO_PLL_ND_MASK >> \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) AT91_PMC_AUDIO_PLL_ND_OFFSET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define AUDIO_PLL_QDPAD(qd, div) ((AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV(qd) & \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_MASK) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) (AT91_PMC_AUDIO_PLL_QDPAD_DIV(div) & \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) AT91_PMC_AUDIO_PLL_QDPAD_DIV_MASK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define AUDIO_PLL_QDPMC_MAX (AT91_PMC_AUDIO_PLL_QDPMC_MASK >> \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) AT91_PMC_AUDIO_PLL_QDPMC_OFFSET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define AUDIO_PLL_FOUT_MIN 620000000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define AUDIO_PLL_FOUT_MAX 700000000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct clk_audio_frac {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct clk_hw hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) u32 fracr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) u8 nd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct clk_audio_pad {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct clk_hw hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) u8 qdaudio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) u8 div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct clk_audio_pmc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct clk_hw hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) u8 qdpmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define to_clk_audio_frac(hw) container_of(hw, struct clk_audio_frac, hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define to_clk_audio_pad(hw) container_of(hw, struct clk_audio_pad, hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define to_clk_audio_pmc(hw) container_of(hw, struct clk_audio_pmc, hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static int clk_audio_pll_frac_enable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct clk_audio_frac *frac = to_clk_audio_frac(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) regmap_update_bits(frac->regmap, AT91_PMC_AUDIO_PLL0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) AT91_PMC_AUDIO_PLL_RESETN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) regmap_update_bits(frac->regmap, AT91_PMC_AUDIO_PLL0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) AT91_PMC_AUDIO_PLL_RESETN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) AT91_PMC_AUDIO_PLL_RESETN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) regmap_update_bits(frac->regmap, AT91_PMC_AUDIO_PLL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) AT91_PMC_AUDIO_PLL_FRACR_MASK, frac->fracr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * reset and enable have to be done in 2 separated writes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * for AT91_PMC_AUDIO_PLL0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) regmap_update_bits(frac->regmap, AT91_PMC_AUDIO_PLL0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) AT91_PMC_AUDIO_PLL_PLLEN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) AT91_PMC_AUDIO_PLL_ND_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) AT91_PMC_AUDIO_PLL_PLLEN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) AT91_PMC_AUDIO_PLL_ND(frac->nd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static int clk_audio_pll_pad_enable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct clk_audio_pad *apad_ck = to_clk_audio_pad(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) regmap_update_bits(apad_ck->regmap, AT91_PMC_AUDIO_PLL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) AT91_PMC_AUDIO_PLL_QDPAD_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) AUDIO_PLL_QDPAD(apad_ck->qdaudio, apad_ck->div));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) regmap_update_bits(apad_ck->regmap, AT91_PMC_AUDIO_PLL0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) AT91_PMC_AUDIO_PLL_PADEN, AT91_PMC_AUDIO_PLL_PADEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static int clk_audio_pll_pmc_enable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct clk_audio_pmc *apmc_ck = to_clk_audio_pmc(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) regmap_update_bits(apmc_ck->regmap, AT91_PMC_AUDIO_PLL0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) AT91_PMC_AUDIO_PLL_PMCEN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) AT91_PMC_AUDIO_PLL_QDPMC_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) AT91_PMC_AUDIO_PLL_PMCEN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) AT91_PMC_AUDIO_PLL_QDPMC(apmc_ck->qdpmc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static void clk_audio_pll_frac_disable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct clk_audio_frac *frac = to_clk_audio_frac(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) regmap_update_bits(frac->regmap, AT91_PMC_AUDIO_PLL0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) AT91_PMC_AUDIO_PLL_PLLEN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /* do it in 2 separated writes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) regmap_update_bits(frac->regmap, AT91_PMC_AUDIO_PLL0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) AT91_PMC_AUDIO_PLL_RESETN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static void clk_audio_pll_pad_disable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) struct clk_audio_pad *apad_ck = to_clk_audio_pad(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) regmap_update_bits(apad_ck->regmap, AT91_PMC_AUDIO_PLL0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) AT91_PMC_AUDIO_PLL_PADEN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static void clk_audio_pll_pmc_disable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) struct clk_audio_pmc *apmc_ck = to_clk_audio_pmc(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) regmap_update_bits(apmc_ck->regmap, AT91_PMC_AUDIO_PLL0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) AT91_PMC_AUDIO_PLL_PMCEN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) static unsigned long clk_audio_pll_fout(unsigned long parent_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) unsigned long nd, unsigned long fracr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) unsigned long long fr = (unsigned long long)parent_rate * fracr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) pr_debug("A PLL: %s, fr = %llu\n", __func__, fr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) fr = DIV_ROUND_CLOSEST_ULL(fr, AUDIO_PLL_DIV_FRAC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) pr_debug("A PLL: %s, fr = %llu\n", __func__, fr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return parent_rate * (nd + 1) + fr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static unsigned long clk_audio_pll_frac_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct clk_audio_frac *frac = to_clk_audio_frac(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) unsigned long fout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) fout = clk_audio_pll_fout(parent_rate, frac->nd, frac->fracr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) pr_debug("A PLL: %s, fout = %lu (nd = %u, fracr = %lu)\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) fout, frac->nd, (unsigned long)frac->fracr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return fout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) static unsigned long clk_audio_pll_pad_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct clk_audio_pad *apad_ck = to_clk_audio_pad(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) unsigned long apad_rate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (apad_ck->qdaudio && apad_ck->div)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) apad_rate = parent_rate / (apad_ck->qdaudio * apad_ck->div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) pr_debug("A PLL/PAD: %s, apad_rate = %lu (div = %u, qdaudio = %u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) __func__, apad_rate, apad_ck->div, apad_ck->qdaudio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) return apad_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) static unsigned long clk_audio_pll_pmc_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) struct clk_audio_pmc *apmc_ck = to_clk_audio_pmc(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) unsigned long apmc_rate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) apmc_rate = parent_rate / (apmc_ck->qdpmc + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) pr_debug("A PLL/PMC: %s, apmc_rate = %lu (qdpmc = %u)\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) apmc_rate, apmc_ck->qdpmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return apmc_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) static int clk_audio_pll_frac_compute_frac(unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) unsigned long parent_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) unsigned long *nd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) unsigned long *fracr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) unsigned long long tmp, rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (!rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) tmp = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) rem = do_div(tmp, parent_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (!tmp || tmp >= AUDIO_PLL_ND_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) *nd = tmp - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) tmp = rem * AUDIO_PLL_DIV_FRAC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) tmp = DIV_ROUND_CLOSEST_ULL(tmp, parent_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (tmp > AT91_PMC_AUDIO_PLL_FRACR_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) /* we can cast here as we verified the bounds just above */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) *fracr = (unsigned long)tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static int clk_audio_pll_frac_determine_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) struct clk_rate_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) unsigned long fracr, nd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) pr_debug("A PLL: %s, rate = %lu (parent_rate = %lu)\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) req->rate, req->best_parent_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) req->rate = clamp(req->rate, AUDIO_PLL_FOUT_MIN, AUDIO_PLL_FOUT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) req->min_rate = max(req->min_rate, AUDIO_PLL_FOUT_MIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) req->max_rate = min(req->max_rate, AUDIO_PLL_FOUT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) ret = clk_audio_pll_frac_compute_frac(req->rate, req->best_parent_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) &nd, &fracr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) req->rate = clk_audio_pll_fout(req->best_parent_rate, nd, fracr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) req->best_parent_hw = clk_hw_get_parent(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) pr_debug("A PLL: %s, best_rate = %lu (nd = %lu, fracr = %lu)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) __func__, req->rate, nd, fracr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) static long clk_audio_pll_pad_round_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) unsigned long *parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct clk_hw *pclk = clk_hw_get_parent(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) long best_rate = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) unsigned long best_parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) unsigned long tmp_qd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) u32 div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) long tmp_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) int tmp_diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) int best_diff = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) pr_debug("A PLL/PAD: %s, rate = %lu (parent_rate = %lu)\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) rate, *parent_rate);
^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) * Rate divisor is actually made of two different divisors, multiplied
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * between themselves before dividing the rate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * tmp_qd goes from 1 to 31 and div is either 2 or 3.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * In order to avoid testing twice the rate divisor (e.g. divisor 12 can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * be found with (tmp_qd, div) = (2, 6) or (3, 4)), we remove any loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * for a rate divisor when div is 2 and tmp_qd is a multiple of 3.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * We cannot inverse it (condition div is 3 and tmp_qd is even) or we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * would miss some rate divisor that aren't reachable with div being 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * (e.g. rate divisor 90 is made with div = 3 and tmp_qd = 30, thus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * tmp_qd is even so we skip it because we think div 2 could make this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) * rate divisor which isn't possible since tmp_qd has to be <= 31).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) for (tmp_qd = 1; tmp_qd < AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_MAX; tmp_qd++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) for (div = 2; div <= 3; div++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (div == 2 && tmp_qd % 3 == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) best_parent_rate = clk_hw_round_rate(pclk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) rate * tmp_qd * div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) tmp_rate = best_parent_rate / (div * tmp_qd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) tmp_diff = abs(rate - tmp_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (best_diff < 0 || best_diff > tmp_diff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) *parent_rate = best_parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) best_rate = tmp_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) best_diff = tmp_diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) pr_debug("A PLL/PAD: %s, best_rate = %ld, best_parent_rate = %lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) __func__, best_rate, best_parent_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return best_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static long clk_audio_pll_pmc_round_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) unsigned long *parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) struct clk_hw *pclk = clk_hw_get_parent(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) long best_rate = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) unsigned long best_parent_rate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) u32 tmp_qd = 0, div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) long tmp_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) int tmp_diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) int best_diff = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) pr_debug("A PLL/PMC: %s, rate = %lu (parent_rate = %lu)\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) rate, *parent_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (!rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) best_parent_rate = clk_round_rate(pclk->clk, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) div = max(best_parent_rate / rate, 1UL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) for (; div <= AUDIO_PLL_QDPMC_MAX; div++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) best_parent_rate = clk_round_rate(pclk->clk, rate * div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) tmp_rate = best_parent_rate / div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) tmp_diff = abs(rate - tmp_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (best_diff < 0 || best_diff > tmp_diff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) *parent_rate = best_parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) best_rate = tmp_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) best_diff = tmp_diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) tmp_qd = div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (!best_diff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) break; /* got exact match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) pr_debug("A PLL/PMC: %s, best_rate = %ld, best_parent_rate = %lu (qd = %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) __func__, best_rate, *parent_rate, tmp_qd - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return best_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) static int clk_audio_pll_frac_set_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) struct clk_audio_frac *frac = to_clk_audio_frac(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) unsigned long fracr, nd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) pr_debug("A PLL: %s, rate = %lu (parent_rate = %lu)\n", __func__, rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) parent_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (rate < AUDIO_PLL_FOUT_MIN || rate > AUDIO_PLL_FOUT_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) ret = clk_audio_pll_frac_compute_frac(rate, parent_rate, &nd, &fracr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) frac->nd = nd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) frac->fracr = fracr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) static int clk_audio_pll_pad_set_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) struct clk_audio_pad *apad_ck = to_clk_audio_pad(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) u8 tmp_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) pr_debug("A PLL/PAD: %s, rate = %lu (parent_rate = %lu)\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) rate, parent_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (!rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) tmp_div = parent_rate / rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (tmp_div % 3 == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) apad_ck->qdaudio = tmp_div / 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) apad_ck->div = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) apad_ck->qdaudio = tmp_div / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) apad_ck->div = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) static int clk_audio_pll_pmc_set_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) struct clk_audio_pmc *apmc_ck = to_clk_audio_pmc(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) if (!rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) pr_debug("A PLL/PMC: %s, rate = %lu (parent_rate = %lu)\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) rate, parent_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) apmc_ck->qdpmc = parent_rate / rate - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) static const struct clk_ops audio_pll_frac_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) .enable = clk_audio_pll_frac_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) .disable = clk_audio_pll_frac_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) .recalc_rate = clk_audio_pll_frac_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) .determine_rate = clk_audio_pll_frac_determine_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) .set_rate = clk_audio_pll_frac_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) static const struct clk_ops audio_pll_pad_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) .enable = clk_audio_pll_pad_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) .disable = clk_audio_pll_pad_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) .recalc_rate = clk_audio_pll_pad_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) .round_rate = clk_audio_pll_pad_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) .set_rate = clk_audio_pll_pad_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) static const struct clk_ops audio_pll_pmc_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) .enable = clk_audio_pll_pmc_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) .disable = clk_audio_pll_pmc_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) .recalc_rate = clk_audio_pll_pmc_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) .round_rate = clk_audio_pll_pmc_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) .set_rate = clk_audio_pll_pmc_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) struct clk_hw * __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) at91_clk_register_audio_pll_frac(struct regmap *regmap, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) const char *parent_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) struct clk_audio_frac *frac_ck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) struct clk_init_data init = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) frac_ck = kzalloc(sizeof(*frac_ck), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (!frac_ck)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) init.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) init.ops = &audio_pll_frac_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) init.parent_names = &parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) init.num_parents = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) init.flags = CLK_SET_RATE_GATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) frac_ck->hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) frac_ck->regmap = regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) ret = clk_hw_register(NULL, &frac_ck->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) kfree(frac_ck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return &frac_ck->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) struct clk_hw * __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) at91_clk_register_audio_pll_pad(struct regmap *regmap, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) const char *parent_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) struct clk_audio_pad *apad_ck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct clk_init_data init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) apad_ck = kzalloc(sizeof(*apad_ck), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (!apad_ck)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) init.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) init.ops = &audio_pll_pad_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) init.parent_names = &parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) init.num_parents = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) CLK_SET_RATE_PARENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) apad_ck->hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) apad_ck->regmap = regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) ret = clk_hw_register(NULL, &apad_ck->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) kfree(apad_ck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) return &apad_ck->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) struct clk_hw * __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) at91_clk_register_audio_pll_pmc(struct regmap *regmap, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) const char *parent_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) struct clk_audio_pmc *apmc_ck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) struct clk_init_data init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) apmc_ck = kzalloc(sizeof(*apmc_ck), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) if (!apmc_ck)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) init.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) init.ops = &audio_pll_pmc_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) init.parent_names = &parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) init.num_parents = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) CLK_SET_RATE_PARENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) apmc_ck->hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) apmc_ck->regmap = regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) ret = clk_hw_register(NULL, &apmc_ck->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) kfree(apmc_ck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) return &apmc_ck->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }