From 59401c3c08e1a306e29a8d6c826685e2c5c6c794 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Tue, 26 Mar 2024 09:01:18 +0000 Subject: soundwire: remove unused sdw_bus_conf structure This is redundant with sdw_bus_params, and was never used. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Signed-off-by: Bard Liao Link: https://lore.kernel.org/r/20240326090122.1051806-4-yung-chuan.liao@linux.intel.com Signed-off-by: Vinod Koul --- include/linux/soundwire/sdw.h | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'include') diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h index 66f814b63a43..e5d0aa58e7f6 100644 --- a/include/linux/soundwire/sdw.h +++ b/include/linux/soundwire/sdw.h @@ -542,21 +542,6 @@ enum sdw_reg_bank { SDW_BANK1, }; -/** - * struct sdw_bus_conf: Bus configuration - * - * @clk_freq: Clock frequency, in Hz - * @num_rows: Number of rows in frame - * @num_cols: Number of columns in frame - * @bank: Next register bank - */ -struct sdw_bus_conf { - unsigned int clk_freq; - unsigned int num_rows; - unsigned int num_cols; - unsigned int bank; -}; - /** * struct sdw_prepare_ch: Prepare/De-prepare Data Port channel * -- cgit v1.2.3 From bc13cf3f6e63dd708ccd160a28e6bb696af7e9f6 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Tue, 26 Mar 2024 09:01:20 +0000 Subject: soundwire: clarify maximum allowed address The existing code sets the maximum address at 0x80000000, which is not completely accurate. The last 2 Gbytes are indeed reserved, but so are the 896 Mbytes just before. The maximum address which can be used with paging or BRA is 0x47FFFFFF per Table 131 of the SoundWire 1.2.1 specification. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Signed-off-by: Bard Liao Link: https://lore.kernel.org/r/20240326090122.1051806-6-yung-chuan.liao@linux.intel.com Signed-off-by: Vinod Koul --- include/linux/soundwire/sdw_registers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/soundwire/sdw_registers.h b/include/linux/soundwire/sdw_registers.h index 138bec908c40..658b10fa5b20 100644 --- a/include/linux/soundwire/sdw_registers.h +++ b/include/linux/soundwire/sdw_registers.h @@ -13,7 +13,7 @@ #define SDW_REG_NO_PAGE 0x00008000 #define SDW_REG_OPTIONAL_PAGE 0x00010000 -#define SDW_REG_MAX 0x80000000 +#define SDW_REG_MAX 0x48000000 #define SDW_DPN_SIZE 0x100 #define SDW_BANK1_OFFSET 0x10 -- cgit v1.2.3 From d0a69cd0369a390cc1c100e52e78a273695a170c Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Tue, 26 Mar 2024 09:20:26 +0000 Subject: soundwire: intel: add more values for SYNCPRD Starting with MeteorLake, the input to the SoundWire IP can be 24.576 MHz (aka Audio Cardinal Clock) or 96 MHz (Audio PLL). Signed-off-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Signed-off-by: Bard Liao Link: https://lore.kernel.org/r/20240326092030.1062802-4-yung-chuan.liao@linux.intel.com Signed-off-by: Vinod Koul --- include/linux/soundwire/sdw_intel.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/soundwire/sdw_intel.h b/include/linux/soundwire/sdw_intel.h index 00bb22d96ae5..fa40b85d5019 100644 --- a/include/linux/soundwire/sdw_intel.h +++ b/include/linux/soundwire/sdw_intel.h @@ -34,8 +34,10 @@ /* SYNC */ #define SDW_SHIM_SYNC 0xC -#define SDW_SHIM_SYNC_SYNCPRD_VAL_24 (24000 / SDW_CADENCE_GSYNC_KHZ - 1) -#define SDW_SHIM_SYNC_SYNCPRD_VAL_38_4 (38400 / SDW_CADENCE_GSYNC_KHZ - 1) +#define SDW_SHIM_SYNC_SYNCPRD_VAL_24 (24000 / SDW_CADENCE_GSYNC_KHZ - 1) +#define SDW_SHIM_SYNC_SYNCPRD_VAL_24_576 (24576 / SDW_CADENCE_GSYNC_KHZ - 1) +#define SDW_SHIM_SYNC_SYNCPRD_VAL_38_4 (38400 / SDW_CADENCE_GSYNC_KHZ - 1) +#define SDW_SHIM_SYNC_SYNCPRD_VAL_96 (96000 / SDW_CADENCE_GSYNC_KHZ - 1) #define SDW_SHIM_SYNC_SYNCPRD GENMASK(14, 0) #define SDW_SHIM_SYNC_SYNCCPU BIT(15) #define SDW_SHIM_SYNC_CMDSYNC_MASK GENMASK(19, 16) -- cgit v1.2.3 From 09ee49e3de6bcecc57028682c673d180ec2d436b Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Tue, 26 Mar 2024 09:20:27 +0000 Subject: soundwire: intel: add support for MeteorLake additional clocks In the MeteorLake hardware, the SoundWire link clock can be selected from the Xtal, audio cardinal clock (24.576 MHz) or the 96 MHz audio PLL. This patches add the clock selection in a backwards-compatible manner, using the ACPI firmware as the source of information and checking its compatibility with hardware capabilities. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Signed-off-by: Bard Liao Link: https://lore.kernel.org/r/20240326092030.1062802-5-yung-chuan.liao@linux.intel.com Signed-off-by: Vinod Koul --- drivers/soundwire/intel.c | 43 +++++++++++++++++++++++++++++++------ include/linux/soundwire/sdw_intel.h | 5 +++++ 2 files changed, 42 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c index 839268175079..01e1a0f3ec39 100644 --- a/drivers/soundwire/intel.c +++ b/drivers/soundwire/intel.c @@ -345,8 +345,10 @@ static int intel_link_power_up(struct sdw_intel *sdw) u32 spa_mask, cpa_mask; u32 link_control; int ret = 0; + u32 clock_source; u32 syncprd; u32 sync_reg; + bool lcap_mlcs; mutex_lock(sdw->link_res->shim_lock); @@ -358,12 +360,35 @@ static int intel_link_power_up(struct sdw_intel *sdw) * is only dependent on the oscillator clock provided to * the IP, so adjust based on _DSD properties reported in DSDT * tables. The values reported are based on either 24MHz - * (CNL/CML) or 38.4 MHz (ICL/TGL+). + * (CNL/CML) or 38.4 MHz (ICL/TGL+). On MeteorLake additional + * frequencies are available with the MLCS clock source selection. */ - if (prop->mclk_freq % 6000000) - syncprd = SDW_SHIM_SYNC_SYNCPRD_VAL_38_4; - else - syncprd = SDW_SHIM_SYNC_SYNCPRD_VAL_24; + lcap_mlcs = intel_readl(shim, SDW_SHIM_LCAP) & SDW_SHIM_LCAP_MLCS_MASK; + + if (prop->mclk_freq % 6000000) { + if (prop->mclk_freq % 2400000) { + if (lcap_mlcs) { + syncprd = SDW_SHIM_SYNC_SYNCPRD_VAL_24_576; + clock_source = SDW_SHIM_MLCS_CARDINAL_CLK; + } else { + dev_err(sdw->cdns.dev, "%s: invalid clock configuration, mclk %d lcap_mlcs %d\n", + __func__, prop->mclk_freq, lcap_mlcs); + ret = -EINVAL; + goto out; + } + } else { + syncprd = SDW_SHIM_SYNC_SYNCPRD_VAL_38_4; + clock_source = SDW_SHIM_MLCS_XTAL_CLK; + } + } else { + if (lcap_mlcs) { + syncprd = SDW_SHIM_SYNC_SYNCPRD_VAL_96; + clock_source = SDW_SHIM_MLCS_AUDIO_PLL_CLK; + } else { + syncprd = SDW_SHIM_SYNC_SYNCPRD_VAL_24; + clock_source = SDW_SHIM_MLCS_XTAL_CLK; + } + } if (!*shim_mask) { dev_dbg(sdw->cdns.dev, "powering up all links\n"); @@ -403,6 +428,13 @@ static int intel_link_power_up(struct sdw_intel *sdw) "Failed to set SHIM_SYNC: %d\n", ret); goto out; } + + /* update link clock if needed */ + if (lcap_mlcs) { + link_control = intel_readl(shim, SDW_SHIM_LCTL); + u32p_replace_bits(&link_control, clock_source, SDW_SHIM_LCTL_MLCS_MASK); + intel_writel(shim, SDW_SHIM_LCTL, link_control); + } } *shim_mask |= BIT(link_id); @@ -1087,4 +1119,3 @@ const struct sdw_intel_hw_ops sdw_intel_cnl_hw_ops = { .sync_check_cmdsync_unlocked = intel_check_cmdsync_unlocked, }; EXPORT_SYMBOL_NS(sdw_intel_cnl_hw_ops, SOUNDWIRE_INTEL); - diff --git a/include/linux/soundwire/sdw_intel.h b/include/linux/soundwire/sdw_intel.h index fa40b85d5019..8e78417156e3 100644 --- a/include/linux/soundwire/sdw_intel.h +++ b/include/linux/soundwire/sdw_intel.h @@ -22,6 +22,7 @@ /* LCAP */ #define SDW_SHIM_LCAP 0x0 #define SDW_SHIM_LCAP_LCOUNT_MASK GENMASK(2, 0) +#define SDW_SHIM_LCAP_MLCS_MASK BIT(8) /* LCTL */ #define SDW_SHIM_LCTL 0x4 @@ -30,6 +31,10 @@ #define SDW_SHIM_LCTL_SPA_MASK GENMASK(3, 0) #define SDW_SHIM_LCTL_CPA BIT(8) #define SDW_SHIM_LCTL_CPA_MASK GENMASK(11, 8) +#define SDW_SHIM_LCTL_MLCS_MASK GENMASK(29, 27) +#define SDW_SHIM_MLCS_XTAL_CLK 0x0 +#define SDW_SHIM_MLCS_CARDINAL_CLK 0x1 +#define SDW_SHIM_MLCS_AUDIO_PLL_CLK 0x2 /* SYNC */ #define SDW_SHIM_SYNC 0xC -- cgit v1.2.3 From 8dfd00f7069c54db78463f2a8a8cb677844fdf1f Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 8 Apr 2024 06:38:22 +0000 Subject: soundwire: reconcile dp0_prop and dpn_prop The definitions for DP0 are missing a set of fields that are required to reuse the same configuration code as DPn. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Signed-off-by: Bard Liao Link: https://lore.kernel.org/r/20240408063822.421963-1-yung-chuan.liao@linux.intel.com Signed-off-by: Vinod Koul --- include/linux/soundwire/sdw.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h index e5d0aa58e7f6..7bb9119f3069 100644 --- a/include/linux/soundwire/sdw.h +++ b/include/linux/soundwire/sdw.h @@ -235,6 +235,7 @@ enum sdw_clk_stop_mode { * @BRA_flow_controlled: Slave implementation results in an OK_NotReady * response * @simple_ch_prep_sm: If channel prepare sequence is required + * @ch_prep_timeout: Port-specific timeout value, in milliseconds * @imp_def_interrupts: If set, each bit corresponds to support for * implementation-defined interrupts * @@ -249,6 +250,7 @@ struct sdw_dp0_prop { u32 *words; bool BRA_flow_controlled; bool simple_ch_prep_sm; + u32 ch_prep_timeout; bool imp_def_interrupts; }; -- cgit v1.2.3 From 3b0b441a297e7fe11baab51439a81cd6a336ed64 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 29 Apr 2024 00:43:19 +0000 Subject: soundwire: intel_ace2x: use DOAIS and DODS settings from firmware Starting with LNL, the recommendation is to use settings read from DSD properties instead of hard-coding the values. The DOAIS and DODS values are completely-specific to Intel and are stored in a vendor-specific property structure. Signed-off-by: Pierre-Louis Bossart Signed-off-by: Bard Liao Link: https://lore.kernel.org/r/20240429004321.2399754-3-yung-chuan.liao@linux.intel.com Signed-off-by: Vinod Koul --- drivers/soundwire/intel.h | 5 +++++ drivers/soundwire/intel_ace2x.c | 7 +++++-- drivers/soundwire/intel_auxdevice.c | 21 +++++++++++++++++++++ include/linux/soundwire/sdw.h | 2 ++ 4 files changed, 33 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/drivers/soundwire/intel.h b/drivers/soundwire/intel.h index 511932c55216..b36d46319f0f 100644 --- a/drivers/soundwire/intel.h +++ b/drivers/soundwire/intel.h @@ -58,6 +58,11 @@ struct sdw_intel { #endif }; +struct sdw_intel_prop { + u16 doais; + u16 dods; +}; + enum intel_pdi_type { INTEL_PDI_IN = 0, INTEL_PDI_OUT = 1, diff --git a/drivers/soundwire/intel_ace2x.c b/drivers/soundwire/intel_ace2x.c index 32b538cd6d66..917cc79d4d85 100644 --- a/drivers/soundwire/intel_ace2x.c +++ b/drivers/soundwire/intel_ace2x.c @@ -25,12 +25,15 @@ static void intel_shim_vs_init(struct sdw_intel *sdw) { void __iomem *shim_vs = sdw->link_res->shim_vs; + struct sdw_bus *bus = &sdw->cdns.bus; + struct sdw_intel_prop *intel_prop; u16 doais; u16 dods; u16 act; - doais = 0x3; - dods = 0x1; + intel_prop = bus->vendor_specific_prop; + doais = intel_prop->doais; + dods = intel_prop->dods; act = intel_readw(shim_vs, SDW_SHIM2_INTEL_VS_ACTMCTL); u16p_replace_bits(&act, doais, SDW_SHIM2_INTEL_VS_ACTMCTL_DOAIS); diff --git a/drivers/soundwire/intel_auxdevice.c b/drivers/soundwire/intel_auxdevice.c index 296a470ce1e0..697d64070794 100644 --- a/drivers/soundwire/intel_auxdevice.c +++ b/drivers/soundwire/intel_auxdevice.c @@ -122,6 +122,7 @@ static void generic_new_peripheral_assigned(struct sdw_bus *bus, static int sdw_master_read_intel_prop(struct sdw_bus *bus) { struct sdw_master_prop *prop = &bus->prop; + struct sdw_intel_prop *intel_prop; struct fwnode_handle *link; char name[32]; u32 quirk_mask; @@ -153,6 +154,26 @@ static int sdw_master_read_intel_prop(struct sdw_bus *bus) prop->quirks = SDW_MASTER_QUIRKS_CLEAR_INITIAL_CLASH | SDW_MASTER_QUIRKS_CLEAR_INITIAL_PARITY; + intel_prop = devm_kzalloc(bus->dev, sizeof(*intel_prop), GFP_KERNEL); + if (!intel_prop) + return -ENOMEM; + + /* initialize with hardware defaults, in case the properties are not found */ + intel_prop->doais = 0x3; + intel_prop->dods = 0x1; + + fwnode_property_read_u16(link, + "intel-sdw-doais", + &intel_prop->doais); + fwnode_property_read_u16(link, + "intel-sdw-dods", + &intel_prop->dods); + bus->vendor_specific_prop = intel_prop; + + dev_dbg(bus->dev, "doais %#x dods %#x\n", + intel_prop->doais, + intel_prop->dods); + return 0; } diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h index 7bb9119f3069..13e96d8b7423 100644 --- a/include/linux/soundwire/sdw.h +++ b/include/linux/soundwire/sdw.h @@ -886,6 +886,7 @@ struct sdw_master_ops { * @port_ops: Master port callback ops * @params: Current bus parameters * @prop: Master properties + * @vendor_specific_prop: pointer to non-standard properties * @m_rt_list: List of Master instance of all stream(s) running on Bus. This * is used to compute and program bus bandwidth, clock, frame shape, * transport and port parameters @@ -920,6 +921,7 @@ struct sdw_bus { const struct sdw_master_port_ops *port_ops; struct sdw_bus_params params; struct sdw_master_prop prop; + void *vendor_specific_prop; struct list_head m_rt_list; #ifdef CONFIG_DEBUG_FS struct dentry *debugfs; -- cgit v1.2.3