root/drivers/soundwire/intel.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. intel_readl
  2. intel_writel
  3. intel_readw
  4. intel_writew
  5. intel_clear_bit
  6. intel_set_bit
  7. intel_sprintf
  8. intel_reg_show
  9. intel_debugfs_init
  10. intel_debugfs_exit
  11. intel_debugfs_init
  12. intel_debugfs_exit
  13. intel_link_power_up
  14. intel_shim_init
  15. intel_pdi_init
  16. intel_pdi_get_ch_cap
  17. intel_pdi_get_ch_update
  18. intel_pdi_stream_ch_update
  19. intel_pdi_ch_update
  20. intel_pdi_shim_configure
  21. intel_pdi_alh_configure
  22. intel_config_stream
  23. intel_pre_bank_switch
  24. intel_post_bank_switch
  25. intel_alloc_port
  26. intel_port_cleanup
  27. intel_hw_params
  28. intel_hw_free
  29. intel_shutdown
  30. intel_pcm_set_sdw_stream
  31. intel_pdm_set_sdw_stream
  32. intel_create_dai
  33. intel_register_dai
  34. sdw_master_read_intel_prop
  35. intel_prop_read
  36. intel_probe
  37. intel_remove

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

/* [<][>][^][v][top][bottom][index][help] */