^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) // Helper routines for R-Car sound ADG.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) // Copyright (C) 2013 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
^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 "rsnd.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #define CLKA 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #define CLKB 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #define CLKC 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #define CLKI 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #define CLKMAX 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define CLKOUT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define CLKOUT1 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define CLKOUT2 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define CLKOUT3 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define CLKOUTMAX 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define BRRx_MASK(x) (0x3FF & x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) static struct rsnd_mod_ops adg_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) .name = "adg",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct rsnd_adg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct clk *clk[CLKMAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct clk *clkout[CLKOUTMAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct clk_onecell_data onecell;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct rsnd_mod mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) int clk_rate[CLKMAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) u32 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) u32 ckr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) u32 rbga;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) u32 rbgb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) int rbga_rate_for_441khz; /* RBGA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) int rbgb_rate_for_48khz; /* RBGB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define LRCLK_ASYNC (1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define AUDIO_OUT_48 (1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define for_each_rsnd_clk(pos, adg, i) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) for (i = 0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) (i < CLKMAX) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) ((pos) = adg->clk[i]); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define for_each_rsnd_clkout(pos, adg, i) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) for (i = 0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) (i < CLKOUTMAX) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) ((pos) = adg->clkout[i]); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define rsnd_priv_to_adg(priv) ((struct rsnd_adg *)(priv)->adg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static const char * const clk_name[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) [CLKA] = "clk_a",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) [CLKB] = "clk_b",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) [CLKC] = "clk_c",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) [CLKI] = "clk_i",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static u32 rsnd_adg_calculate_rbgx(unsigned long div)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) int i, ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (!div)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) for (i = 3; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) ratio = 2 << (i * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (0 == (div % ratio))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return (u32)((i << 8) | ((div / ratio) - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return ~0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static u32 rsnd_adg_ssi_ws_timing_gen2(struct rsnd_dai_stream *io)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct rsnd_mod *ssi_mod = rsnd_io_to_mod_ssi(io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) int id = rsnd_mod_id(ssi_mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) int ws = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (rsnd_ssi_is_pin_sharing(io)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) switch (id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) case 9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) ws = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) ws = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) ws = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return (0x6 + ws) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static void __rsnd_adg_get_timesel_ratio(struct rsnd_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct rsnd_dai_stream *io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) unsigned int target_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) unsigned int *target_val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) unsigned int *target_en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct device *dev = rsnd_priv_to_dev(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) int idx, sel, div, step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) unsigned int val, en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) unsigned int min, diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) unsigned int sel_rate[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) adg->clk_rate[CLKA], /* 0000: CLKA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) adg->clk_rate[CLKB], /* 0001: CLKB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) adg->clk_rate[CLKC], /* 0010: CLKC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) adg->rbga_rate_for_441khz, /* 0011: RBGA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) adg->rbgb_rate_for_48khz, /* 0100: RBGB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) min = ~0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) en = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) for (sel = 0; sel < ARRAY_SIZE(sel_rate); sel++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) step = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (!sel_rate[sel])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) for (div = 2; div <= 98304; div += step) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) diff = abs(target_rate - sel_rate[sel] / div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (min > diff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) val = (sel << 8) | idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) min = diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) en = 1 << (sel + 1); /* fixme */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * step of 0_0000 / 0_0001 / 0_1101
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * are out of order
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if ((idx > 2) && (idx % 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) step *= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (idx == 0x1c) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) div += step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) step *= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^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) if (min == ~0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) dev_err(dev, "no Input clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) *target_val = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (target_en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) *target_en = en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static void rsnd_adg_get_timesel_ratio(struct rsnd_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct rsnd_dai_stream *io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) unsigned int in_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) unsigned int out_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) u32 *in, u32 *out, u32 *en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) unsigned int target_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) u32 *target_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) u32 _in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) u32 _out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) u32 _en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /* default = SSI WS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) _in =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) _out = rsnd_adg_ssi_ws_timing_gen2(io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) target_rate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) target_val = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) _en = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (runtime->rate != in_rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) target_rate = out_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) target_val = &_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) } else if (runtime->rate != out_rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) target_rate = in_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) target_val = &_in;
^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) if (target_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) __rsnd_adg_get_timesel_ratio(priv, io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) target_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) target_val, &_en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) *in = _in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) *out = _out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) *en = _en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *cmd_mod,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) struct rsnd_dai_stream *io)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct rsnd_priv *priv = rsnd_mod_to_priv(cmd_mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) int id = rsnd_mod_id(cmd_mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) int shift = (id % 2) ? 16 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) u32 mask, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) rsnd_adg_get_timesel_ratio(priv, io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) rsnd_src_get_in_rate(priv, io),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) rsnd_src_get_out_rate(priv, io),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) NULL, &val, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) val = val << shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) mask = 0x0f1f << shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) rsnd_mod_bset(adg_mod, CMDOUT_TIMSEL, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) int rsnd_adg_set_src_timesel_gen2(struct rsnd_mod *src_mod,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) struct rsnd_dai_stream *io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) unsigned int in_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) unsigned int out_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) struct rsnd_priv *priv = rsnd_mod_to_priv(src_mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) u32 in, out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) u32 mask, en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) int id = rsnd_mod_id(src_mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) int shift = (id % 2) ? 16 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) rsnd_mod_confirm_src(src_mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) rsnd_adg_get_timesel_ratio(priv, io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) in_rate, out_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) &in, &out, &en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) in = in << shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) out = out << shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) mask = 0x0f1f << shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) rsnd_mod_bset(adg_mod, SRCIN_TIMSEL(id / 2), mask, in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) rsnd_mod_bset(adg_mod, SRCOUT_TIMSEL(id / 2), mask, out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) rsnd_mod_bset(adg_mod, DIV_EN, en, en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static void rsnd_adg_set_ssi_clk(struct rsnd_mod *ssi_mod, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) struct device *dev = rsnd_priv_to_dev(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) int id = rsnd_mod_id(ssi_mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) int shift = (id % 4) * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) u32 mask = 0xFF << shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) rsnd_mod_confirm_ssi(ssi_mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) val = val << shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * SSI 8 is not connected to ADG.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * it works with SSI 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (id == 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL(id / 4), mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) dev_dbg(dev, "AUDIO_CLK_SEL is 0x%x\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) int rsnd_adg_clk_query(struct rsnd_priv *priv, unsigned int rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) int sel_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) [CLKA] = 0x1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) [CLKB] = 0x2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) [CLKC] = 0x3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) [CLKI] = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * find suitable clock from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC/AUDIO_CLKI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) for (i = 0; i < CLKMAX; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (rate == adg->clk_rate[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return sel_table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * find divided clock from BRGA/BRGB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (rate == adg->rbga_rate_for_441khz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (rate == adg->rbgb_rate_for_48khz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) int rsnd_adg_ssi_clk_stop(struct rsnd_mod *ssi_mod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) rsnd_adg_set_ssi_clk(ssi_mod, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *ssi_mod, unsigned int rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) struct device *dev = rsnd_priv_to_dev(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) int data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) u32 ckr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) data = rsnd_adg_clk_query(priv, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (data < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) rsnd_adg_set_ssi_clk(ssi_mod, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (rsnd_flags_has(adg, LRCLK_ASYNC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (rsnd_flags_has(adg, AUDIO_OUT_48))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) ckr = 0x80000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (0 == (rate % 8000))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) ckr = 0x80000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) rsnd_mod_bset(adg_mod, BRGCKR, 0x80770000, adg->ckr | ckr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) rsnd_mod_write(adg_mod, BRRA, adg->rbga);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) rsnd_mod_write(adg_mod, BRRB, adg->rbgb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) dev_dbg(dev, "CLKOUT is based on BRG%c (= %dHz)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) (ckr) ? 'B' : 'A',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) (ckr) ? adg->rbgb_rate_for_48khz :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) adg->rbga_rate_for_441khz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) void rsnd_adg_clk_control(struct rsnd_priv *priv, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) struct device *dev = rsnd_priv_to_dev(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) for_each_rsnd_clk(clk, adg, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) ret = clk_prepare_enable(clk);
^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) * We shouldn't use clk_get_rate() under
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) * atomic context. Let's keep it when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * rsnd_adg_clk_enable() was called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) adg->clk_rate[i] = clk_get_rate(adg->clk[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) clk_disable_unprepare(clk);
^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) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) dev_warn(dev, "can't use clk %d\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) static void rsnd_adg_get_clkin(struct rsnd_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) struct rsnd_adg *adg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) struct device *dev = rsnd_priv_to_dev(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) for (i = 0; i < CLKMAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) clk = devm_clk_get(dev, clk_name[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) adg->clk[i] = IS_ERR(clk) ? NULL : clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) struct rsnd_adg *adg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) struct device *dev = rsnd_priv_to_dev(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) struct device_node *np = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) struct property *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) u32 ckr, rbgx, rbga, rbgb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) u32 rate, div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) #define REQ_SIZE 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) u32 req_rate[REQ_SIZE] = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) uint32_t count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) unsigned long req_48kHz_rate, req_441kHz_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) int i, req_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) const char *parent_clk_name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) static const char * const clkout_name[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) [CLKOUT] = "audio_clkout",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) [CLKOUT1] = "audio_clkout1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) [CLKOUT2] = "audio_clkout2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) [CLKOUT3] = "audio_clkout3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) int brg_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) [CLKA] = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) [CLKB] = 0x1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) [CLKC] = 0x4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) [CLKI] = 0x2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) ckr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) rbga = 2; /* default 1/6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) rbgb = 2; /* default 1/6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) * ADG supports BRRA/BRRB output only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) * this means all clkout0/1/2/3 will be same rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) prop = of_find_property(np, "clock-frequency", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (!prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) goto rsnd_adg_get_clkout_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) req_size = prop->length / sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) if (req_size > REQ_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) dev_err(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) "too many clock-frequency, use top %d\n", REQ_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) req_size = REQ_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) of_property_read_u32_array(np, "clock-frequency", req_rate, req_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) req_48kHz_rate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) req_441kHz_rate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) for (i = 0; i < req_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (0 == (req_rate[i] % 44100))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) req_441kHz_rate = req_rate[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (0 == (req_rate[i] % 48000))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) req_48kHz_rate = req_rate[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (req_rate[0] % 48000 == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) rsnd_flags_set(adg, AUDIO_OUT_48);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (of_get_property(np, "clkout-lr-asynchronous", NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) rsnd_flags_set(adg, LRCLK_ASYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) * This driver is assuming that AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) * have 44.1kHz or 48kHz base clocks for now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) * SSI itself can divide parent clock by 1/1 - 1/16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) * see
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) * rsnd_adg_ssi_clk_try_start()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) * rsnd_ssi_master_clk_start()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) adg->rbga_rate_for_441khz = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) adg->rbgb_rate_for_48khz = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) for_each_rsnd_clk(clk, adg, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) rate = clk_get_rate(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) if (0 == rate) /* not used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) /* RBGA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (!adg->rbga_rate_for_441khz && (0 == rate % 44100)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) div = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (req_441kHz_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) div = rate / req_441kHz_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) rbgx = rsnd_adg_calculate_rbgx(div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (BRRx_MASK(rbgx) == rbgx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) rbga = rbgx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) adg->rbga_rate_for_441khz = rate / div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) ckr |= brg_table[i] << 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (req_441kHz_rate &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) !rsnd_flags_has(adg, AUDIO_OUT_48))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) parent_clk_name = __clk_get_name(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) /* RBGB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (!adg->rbgb_rate_for_48khz && (0 == rate % 48000)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) div = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (req_48kHz_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) div = rate / req_48kHz_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) rbgx = rsnd_adg_calculate_rbgx(div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (BRRx_MASK(rbgx) == rbgx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) rbgb = rbgx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) adg->rbgb_rate_for_48khz = rate / div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) ckr |= brg_table[i] << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) if (req_48kHz_rate &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) rsnd_flags_has(adg, AUDIO_OUT_48))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) parent_clk_name = __clk_get_name(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) * ADG supports BRRA/BRRB output only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) * this means all clkout0/1/2/3 will be * same rate
^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) of_property_read_u32(np, "#clock-cells", &count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) * for clkout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (!count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) clk = clk_register_fixed_rate(dev, clkout_name[CLKOUT],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) parent_clk_name, 0, req_rate[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (!IS_ERR(clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) adg->clkout[CLKOUT] = clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) of_clk_add_provider(np, of_clk_src_simple_get, clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^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) * for clkout0/1/2/3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) for (i = 0; i < CLKOUTMAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) clk = clk_register_fixed_rate(dev, clkout_name[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) parent_clk_name, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) req_rate[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (!IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) adg->clkout[i] = clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) adg->onecell.clks = adg->clkout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) adg->onecell.clk_num = CLKOUTMAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) of_clk_add_provider(np, of_clk_src_onecell_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) &adg->onecell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) rsnd_adg_get_clkout_end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) adg->ckr = ckr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) adg->rbga = rbga;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) adg->rbgb = rbgb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) static void rsnd_adg_clk_dbg_info(struct rsnd_priv *priv, struct rsnd_adg *adg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) struct device *dev = rsnd_priv_to_dev(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) for_each_rsnd_clk(clk, adg, i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) dev_dbg(dev, "%s : %pa : %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) clk_name[i], clk, clk_get_rate(clk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) dev_dbg(dev, "BRGCKR = 0x%08x, BRRA/BRRB = 0x%x/0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) adg->ckr, adg->rbga, adg->rbgb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) dev_dbg(dev, "BRGA (for 44100 base) = %d\n", adg->rbga_rate_for_441khz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) dev_dbg(dev, "BRGB (for 48000 base) = %d\n", adg->rbgb_rate_for_48khz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) * Actual CLKOUT will be exchanged in rsnd_adg_ssi_clk_try_start()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) * by BRGCKR::BRGCKR_31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) for_each_rsnd_clkout(clk, adg, i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) dev_dbg(dev, "clkout %d : %pa : %ld\n", i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) clk, clk_get_rate(clk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) #define rsnd_adg_clk_dbg_info(priv, adg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) int rsnd_adg_probe(struct rsnd_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) struct rsnd_adg *adg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) struct device *dev = rsnd_priv_to_dev(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) if (!adg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) ret = rsnd_mod_init(priv, &adg->mod, &adg_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) NULL, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) rsnd_adg_get_clkin(priv, adg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) rsnd_adg_get_clkout(priv, adg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) rsnd_adg_clk_dbg_info(priv, adg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) priv->adg = adg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) rsnd_adg_clk_enable(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) void rsnd_adg_remove(struct rsnd_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) struct device *dev = rsnd_priv_to_dev(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) struct device_node *np = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) struct rsnd_adg *adg = priv->adg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) for_each_rsnd_clkout(clk, adg, i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) if (adg->clkout[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) clk_unregister_fixed_rate(adg->clkout[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) of_clk_del_provider(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) rsnd_adg_clk_disable(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }