Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'soundwire-6.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire

Pull soundwire updates from Vinod Koul:

- cleanup and conversion for soundwire sysfs groups

- intel support for ace2x bits, auxdevice pm improvements

- qcom multi link device support

* tag 'soundwire-6.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire: (33 commits)
soundwire: intel_ace2.x: add support for DOAISE property
soundwire: intel_ace2.x: add support for DODSE property
soundwire: intel_ace2x: use DOAIS and DODS settings from firmware
soundwire: intel_ace2x: cleanup DOAIS/DODS settings
soundwire: intel_ace2x: simplify check_wake()
soundwire: intel_ace2x: fix wakeup handling
soundwire: intel_init: resume all devices on exit.
soundwire: intel: export intel_resume_child_device
soundwire: intel_auxdevice: use pm_runtime_resume() instead of pm_request_resume()
ASoC: SOF: Intel: hda: disable SoundWire interrupt later
soundwire: qcom: allow multi-link on newer devices
soundwire: intel_ace2x: use legacy formula for intel_alh_id
soundwire: reconcile dp0_prop and dpn_prop
soundwire: intel_ace2x: set the clock source
soundwire: intel_ace2.x: power-up first before setting SYNCPRD
soundwire: intel_ace2x: move and extend clock selection
soundwire: intel: add support for MeteorLake additional clocks
soundwire: intel: add more values for SYNCPRD
soundwire: bus: extend base clock checks to 96 MHz
soundwire: cadence: show the bus frequency and frame shape
...

