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