^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 2013 Emilio López
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Emilio López <emilio@elopez.com.ar>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/clkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/reset-controller.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/log2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "clk-factors.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) static DEFINE_SPINLOCK(clk_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) /* Maximum number of parents our clocks have */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define SUNXI_MAX_PARENTS 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * sun4i_get_pll1_factors() - calculates n, k, m, p factors for PLL1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * PLL1 rate is calculated as follows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * rate = (parent_rate * n * (k + 1) >> p) / (m + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * parent_rate is always 24Mhz
^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) static void sun4i_get_pll1_factors(struct factors_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) u8 div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) /* Normalize value to a 6M multiple */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) div = req->rate / 6000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) req->rate = 6000000 * div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* m is always zero for pll1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) req->m = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /* k is 1 only on these cases */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) if (req->rate >= 768000000 || req->rate == 42000000 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) req->rate == 54000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) req->k = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) req->k = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* p will be 3 for divs under 10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (div < 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) req->p = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* p will be 2 for divs between 10 - 20 and odd divs under 32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) else if (div < 20 || (div < 32 && (div & 1)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) req->p = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /* p will be 1 for even divs under 32, divs under 40 and odd pairs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * of divs between 40-62 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) else if (div < 40 || (div < 64 && (div & 2)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) req->p = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /* any other entries have p = 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) req->p = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /* calculate a suitable n based on k and p */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) div <<= req->p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) div /= (req->k + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) req->n = div / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * sun6i_a31_get_pll1_factors() - calculates n, k and m factors for PLL1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * PLL1 rate is calculated as follows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * rate = parent_rate * (n + 1) * (k + 1) / (m + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * parent_rate should always be 24MHz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static void sun6i_a31_get_pll1_factors(struct factors_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * We can operate only on MHz, this will make our life easier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) u32 freq_mhz = req->rate / 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) u32 parent_freq_mhz = req->parent_rate / 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * Round down the frequency to the closest multiple of either
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * 6 or 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) u32 round_freq_6 = rounddown(freq_mhz, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) u32 round_freq_16 = round_down(freq_mhz, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (round_freq_6 > round_freq_16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) freq_mhz = round_freq_6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) freq_mhz = round_freq_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) req->rate = freq_mhz * 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /* If the frequency is a multiple of 32 MHz, k is always 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (!(freq_mhz % 32))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) req->k = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* If the frequency is a multiple of 9 MHz, k is always 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) else if (!(freq_mhz % 9))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) req->k = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /* If the frequency is a multiple of 8 MHz, k is always 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) else if (!(freq_mhz % 8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) req->k = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /* Otherwise, we don't use the k factor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) req->k = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * If the frequency is a multiple of 2 but not a multiple of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * 3, m is 3. This is the first time we use 6 here, yet we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * will use it on several other places.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * We use this number because it's the lowest frequency we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * generate (with n = 0, k = 0, m = 3), so every other frequency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * somehow relates to this frequency.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if ((freq_mhz % 6) == 2 || (freq_mhz % 6) == 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) req->m = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * If the frequency is a multiple of 6MHz, but the factor is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * odd, m will be 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) else if ((freq_mhz / 6) & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) req->m = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* Otherwise, we end up with m = 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) req->m = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /* Calculate n thanks to the above factors we already got */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) req->n = freq_mhz * (req->m + 1) / ((req->k + 1) * parent_freq_mhz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * If n end up being outbound, and that we can still decrease
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * m, do it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if ((req->n + 1) > 31 && (req->m + 1) > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) req->n = (req->n + 1) / 2 - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) req->m = (req->m + 1) / 2 - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^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) * sun8i_a23_get_pll1_factors() - calculates n, k, m, p factors for PLL1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * PLL1 rate is calculated as follows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * rate = (parent_rate * (n + 1) * (k + 1) >> p) / (m + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * parent_rate is always 24Mhz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static void sun8i_a23_get_pll1_factors(struct factors_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) u8 div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /* Normalize value to a 6M multiple */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) div = req->rate / 6000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) req->rate = 6000000 * div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /* m is always zero for pll1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) req->m = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /* k is 1 only on these cases */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (req->rate >= 768000000 || req->rate == 42000000 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) req->rate == 54000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) req->k = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) req->k = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /* p will be 2 for divs under 20 and odd divs under 32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (div < 20 || (div < 32 && (div & 1)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) req->p = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /* p will be 1 for even divs under 32, divs under 40 and odd pairs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * of divs between 40-62 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) else if (div < 40 || (div < 64 && (div & 2)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) req->p = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /* any other entries have p = 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) req->p = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /* calculate a suitable n based on k and p */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) div <<= req->p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) div /= (req->k + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) req->n = div / 4 - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * sun4i_get_pll5_factors() - calculates n, k factors for PLL5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * PLL5 rate is calculated as follows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * rate = parent_rate * n * (k + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * parent_rate is always 24Mhz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static void sun4i_get_pll5_factors(struct factors_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) u8 div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) /* Normalize value to a parent_rate multiple (24M) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) div = req->rate / req->parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) req->rate = req->parent_rate * div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (div < 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) req->k = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) else if (div / 2 < 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) req->k = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) else if (div / 3 < 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) req->k = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) req->k = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) req->n = DIV_ROUND_UP(div, (req->k + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * sun6i_a31_get_pll6_factors() - calculates n, k factors for A31 PLL6x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * PLL6x2 rate is calculated as follows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * rate = parent_rate * (n + 1) * (k + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * parent_rate is always 24Mhz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static void sun6i_a31_get_pll6_factors(struct factors_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) u8 div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) /* Normalize value to a parent_rate multiple (24M) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) div = req->rate / req->parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) req->rate = req->parent_rate * div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) req->k = div / 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (req->k > 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) req->k = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) req->n = DIV_ROUND_UP(div, (req->k + 1)) - 1;
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * sun5i_a13_get_ahb_factors() - calculates m, p factors for AHB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * AHB rate is calculated as follows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * rate = parent_rate >> p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) static void sun5i_a13_get_ahb_factors(struct factors_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) u32 div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) /* divide only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (req->parent_rate < req->rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) req->rate = req->parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * user manual says valid speed is 8k ~ 276M, but tests show it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * can work at speeds up to 300M, just after reparenting to pll6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (req->rate < 8000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) req->rate = 8000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (req->rate > 300000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) req->rate = 300000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) div = order_base_2(DIV_ROUND_UP(req->parent_rate, req->rate));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /* p = 0 ~ 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (div > 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) div = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) req->rate = req->parent_rate >> div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) req->p = div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) #define SUN6I_AHB1_PARENT_PLL6 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * sun6i_a31_get_ahb_factors() - calculates m, p factors for AHB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * AHB rate is calculated as follows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * rate = parent_rate >> p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * if parent is pll6, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) * parent_rate = pll6 rate / (m + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static void sun6i_get_ahb1_factors(struct factors_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) u8 div, calcp, calcm = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * clock can only divide, so we will never be able to achieve
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * frequencies higher than the parent frequency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (req->parent_rate && req->rate > req->parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) req->rate = req->parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) div = DIV_ROUND_UP(req->parent_rate, req->rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) /* calculate pre-divider if parent is pll6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (req->parent_index == SUN6I_AHB1_PARENT_PLL6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (div < 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) calcp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) else if (div / 2 < 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) calcp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) else if (div / 4 < 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) calcp = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) calcp = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) calcm = DIV_ROUND_UP(div, 1 << calcp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) calcp = __roundup_pow_of_two(div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) calcp = calcp > 3 ? 3 : calcp;
^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) req->rate = (req->parent_rate / calcm) >> calcp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) req->p = calcp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) req->m = calcm - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^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) * sun6i_ahb1_recalc() - calculates AHB clock rate from m, p factors and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * parent index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) static void sun6i_ahb1_recalc(struct factors_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) req->rate = req->parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) /* apply pre-divider first if parent is pll6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (req->parent_index == SUN6I_AHB1_PARENT_PLL6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) req->rate /= req->m + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) /* clk divider */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) req->rate >>= req->p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) * sun4i_get_apb1_factors() - calculates m, p factors for APB1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * APB1 rate is calculated as follows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) * rate = (parent_rate >> p) / (m + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static void sun4i_get_apb1_factors(struct factors_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) u8 calcm, calcp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) int div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (req->parent_rate < req->rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) req->rate = req->parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) div = DIV_ROUND_UP(req->parent_rate, req->rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /* Invalid rate! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (div > 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (div <= 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) calcp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) else if (div <= 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) calcp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) else if (div <= 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) calcp = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) calcp = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) calcm = (div >> calcp) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) req->rate = (req->parent_rate >> calcp) / (calcm + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) req->m = calcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) req->p = calcp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * sun7i_a20_get_out_factors() - calculates m, p factors for CLK_OUT_A/B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) * CLK_OUT rate is calculated as follows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) * rate = (parent_rate >> p) / (m + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) static void sun7i_a20_get_out_factors(struct factors_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) u8 div, calcm, calcp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) /* These clocks can only divide, so we will never be able to achieve
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) * frequencies higher than the parent frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (req->rate > req->parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) req->rate = req->parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) div = DIV_ROUND_UP(req->parent_rate, req->rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (div < 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) calcp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) else if (div / 2 < 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) calcp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) else if (div / 4 < 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) calcp = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) calcp = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) calcm = DIV_ROUND_UP(div, 1 << calcp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) req->rate = (req->parent_rate >> calcp) / calcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) req->m = calcm - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) req->p = calcp;
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) * sunxi_factors_clk_setup() - Setup function for factor clocks
^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 const struct clk_factors_config sun4i_pll1_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) .nshift = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) .nwidth = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) .kshift = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) .kwidth = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) .mshift = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) .mwidth = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) .pshift = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) .pwidth = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) static const struct clk_factors_config sun6i_a31_pll1_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) .nshift = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) .nwidth = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) .kshift = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) .kwidth = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) .mshift = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) .mwidth = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) .n_start = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static const struct clk_factors_config sun8i_a23_pll1_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) .nshift = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) .nwidth = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) .kshift = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) .kwidth = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) .mshift = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) .mwidth = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) .pshift = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) .pwidth = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) .n_start = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) static const struct clk_factors_config sun4i_pll5_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) .nshift = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) .nwidth = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) .kshift = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) .kwidth = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) static const struct clk_factors_config sun6i_a31_pll6_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) .nshift = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) .nwidth = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) .kshift = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) .kwidth = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) .n_start = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) static const struct clk_factors_config sun5i_a13_ahb_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) .pshift = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) .pwidth = 2,
^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_factors_config sun6i_ahb1_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) .mshift = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) .mwidth = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) .pshift = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) .pwidth = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) static const struct clk_factors_config sun4i_apb1_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) .mshift = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) .mwidth = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) .pshift = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) .pwidth = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) /* user manual says "n" but it's really "p" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) static const struct clk_factors_config sun7i_a20_out_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) .mshift = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) .mwidth = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) .pshift = 20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) .pwidth = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) static const struct factors_data sun4i_pll1_data __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) .enable = 31,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) .table = &sun4i_pll1_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) .getter = sun4i_get_pll1_factors,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) static const struct factors_data sun6i_a31_pll1_data __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) .enable = 31,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) .table = &sun6i_a31_pll1_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) .getter = sun6i_a31_get_pll1_factors,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) static const struct factors_data sun8i_a23_pll1_data __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) .enable = 31,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) .table = &sun8i_a23_pll1_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) .getter = sun8i_a23_get_pll1_factors,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) static const struct factors_data sun7i_a20_pll4_data __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) .enable = 31,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) .table = &sun4i_pll5_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) .getter = sun4i_get_pll5_factors,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) static const struct factors_data sun4i_pll5_data __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) .enable = 31,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) .table = &sun4i_pll5_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) .getter = sun4i_get_pll5_factors,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) static const struct factors_data sun6i_a31_pll6_data __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) .enable = 31,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) .table = &sun6i_a31_pll6_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) .getter = sun6i_a31_get_pll6_factors,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) static const struct factors_data sun5i_a13_ahb_data __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) .mux = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) .muxmask = BIT(1) | BIT(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) .table = &sun5i_a13_ahb_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) .getter = sun5i_a13_get_ahb_factors,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) static const struct factors_data sun6i_ahb1_data __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) .mux = 12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) .muxmask = BIT(1) | BIT(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) .table = &sun6i_ahb1_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) .getter = sun6i_get_ahb1_factors,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) .recalc = sun6i_ahb1_recalc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) static const struct factors_data sun4i_apb1_data __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) .mux = 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) .muxmask = BIT(1) | BIT(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) .table = &sun4i_apb1_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) .getter = sun4i_get_apb1_factors,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) static const struct factors_data sun7i_a20_out_data __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) .enable = 31,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) .mux = 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) .muxmask = BIT(1) | BIT(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) .table = &sun7i_a20_out_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) .getter = sun7i_a20_get_out_factors,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) static struct clk * __init sunxi_factors_clk_setup(struct device_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) const struct factors_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) void __iomem *reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) reg = of_iomap(node, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (!reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) pr_err("Could not get registers for factors-clk: %pOFn\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) return sunxi_factors_register(node, data, &clk_lock, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) static void __init sun4i_pll1_clk_setup(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) sunxi_factors_clk_setup(node, &sun4i_pll1_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) CLK_OF_DECLARE(sun4i_pll1, "allwinner,sun4i-a10-pll1-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) sun4i_pll1_clk_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) static void __init sun6i_pll1_clk_setup(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) sunxi_factors_clk_setup(node, &sun6i_a31_pll1_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) CLK_OF_DECLARE(sun6i_pll1, "allwinner,sun6i-a31-pll1-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) sun6i_pll1_clk_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) static void __init sun8i_pll1_clk_setup(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) sunxi_factors_clk_setup(node, &sun8i_a23_pll1_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) CLK_OF_DECLARE(sun8i_pll1, "allwinner,sun8i-a23-pll1-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) sun8i_pll1_clk_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) static void __init sun7i_pll4_clk_setup(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) sunxi_factors_clk_setup(node, &sun7i_a20_pll4_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) CLK_OF_DECLARE(sun7i_pll4, "allwinner,sun7i-a20-pll4-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) sun7i_pll4_clk_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) static void __init sun5i_ahb_clk_setup(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) sunxi_factors_clk_setup(node, &sun5i_a13_ahb_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) CLK_OF_DECLARE(sun5i_ahb, "allwinner,sun5i-a13-ahb-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) sun5i_ahb_clk_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) static void __init sun6i_ahb1_clk_setup(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) sunxi_factors_clk_setup(node, &sun6i_ahb1_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) CLK_OF_DECLARE(sun6i_a31_ahb1, "allwinner,sun6i-a31-ahb1-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) sun6i_ahb1_clk_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) static void __init sun4i_apb1_clk_setup(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) sunxi_factors_clk_setup(node, &sun4i_apb1_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) CLK_OF_DECLARE(sun4i_apb1, "allwinner,sun4i-a10-apb1-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) sun4i_apb1_clk_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) static void __init sun7i_out_clk_setup(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) sunxi_factors_clk_setup(node, &sun7i_a20_out_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) CLK_OF_DECLARE(sun7i_out, "allwinner,sun7i-a20-out-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) sun7i_out_clk_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) * sunxi_mux_clk_setup() - Setup function for muxes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) #define SUNXI_MUX_GATE_WIDTH 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) struct mux_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) u8 shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) static const struct mux_data sun4i_cpu_mux_data __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) .shift = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) static const struct mux_data sun6i_a31_ahb1_mux_data __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) .shift = 12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) static const struct mux_data sun8i_h3_ahb2_mux_data __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) .shift = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) static struct clk * __init sunxi_mux_clk_setup(struct device_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) const struct mux_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) unsigned long flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) const char *clk_name = node->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) const char *parents[SUNXI_MAX_PARENTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) void __iomem *reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) reg = of_iomap(node, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) if (!reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) pr_err("Could not map registers for mux-clk: %pOF\n", node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) i = of_clk_parent_fill(node, parents, SUNXI_MAX_PARENTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (of_property_read_string(node, "clock-output-names", &clk_name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) pr_err("%s: could not read clock-output-names from \"%pOF\"\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) __func__, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) goto out_unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) clk = clk_register_mux(NULL, clk_name, parents, i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) CLK_SET_RATE_PARENT | flags, reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) data->shift, SUNXI_MUX_GATE_WIDTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 0, &clk_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) if (IS_ERR(clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) pr_err("%s: failed to register mux clock %s: %ld\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) clk_name, PTR_ERR(clk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) goto out_unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if (of_clk_add_provider(node, of_clk_src_simple_get, clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) pr_err("%s: failed to add clock provider for %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) __func__, clk_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) clk_unregister_divider(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) goto out_unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) return clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) out_unmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) iounmap(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) static void __init sun4i_cpu_clk_setup(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) /* Protect CPU clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) sunxi_mux_clk_setup(node, &sun4i_cpu_mux_data, CLK_IS_CRITICAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) CLK_OF_DECLARE(sun4i_cpu, "allwinner,sun4i-a10-cpu-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) sun4i_cpu_clk_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) static void __init sun6i_ahb1_mux_clk_setup(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) sunxi_mux_clk_setup(node, &sun6i_a31_ahb1_mux_data, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) CLK_OF_DECLARE(sun6i_ahb1_mux, "allwinner,sun6i-a31-ahb1-mux-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) sun6i_ahb1_mux_clk_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) static void __init sun8i_ahb2_clk_setup(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) sunxi_mux_clk_setup(node, &sun8i_h3_ahb2_mux_data, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) CLK_OF_DECLARE(sun8i_ahb2, "allwinner,sun8i-h3-ahb2-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) sun8i_ahb2_clk_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) * sunxi_divider_clk_setup() - Setup function for simple divider clocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) struct div_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) u8 shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) u8 pow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) u8 width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) const struct clk_div_table *table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) static const struct div_data sun4i_axi_data __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) .shift = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) .pow = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) .width = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) static const struct clk_div_table sun8i_a23_axi_table[] __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) { .val = 0, .div = 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) { .val = 1, .div = 2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) { .val = 2, .div = 3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) { .val = 3, .div = 4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) { .val = 4, .div = 4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) { .val = 5, .div = 4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) { .val = 6, .div = 4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) { .val = 7, .div = 4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) { } /* sentinel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) static const struct div_data sun8i_a23_axi_data __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) .width = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) .table = sun8i_a23_axi_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) static const struct div_data sun4i_ahb_data __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) .shift = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) .pow = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) .width = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) static const struct clk_div_table sun4i_apb0_table[] __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) { .val = 0, .div = 2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) { .val = 1, .div = 2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) { .val = 2, .div = 4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) { .val = 3, .div = 8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) { } /* sentinel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) static const struct div_data sun4i_apb0_data __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) .shift = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) .pow = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) .width = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) .table = sun4i_apb0_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) static void __init sunxi_divider_clk_setup(struct device_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) const struct div_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) const char *clk_name = node->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) const char *clk_parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) void __iomem *reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) reg = of_iomap(node, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if (!reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) pr_err("Could not map registers for mux-clk: %pOF\n", node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) clk_parent = of_clk_get_parent_name(node, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) if (of_property_read_string(node, "clock-output-names", &clk_name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) pr_err("%s: could not read clock-output-names from \"%pOF\"\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) __func__, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) goto out_unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) clk = clk_register_divider_table(NULL, clk_name, clk_parent, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) reg, data->shift, data->width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) data->pow ? CLK_DIVIDER_POWER_OF_TWO : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) data->table, &clk_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (IS_ERR(clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) pr_err("%s: failed to register divider clock %s: %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) __func__, clk_name, PTR_ERR(clk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) goto out_unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) if (of_clk_add_provider(node, of_clk_src_simple_get, clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) pr_err("%s: failed to add clock provider for %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) __func__, clk_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) goto out_unregister;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) if (clk_register_clkdev(clk, clk_name, NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) of_clk_del_provider(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) goto out_unregister;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) out_unregister:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) clk_unregister_divider(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) out_unmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) iounmap(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) static void __init sun4i_ahb_clk_setup(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) sunxi_divider_clk_setup(node, &sun4i_ahb_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) CLK_OF_DECLARE(sun4i_ahb, "allwinner,sun4i-a10-ahb-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) sun4i_ahb_clk_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) static void __init sun4i_apb0_clk_setup(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) sunxi_divider_clk_setup(node, &sun4i_apb0_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) CLK_OF_DECLARE(sun4i_apb0, "allwinner,sun4i-a10-apb0-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) sun4i_apb0_clk_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) static void __init sun4i_axi_clk_setup(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) sunxi_divider_clk_setup(node, &sun4i_axi_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) CLK_OF_DECLARE(sun4i_axi, "allwinner,sun4i-a10-axi-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) sun4i_axi_clk_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) static void __init sun8i_axi_clk_setup(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) sunxi_divider_clk_setup(node, &sun8i_a23_axi_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) CLK_OF_DECLARE(sun8i_axi, "allwinner,sun8i-a23-axi-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) sun8i_axi_clk_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) * sunxi_gates_clk_setup() - Setup function for leaf gates on clocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) #define SUNXI_GATES_MAX_SIZE 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) struct gates_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) DECLARE_BITMAP(mask, SUNXI_GATES_MAX_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) * sunxi_divs_clk_setup() helper data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) #define SUNXI_DIVS_MAX_QTY 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) #define SUNXI_DIVISOR_WIDTH 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) struct divs_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) const struct factors_data *factors; /* data for the factor clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) int ndivs; /* number of outputs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) * List of outputs. Refer to the diagram for sunxi_divs_clk_setup():
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) * self or base factor clock refers to the output from the pll
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) * itself. The remaining refer to fixed or configurable divider
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) * outputs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) u8 self; /* is it the base factor clock? (only one) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) u8 fixed; /* is it a fixed divisor? if not... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) struct clk_div_table *table; /* is it a table based divisor? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) u8 shift; /* otherwise it's a normal divisor with this shift */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) u8 pow; /* is it power-of-two based? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) u8 gate; /* is it independently gateable? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) bool critical;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) } div[SUNXI_DIVS_MAX_QTY];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) static struct clk_div_table pll6_sata_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) { .val = 0, .div = 6, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) { .val = 1, .div = 12, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) { .val = 2, .div = 18, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) { .val = 3, .div = 24, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) { } /* sentinel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) static const struct divs_data pll5_divs_data __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) .factors = &sun4i_pll5_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) .ndivs = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) .div = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) /* Protect PLL5_DDR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) { .shift = 0, .pow = 0, .critical = true }, /* M, DDR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) { .shift = 16, .pow = 1, }, /* P, other */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) /* No output for the base factor clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) static const struct divs_data pll6_divs_data __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) .factors = &sun4i_pll5_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) .ndivs = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) .div = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) { .shift = 0, .table = pll6_sata_tbl, .gate = 14 }, /* M, SATA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) { .fixed = 2 }, /* P, other */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) { .self = 1 }, /* base factor clock, 2x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) { .fixed = 4 }, /* pll6 / 4, used as ahb input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) static const struct divs_data sun6i_a31_pll6_divs_data __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) .factors = &sun6i_a31_pll6_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) .ndivs = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) .div = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) { .fixed = 2 }, /* normal output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) { .self = 1 }, /* base factor clock, 2x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) * sunxi_divs_clk_setup() - Setup function for leaf divisors on clocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) * These clocks look something like this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) * ________________________
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) * | ___divisor 1---|----> to consumer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) * parent >--| pll___/___divisor 2---|----> to consumer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) * | \_______________|____> to consumer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) * |________________________|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) static struct clk ** __init sunxi_divs_clk_setup(struct device_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) const struct divs_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) struct clk_onecell_data *clk_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) const char *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) const char *clk_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) struct clk **clks, *pclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) struct clk_hw *gate_hw, *rate_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) const struct clk_ops *rate_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) struct clk_gate *gate = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) struct clk_fixed_factor *fix_factor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) struct clk_divider *divider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) struct factors_data factors = *data->factors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) char *derived_name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) void __iomem *reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) int ndivs = SUNXI_DIVS_MAX_QTY, i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) int flags, clkflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) /* if number of children known, use it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) if (data->ndivs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) ndivs = data->ndivs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) /* Try to find a name for base factor clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) for (i = 0; i < ndivs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) if (data->div[i].self) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) of_property_read_string_index(node, "clock-output-names",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) i, &factors.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) /* If we don't have a .self clk use the first output-name up to '_' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) if (factors.name == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) char *endp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) of_property_read_string_index(node, "clock-output-names",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) 0, &clk_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) endp = strchr(clk_name, '_');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) if (endp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) derived_name = kstrndup(clk_name, endp - clk_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) if (!derived_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) factors.name = derived_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) factors.name = clk_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) /* Set up factor clock that we will be dividing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) pclk = sunxi_factors_clk_setup(node, &factors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) if (!pclk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) parent = __clk_get_name(pclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) kfree(derived_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) reg = of_iomap(node, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) if (!reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) pr_err("Could not map registers for divs-clk: %pOF\n", node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) clk_data = kmalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) if (!clk_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) goto out_unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) clks = kcalloc(ndivs, sizeof(*clks), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) if (!clks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) goto free_clkdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) clk_data->clks = clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) /* It's not a good idea to have automatic reparenting changing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) * our RAM clock! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) clkflags = !strcmp("pll5", parent) ? 0 : CLK_SET_RATE_PARENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) for (i = 0; i < ndivs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) if (of_property_read_string_index(node, "clock-output-names",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) i, &clk_name) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) /* If this is the base factor clock, only update clks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) if (data->div[i].self) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) clk_data->clks[i] = pclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) gate_hw = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) rate_hw = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) rate_ops = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) /* If this leaf clock can be gated, create a gate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) if (data->div[i].gate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) gate = kzalloc(sizeof(*gate), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) if (!gate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) goto free_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) gate->reg = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) gate->bit_idx = data->div[i].gate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) gate->lock = &clk_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) gate_hw = &gate->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) /* Leaves can be fixed or configurable divisors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) if (data->div[i].fixed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) fix_factor = kzalloc(sizeof(*fix_factor), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) if (!fix_factor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) goto free_gate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) fix_factor->mult = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) fix_factor->div = data->div[i].fixed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) rate_hw = &fix_factor->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) rate_ops = &clk_fixed_factor_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) divider = kzalloc(sizeof(*divider), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) if (!divider)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) goto free_gate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) flags = data->div[i].pow ? CLK_DIVIDER_POWER_OF_TWO : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) divider->reg = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) divider->shift = data->div[i].shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) divider->width = SUNXI_DIVISOR_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) divider->flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) divider->lock = &clk_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) divider->table = data->div[i].table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) rate_hw = ÷r->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) rate_ops = &clk_divider_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) /* Wrap the (potential) gate and the divisor on a composite
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) * clock to unify them */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) clks[i] = clk_register_composite(NULL, clk_name, &parent, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) rate_hw, rate_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) gate_hw, &clk_gate_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) clkflags |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) (data->div[i].critical ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) CLK_IS_CRITICAL : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) WARN_ON(IS_ERR(clk_data->clks[i]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) /* Adjust to the real max */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) clk_data->clk_num = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) if (of_clk_add_provider(node, of_clk_src_onecell_get, clk_data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) pr_err("%s: failed to add clock provider for %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) __func__, clk_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) goto free_gate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) return clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) free_gate:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) kfree(gate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) free_clks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) kfree(clks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) free_clkdata:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) kfree(clk_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) out_unmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) iounmap(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) static void __init sun4i_pll5_clk_setup(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) sunxi_divs_clk_setup(node, &pll5_divs_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) CLK_OF_DECLARE(sun4i_pll5, "allwinner,sun4i-a10-pll5-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) sun4i_pll5_clk_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) static void __init sun4i_pll6_clk_setup(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) sunxi_divs_clk_setup(node, &pll6_divs_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) CLK_OF_DECLARE(sun4i_pll6, "allwinner,sun4i-a10-pll6-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) sun4i_pll6_clk_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) static void __init sun6i_pll6_clk_setup(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) sunxi_divs_clk_setup(node, &sun6i_a31_pll6_divs_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) CLK_OF_DECLARE(sun6i_pll6, "allwinner,sun6i-a31-pll6-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) sun6i_pll6_clk_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) * sun6i display
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) * rate = parent_rate / (m + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) static void sun6i_display_factors(struct factors_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) u8 m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) if (req->rate > req->parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) req->rate = req->parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) m = DIV_ROUND_UP(req->parent_rate, req->rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) req->rate = req->parent_rate / m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) req->m = m - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) static const struct clk_factors_config sun6i_display_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) .mshift = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) .mwidth = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) static const struct factors_data sun6i_display_data __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) .enable = 31,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) .mux = 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) .muxmask = BIT(2) | BIT(1) | BIT(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) .table = &sun6i_display_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) .getter = sun6i_display_factors,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) static void __init sun6i_display_setup(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) sunxi_factors_clk_setup(node, &sun6i_display_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) CLK_OF_DECLARE(sun6i_display, "allwinner,sun6i-a31-display-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) sun6i_display_setup);