+338 -161
+16 -20
drivers/soundwire/amd_init.c
··· 17 17 18 18 #define ACP_PAD_PULLDOWN_CTRL 0x0001448 19 19 #define ACP_SW_PAD_KEEPER_EN 0x0001454 20 - #define AMD_SDW_PAD_PULLDOWN_CTRL_ENABLE_MASK 0x7f9a 21 - #define AMD_SDW0_PAD_PULLDOWN_CTRL_ENABLE_MASK 0x7f9f 22 - #define AMD_SDW1_PAD_PULLDOWN_CTRL_ENABLE_MASK 0x7ffa 23 - #define AMD_SDW0_PAD_EN_MASK 1 24 - #define AMD_SDW1_PAD_EN_MASK 0x10 25 - #define AMD_SDW_PAD_EN_MASK (AMD_SDW0_PAD_EN_MASK | AMD_SDW1_PAD_EN_MASK) 20 + #define AMD_SDW0_PAD_CTRL_MASK 0x60 21 + #define AMD_SDW1_PAD_CTRL_MASK 5 22 + #define AMD_SDW_PAD_CTRL_MASK (AMD_SDW0_PAD_CTRL_MASK | AMD_SDW1_PAD_CTRL_MASK) 23 + #define AMD_SDW0_PAD_EN 1 24 + #define AMD_SDW1_PAD_EN 0x10 25 + #define AMD_SDW_PAD_EN (AMD_SDW0_PAD_EN | AMD_SDW1_PAD_EN) 26 26 27 27 static int amd_enable_sdw_pads(void __iomem *mmio, u32 link_mask, struct device *dev) 28 28 { 29 - u32 val; 30 - u32 pad_keeper_en_mask, pad_pulldown_ctrl_mask; 29 + u32 pad_keeper_en, pad_pulldown_ctrl_mask; 31 30 32 31 switch (link_mask) { 33 32 case 1: 34 - pad_keeper_en_mask = AMD_SDW0_PAD_EN_MASK; 35 - pad_pulldown_ctrl_mask = AMD_SDW0_PAD_PULLDOWN_CTRL_ENABLE_MASK; 33 + pad_keeper_en = AMD_SDW0_PAD_EN; 34 + pad_pulldown_ctrl_mask = AMD_SDW0_PAD_CTRL_MASK; 36 35 break; 37 36 case 2: 38 - pad_keeper_en_mask = AMD_SDW1_PAD_EN_MASK; 39 - pad_pulldown_ctrl_mask = AMD_SDW1_PAD_PULLDOWN_CTRL_ENABLE_MASK; 37 + pad_keeper_en = AMD_SDW1_PAD_EN; 38 + pad_pulldown_ctrl_mask = AMD_SDW1_PAD_CTRL_MASK; 40 39 break; 41 40 case 3: 42 - pad_keeper_en_mask = AMD_SDW_PAD_EN_MASK; 43 - pad_pulldown_ctrl_mask = AMD_SDW_PAD_PULLDOWN_CTRL_ENABLE_MASK; 41 + pad_keeper_en = AMD_SDW_PAD_EN; 42 + pad_pulldown_ctrl_mask = AMD_SDW_PAD_CTRL_MASK; 44 43 break; 45 44 default: 46 45 dev_err(dev, "No SDW Links are enabled\n"); 47 46 return -ENODEV; 48 47 } 49 48 50 - val = readl(mmio + ACP_SW_PAD_KEEPER_EN); 51 - val |= pad_keeper_en_mask; 52 - writel(val, mmio + ACP_SW_PAD_KEEPER_EN); 53 - val = readl(mmio + ACP_PAD_PULLDOWN_CTRL); 54 - val &= pad_pulldown_ctrl_mask; 55 - writel(val, mmio + ACP_PAD_PULLDOWN_CTRL); 49 + amd_updatel(mmio, ACP_SW_PAD_KEEPER_EN, pad_keeper_en, pad_keeper_en); 50 + amd_updatel(mmio, ACP_PAD_PULLDOWN_CTRL, pad_pulldown_ctrl_mask, 0); 51 + 56 52 return 0; 57 53 } 58 54
+8
drivers/soundwire/amd_init.h
··· 10 10 11 11 int amd_sdw_manager_start(struct amd_sdw_manager *amd_manager); 12 12 13 + static inline void amd_updatel(void __iomem *mmio, int offset, u32 mask, u32 val) 14 + { 15 + u32 tmp; 16 + 17 + tmp = readl(mmio + offset); 18 + tmp = (tmp & ~mask) | val; 19 + writel(tmp, mmio + offset); 20 + } 13 21 #endif
+6 -7
drivers/soundwire/amd_manager.c
··· 89 89 u32 val; 90 90 91 91 mutex_lock(amd_manager->acp_sdw_lock); 92 - val = readl(amd_manager->acp_mmio + ACP_EXTERNAL_INTR_CNTL(amd_manager->instance)); 93 - val |= sdw_manager_reg_mask_array[amd_manager->instance]; 94 - writel(val, amd_manager->acp_mmio + ACP_EXTERNAL_INTR_CNTL(amd_manager->instance)); 92 + val = sdw_manager_reg_mask_array[amd_manager->instance]; 93 + amd_updatel(amd_manager->acp_mmio, ACP_EXTERNAL_INTR_CNTL(amd_manager->instance), val, val); 95 94 mutex_unlock(amd_manager->acp_sdw_lock); 96 95 97 96 writel(AMD_SDW_IRQ_MASK_0TO7, amd_manager->mmio + ··· 102 103 103 104 static void amd_disable_sdw_interrupts(struct amd_sdw_manager *amd_manager) 104 105 { 105 - u32 val; 106 + u32 irq_mask; 106 107 107 108 mutex_lock(amd_manager->acp_sdw_lock); 108 - val = readl(amd_manager->acp_mmio + ACP_EXTERNAL_INTR_CNTL(amd_manager->instance)); 109 - val &= ~sdw_manager_reg_mask_array[amd_manager->instance]; 110 - writel(val, amd_manager->acp_mmio + ACP_EXTERNAL_INTR_CNTL(amd_manager->instance)); 109 + irq_mask = sdw_manager_reg_mask_array[amd_manager->instance]; 110 + amd_updatel(amd_manager->acp_mmio, ACP_EXTERNAL_INTR_CNTL(amd_manager->instance), 111 + irq_mask, 0); 111 112 mutex_unlock(amd_manager->acp_sdw_lock); 112 113 113 114 writel(0x00, amd_manager->mmio + ACP_SW_STATE_CHANGE_STATUS_MASK_0TO7);
+7 -7
drivers/soundwire/bus.c
··· 1312 1312 if (!(19200000 % mclk_freq)) { 1313 1313 mclk_freq = 19200000; 1314 1314 base = SDW_SCP_BASE_CLOCK_19200000_HZ; 1315 - } else if (!(24000000 % mclk_freq)) { 1316 - mclk_freq = 24000000; 1317 - base = SDW_SCP_BASE_CLOCK_24000000_HZ; 1318 - } else if (!(24576000 % mclk_freq)) { 1319 - mclk_freq = 24576000; 1320 - base = SDW_SCP_BASE_CLOCK_24576000_HZ; 1321 1315 } else if (!(22579200 % mclk_freq)) { 1322 1316 mclk_freq = 22579200; 1323 1317 base = SDW_SCP_BASE_CLOCK_22579200_HZ; 1318 + } else if (!(24576000 % mclk_freq)) { 1319 + mclk_freq = 24576000; 1320 + base = SDW_SCP_BASE_CLOCK_24576000_HZ; 1324 1321 } else if (!(32000000 % mclk_freq)) { 1325 1322 mclk_freq = 32000000; 1326 1323 base = SDW_SCP_BASE_CLOCK_32000000_HZ; 1324 + } else if (!(96000000 % mclk_freq)) { 1325 + mclk_freq = 24000000; 1326 + base = SDW_SCP_BASE_CLOCK_24000000_HZ; 1327 1327 } else { 1328 1328 dev_err(&slave->dev, 1329 1329 "Unsupported clock base, mclk %d\n", ··· 1474 1474 } 1475 1475 1476 1476 do { 1477 - clear = status & ~SDW_DP0_INTERRUPTS; 1477 + clear = status & ~(SDW_DP0_INTERRUPTS | SDW_DP0_SDCA_CASCADE); 1478 1478 1479 1479 if (status & SDW_DP0_INT_TEST_FAIL) { 1480 1480 dev_err(&slave->dev, "Test fail for port 0\n");
+3 -2
drivers/soundwire/bus_type.c
··· 126 126 if (slave->prop.use_domain_irq) 127 127 sdw_irq_create_mapping(slave); 128 128 129 - /* init the sysfs as we have properties now */ 130 - ret = sdw_slave_sysfs_init(slave); 129 + /* init the dynamic sysfs attributes we need */ 130 + ret = sdw_slave_sysfs_dpn_init(slave); 131 131 if (ret < 0) 132 132 dev_warn(dev, "Slave sysfs init failed:%d\n", ret); 133 133 ··· 221 221 drv->driver.probe = sdw_drv_probe; 222 222 drv->driver.remove = sdw_drv_remove; 223 223 drv->driver.shutdown = sdw_drv_shutdown; 224 + drv->driver.dev_groups = sdw_attr_groups; 224 225 225 226 return driver_register(&drv->driver); 226 227 }
+15 -21
drivers/soundwire/cadence_master.c
··· 1236 1236 1237 1237 static int cdns_allocate_pdi(struct sdw_cdns *cdns, 1238 1238 struct sdw_cdns_pdi **stream, 1239 - u32 num, u32 pdi_offset) 1239 + u32 num) 1240 1240 { 1241 1241 struct sdw_cdns_pdi *pdi; 1242 1242 int i; ··· 1249 1249 return -ENOMEM; 1250 1250 1251 1251 for (i = 0; i < num; i++) { 1252 - pdi[i].num = i + pdi_offset; 1252 + pdi[i].num = i; 1253 1253 } 1254 1254 1255 1255 *stream = pdi; ··· 1266 1266 struct sdw_cdns_stream_config config) 1267 1267 { 1268 1268 struct sdw_cdns_streams *stream; 1269 - int offset; 1270 1269 int ret; 1271 1270 1272 1271 cdns->pcm.num_bd = config.pcm_bd; ··· 1276 1277 stream = &cdns->pcm; 1277 1278 1278 1279 /* we allocate PDI0 and PDI1 which are used for Bulk */ 1279 - offset = 0; 1280 - 1281 - ret = cdns_allocate_pdi(cdns, &stream->bd, 1282 - stream->num_bd, offset); 1280 + ret = cdns_allocate_pdi(cdns, &stream->bd, stream->num_bd); 1283 1281 if (ret) 1284 1282 return ret; 1285 1283 1286 - offset += stream->num_bd; 1287 - 1288 - ret = cdns_allocate_pdi(cdns, &stream->in, 1289 - stream->num_in, offset); 1284 + ret = cdns_allocate_pdi(cdns, &stream->in, stream->num_in); 1290 1285 if (ret) 1291 1286 return ret; 1292 1287 1293 - offset += stream->num_in; 1294 - 1295 - ret = cdns_allocate_pdi(cdns, &stream->out, 1296 - stream->num_out, offset); 1288 + ret = cdns_allocate_pdi(cdns, &stream->out, stream->num_out); 1297 1289 if (ret) 1298 1290 return ret; 1299 1291 ··· 1318 1328 u32 val; 1319 1329 u32 ssp_interval; 1320 1330 int divider; 1331 + 1332 + dev_dbg(cdns->dev, "mclk %d max %d row %d col %d\n", 1333 + prop->mclk_freq, 1334 + prop->max_clk_freq, 1335 + prop->default_row, 1336 + prop->default_col); 1321 1337 1322 1338 /* Set clock divider */ 1323 1339 divider = (prop->mclk_freq / prop->max_clk_freq) - 1; ··· 1798 1802 * cdns_find_pdi() - Find a free PDI 1799 1803 * 1800 1804 * @cdns: Cadence instance 1801 - * @offset: Starting offset 1802 1805 * @num: Number of PDIs 1803 1806 * @pdi: PDI instances 1804 1807 * @dai_id: DAI id ··· 1806 1811 * expected to match, return NULL otherwise. 1807 1812 */ 1808 1813 static struct sdw_cdns_pdi *cdns_find_pdi(struct sdw_cdns *cdns, 1809 - unsigned int offset, 1810 1814 unsigned int num, 1811 1815 struct sdw_cdns_pdi *pdi, 1812 1816 int dai_id) 1813 1817 { 1814 1818 int i; 1815 1819 1816 - for (i = offset; i < offset + num; i++) 1820 + for (i = 0; i < num; i++) 1817 1821 if (pdi[i].num == dai_id) 1818 1822 return &pdi[i]; 1819 1823 ··· 1866 1872 struct sdw_cdns_pdi *pdi = NULL; 1867 1873 1868 1874 if (dir == SDW_DATA_DIR_RX) 1869 - pdi = cdns_find_pdi(cdns, 0, stream->num_in, stream->in, 1875 + pdi = cdns_find_pdi(cdns, stream->num_in, stream->in, 1870 1876 dai_id); 1871 1877 else 1872 - pdi = cdns_find_pdi(cdns, 0, stream->num_out, stream->out, 1878 + pdi = cdns_find_pdi(cdns, stream->num_out, stream->out, 1873 1879 dai_id); 1874 1880 1875 1881 /* check if we found a PDI, else find in bi-directional */ 1876 1882 if (!pdi) 1877 - pdi = cdns_find_pdi(cdns, 2, stream->num_bd, stream->bd, 1883 + pdi = cdns_find_pdi(cdns, stream->num_bd, stream->bd, 1878 1884 dai_id); 1879 1885 1880 1886 if (pdi) {
+62 -6
drivers/soundwire/intel.c
··· 345 345 u32 spa_mask, cpa_mask; 346 346 u32 link_control; 347 347 int ret = 0; 348 + u32 clock_source; 348 349 u32 syncprd; 349 350 u32 sync_reg; 351 + bool lcap_mlcs; 350 352 351 353 mutex_lock(sdw->link_res->shim_lock); 352 354 ··· 360 358 * is only dependent on the oscillator clock provided to 361 359 * the IP, so adjust based on _DSD properties reported in DSDT 362 360 * tables. The values reported are based on either 24MHz 363 - * (CNL/CML) or 38.4 MHz (ICL/TGL+). 361 + * (CNL/CML) or 38.4 MHz (ICL/TGL+). On MeteorLake additional 362 + * frequencies are available with the MLCS clock source selection. 364 363 */ 365 - if (prop->mclk_freq % 6000000) 366 - syncprd = SDW_SHIM_SYNC_SYNCPRD_VAL_38_4; 367 - else 368 - syncprd = SDW_SHIM_SYNC_SYNCPRD_VAL_24; 364 + lcap_mlcs = intel_readl(shim, SDW_SHIM_LCAP) & SDW_SHIM_LCAP_MLCS_MASK; 365 + 366 + if (prop->mclk_freq % 6000000) { 367 + if (prop->mclk_freq % 2400000) { 368 + if (lcap_mlcs) { 369 + syncprd = SDW_SHIM_SYNC_SYNCPRD_VAL_24_576; 370 + clock_source = SDW_SHIM_MLCS_CARDINAL_CLK; 371 + } else { 372 + dev_err(sdw->cdns.dev, "%s: invalid clock configuration, mclk %d lcap_mlcs %d\n", 373 + __func__, prop->mclk_freq, lcap_mlcs); 374 + ret = -EINVAL; 375 + goto out; 376 + } 377 + } else { 378 + syncprd = SDW_SHIM_SYNC_SYNCPRD_VAL_38_4; 379 + clock_source = SDW_SHIM_MLCS_XTAL_CLK; 380 + } 381 + } else { 382 + if (lcap_mlcs) { 383 + syncprd = SDW_SHIM_SYNC_SYNCPRD_VAL_96; 384 + clock_source = SDW_SHIM_MLCS_AUDIO_PLL_CLK; 385 + } else { 386 + syncprd = SDW_SHIM_SYNC_SYNCPRD_VAL_24; 387 + clock_source = SDW_SHIM_MLCS_XTAL_CLK; 388 + } 389 + } 369 390 370 391 if (!*shim_mask) { 371 392 dev_dbg(sdw->cdns.dev, "powering up all links\n"); ··· 427 402 dev_err(sdw->cdns.dev, 428 403 "Failed to set SHIM_SYNC: %d\n", ret); 429 404 goto out; 405 + } 406 + 407 + /* update link clock if needed */ 408 + if (lcap_mlcs) { 409 + link_control = intel_readl(shim, SDW_SHIM_LCTL); 410 + u32p_replace_bits(&link_control, clock_source, SDW_SHIM_LCTL_MLCS_MASK); 411 + intel_writel(shim, SDW_SHIM_LCTL, link_control); 430 412 } 431 413 } 432 414 ··· 700 668 * DAI routines 701 669 */ 702 670 671 + static int intel_free_stream(struct sdw_intel *sdw, 672 + struct snd_pcm_substream *substream, 673 + struct snd_soc_dai *dai, 674 + int link_id) 675 + { 676 + struct sdw_intel_link_res *res = sdw->link_res; 677 + struct sdw_intel_stream_free_data free_data; 678 + 679 + free_data.substream = substream; 680 + free_data.dai = dai; 681 + free_data.link_id = link_id; 682 + 683 + if (res->ops && res->ops->free_stream && res->dev) 684 + return res->ops->free_stream(res->dev, &free_data); 685 + 686 + return 0; 687 + } 688 + 703 689 static int intel_hw_params(struct snd_pcm_substream *substream, 704 690 struct snd_pcm_hw_params *params, 705 691 struct snd_soc_dai *dai) ··· 849 799 intel_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) 850 800 { 851 801 struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai); 802 + struct sdw_intel *sdw = cdns_to_intel(cdns); 852 803 struct sdw_cdns_dai_runtime *dai_runtime; 853 804 int ret; 854 805 ··· 867 816 if (ret < 0) { 868 817 dev_err(dai->dev, "remove master from stream %s failed: %d\n", 869 818 dai_runtime->stream->name, ret); 819 + return ret; 820 + } 821 + 822 + ret = intel_free_stream(sdw, substream, dai, sdw->instance); 823 + if (ret < 0) { 824 + dev_err(dai->dev, "intel_free_stream: failed %d\n", ret); 870 825 return ret; 871 826 } 872 827 ··· 1119 1062 .sync_check_cmdsync_unlocked = intel_check_cmdsync_unlocked, 1120 1063 }; 1121 1064 EXPORT_SYMBOL_NS(sdw_intel_cnl_hw_ops, SOUNDWIRE_INTEL); 1122 -
+7
drivers/soundwire/intel.h
··· 58 58 #endif 59 59 }; 60 60 61 + struct sdw_intel_prop { 62 + u16 doaise; 63 + u16 doais; 64 + u16 dodse; 65 + u16 dods; 66 + }; 67 + 61 68 enum intel_pdi_type { 62 69 INTEL_PDI_IN = 0, 63 70 INTEL_PDI_OUT = 1,
+86 -33
drivers/soundwire/intel_ace2x.c
··· 10 10 #include <linux/soundwire/sdw_registers.h> 11 11 #include <linux/soundwire/sdw.h> 12 12 #include <linux/soundwire/sdw_intel.h> 13 - #include <sound/pcm_params.h> 13 + #include <sound/hdaudio.h> 14 14 #include <sound/hda-mlink.h> 15 + #include <sound/hda_register.h> 16 + #include <sound/pcm_params.h> 15 17 #include "cadence_master.h" 16 18 #include "bus.h" 17 19 #include "intel.h" ··· 25 23 static void intel_shim_vs_init(struct sdw_intel *sdw) 26 24 { 27 25 void __iomem *shim_vs = sdw->link_res->shim_vs; 26 + struct sdw_bus *bus = &sdw->cdns.bus; 27 + struct sdw_intel_prop *intel_prop; 28 + u16 doaise; 29 + u16 doais; 30 + u16 dodse; 31 + u16 dods; 28 32 u16 act; 29 33 34 + intel_prop = bus->vendor_specific_prop; 35 + doaise = intel_prop->doaise; 36 + doais = intel_prop->doais; 37 + dodse = intel_prop->dodse; 38 + dods = intel_prop->dods; 39 + 30 40 act = intel_readw(shim_vs, SDW_SHIM2_INTEL_VS_ACTMCTL); 31 - u16p_replace_bits(&act, 0x1, SDW_SHIM2_INTEL_VS_ACTMCTL_DOAIS); 41 + u16p_replace_bits(&act, doaise, SDW_SHIM2_INTEL_VS_ACTMCTL_DOAISE); 42 + u16p_replace_bits(&act, doais, SDW_SHIM2_INTEL_VS_ACTMCTL_DOAIS); 43 + u16p_replace_bits(&act, dodse, SDW_SHIM2_INTEL_VS_ACTMCTL_DODSE); 44 + u16p_replace_bits(&act, dods, SDW_SHIM2_INTEL_VS_ACTMCTL_DODS); 32 45 act |= SDW_SHIM2_INTEL_VS_ACTMCTL_DACTQE; 33 - act |= SDW_SHIM2_INTEL_VS_ACTMCTL_DODS; 34 46 intel_writew(shim_vs, SDW_SHIM2_INTEL_VS_ACTMCTL, act); 35 47 usleep_range(10, 15); 36 48 } 37 49 50 + static void intel_shim_vs_set_clock_source(struct sdw_intel *sdw, u32 source) 51 + { 52 + void __iomem *shim_vs = sdw->link_res->shim_vs; 53 + u32 val; 54 + 55 + val = intel_readl(shim_vs, SDW_SHIM2_INTEL_VS_LVSCTL); 56 + 57 + u32p_replace_bits(&val, source, SDW_SHIM2_INTEL_VS_LVSCTL_MLCS); 58 + 59 + intel_writel(shim_vs, SDW_SHIM2_INTEL_VS_LVSCTL, val); 60 + 61 + dev_dbg(sdw->cdns.dev, "clock source %d LVSCTL %#x\n", source, val); 62 + } 63 + 38 64 static int intel_shim_check_wake(struct sdw_intel *sdw) 39 65 { 40 - void __iomem *shim_vs; 41 - u16 wake_sts; 66 + /* 67 + * We follow the HDaudio example and resume unconditionally 68 + * without checking the WAKESTS bit for that specific link 69 + */ 42 70 43 - shim_vs = sdw->link_res->shim_vs; 44 - wake_sts = intel_readw(shim_vs, SDW_SHIM2_INTEL_VS_WAKESTS); 45 - 46 - return wake_sts & SDW_SHIM2_INTEL_VS_WAKEEN_PWS; 71 + return 1; 47 72 } 48 73 49 74 static void intel_shim_wake(struct sdw_intel *sdw, bool wake_enable) 50 75 { 51 - void __iomem *shim_vs = sdw->link_res->shim_vs; 76 + u16 lsdiid = 0; 52 77 u16 wake_en; 53 78 u16 wake_sts; 79 + int ret; 54 80 55 - wake_en = intel_readw(shim_vs, SDW_SHIM2_INTEL_VS_WAKEEN); 81 + mutex_lock(sdw->link_res->shim_lock); 82 + 83 + ret = hdac_bus_eml_sdw_get_lsdiid_unlocked(sdw->link_res->hbus, sdw->instance, &lsdiid); 84 + if (ret < 0) 85 + goto unlock; 86 + 87 + wake_en = snd_hdac_chip_readw(sdw->link_res->hbus, WAKEEN); 56 88 57 89 if (wake_enable) { 58 90 /* Enable the wakeup */ 59 - wake_en |= SDW_SHIM2_INTEL_VS_WAKEEN_PWE; 60 - intel_writew(shim_vs, SDW_SHIM2_INTEL_VS_WAKEEN, wake_en); 91 + wake_en |= lsdiid; 92 + 93 + snd_hdac_chip_writew(sdw->link_res->hbus, WAKEEN, wake_en); 61 94 } else { 62 95 /* Disable the wake up interrupt */ 63 - wake_en &= ~SDW_SHIM2_INTEL_VS_WAKEEN_PWE; 64 - intel_writew(shim_vs, SDW_SHIM2_INTEL_VS_WAKEEN, wake_en); 96 + wake_en &= ~lsdiid; 97 + snd_hdac_chip_writew(sdw->link_res->hbus, WAKEEN, wake_en); 65 98 66 99 /* Clear wake status (W1C) */ 67 - wake_sts = intel_readw(shim_vs, SDW_SHIM2_INTEL_VS_WAKESTS); 68 - wake_sts |= SDW_SHIM2_INTEL_VS_WAKEEN_PWS; 69 - intel_writew(shim_vs, SDW_SHIM2_INTEL_VS_WAKESTS, wake_sts); 100 + wake_sts = snd_hdac_chip_readw(sdw->link_res->hbus, STATESTS); 101 + wake_sts |= lsdiid; 102 + snd_hdac_chip_writew(sdw->link_res->hbus, STATESTS, wake_sts); 70 103 } 104 + unlock: 105 + mutex_unlock(sdw->link_res->shim_lock); 71 106 } 72 107 73 108 static int intel_link_power_up(struct sdw_intel *sdw) ··· 113 74 struct sdw_master_prop *prop = &bus->prop; 114 75 u32 *shim_mask = sdw->link_res->shim_mask; 115 76 unsigned int link_id = sdw->instance; 77 + u32 clock_source; 116 78 u32 syncprd; 117 79 int ret; 118 80 119 - mutex_lock(sdw->link_res->shim_lock); 120 - 121 - if (!*shim_mask) { 122 - /* we first need to program the SyncPRD/CPU registers */ 123 - dev_dbg(sdw->cdns.dev, "first link up, programming SYNCPRD\n"); 124 - 125 - if (prop->mclk_freq % 6000000) 81 + if (prop->mclk_freq % 6000000) { 82 + if (prop->mclk_freq % 2400000) { 83 + syncprd = SDW_SHIM_SYNC_SYNCPRD_VAL_24_576; 84 + clock_source = SDW_SHIM2_MLCS_CARDINAL_CLK; 85 + } else { 126 86 syncprd = SDW_SHIM_SYNC_SYNCPRD_VAL_38_4; 127 - else 128 - syncprd = SDW_SHIM_SYNC_SYNCPRD_VAL_24; 129 - 130 - ret = hdac_bus_eml_sdw_set_syncprd_unlocked(sdw->link_res->hbus, syncprd); 131 - if (ret < 0) { 132 - dev_err(sdw->cdns.dev, "%s: hdac_bus_eml_sdw_set_syncprd failed: %d\n", 133 - __func__, ret); 134 - goto out; 87 + clock_source = SDW_SHIM2_MLCS_XTAL_CLK; 135 88 } 89 + } else { 90 + syncprd = SDW_SHIM_SYNC_SYNCPRD_VAL_96; 91 + clock_source = SDW_SHIM2_MLCS_AUDIO_PLL_CLK; 136 92 } 93 + 94 + mutex_lock(sdw->link_res->shim_lock); 137 95 138 96 ret = hdac_bus_eml_sdw_power_up_unlocked(sdw->link_res->hbus, link_id); 139 97 if (ret < 0) { ··· 139 103 goto out; 140 104 } 141 105 106 + intel_shim_vs_set_clock_source(sdw, clock_source); 107 + 142 108 if (!*shim_mask) { 109 + /* we first need to program the SyncPRD/CPU registers */ 110 + dev_dbg(sdw->cdns.dev, "first link up, programming SYNCPRD\n"); 111 + 112 + ret = hdac_bus_eml_sdw_set_syncprd_unlocked(sdw->link_res->hbus, syncprd); 113 + if (ret < 0) { 114 + dev_err(sdw->cdns.dev, "%s: hdac_bus_eml_sdw_set_syncprd failed: %d\n", 115 + __func__, ret); 116 + goto out; 117 + } 118 + 143 119 /* SYNCPU will change once link is active */ 144 120 ret = hdac_bus_eml_sdw_wait_syncpu_unlocked(sdw->link_res->hbus); 145 121 if (ret < 0) { ··· 315 267 ret = -EINVAL; 316 268 goto error; 317 269 } 270 + 271 + /* use same definitions for alh_id as previous generations */ 272 + pdi->intel_alh_id = (sdw->instance * 16) + pdi->num + 3; 273 + if (pdi->num >= 2) 274 + pdi->intel_alh_id += 2; 318 275 319 276 /* the SHIM will be configured in the callback functions */ 320 277
+36 -5
drivers/soundwire/intel_auxdevice.c
··· 122 122 static int sdw_master_read_intel_prop(struct sdw_bus *bus) 123 123 { 124 124 struct sdw_master_prop *prop = &bus->prop; 125 + struct sdw_intel_prop *intel_prop; 125 126 struct fwnode_handle *link; 126 127 char name[32]; 127 128 u32 quirk_mask; ··· 153 152 154 153 prop->quirks = SDW_MASTER_QUIRKS_CLEAR_INITIAL_CLASH | 155 154 SDW_MASTER_QUIRKS_CLEAR_INITIAL_PARITY; 155 + 156 + intel_prop = devm_kzalloc(bus->dev, sizeof(*intel_prop), GFP_KERNEL); 157 + if (!intel_prop) 158 + return -ENOMEM; 159 + 160 + /* initialize with hardware defaults, in case the properties are not found */ 161 + intel_prop->doaise = 0x1; 162 + intel_prop->doais = 0x3; 163 + intel_prop->dodse = 0x0; 164 + intel_prop->dods = 0x1; 165 + 166 + fwnode_property_read_u16(link, 167 + "intel-sdw-doaise", 168 + &intel_prop->doaise); 169 + fwnode_property_read_u16(link, 170 + "intel-sdw-doais", 171 + &intel_prop->doais); 172 + fwnode_property_read_u16(link, 173 + "intel-sdw-dodse", 174 + &intel_prop->dodse); 175 + fwnode_property_read_u16(link, 176 + "intel-sdw-dods", 177 + &intel_prop->dods); 178 + bus->vendor_specific_prop = intel_prop; 179 + 180 + dev_dbg(bus->dev, "doaise %#x doais %#x dodse %#x dods %#x\n", 181 + intel_prop->doaise, 182 + intel_prop->doais, 183 + intel_prop->dodse, 184 + intel_prop->dods); 156 185 157 186 return 0; 158 187 } ··· 471 440 * PM calls 472 441 */ 473 442 474 - static int intel_resume_child_device(struct device *dev, void *data) 443 + int intel_resume_child_device(struct device *dev, void *data) 475 444 { 476 445 int ret; 477 446 struct sdw_slave *slave = dev_to_sdw_dev(dev); ··· 485 454 return 0; 486 455 } 487 456 488 - ret = pm_request_resume(dev); 457 + ret = pm_runtime_resume(dev); 489 458 if (ret < 0) { 490 - dev_err(dev, "%s: pm_request_resume failed: %d\n", __func__, ret); 459 + dev_err(dev, "%s: pm_runtime_resume failed: %d\n", __func__, ret); 491 460 return ret; 492 461 } 493 462 ··· 530 499 * first resume the device for this link. This will also by construction 531 500 * resume the PCI parent device. 532 501 */ 533 - ret = pm_request_resume(dev); 502 + ret = pm_runtime_resume(dev); 534 503 if (ret < 0) { 535 - dev_err(dev, "%s: pm_request_resume failed: %d\n", __func__, ret); 504 + dev_err(dev, "%s: pm_runtime_resume failed: %d\n", __func__, ret); 536 505 return 0; 537 506 } 538 507
+1
drivers/soundwire/intel_auxdevice.h
··· 6 6 7 7 int intel_link_startup(struct auxiliary_device *auxdev); 8 8 int intel_link_process_wakeen_event(struct auxiliary_device *auxdev); 9 + int intel_resume_child_device(struct device *dev, void *data); 9 10 10 11 struct sdw_intel_link_dev { 11 12 struct auxiliary_device auxdev;
+14
drivers/soundwire/intel_init.c
··· 16 16 #include <linux/pm_runtime.h> 17 17 #include <linux/soundwire/sdw_intel.h> 18 18 #include "cadence_master.h" 19 + #include "bus.h" 19 20 #include "intel.h" 20 21 #include "intel_auxdevice.h" 21 22 ··· 357 356 */ 358 357 void sdw_intel_exit(struct sdw_intel_ctx *ctx) 359 358 { 359 + struct sdw_intel_link_res *link; 360 + 361 + /* we first resume links and devices and wait synchronously before the cleanup */ 362 + list_for_each_entry(link, &ctx->link_list, list) { 363 + struct sdw_bus *bus = &link->cdns->bus; 364 + int ret; 365 + 366 + ret = device_for_each_child(bus->dev, NULL, intel_resume_child_device); 367 + if (ret < 0) 368 + dev_err(bus->dev, "%s: intel_resume_child_device failed: %d\n", 369 + __func__, ret); 370 + } 371 + 360 372 sdw_intel_cleanup(ctx); 361 373 kfree(ctx->ids); 362 374 kfree(ctx->ldev);
+24 -4
drivers/soundwire/qcom.c
··· 905 905 return 0; 906 906 } 907 907 908 + static int qcom_swrm_read_prop(struct sdw_bus *bus) 909 + { 910 + struct qcom_swrm_ctrl *ctrl = to_qcom_sdw(bus); 911 + 912 + if (ctrl->version >= SWRM_VERSION_2_0_0) { 913 + bus->multi_link = true; 914 + bus->hw_sync_min_links = 3; 915 + } 916 + 917 + return 0; 918 + } 919 + 908 920 static enum sdw_command_response qcom_swrm_xfer_msg(struct sdw_bus *bus, 909 921 struct sdw_msg *msg) 910 922 { ··· 1068 1056 }; 1069 1057 1070 1058 static const struct sdw_master_ops qcom_swrm_ops = { 1059 + .read_prop = qcom_swrm_read_prop, 1071 1060 .xfer_msg = qcom_swrm_xfer_msg, 1072 1061 .pre_bank_switch = qcom_swrm_pre_bank_switch, 1073 1062 }; ··· 1186 1173 1187 1174 mutex_lock(&ctrl->port_lock); 1188 1175 list_for_each_entry(m_rt, &stream->master_list, stream_node) { 1176 + /* 1177 + * For streams with multiple masters: 1178 + * Allocate ports only for devices connected to this master. 1179 + * Such devices will have ports allocated by their own master 1180 + * and its qcom_swrm_stream_alloc_ports() call. 1181 + */ 1182 + if (ctrl->bus.id != m_rt->bus->id) 1183 + continue; 1184 + 1189 1185 if (m_rt->direction == SDW_DATA_DIR_RX) { 1190 1186 maxport = ctrl->num_dout_ports; 1191 1187 port_mask = &ctrl->dout_port_mask; ··· 1658 1636 return ret; 1659 1637 } 1660 1638 1661 - static int qcom_swrm_remove(struct platform_device *pdev) 1639 + static void qcom_swrm_remove(struct platform_device *pdev) 1662 1640 { 1663 1641 struct qcom_swrm_ctrl *ctrl = dev_get_drvdata(&pdev->dev); 1664 1642 1665 1643 sdw_bus_master_delete(&ctrl->bus); 1666 1644 clk_disable_unprepare(ctrl->hclk); 1667 - 1668 - return 0; 1669 1645 } 1670 1646 1671 1647 static int __maybe_unused swrm_runtime_resume(struct device *dev) ··· 1789 1769 1790 1770 static struct platform_driver qcom_swrm_driver = { 1791 1771 .probe = &qcom_swrm_probe, 1792 - .remove = &qcom_swrm_remove, 1772 + .remove_new = qcom_swrm_remove, 1793 1773 .driver = { 1794 1774 .name = "qcom-soundwire", 1795 1775 .of_match_table = qcom_swrm_of_match,
+3 -1
drivers/soundwire/sysfs_local.h
··· 11 11 /* basic attributes to report status of Slave (attachment, dev_num) */ 12 12 extern const struct attribute_group *sdw_slave_status_attr_groups[]; 13 13 14 + /* attributes for all soundwire devices */ 15 + extern const struct attribute_group *sdw_attr_groups[]; 16 + 14 17 /* additional device-managed properties reported after driver probe */ 15 - int sdw_slave_sysfs_init(struct sdw_slave *slave); 16 18 int sdw_slave_sysfs_dpn_init(struct sdw_slave *slave); 17 19 18 20 #endif /* __SDW_SYSFS_LOCAL_H */
+31 -35
drivers/soundwire/sysfs_slave.c
··· 105 105 &dev_attr_modalias.attr, 106 106 NULL, 107 107 }; 108 - ATTRIBUTE_GROUPS(slave); 108 + 109 + static const struct attribute_group slave_attr_group = { 110 + .attrs = slave_attrs, 111 + }; 109 112 110 113 static struct attribute *slave_dev_attrs[] = { 111 114 &dev_attr_mipi_revision.attr, ··· 129 126 NULL, 130 127 }; 131 128 132 - /* 133 - * we don't use ATTRIBUTES_GROUP here since we want to add a subdirectory 134 - * for device-level properties 135 - */ 136 129 static const struct attribute_group sdw_slave_dev_attr_group = { 137 130 .attrs = slave_dev_attrs, 138 131 .name = "dev-properties", ··· 180 181 NULL, 181 182 }; 182 183 183 - /* 184 - * we don't use ATTRIBUTES_GROUP here since we want to add a subdirectory 185 - * for dp0-level properties 186 - */ 184 + static umode_t dp0_attr_visible(struct kobject *kobj, struct attribute *attr, 185 + int n) 186 + { 187 + struct sdw_slave *slave = dev_to_sdw_dev(kobj_to_dev(kobj)); 188 + 189 + if (slave->prop.dp0_prop) 190 + return attr->mode; 191 + return 0; 192 + } 193 + 194 + static bool dp0_group_visible(struct kobject *kobj) 195 + { 196 + struct sdw_slave *slave = dev_to_sdw_dev(kobj_to_dev(kobj)); 197 + 198 + if (slave->prop.dp0_prop) 199 + return true; 200 + return false; 201 + } 202 + DEFINE_SYSFS_GROUP_VISIBLE(dp0); 203 + 187 204 static const struct attribute_group dp0_group = { 188 205 .attrs = dp0_attrs, 206 + .is_visible = SYSFS_GROUP_VISIBLE(dp0), 189 207 .name = "dp0", 190 208 }; 191 209 192 - int sdw_slave_sysfs_init(struct sdw_slave *slave) 193 - { 194 - int ret; 195 - 196 - ret = devm_device_add_groups(&slave->dev, slave_groups); 197 - if (ret < 0) 198 - return ret; 199 - 200 - ret = devm_device_add_group(&slave->dev, &sdw_slave_dev_attr_group); 201 - if (ret < 0) 202 - return ret; 203 - 204 - if (slave->prop.dp0_prop) { 205 - ret = devm_device_add_group(&slave->dev, &dp0_group); 206 - if (ret < 0) 207 - return ret; 208 - } 209 - 210 - if (slave->prop.source_ports || slave->prop.sink_ports) { 211 - ret = sdw_slave_sysfs_dpn_init(slave); 212 - if (ret < 0) 213 - return ret; 214 - } 215 - 216 - return 0; 217 - } 210 + const struct attribute_group *sdw_attr_groups[] = { 211 + &slave_attr_group, 212 + &sdw_slave_dev_attr_group, 213 + &dp0_group, 214 + NULL, 215 + }; 218 216 219 217 /* 220 218 * the status is shown in capital letters for UNATTACHED and RESERVED
+3
drivers/soundwire/sysfs_slave_dpn.c
··· 283 283 int ret; 284 284 int i; 285 285 286 + if (!slave->prop.source_ports && !slave->prop.sink_ports) 287 + return 0; 288 + 286 289 mask = slave->prop.source_ports; 287 290 for_each_set_bit(i, &mask, 32) { 288 291 ret = add_all_attributes(&slave->dev, i, 1);
+4 -15
include/linux/soundwire/sdw.h
··· 235 235 * @BRA_flow_controlled: Slave implementation results in an OK_NotReady 236 236 * response 237 237 * @simple_ch_prep_sm: If channel prepare sequence is required 238 + * @ch_prep_timeout: Port-specific timeout value, in milliseconds 238 239 * @imp_def_interrupts: If set, each bit corresponds to support for 239 240 * implementation-defined interrupts 240 241 * ··· 250 249 u32 *words; 251 250 bool BRA_flow_controlled; 252 251 bool simple_ch_prep_sm; 252 + u32 ch_prep_timeout; 253 253 bool imp_def_interrupts; 254 254 }; 255 255 ··· 542 540 enum sdw_reg_bank { 543 541 SDW_BANK0, 544 542 SDW_BANK1, 545 - }; 546 - 547 - /** 548 - * struct sdw_bus_conf: Bus configuration 549 - * 550 - * @clk_freq: Clock frequency, in Hz 551 - * @num_rows: Number of rows in frame 552 - * @num_cols: Number of columns in frame 553 - * @bank: Next register bank 554 - */ 555 - struct sdw_bus_conf { 556 - unsigned int clk_freq; 557 - unsigned int num_rows; 558 - unsigned int num_cols; 559 - unsigned int bank; 560 543 }; 561 544 562 545 /** ··· 886 899 * @port_ops: Master port callback ops 887 900 * @params: Current bus parameters 888 901 * @prop: Master properties 902 + * @vendor_specific_prop: pointer to non-standard properties 889 903 * @m_rt_list: List of Master instance of all stream(s) running on Bus. This 890 904 * is used to compute and program bus bandwidth, clock, frame shape, 891 905 * transport and port parameters ··· 921 933 const struct sdw_master_port_ops *port_ops; 922 934 struct sdw_bus_params params; 923 935 struct sdw_master_prop prop; 936 + void *vendor_specific_prop; 924 937 struct list_head m_rt_list; 925 938 #ifdef CONFIG_DEBUG_FS 926 939 struct dentry *debugfs;
+9 -2
include/linux/soundwire/sdw_intel.h
··· 22 22 /* LCAP */ 23 23 #define SDW_SHIM_LCAP 0x0 24 24 #define SDW_SHIM_LCAP_LCOUNT_MASK GENMASK(2, 0) 25 + #define SDW_SHIM_LCAP_MLCS_MASK BIT(8) 25 26 26 27 /* LCTL */ 27 28 #define SDW_SHIM_LCTL 0x4 ··· 31 30 #define SDW_SHIM_LCTL_SPA_MASK GENMASK(3, 0) 32 31 #define SDW_SHIM_LCTL_CPA BIT(8) 33 32 #define SDW_SHIM_LCTL_CPA_MASK GENMASK(11, 8) 33 + #define SDW_SHIM_LCTL_MLCS_MASK GENMASK(29, 27) 34 + #define SDW_SHIM_MLCS_XTAL_CLK 0x0 35 + #define SDW_SHIM_MLCS_CARDINAL_CLK 0x1 36 + #define SDW_SHIM_MLCS_AUDIO_PLL_CLK 0x2 34 37 35 38 /* SYNC */ 36 39 #define SDW_SHIM_SYNC 0xC 37 40 38 - #define SDW_SHIM_SYNC_SYNCPRD_VAL_24 (24000 / SDW_CADENCE_GSYNC_KHZ - 1) 39 - #define SDW_SHIM_SYNC_SYNCPRD_VAL_38_4 (38400 / SDW_CADENCE_GSYNC_KHZ - 1) 41 + #define SDW_SHIM_SYNC_SYNCPRD_VAL_24 (24000 / SDW_CADENCE_GSYNC_KHZ - 1) 42 + #define SDW_SHIM_SYNC_SYNCPRD_VAL_24_576 (24576 / SDW_CADENCE_GSYNC_KHZ - 1) 43 + #define SDW_SHIM_SYNC_SYNCPRD_VAL_38_4 (38400 / SDW_CADENCE_GSYNC_KHZ - 1) 44 + #define SDW_SHIM_SYNC_SYNCPRD_VAL_96 (96000 / SDW_CADENCE_GSYNC_KHZ - 1) 40 45 #define SDW_SHIM_SYNC_SYNCPRD GENMASK(14, 0) 41 46 #define SDW_SHIM_SYNC_SYNCCPU BIT(15) 42 47 #define SDW_SHIM_SYNC_CMDSYNC_MASK GENMASK(19, 16)
+1 -1
include/linux/soundwire/sdw_registers.h
··· 13 13 14 14 #define SDW_REG_NO_PAGE 0x00008000 15 15 #define SDW_REG_OPTIONAL_PAGE 0x00010000 16 - #define SDW_REG_MAX 0x80000000 16 + #define SDW_REG_MAX 0x48000000 17 17 18 18 #define SDW_DPN_SIZE 0x100 19 19 #define SDW_BANK1_OFFSET 0x10
+2 -2
sound/soc/sof/intel/hda.c
··· 246 246 247 247 hdev = sdev->pdata->hw_pdata; 248 248 249 - hda_sdw_int_enable(sdev, false); 250 - 251 249 if (hdev->sdw) 252 250 sdw_intel_exit(hdev->sdw); 253 251 hdev->sdw = NULL; 252 + 253 + hda_sdw_int_enable(sdev, false); 254 254 255 255 return 0; 256 256 }