^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 Maxime Ripard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Maxime Ripard <maxime.ripard@free-electrons.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "ccu_gate.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "ccu_nkmp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) struct _ccu_nkmp {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) unsigned long n, min_n, max_n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) unsigned long k, min_k, max_k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) unsigned long m, min_m, max_m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) unsigned long p, min_p, max_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static unsigned long ccu_nkmp_calc_rate(unsigned long parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) unsigned long n, unsigned long k,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) unsigned long m, unsigned long p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) u64 rate = parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) rate *= n * k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) do_div(rate, m * p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) return rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static void ccu_nkmp_find_best(unsigned long parent, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct _ccu_nkmp *nkmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) unsigned long best_rate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) unsigned long best_n = 0, best_k = 0, best_m = 0, best_p = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) unsigned long _n, _k, _m, _p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) for (_k = nkmp->min_k; _k <= nkmp->max_k; _k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) for (_n = nkmp->min_n; _n <= nkmp->max_n; _n++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) for (_m = nkmp->min_m; _m <= nkmp->max_m; _m++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) for (_p = nkmp->min_p; _p <= nkmp->max_p; _p <<= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) unsigned long tmp_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) tmp_rate = ccu_nkmp_calc_rate(parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) _n, _k,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) _m, _p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (tmp_rate > rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if ((rate - tmp_rate) < (rate - best_rate)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) best_rate = tmp_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) best_n = _n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) best_k = _k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) best_m = _m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) best_p = _p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) nkmp->n = best_n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) nkmp->k = best_k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) nkmp->m = best_m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) nkmp->p = best_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static void ccu_nkmp_disable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return ccu_gate_helper_disable(&nkmp->common, nkmp->enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static int ccu_nkmp_enable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return ccu_gate_helper_enable(&nkmp->common, nkmp->enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static int ccu_nkmp_is_enabled(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return ccu_gate_helper_is_enabled(&nkmp->common, nkmp->enable);
^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 unsigned long ccu_nkmp_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) unsigned long n, m, k, p, rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) reg = readl(nkmp->common.base + nkmp->common.reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) n = reg >> nkmp->n.shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) n &= (1 << nkmp->n.width) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) n += nkmp->n.offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (!n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) k = reg >> nkmp->k.shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) k &= (1 << nkmp->k.width) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) k += nkmp->k.offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (!k)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) k++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) m = reg >> nkmp->m.shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) m &= (1 << nkmp->m.width) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) m += nkmp->m.offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (!m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) m++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) p = reg >> nkmp->p.shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) p &= (1 << nkmp->p.width) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) rate = ccu_nkmp_calc_rate(parent_rate, n, k, m, 1 << p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) rate /= nkmp->fixed_post_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) unsigned long *parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct _ccu_nkmp _nkmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) rate *= nkmp->fixed_post_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (nkmp->max_rate && rate > nkmp->max_rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) rate = nkmp->max_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) rate /= nkmp->fixed_post_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) _nkmp.min_n = nkmp->n.min ?: 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) _nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) _nkmp.min_k = nkmp->k.min ?: 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) _nkmp.max_k = nkmp->k.max ?: 1 << nkmp->k.width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) _nkmp.min_m = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) _nkmp.max_m = nkmp->m.max ?: 1 << nkmp->m.width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) _nkmp.min_p = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) _nkmp.max_p = nkmp->p.max ?: 1 << ((1 << nkmp->p.width) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) ccu_nkmp_find_best(*parent_rate, rate, &_nkmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) rate = ccu_nkmp_calc_rate(*parent_rate, _nkmp.n, _nkmp.k,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) _nkmp.m, _nkmp.p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) rate = rate / nkmp->fixed_post_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct ccu_nkmp *nkmp = hw_to_ccu_nkmp(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) u32 n_mask = 0, k_mask = 0, m_mask = 0, p_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct _ccu_nkmp _nkmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) rate = rate * nkmp->fixed_post_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) _nkmp.min_n = nkmp->n.min ?: 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) _nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) _nkmp.min_k = nkmp->k.min ?: 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) _nkmp.max_k = nkmp->k.max ?: 1 << nkmp->k.width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) _nkmp.min_m = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) _nkmp.max_m = nkmp->m.max ?: 1 << nkmp->m.width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) _nkmp.min_p = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) _nkmp.max_p = nkmp->p.max ?: 1 << ((1 << nkmp->p.width) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) ccu_nkmp_find_best(parent_rate, rate, &_nkmp);
^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) * If width is 0, GENMASK() macro may not generate expected mask (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * as it falls under undefined behaviour by C standard due to shifts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * which are equal or greater than width of left operand. This can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * be easily avoided by explicitly checking if width is 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (nkmp->n.width)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) n_mask = GENMASK(nkmp->n.width + nkmp->n.shift - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) nkmp->n.shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (nkmp->k.width)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) k_mask = GENMASK(nkmp->k.width + nkmp->k.shift - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) nkmp->k.shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (nkmp->m.width)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) m_mask = GENMASK(nkmp->m.width + nkmp->m.shift - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) nkmp->m.shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (nkmp->p.width)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) p_mask = GENMASK(nkmp->p.width + nkmp->p.shift - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) nkmp->p.shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) spin_lock_irqsave(nkmp->common.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) reg = readl(nkmp->common.base + nkmp->common.reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) reg &= ~(n_mask | k_mask | m_mask | p_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) reg |= ((_nkmp.n - nkmp->n.offset) << nkmp->n.shift) & n_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) reg |= ((_nkmp.k - nkmp->k.offset) << nkmp->k.shift) & k_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) reg |= ((_nkmp.m - nkmp->m.offset) << nkmp->m.shift) & m_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) reg |= (ilog2(_nkmp.p) << nkmp->p.shift) & p_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) writel(reg, nkmp->common.base + nkmp->common.reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) spin_unlock_irqrestore(nkmp->common.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) ccu_helper_wait_for_lock(&nkmp->common, nkmp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) const struct clk_ops ccu_nkmp_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) .disable = ccu_nkmp_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) .enable = ccu_nkmp_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) .is_enabled = ccu_nkmp_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) .recalc_rate = ccu_nkmp_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) .round_rate = ccu_nkmp_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) .set_rate = ccu_nkmp_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) };