linux/drivers/soundwire/intel.c
<<
>>
Prefs
   1// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
   2// Copyright(c) 2015-17 Intel Corporation.
   3
   4/*
   5 * Soundwire Intel Master Driver
   6 */
   7
   8#include <linux/acpi.h>
   9#include <linux/debugfs.h>
  10#include <linux/delay.h>
  11#include <linux/module.h>
  12#include <linux/interrupt.h>
  13#include <linux/io.h>
  14#include <linux/platform_device.h>
  15#include <sound/pcm_params.h>
  16#include <sound/soc.h>
  17#include <linux/soundwire/sdw_registers.h>
  18#include <linux/soundwire/sdw.h>
  19#include <linux/soundwire/sdw_intel.h>
  20#include "cadence_master.h"
  21#include "bus.h"
  22#include "intel.h"
  23
  24/* Intel SHIM Registers Definition */
  25#define SDW_SHIM_LCAP                   0x0
  26#define SDW_SHIM_LCTL                   0x4
  27#define SDW_SHIM_IPPTR                  0x8
  28#define SDW_SHIM_SYNC                   0xC
  29
  30#define SDW_SHIM_CTLSCAP(x)             (0x010 + 0x60 * (x))
  31#define SDW_SHIM_CTLS0CM(x)             (0x012 + 0x60 * (x))
  32#define SDW_SHIM_CTLS1CM(x)             (0x014 + 0x60 * (x))
  33#define SDW_SHIM_CTLS2CM(x)             (0x016 + 0x60 * (x))
  34#define SDW_SHIM_CTLS3CM(x)             (0x018 + 0x60 * (x))
  35#define SDW_SHIM_PCMSCAP(x)             (0x020 + 0x60 * (x))
  36
  37#define SDW_SHIM_PCMSYCHM(x, y)         (0x022 + (0x60 * (x)) + (0x2 * (y)))
  38#define SDW_SHIM_PCMSYCHC(x, y)         (0x042 + (0x60 * (x)) + (0x2 * (y)))
  39#define SDW_SHIM_PDMSCAP(x)             (0x062 + 0x60 * (x))
  40#define SDW_SHIM_IOCTL(x)               (0x06C + 0x60 * (x))
  41#define SDW_SHIM_CTMCTL(x)              (0x06E + 0x60 * (x))
  42
  43#define SDW_SHIM_WAKEEN                 0x190
  44#define SDW_SHIM_WAKESTS                0x192
  45
  46#define SDW_SHIM_LCTL_SPA               BIT(0)
  47#define SDW_SHIM_LCTL_CPA               BIT(8)
  48
  49#define SDW_SHIM_SYNC_SYNCPRD_VAL       0x176F
  50#define SDW_SHIM_SYNC_SYNCPRD           GENMASK(14, 0)
  51#define SDW_SHIM_SYNC_SYNCCPU           BIT(15)
  52#define SDW_SHIM_SYNC_CMDSYNC_MASK      GENMASK(19, 16)
  53#define SDW_SHIM_SYNC_CMDSYNC           BIT(16)
  54#define SDW_SHIM_SYNC_SYNCGO            BIT(24)
  55
  56#define SDW_SHIM_PCMSCAP_ISS            GENMASK(3, 0)
  57#define SDW_SHIM_PCMSCAP_OSS            GENMASK(7, 4)
  58#define SDW_SHIM_PCMSCAP_BSS            GENMASK(12, 8)
  59
  60#define SDW_SHIM_PCMSYCM_LCHN           GENMASK(3, 0)
  61#define SDW_SHIM_PCMSYCM_HCHN           GENMASK(7, 4)
  62#define SDW_SHIM_PCMSYCM_STREAM         GENMASK(13, 8)
  63#define SDW_SHIM_PCMSYCM_DIR            BIT(15)
  64
  65#define SDW_SHIM_PDMSCAP_ISS            GENMASK(3, 0)
  66#define SDW_SHIM_PDMSCAP_OSS            GENMASK(7, 4)
  67#define SDW_SHIM_PDMSCAP_BSS            GENMASK(12, 8)
  68#define SDW_SHIM_PDMSCAP_CPSS           GENMASK(15, 13)
  69
  70#define SDW_SHIM_IOCTL_MIF              BIT(0)
  71#define SDW_SHIM_IOCTL_CO               BIT(1)
  72#define SDW_SHIM_IOCTL_COE              BIT(2)
  73#define SDW_SHIM_IOCTL_DO               BIT(3)
  74#define SDW_SHIM_IOCTL_DOE              BIT(4)
  75#define SDW_SHIM_IOCTL_BKE              BIT(5)
  76#define SDW_SHIM_IOCTL_WPDD             BIT(6)
  77#define SDW_SHIM_IOCTL_CIBD             BIT(8)
  78#define SDW_SHIM_IOCTL_DIBD             BIT(9)
  79
  80#define SDW_SHIM_CTMCTL_DACTQE          BIT(0)
  81#define SDW_SHIM_CTMCTL_DODS            BIT(1)
  82#define SDW_SHIM_CTMCTL_DOAIS           GENMASK(4, 3)
  83
  84#define SDW_SHIM_WAKEEN_ENABLE          BIT(0)
  85#define SDW_SHIM_WAKESTS_STATUS         BIT(0)
  86
  87/* Intel ALH Register definitions */
  88#define SDW_ALH_STRMZCFG(x)             (0x000 + (0x4 * (x)))
  89#define SDW_ALH_NUM_STREAMS             64
  90
  91#define SDW_ALH_STRMZCFG_DMAT_VAL       0x3
  92#define SDW_ALH_STRMZCFG_DMAT           GENMASK(7, 0)
  93#define SDW_ALH_STRMZCFG_CHN            GENMASK(19, 16)
  94
  95#define SDW_INTEL_QUIRK_MASK_BUS_DISABLE        BIT(1)
  96
  97enum intel_pdi_type {
  98        INTEL_PDI_IN = 0,
  99        INTEL_PDI_OUT = 1,
 100        INTEL_PDI_BD = 2,
 101};
 102
 103struct sdw_intel {
 104        struct sdw_cdns cdns;
 105        int instance;
 106        struct sdw_intel_link_res *res;
 107#ifdef CONFIG_DEBUG_FS
 108        struct dentry *debugfs;
 109#endif
 110};
 111
 112#define cdns_to_intel(_cdns) container_of(_cdns, struct sdw_intel, cdns)
 113
 114/*
 115 * Read, write helpers for HW registers
 116 */
 117static inline int intel_readl(void __iomem *base, int offset)
 118{
 119        return readl(base + offset);
 120}
 121
 122static inline void intel_writel(void __iomem *base, int offset, int value)
 123{
 124        writel(value, base + offset);
 125}
 126
 127static inline u16 intel_readw(void __iomem *base, int offset)
 128{
 129        return readw(base + offset);
 130}
 131
 132static inline void intel_writew(void __iomem *base, int offset, u16 value)
 133{
 134        writew(value, base + offset);
 135}
 136
 137static int intel_clear_bit(void __iomem *base, int offset, u32 value, u32 mask)
 138{
 139        int timeout = 10;
 140        u32 reg_read;
 141
 142        writel(value, base + offset);
 143        do {
 144                reg_read = readl(base + offset);
 145                if (!(reg_read & mask))
 146                        return 0;
 147
 148                timeout--;
 149                udelay(50);
 150        } while (timeout != 0);
 151
 152        return -EAGAIN;
 153}
 154
 155static int intel_set_bit(void __iomem *base, int offset, u32 value, u32 mask)
 156{
 157        int timeout = 10;
 158        u32 reg_read;
 159
 160        writel(value, base + offset);
 161        do {
 162                reg_read = readl(base + offset);
 163                if (reg_read & mask)
 164                        return 0;
 165
 166                timeout--;
 167                udelay(50);
 168        } while (timeout != 0);
 169
 170        return -EAGAIN;
 171}
 172
 173/*
 174 * debugfs
 175 */
 176#ifdef CONFIG_DEBUG_FS
 177
 178#define RD_BUF (2 * PAGE_SIZE)
 179
 180static ssize_t intel_sprintf(void __iomem *mem, bool l,
 181                             char *buf, size_t pos, unsigned int reg)
 182{
 183        int value;
 184
 185        if (l)
 186                value = intel_readl(mem, reg);
 187        else
 188                value = intel_readw(mem, reg);
 189
 190        return scnprintf(buf + pos, RD_BUF - pos, "%4x\t%4x\n", reg, value);
 191}
 192
 193static int intel_reg_show(struct seq_file *s_file, void *data)
 194{
 195        struct sdw_intel *sdw = s_file->private;
 196        void __iomem *s = sdw->res->shim;
 197        void __iomem *a = sdw->res->alh;
 198        char *buf;
 199        ssize_t ret;
 200        int i, j;
 201        unsigned int links, reg;
 202
 203        buf = kzalloc(RD_BUF, GFP_KERNEL);
 204        if (!buf)
 205                return -ENOMEM;
 206
 207        links = intel_readl(s, SDW_SHIM_LCAP) & GENMASK(2, 0);
 208
 209        ret = scnprintf(buf, RD_BUF, "Register  Value\n");
 210        ret += scnprintf(buf + ret, RD_BUF - ret, "\nShim\n");
 211
 212        for (i = 0; i < links; i++) {
 213                reg = SDW_SHIM_LCAP + i * 4;
 214                ret += intel_sprintf(s, true, buf, ret, reg);
 215        }
 216
 217        for (i = 0; i < links; i++) {
 218                ret += scnprintf(buf + ret, RD_BUF - ret, "\nLink%d\n", i);
 219                ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTLSCAP(i));
 220                ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTLS0CM(i));
 221                ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTLS1CM(i));
 222                ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTLS2CM(i));
 223                ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTLS3CM(i));
 224                ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_PCMSCAP(i));
 225
 226                ret += scnprintf(buf + ret, RD_BUF - ret, "\n PCMSyCH registers\n");
 227
 228                /*
 229                 * the value 10 is the number of PDIs. We will need a
 230                 * cleanup to remove hard-coded Intel configurations
 231                 * from cadence_master.c
 232                 */
 233                for (j = 0; j < 10; j++) {
 234                        ret += intel_sprintf(s, false, buf, ret,
 235                                        SDW_SHIM_PCMSYCHM(i, j));
 236                        ret += intel_sprintf(s, false, buf, ret,
 237                                        SDW_SHIM_PCMSYCHC(i, j));
 238                }
 239                ret += scnprintf(buf + ret, RD_BUF - ret, "\n PDMSCAP, IOCTL, CTMCTL\n");
 240
 241                ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_PDMSCAP(i));
 242                ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_IOCTL(i));
 243                ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTMCTL(i));
 244        }
 245
 246        ret += scnprintf(buf + ret, RD_BUF - ret, "\nWake registers\n");
 247        ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_WAKEEN);
 248        ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_WAKESTS);
 249
 250        ret += scnprintf(buf + ret, RD_BUF - ret, "\nALH STRMzCFG\n");
 251        for (i = 0; i < SDW_ALH_NUM_STREAMS; i++)
 252                ret += intel_sprintf(a, true, buf, ret, SDW_ALH_STRMZCFG(i));
 253
 254        seq_printf(s_file, "%s", buf);
 255        kfree(buf);
 256
 257        return 0;
 258}
 259DEFINE_SHOW_ATTRIBUTE(intel_reg);
 260
 261static void intel_debugfs_init(struct sdw_intel *sdw)
 262{
 263        struct dentry *root = sdw->cdns.bus.debugfs;
 264
 265        if (!root)
 266                return;
 267
 268        sdw->debugfs = debugfs_create_dir("intel-sdw", root);
 269
 270        debugfs_create_file("intel-registers", 0400, sdw->debugfs, sdw,
 271                            &intel_reg_fops);
 272
 273        sdw_cdns_debugfs_init(&sdw->cdns, sdw->debugfs);
 274}
 275
 276static void intel_debugfs_exit(struct sdw_intel *sdw)
 277{
 278        debugfs_remove_recursive(sdw->debugfs);
 279}
 280#else
 281static void intel_debugfs_init(struct sdw_intel *sdw) {}
 282static void intel_debugfs_exit(struct sdw_intel *sdw) {}
 283#endif /* CONFIG_DEBUG_FS */
 284
 285/*
 286 * shim ops
 287 */
 288
 289static int intel_link_power_up(struct sdw_intel *sdw)
 290{
 291        unsigned int link_id = sdw->instance;
 292        void __iomem *shim = sdw->res->shim;
 293        int spa_mask, cpa_mask;
 294        int link_control, ret;
 295
 296        /* Link power up sequence */
 297        link_control = intel_readl(shim, SDW_SHIM_LCTL);
 298        spa_mask = (SDW_SHIM_LCTL_SPA << link_id);
 299        cpa_mask = (SDW_SHIM_LCTL_CPA << link_id);
 300        link_control |=  spa_mask;
 301
 302        ret = intel_set_bit(shim, SDW_SHIM_LCTL, link_control, cpa_mask);
 303        if (ret < 0)
 304                return ret;
 305
 306        sdw->cdns.link_up = true;
 307        return 0;
 308}
 309
 310static int intel_shim_init(struct sdw_intel *sdw)
 311{
 312        void __iomem *shim = sdw->res->shim;
 313        unsigned int link_id = sdw->instance;
 314        int sync_reg, ret;
 315        u16 ioctl = 0, act = 0;
 316
 317        /* Initialize Shim */
 318        ioctl |= SDW_SHIM_IOCTL_BKE;
 319        intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
 320
 321        ioctl |= SDW_SHIM_IOCTL_WPDD;
 322        intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
 323
 324        ioctl |= SDW_SHIM_IOCTL_DO;
 325        intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
 326
 327        ioctl |= SDW_SHIM_IOCTL_DOE;
 328        intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
 329
 330        /* Switch to MIP from Glue logic */
 331        ioctl = intel_readw(shim,  SDW_SHIM_IOCTL(link_id));
 332
 333        ioctl &= ~(SDW_SHIM_IOCTL_DOE);
 334        intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
 335
 336        ioctl &= ~(SDW_SHIM_IOCTL_DO);
 337        intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
 338
 339        ioctl |= (SDW_SHIM_IOCTL_MIF);
 340        intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
 341
 342        ioctl &= ~(SDW_SHIM_IOCTL_BKE);
 343        ioctl &= ~(SDW_SHIM_IOCTL_COE);
 344
 345        intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
 346
 347        act |= 0x1 << SDW_REG_SHIFT(SDW_SHIM_CTMCTL_DOAIS);
 348        act |= SDW_SHIM_CTMCTL_DACTQE;
 349        act |= SDW_SHIM_CTMCTL_DODS;
 350        intel_writew(shim, SDW_SHIM_CTMCTL(link_id), act);
 351
 352        /* Now set SyncPRD period */
 353        sync_reg = intel_readl(shim, SDW_SHIM_SYNC);
 354        sync_reg |= (SDW_SHIM_SYNC_SYNCPRD_VAL <<
 355                        SDW_REG_SHIFT(SDW_SHIM_SYNC_SYNCPRD));
 356
 357        /* Set SyncCPU bit */
 358        sync_reg |= SDW_SHIM_SYNC_SYNCCPU;
 359        ret = intel_clear_bit(shim, SDW_SHIM_SYNC, sync_reg,
 360                              SDW_SHIM_SYNC_SYNCCPU);
 361        if (ret < 0)
 362                dev_err(sdw->cdns.dev, "Failed to set sync period: %d\n", ret);
 363
 364        return ret;
 365}
 366
 367/*
 368 * PDI routines
 369 */
 370static void intel_pdi_init(struct sdw_intel *sdw,
 371                           struct sdw_cdns_stream_config *config)
 372{
 373        void __iomem *shim = sdw->res->shim;
 374        unsigned int link_id = sdw->instance;
 375        int pcm_cap, pdm_cap;
 376
 377        /* PCM Stream Capability */
 378        pcm_cap = intel_readw(shim, SDW_SHIM_PCMSCAP(link_id));
 379
 380        config->pcm_bd = (pcm_cap & SDW_SHIM_PCMSCAP_BSS) >>
 381                                        SDW_REG_SHIFT(SDW_SHIM_PCMSCAP_BSS);
 382        config->pcm_in = (pcm_cap & SDW_SHIM_PCMSCAP_ISS) >>
 383                                        SDW_REG_SHIFT(SDW_SHIM_PCMSCAP_ISS);
 384        config->pcm_out = (pcm_cap & SDW_SHIM_PCMSCAP_OSS) >>
 385                                        SDW_REG_SHIFT(SDW_SHIM_PCMSCAP_OSS);
 386
 387        dev_dbg(sdw->cdns.dev, "PCM cap bd:%d in:%d out:%d\n",
 388                config->pcm_bd, config->pcm_in, config->pcm_out);
 389
 390        /* PDM Stream Capability */
 391        pdm_cap = intel_readw(shim, SDW_SHIM_PDMSCAP(link_id));
 392
 393        config->pdm_bd = (pdm_cap & SDW_SHIM_PDMSCAP_BSS) >>
 394                                        SDW_REG_SHIFT(SDW_SHIM_PDMSCAP_BSS);
 395        config->pdm_in = (pdm_cap & SDW_SHIM_PDMSCAP_ISS) >>
 396                                        SDW_REG_SHIFT(SDW_SHIM_PDMSCAP_ISS);
 397        config->pdm_out = (pdm_cap & SDW_SHIM_PDMSCAP_OSS) >>
 398                                        SDW_REG_SHIFT(SDW_SHIM_PDMSCAP_OSS);
 399
 400        dev_dbg(sdw->cdns.dev, "PDM cap bd:%d in:%d out:%d\n",
 401                config->pdm_bd, config->pdm_in, config->pdm_out);
 402}
 403
 404static int
 405intel_pdi_get_ch_cap(struct sdw_intel *sdw, unsigned int pdi_num, bool pcm)
 406{
 407        void __iomem *shim = sdw->res->shim;
 408        unsigned int link_id = sdw->instance;
 409        int count;
 410
 411        if (pcm) {
 412                count = intel_readw(shim, SDW_SHIM_PCMSYCHC(link_id, pdi_num));
 413
 414                /*
 415                 * WORKAROUND: on all existing Intel controllers, pdi
 416                 * number 2 reports channel count as 1 even though it
 417                 * supports 8 channels. Performing hardcoding for pdi
 418                 * number 2.
 419                 */
 420                if (pdi_num == 2)
 421                        count = 7;
 422
 423        } else {
 424                count = intel_readw(shim, SDW_SHIM_PDMSCAP(link_id));
 425                count = ((count & SDW_SHIM_PDMSCAP_CPSS) >>
 426                                        SDW_REG_SHIFT(SDW_SHIM_PDMSCAP_CPSS));
 427        }
 428
 429        /* zero based values for channel count in register */
 430        count++;
 431
 432        return count;
 433}
 434
 435static int intel_pdi_get_ch_update(struct sdw_intel *sdw,
 436                                   struct sdw_cdns_pdi *pdi,
 437                                   unsigned int num_pdi,
 438                                   unsigned int *num_ch, bool pcm)
 439{
 440        int i, ch_count = 0;
 441
 442        for (i = 0; i < num_pdi; i++) {
 443                pdi->ch_count = intel_pdi_get_ch_cap(sdw, pdi->num, pcm);
 444                ch_count += pdi->ch_count;
 445                pdi++;
 446        }
 447
 448        *num_ch = ch_count;
 449        return 0;
 450}
 451
 452static int intel_pdi_stream_ch_update(struct sdw_intel *sdw,
 453                                      struct sdw_cdns_streams *stream, bool pcm)
 454{
 455        intel_pdi_get_ch_update(sdw, stream->bd, stream->num_bd,
 456                                &stream->num_ch_bd, pcm);
 457
 458        intel_pdi_get_ch_update(sdw, stream->in, stream->num_in,
 459                                &stream->num_ch_in, pcm);
 460
 461        intel_pdi_get_ch_update(sdw, stream->out, stream->num_out,
 462                                &stream->num_ch_out, pcm);
 463
 464        return 0;
 465}
 466
 467static int intel_pdi_ch_update(struct sdw_intel *sdw)
 468{
 469        /* First update PCM streams followed by PDM streams */
 470        intel_pdi_stream_ch_update(sdw, &sdw->cdns.pcm, true);
 471        intel_pdi_stream_ch_update(sdw, &sdw->cdns.pdm, false);
 472
 473        return 0;
 474}
 475
 476static void
 477intel_pdi_shim_configure(struct sdw_intel *sdw, struct sdw_cdns_pdi *pdi)
 478{
 479        void __iomem *shim = sdw->res->shim;
 480        unsigned int link_id = sdw->instance;
 481        int pdi_conf = 0;
 482
 483        /* the Bulk and PCM streams are not contiguous */
 484        pdi->intel_alh_id = (link_id * 16) + pdi->num + 3;
 485        if (pdi->num >= 2)
 486                pdi->intel_alh_id += 2;
 487
 488        /*
 489         * Program stream parameters to stream SHIM register
 490         * This is applicable for PCM stream only.
 491         */
 492        if (pdi->type != SDW_STREAM_PCM)
 493                return;
 494
 495        if (pdi->dir == SDW_DATA_DIR_RX)
 496                pdi_conf |= SDW_SHIM_PCMSYCM_DIR;
 497        else
 498                pdi_conf &= ~(SDW_SHIM_PCMSYCM_DIR);
 499
 500        pdi_conf |= (pdi->intel_alh_id <<
 501                        SDW_REG_SHIFT(SDW_SHIM_PCMSYCM_STREAM));
 502        pdi_conf |= (pdi->l_ch_num << SDW_REG_SHIFT(SDW_SHIM_PCMSYCM_LCHN));
 503        pdi_conf |= (pdi->h_ch_num << SDW_REG_SHIFT(SDW_SHIM_PCMSYCM_HCHN));
 504
 505        intel_writew(shim, SDW_SHIM_PCMSYCHM(link_id, pdi->num), pdi_conf);
 506}
 507
 508static void
 509intel_pdi_alh_configure(struct sdw_intel *sdw, struct sdw_cdns_pdi *pdi)
 510{
 511        void __iomem *alh = sdw->res->alh;
 512        unsigned int link_id = sdw->instance;
 513        unsigned int conf;
 514
 515        /* the Bulk and PCM streams are not contiguous */
 516        pdi->intel_alh_id = (link_id * 16) + pdi->num + 3;
 517        if (pdi->num >= 2)
 518                pdi->intel_alh_id += 2;
 519
 520        /* Program Stream config ALH register */
 521        conf = intel_readl(alh, SDW_ALH_STRMZCFG(pdi->intel_alh_id));
 522
 523        conf |= (SDW_ALH_STRMZCFG_DMAT_VAL <<
 524                        SDW_REG_SHIFT(SDW_ALH_STRMZCFG_DMAT));
 525
 526        conf |= ((pdi->ch_count - 1) <<
 527                        SDW_REG_SHIFT(SDW_ALH_STRMZCFG_CHN));
 528
 529        intel_writel(alh, SDW_ALH_STRMZCFG(pdi->intel_alh_id), conf);
 530}
 531
 532static int intel_config_stream(struct sdw_intel *sdw,
 533                               struct snd_pcm_substream *substream,
 534                               struct snd_soc_dai *dai,
 535                               struct snd_pcm_hw_params *hw_params, int link_id)
 536{
 537        struct sdw_intel_link_res *res = sdw->res;
 538
 539        if (res->ops && res->ops->config_stream && res->arg)
 540                return res->ops->config_stream(res->arg,
 541                                substream, dai, hw_params, link_id);
 542
 543        return -EIO;
 544}
 545
 546/*
 547 * bank switch routines
 548 */
 549
 550static int intel_pre_bank_switch(struct sdw_bus *bus)
 551{
 552        struct sdw_cdns *cdns = bus_to_cdns(bus);
 553        struct sdw_intel *sdw = cdns_to_intel(cdns);
 554        void __iomem *shim = sdw->res->shim;
 555        int sync_reg;
 556
 557        /* Write to register only for multi-link */
 558        if (!bus->multi_link)
 559                return 0;
 560
 561        /* Read SYNC register */
 562        sync_reg = intel_readl(shim, SDW_SHIM_SYNC);
 563        sync_reg |= SDW_SHIM_SYNC_CMDSYNC << sdw->instance;
 564        intel_writel(shim, SDW_SHIM_SYNC, sync_reg);
 565
 566        return 0;
 567}
 568
 569static int intel_post_bank_switch(struct sdw_bus *bus)
 570{
 571        struct sdw_cdns *cdns = bus_to_cdns(bus);
 572        struct sdw_intel *sdw = cdns_to_intel(cdns);
 573        void __iomem *shim = sdw->res->shim;
 574        int sync_reg, ret;
 575
 576        /* Write to register only for multi-link */
 577        if (!bus->multi_link)
 578                return 0;
 579
 580        /* Read SYNC register */
 581        sync_reg = intel_readl(shim, SDW_SHIM_SYNC);
 582
 583        /*
 584         * post_bank_switch() ops is called from the bus in loop for
 585         * all the Masters in the steam with the expectation that
 586         * we trigger the bankswitch for the only first Master in the list
 587         * and do nothing for the other Masters
 588         *
 589         * So, set the SYNCGO bit only if CMDSYNC bit is set for any Master.
 590         */
 591        if (!(sync_reg & SDW_SHIM_SYNC_CMDSYNC_MASK))
 592                return 0;
 593
 594        /*
 595         * Set SyncGO bit to synchronously trigger a bank switch for
 596         * all the masters. A write to SYNCGO bit clears CMDSYNC bit for all
 597         * the Masters.
 598         */
 599        sync_reg |= SDW_SHIM_SYNC_SYNCGO;
 600
 601        ret = intel_clear_bit(shim, SDW_SHIM_SYNC, sync_reg,
 602                              SDW_SHIM_SYNC_SYNCGO);
 603        if (ret < 0)
 604                dev_err(sdw->cdns.dev, "Post bank switch failed: %d\n", ret);
 605
 606        return ret;
 607}
 608
 609/*
 610 * DAI routines
 611 */
 612
 613static int intel_hw_params(struct snd_pcm_substream *substream,
 614                           struct snd_pcm_hw_params *params,
 615                           struct snd_soc_dai *dai)
 616{
 617        struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
 618        struct sdw_intel *sdw = cdns_to_intel(cdns);
 619        struct sdw_cdns_dma_data *dma;
 620        struct sdw_cdns_pdi *pdi;
 621        struct sdw_stream_config sconfig;
 622        struct sdw_port_config *pconfig;
 623        int ch, dir;
 624        int ret;
 625        bool pcm = true;
 626
 627        dma = snd_soc_dai_get_dma_data(dai, substream);
 628        if (!dma)
 629                return -EIO;
 630
 631        ch = params_channels(params);
 632        if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
 633                dir = SDW_DATA_DIR_RX;
 634        else
 635                dir = SDW_DATA_DIR_TX;
 636
 637        if (dma->stream_type == SDW_STREAM_PDM)
 638                pcm = false;
 639
 640        if (pcm)
 641                pdi = sdw_cdns_alloc_pdi(cdns, &cdns->pcm, ch, dir, dai->id);
 642        else
 643                pdi = sdw_cdns_alloc_pdi(cdns, &cdns->pdm, ch, dir, dai->id);
 644
 645        if (!pdi) {
 646                ret = -EINVAL;
 647                goto error;
 648        }
 649
 650        /* do run-time configurations for SHIM, ALH and PDI/PORT */
 651        intel_pdi_shim_configure(sdw, pdi);
 652        intel_pdi_alh_configure(sdw, pdi);
 653        sdw_cdns_config_stream(cdns, ch, dir, pdi);
 654
 655
 656        /* Inform DSP about PDI stream number */
 657        ret = intel_config_stream(sdw, substream, dai, params,
 658                                  pdi->intel_alh_id);
 659        if (ret)
 660                goto error;
 661
 662        sconfig.direction = dir;
 663        sconfig.ch_count = ch;
 664        sconfig.frame_rate = params_rate(params);
 665        sconfig.type = dma->stream_type;
 666
 667        if (dma->stream_type == SDW_STREAM_PDM) {
 668                sconfig.frame_rate *= 50;
 669                sconfig.bps = 1;
 670        } else {
 671                sconfig.bps = snd_pcm_format_width(params_format(params));
 672        }
 673
 674        /* Port configuration */
 675        pconfig = kcalloc(1, sizeof(*pconfig), GFP_KERNEL);
 676        if (!pconfig) {
 677                ret =  -ENOMEM;
 678                goto error;
 679        }
 680
 681        pconfig->num = pdi->num;
 682        pconfig->ch_mask = (1 << ch) - 1;
 683
 684        ret = sdw_stream_add_master(&cdns->bus, &sconfig,
 685                                    pconfig, 1, dma->stream);
 686        if (ret)
 687                dev_err(cdns->dev, "add master to stream failed:%d\n", ret);
 688
 689        kfree(pconfig);
 690error:
 691        return ret;
 692}
 693
 694static int
 695intel_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 696{
 697        struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
 698        struct sdw_cdns_dma_data *dma;
 699        int ret;
 700
 701        dma = snd_soc_dai_get_dma_data(dai, substream);
 702        if (!dma)
 703                return -EIO;
 704
 705        ret = sdw_stream_remove_master(&cdns->bus, dma->stream);
 706        if (ret < 0)
 707                dev_err(dai->dev, "remove master from stream %s failed: %d\n",
 708                        dma->stream->name, ret);
 709
 710        return ret;
 711}
 712
 713static void intel_shutdown(struct snd_pcm_substream *substream,
 714                           struct snd_soc_dai *dai)
 715{
 716        struct sdw_cdns_dma_data *dma;
 717
 718        dma = snd_soc_dai_get_dma_data(dai, substream);
 719        if (!dma)
 720                return;
 721
 722        snd_soc_dai_set_dma_data(dai, substream, NULL);
 723        kfree(dma);
 724}
 725
 726static int intel_pcm_set_sdw_stream(struct snd_soc_dai *dai,
 727                                    void *stream, int direction)
 728{
 729        return cdns_set_sdw_stream(dai, stream, true, direction);
 730}
 731
 732static int intel_pdm_set_sdw_stream(struct snd_soc_dai *dai,
 733                                    void *stream, int direction)
 734{
 735        return cdns_set_sdw_stream(dai, stream, false, direction);
 736}
 737
 738static const struct snd_soc_dai_ops intel_pcm_dai_ops = {
 739        .hw_params = intel_hw_params,
 740        .hw_free = intel_hw_free,
 741        .shutdown = intel_shutdown,
 742        .set_sdw_stream = intel_pcm_set_sdw_stream,
 743};
 744
 745static const struct snd_soc_dai_ops intel_pdm_dai_ops = {
 746        .hw_params = intel_hw_params,
 747        .hw_free = intel_hw_free,
 748        .shutdown = intel_shutdown,
 749        .set_sdw_stream = intel_pdm_set_sdw_stream,
 750};
 751
 752static const struct snd_soc_component_driver dai_component = {
 753        .name           = "soundwire",
 754};
 755
 756static int intel_create_dai(struct sdw_cdns *cdns,
 757                            struct snd_soc_dai_driver *dais,
 758                            enum intel_pdi_type type,
 759                            u32 num, u32 off, u32 max_ch, bool pcm)
 760{
 761        int i;
 762
 763        if (num == 0)
 764                return 0;
 765
 766         /* TODO: Read supported rates/formats from hardware */
 767        for (i = off; i < (off + num); i++) {
 768                dais[i].name = kasprintf(GFP_KERNEL, "SDW%d Pin%d",
 769                                         cdns->instance, i);
 770                if (!dais[i].name)
 771                        return -ENOMEM;
 772
 773                if (type == INTEL_PDI_BD || type == INTEL_PDI_OUT) {
 774                        dais[i].playback.channels_min = 1;
 775                        dais[i].playback.channels_max = max_ch;
 776                        dais[i].playback.rates = SNDRV_PCM_RATE_48000;
 777                        dais[i].playback.formats = SNDRV_PCM_FMTBIT_S16_LE;
 778                }
 779
 780                if (type == INTEL_PDI_BD || type == INTEL_PDI_IN) {
 781                        dais[i].capture.channels_min = 1;
 782                        dais[i].capture.channels_max = max_ch;
 783                        dais[i].capture.rates = SNDRV_PCM_RATE_48000;
 784                        dais[i].capture.formats = SNDRV_PCM_FMTBIT_S16_LE;
 785                }
 786
 787                if (pcm)
 788                        dais[i].ops = &intel_pcm_dai_ops;
 789                else
 790                        dais[i].ops = &intel_pdm_dai_ops;
 791        }
 792
 793        return 0;
 794}
 795
 796static int intel_register_dai(struct sdw_intel *sdw)
 797{
 798        struct sdw_cdns *cdns = &sdw->cdns;
 799        struct sdw_cdns_streams *stream;
 800        struct snd_soc_dai_driver *dais;
 801        int num_dai, ret, off = 0;
 802
 803        /* DAIs are created based on total number of PDIs supported */
 804        num_dai = cdns->pcm.num_pdi + cdns->pdm.num_pdi;
 805
 806        dais = devm_kcalloc(cdns->dev, num_dai, sizeof(*dais), GFP_KERNEL);
 807        if (!dais)
 808                return -ENOMEM;
 809
 810        /* Create PCM DAIs */
 811        stream = &cdns->pcm;
 812
 813        ret = intel_create_dai(cdns, dais, INTEL_PDI_IN, cdns->pcm.num_in,
 814                               off, stream->num_ch_in, true);
 815        if (ret)
 816                return ret;
 817
 818        off += cdns->pcm.num_in;
 819        ret = intel_create_dai(cdns, dais, INTEL_PDI_OUT, cdns->pcm.num_out,
 820                               off, stream->num_ch_out, true);
 821        if (ret)
 822                return ret;
 823
 824        off += cdns->pcm.num_out;
 825        ret = intel_create_dai(cdns, dais, INTEL_PDI_BD, cdns->pcm.num_bd,
 826                               off, stream->num_ch_bd, true);
 827        if (ret)
 828                return ret;
 829
 830        /* Create PDM DAIs */
 831        stream = &cdns->pdm;
 832        off += cdns->pcm.num_bd;
 833        ret = intel_create_dai(cdns, dais, INTEL_PDI_IN, cdns->pdm.num_in,
 834                               off, stream->num_ch_in, false);
 835        if (ret)
 836                return ret;
 837
 838        off += cdns->pdm.num_in;
 839        ret = intel_create_dai(cdns, dais, INTEL_PDI_OUT, cdns->pdm.num_out,
 840                               off, stream->num_ch_out, false);
 841        if (ret)
 842                return ret;
 843
 844        off += cdns->pdm.num_out;
 845        ret = intel_create_dai(cdns, dais, INTEL_PDI_BD, cdns->pdm.num_bd,
 846                               off, stream->num_ch_bd, false);
 847        if (ret)
 848                return ret;
 849
 850        return snd_soc_register_component(cdns->dev, &dai_component,
 851                                          dais, num_dai);
 852}
 853
 854static int sdw_master_read_intel_prop(struct sdw_bus *bus)
 855{
 856        struct sdw_master_prop *prop = &bus->prop;
 857        struct fwnode_handle *link;
 858        char name[32];
 859        u32 quirk_mask;
 860
 861        /* Find master handle */
 862        snprintf(name, sizeof(name),
 863                 "mipi-sdw-link-%d-subproperties", bus->link_id);
 864
 865        link = device_get_named_child_node(bus->dev, name);
 866        if (!link) {
 867                dev_err(bus->dev, "Master node %s not found\n", name);
 868                return -EIO;
 869        }
 870
 871        fwnode_property_read_u32(link,
 872                                 "intel-sdw-ip-clock",
 873                                 &prop->mclk_freq);
 874
 875        fwnode_property_read_u32(link,
 876                                 "intel-quirk-mask",
 877                                 &quirk_mask);
 878
 879        if (quirk_mask & SDW_INTEL_QUIRK_MASK_BUS_DISABLE)
 880                prop->hw_disabled = true;
 881
 882        return 0;
 883}
 884
 885static int intel_prop_read(struct sdw_bus *bus)
 886{
 887        /* Initialize with default handler to read all DisCo properties */
 888        sdw_master_read_prop(bus);
 889
 890        /* read Intel-specific properties */
 891        sdw_master_read_intel_prop(bus);
 892
 893        return 0;
 894}
 895
 896static struct sdw_master_ops sdw_intel_ops = {
 897        .read_prop = sdw_master_read_prop,
 898        .xfer_msg = cdns_xfer_msg,
 899        .xfer_msg_defer = cdns_xfer_msg_defer,
 900        .reset_page_addr = cdns_reset_page_addr,
 901        .set_bus_conf = cdns_bus_conf,
 902        .pre_bank_switch = intel_pre_bank_switch,
 903        .post_bank_switch = intel_post_bank_switch,
 904};
 905
 906static int intel_init(struct sdw_intel *sdw)
 907{
 908        /* Initialize shim and controller */
 909        intel_link_power_up(sdw);
 910        intel_shim_init(sdw);
 911
 912        return sdw_cdns_init(&sdw->cdns, false);
 913}
 914
 915/*
 916 * probe and init
 917 */
 918static int intel_probe(struct platform_device *pdev)
 919{
 920        struct sdw_cdns_stream_config config;
 921        struct sdw_intel *sdw;
 922        int ret;
 923
 924        sdw = devm_kzalloc(&pdev->dev, sizeof(*sdw), GFP_KERNEL);
 925        if (!sdw)
 926                return -ENOMEM;
 927
 928        sdw->instance = pdev->id;
 929        sdw->res = dev_get_platdata(&pdev->dev);
 930        sdw->cdns.dev = &pdev->dev;
 931        sdw->cdns.registers = sdw->res->registers;
 932        sdw->cdns.instance = sdw->instance;
 933        sdw->cdns.msg_count = 0;
 934        sdw->cdns.bus.dev = &pdev->dev;
 935        sdw->cdns.bus.link_id = pdev->id;
 936
 937        sdw_cdns_probe(&sdw->cdns);
 938
 939        /* Set property read ops */
 940        sdw_intel_ops.read_prop = intel_prop_read;
 941        sdw->cdns.bus.ops = &sdw_intel_ops;
 942
 943        platform_set_drvdata(pdev, sdw);
 944
 945        ret = sdw_add_bus_master(&sdw->cdns.bus);
 946        if (ret) {
 947                dev_err(&pdev->dev, "sdw_add_bus_master fail: %d\n", ret);
 948                return ret;
 949        }
 950
 951        if (sdw->cdns.bus.prop.hw_disabled) {
 952                dev_info(&pdev->dev, "SoundWire master %d is disabled, ignoring\n",
 953                         sdw->cdns.bus.link_id);
 954                return 0;
 955        }
 956
 957        /* Initialize shim, controller and Cadence IP */
 958        ret = intel_init(sdw);
 959        if (ret)
 960                goto err_init;
 961
 962        /* Read the PDI config and initialize cadence PDI */
 963        intel_pdi_init(sdw, &config);
 964        ret = sdw_cdns_pdi_init(&sdw->cdns, config);
 965        if (ret)
 966                goto err_init;
 967
 968        intel_pdi_ch_update(sdw);
 969
 970        /* Acquire IRQ */
 971        ret = request_threaded_irq(sdw->res->irq, sdw_cdns_irq, sdw_cdns_thread,
 972                                   IRQF_SHARED, KBUILD_MODNAME, &sdw->cdns);
 973        if (ret < 0) {
 974                dev_err(sdw->cdns.dev, "unable to grab IRQ %d, disabling device\n",
 975                        sdw->res->irq);
 976                goto err_init;
 977        }
 978
 979        ret = sdw_cdns_enable_interrupt(&sdw->cdns, true);
 980        if (ret < 0) {
 981                dev_err(sdw->cdns.dev, "cannot enable interrupts\n");
 982                goto err_init;
 983        }
 984
 985        ret = sdw_cdns_exit_reset(&sdw->cdns);
 986        if (ret < 0) {
 987                dev_err(sdw->cdns.dev, "unable to exit bus reset sequence\n");
 988                goto err_interrupt;
 989        }
 990
 991        /* Register DAIs */
 992        ret = intel_register_dai(sdw);
 993        if (ret) {
 994                dev_err(sdw->cdns.dev, "DAI registration failed: %d\n", ret);
 995                snd_soc_unregister_component(sdw->cdns.dev);
 996                goto err_interrupt;
 997        }
 998
 999        intel_debugfs_init(sdw);
1000
1001        return 0;
1002
1003err_interrupt:
1004        sdw_cdns_enable_interrupt(&sdw->cdns, false);
1005        free_irq(sdw->res->irq, sdw);
1006err_init:
1007        sdw_delete_bus_master(&sdw->cdns.bus);
1008        return ret;
1009}
1010
1011static int intel_remove(struct platform_device *pdev)
1012{
1013        struct sdw_intel *sdw;
1014
1015        sdw = platform_get_drvdata(pdev);
1016
1017        if (!sdw->cdns.bus.prop.hw_disabled) {
1018                intel_debugfs_exit(sdw);
1019                sdw_cdns_enable_interrupt(&sdw->cdns, false);
1020                free_irq(sdw->res->irq, sdw);
1021                snd_soc_unregister_component(sdw->cdns.dev);
1022        }
1023        sdw_delete_bus_master(&sdw->cdns.bus);
1024
1025        return 0;
1026}
1027
1028static struct platform_driver sdw_intel_drv = {
1029        .probe = intel_probe,
1030        .remove = intel_remove,
1031        .driver = {
1032                .name = "int-sdw",
1033
1034        },
1035};
1036
1037module_platform_driver(sdw_intel_drv);
1038
1039MODULE_LICENSE("Dual BSD/GPL");
1040MODULE_ALIAS("platform:int-sdw");
1041MODULE_DESCRIPTION("Intel Soundwire Master Driver");
1042