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