linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: [alsa-devel] [RFC PATCH 01/40] soundwire: add debugfs support
  2019-07-25 23:39 ` [RFC PATCH 01/40] soundwire: add debugfs support Pierre-Louis Bossart
@ 2019-07-25 22:15   ` Guennadi Liakhovetski
  2019-07-26 13:43     ` Pierre-Louis Bossart
  2019-07-26  9:22   ` Cezary Rojewski
  2019-07-26 14:04   ` Greg KH
  2 siblings, 1 reply; 183+ messages in thread
From: Guennadi Liakhovetski @ 2019-07-25 22:15 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, tiwai, gregkh, linux-kernel, vkoul, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale

Hi Pierre,

A couple of nitpicks:

On Thu, Jul 25, 2019 at 06:39:53PM -0500, Pierre-Louis Bossart wrote:
> Add base debugfs mechanism for SoundWire bus by creating soundwire
> root and master-N and slave-x hierarchy.
> 
> Also add SDW Slave SCP, DP0 and DP-N register debug file.
> 
> Registers not implemented will print as "XX"
> 
> Credits: this patch is based on an earlier internal contribution by
> Vinod Koul, Sanyog Kale, Shreyas Nc and Hardik Shah. The main change
> is the use of scnprintf to avoid known issues with snprintf.
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/Makefile    |   4 +-
>  drivers/soundwire/bus.c       |   6 ++
>  drivers/soundwire/bus.h       |  24 ++++++
>  drivers/soundwire/bus_type.c  |   3 +
>  drivers/soundwire/debugfs.c   | 156 ++++++++++++++++++++++++++++++++++
>  drivers/soundwire/slave.c     |   1 +
>  include/linux/soundwire/sdw.h |   4 +
>  7 files changed, 197 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/soundwire/debugfs.c

[snip]

> diff --git a/drivers/soundwire/bus.h b/drivers/soundwire/bus.h
> index 3048ca153f22..06ac4adb0074 100644
> --- a/drivers/soundwire/bus.h
> +++ b/drivers/soundwire/bus.h
> @@ -18,6 +18,30 @@ static inline int sdw_acpi_find_slaves(struct sdw_bus *bus)
>  void sdw_extract_slave_id(struct sdw_bus *bus,
>  			  u64 addr, struct sdw_slave_id *id);
>  
> +#ifdef CONFIG_DEBUG_FS
> +struct dentry *sdw_bus_debugfs_init(struct sdw_bus *bus);
> +void sdw_bus_debugfs_exit(struct dentry *d);
> +struct dentry *sdw_slave_debugfs_init(struct sdw_slave *slave);
> +void sdw_slave_debugfs_exit(struct dentry *d);
> +void sdw_debugfs_init(void);
> +void sdw_debugfs_exit(void);
> +#else
> +struct dentry *sdw_bus_debugfs_init(struct sdw_bus *bus)
> +{ return NULL; }

static?

> +
> +void sdw_bus_debugfs_exit(struct dentry *d) {}
> +
> +struct dentry *sdw_slave_debugfs_init(struct sdw_slave *slave)
> +{ return NULL; }
> +
> +void sdw_slave_debugfs_exit(struct dentry *d) {}
> +
> +void sdw_debugfs_init(void) {}
> +
> +void sdw_debugfs_exit(void) {}

Same for all the above. You could also declare them inline, but I really hope
the compiler will be smart enough to do that itself.

> +
> +#endif
> +
>  enum {
>  	SDW_MSG_FLAG_READ = 0,
>  	SDW_MSG_FLAG_WRITE,
> diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c
> index 2655602f0cfb..4a465f55039f 100644
> --- a/drivers/soundwire/bus_type.c
> +++ b/drivers/soundwire/bus_type.c
> @@ -6,6 +6,7 @@
>  #include <linux/pm_domain.h>
>  #include <linux/soundwire/sdw.h>
>  #include <linux/soundwire/sdw_type.h>
> +#include "bus.h"
>  
>  /**
>   * sdw_get_device_id - find the matching SoundWire device id
> @@ -177,11 +178,13 @@ EXPORT_SYMBOL_GPL(sdw_unregister_driver);
>  
>  static int __init sdw_bus_init(void)
>  {
> +	sdw_debugfs_init();
>  	return bus_register(&sdw_bus_type);
>  }
>  
>  static void __exit sdw_bus_exit(void)
>  {
> +	sdw_debugfs_exit();
>  	bus_unregister(&sdw_bus_type);
>  }
>  
> diff --git a/drivers/soundwire/debugfs.c b/drivers/soundwire/debugfs.c
> new file mode 100644
> index 000000000000..8d86e100516e
> --- /dev/null
> +++ b/drivers/soundwire/debugfs.c
> @@ -0,0 +1,156 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
> +// Copyright(c) 2017-19 Intel Corporation.
> +
> +#include <linux/device.h>
> +#include <linux/debugfs.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/slab.h>
> +#include <linux/soundwire/sdw.h>
> +#include <linux/soundwire/sdw_registers.h>
> +#include "bus.h"
> +
> +#ifdef CONFIG_DEBUG_FS
> +struct dentry *sdw_debugfs_root;
> +#endif
> +
> +struct dentry *sdw_bus_debugfs_init(struct sdw_bus *bus)
> +{
> +	struct dentry *d;

I would remove the above

> +	char name[16];
> +
> +	if (!sdw_debugfs_root)
> +		return NULL;
> +
> +	/* create the debugfs master-N */
> +	snprintf(name, sizeof(name), "master-%d", bus->link_id);
> +	d = debugfs_create_dir(name, sdw_debugfs_root);
> +
> +	return d;

And just do

+	return debugfs_create_dir(name, sdw_debugfs_root);

> +}
> +
> +void sdw_bus_debugfs_exit(struct dentry *d)
> +{
> +	debugfs_remove_recursive(d);
> +}
> +
> +#define RD_BUF (3 * PAGE_SIZE)
> +
> +static ssize_t sdw_sprintf(struct sdw_slave *slave,
> +			   char *buf, size_t pos, unsigned int reg)
> +{
> +	int value;
> +
> +	value = sdw_read(slave, reg);

I personally would join the two lines above, but that's just a personal
preference.

> +
> +	if (value < 0)
> +		return scnprintf(buf + pos, RD_BUF - pos, "%3x\tXX\n", reg);
> +	else

I think it's advised to not use an else in such cases.

Thanks
Guennadi

> +		return scnprintf(buf + pos, RD_BUF - pos,
> +				"%3x\t%2x\n", reg, value);
> +}
> +
> +static ssize_t sdw_slave_reg_read(struct file *file, char __user *user_buf,
> +				  size_t count, loff_t *ppos)
> +{
> +	struct sdw_slave *slave = file->private_data;
> +	unsigned int reg;
> +	char *buf;
> +	ssize_t ret;
> +	int i, j;
> +
> +	buf = kzalloc(RD_BUF, GFP_KERNEL);
> +	if (!buf)
> +		return -ENOMEM;
> +
> +	ret = scnprintf(buf, RD_BUF, "Register  Value\n");
> +	ret += scnprintf(buf + ret, RD_BUF - ret, "\nDP0\n");
> +
> +	for (i = 0; i < 6; i++)
> +		ret += sdw_sprintf(slave, buf, ret, i);
> +
> +	ret += scnprintf(buf + ret, RD_BUF - ret, "Bank0\n");
> +	ret += sdw_sprintf(slave, buf, ret, SDW_DP0_CHANNELEN);
> +	for (i = SDW_DP0_SAMPLECTRL1; i <= SDW_DP0_LANECTRL; i++)
> +		ret += sdw_sprintf(slave, buf, ret, i);
> +
> +	ret += scnprintf(buf + ret, RD_BUF - ret, "Bank1\n");
> +	ret += sdw_sprintf(slave, buf, ret,
> +			SDW_DP0_CHANNELEN + SDW_BANK1_OFFSET);
> +	for (i = SDW_DP0_SAMPLECTRL1 + SDW_BANK1_OFFSET;
> +			i <= SDW_DP0_LANECTRL + SDW_BANK1_OFFSET; i++)
> +		ret += sdw_sprintf(slave, buf, ret, i);
> +
> +	ret += scnprintf(buf + ret, RD_BUF - ret, "\nSCP\n");
> +	for (i = SDW_SCP_INT1; i <= SDW_SCP_BANKDELAY; i++)
> +		ret += sdw_sprintf(slave, buf, ret, i);
> +	for (i = SDW_SCP_DEVID_0; i <= SDW_SCP_DEVID_5; i++)
> +		ret += sdw_sprintf(slave, buf, ret, i);
> +
> +	ret += scnprintf(buf + ret, RD_BUF - ret, "Bank0\n");
> +	ret += sdw_sprintf(slave, buf, ret, SDW_SCP_FRAMECTRL_B0);
> +	ret += sdw_sprintf(slave, buf, ret, SDW_SCP_NEXTFRAME_B0);
> +
> +	ret += scnprintf(buf + ret, RD_BUF - ret, "Bank1\n");
> +	ret += sdw_sprintf(slave, buf, ret, SDW_SCP_FRAMECTRL_B1);
> +	ret += sdw_sprintf(slave, buf, ret, SDW_SCP_NEXTFRAME_B1);
> +
> +	for (i = 1; i < 14; i++) {
> +		ret += scnprintf(buf + ret, RD_BUF - ret, "\nDP%d\n", i);
> +		reg = SDW_DPN_INT(i);
> +		for (j = 0; j < 6; j++)
> +			ret += sdw_sprintf(slave, buf, ret, reg + j);
> +
> +		ret += scnprintf(buf + ret, RD_BUF - ret, "Bank0\n");
> +		reg = SDW_DPN_CHANNELEN_B0(i);
> +		for (j = 0; j < 9; j++)
> +			ret += sdw_sprintf(slave, buf, ret, reg + j);
> +
> +		ret += scnprintf(buf + ret, RD_BUF - ret, "Bank1\n");
> +		reg = SDW_DPN_CHANNELEN_B1(i);
> +		for (j = 0; j < 9; j++)
> +			ret += sdw_sprintf(slave, buf, ret, reg + j);
> +	}
> +
> +	ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
> +	kfree(buf);
> +
> +	return ret;
> +}
> +
> +static const struct file_operations sdw_slave_reg_fops = {
> +	.open = simple_open,
> +	.read = sdw_slave_reg_read,
> +	.llseek = default_llseek,
> +};
> +
> +struct dentry *sdw_slave_debugfs_init(struct sdw_slave *slave)
> +{
> +	struct dentry *master;
> +	struct dentry *d;
> +	char name[32];
> +
> +	master = slave->bus->debugfs;
> +
> +	/* create the debugfs slave-name */
> +	snprintf(name, sizeof(name), "%s", dev_name(&slave->dev));
> +	d = debugfs_create_dir(name, master);
> +
> +	debugfs_create_file("registers", 0400, d, slave, &sdw_slave_reg_fops);
> +
> +	return d;
> +}
> +
> +void sdw_slave_debugfs_exit(struct dentry *d)
> +{
> +	debugfs_remove_recursive(d);
> +}
> +
> +void sdw_debugfs_init(void)
> +{
> +	sdw_debugfs_root = debugfs_create_dir("soundwire", NULL);
> +}
> +
> +void sdw_debugfs_exit(void)
> +{
> +	debugfs_remove_recursive(sdw_debugfs_root);
> +}
> diff --git a/drivers/soundwire/slave.c b/drivers/soundwire/slave.c
> index f39a5815e25d..34d8bb995f45 100644
> --- a/drivers/soundwire/slave.c
> +++ b/drivers/soundwire/slave.c
> @@ -56,6 +56,7 @@ static int sdw_slave_add(struct sdw_bus *bus,
>  		mutex_unlock(&bus->bus_lock);
>  		put_device(&slave->dev);
>  	}
> +	slave->debugfs = sdw_slave_debugfs_init(slave);
>  
>  	return ret;
>  }
> diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
> index 3b231472464a..a49028e9d666 100644
> --- a/include/linux/soundwire/sdw.h
> +++ b/include/linux/soundwire/sdw.h
> @@ -544,6 +544,7 @@ struct sdw_slave_ops {
>   * @bus: Bus handle
>   * @ops: Slave callback ops
>   * @prop: Slave properties
> + * @debugfs: Slave debugfs
>   * @node: node for bus list
>   * @port_ready: Port ready completion flag for each Slave port
>   * @dev_num: Device Number assigned by Bus
> @@ -555,6 +556,7 @@ struct sdw_slave {
>  	struct sdw_bus *bus;
>  	const struct sdw_slave_ops *ops;
>  	struct sdw_slave_prop prop;
> +	struct dentry *debugfs;
>  	struct list_head node;
>  	struct completion *port_ready;
>  	u16 dev_num;
> @@ -731,6 +733,7 @@ struct sdw_master_ops {
>   * @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
> + * @debugfs: Bus debugfs
>   * @defer_msg: Defer message
>   * @clk_stop_timeout: Clock stop timeout computed
>   * @bank_switch_timeout: Bank switch timeout computed
> @@ -750,6 +753,7 @@ struct sdw_bus {
>  	struct sdw_bus_params params;
>  	struct sdw_master_prop prop;
>  	struct list_head m_rt_list;
> +	struct dentry *debugfs;
>  	struct sdw_defer defer_msg;
>  	unsigned int clk_stop_timeout;
>  	u32 bank_switch_timeout;
> -- 
> 2.20.1
> 
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 09/40] soundwire: cadence_master: fix usage of CONFIG_UPDATE
  2019-07-25 23:40 ` [RFC PATCH 09/40] soundwire: cadence_master: fix usage of CONFIG_UPDATE Pierre-Louis Bossart
@ 2019-07-25 22:23   ` Guennadi Liakhovetski
  2019-07-26 14:05     ` Pierre-Louis Bossart
  2019-07-26  2:11   ` Bard liao
                     ` (3 subsequent siblings)
  4 siblings, 1 reply; 183+ messages in thread
From: Guennadi Liakhovetski @ 2019-07-25 22:23 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, tiwai, gregkh, linux-kernel, vkoul, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale

On Thu, Jul 25, 2019 at 06:40:01PM -0500, Pierre-Louis Bossart wrote:
> Per the hardware documentation, all changes to MCP_CONFIG,
> MCP_CONTROL, MCP_CMDCTRL and MCP_PHYCTRL need to be validated with a
> self-clearing write to MCP_CONFIG_UPDATE.
> 
> For some reason, the existing code only does this write to
> CONFIG_UPDATE when enabling interrupts. Add a helper and do the update
> when the CONFIG is changed.
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/cadence_master.c | 29 +++++++++++++++++++++--------
>  1 file changed, 21 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
> index 9f611a1fff0a..eb46cf651d62 100644
> --- a/drivers/soundwire/cadence_master.c
> +++ b/drivers/soundwire/cadence_master.c
> @@ -224,6 +224,22 @@ static int cdns_clear_bit(struct sdw_cdns *cdns, int offset, u32 value)
>  	return -EAGAIN;
>  }
>  
> +/*
> + * all changes to the MCP_CONFIG, MCP_CONTROL, MCP_CMDCTRL and MCP_PHYCTRL
> + * need to be confirmed with a write to MCP_CONFIG_UPDATE
> + */
> +static int cdns_update_config(struct sdw_cdns *cdns)
> +{
> +	int ret;
> +
> +	ret = cdns_clear_bit(cdns, CDNS_MCP_CONFIG_UPDATE,
> +			     CDNS_MCP_CONFIG_UPDATE_BIT);
> +	if (ret < 0)
> +		dev_err(cdns->dev, "Config update timedout\n");
> +
> +	return ret;
> +}
> +
>  /*
>   * debugfs
>   */
> @@ -758,15 +774,9 @@ static int _cdns_enable_interrupt(struct sdw_cdns *cdns)
>   */
>  int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
>  {
> -	int ret;
> -
>  	_cdns_enable_interrupt(cdns);
> -	ret = cdns_clear_bit(cdns, CDNS_MCP_CONFIG_UPDATE,
> -			     CDNS_MCP_CONFIG_UPDATE_BIT);
> -	if (ret < 0)
> -		dev_err(cdns->dev, "Config update timedout\n");
>  
> -	return ret;
> +	return 0;
>  }
>  EXPORT_SYMBOL(sdw_cdns_enable_interrupt);
>  
> @@ -943,7 +953,10 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
>  
>  	cdns_writel(cdns, CDNS_MCP_CONFIG, val);
>  
> -	return 0;
> +	/* commit changes */
> +	ret = cdns_update_config(cdns);
> +
> +	return ret;

+	return cdns_update_config(cdns);

Thanks
Guennadi

>  }
>  EXPORT_SYMBOL(sdw_cdns_init);
>  
> -- 
> 2.20.1
> 
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 15/40] soundwire: cadence_master: handle multiple status reports per Slave
  2019-07-25 23:40 ` [RFC PATCH 15/40] soundwire: cadence_master: handle multiple status reports per Slave Pierre-Louis Bossart
@ 2019-07-25 22:31   ` Guennadi Liakhovetski
  2019-07-26 14:09     ` Pierre-Louis Bossart
  2019-08-02 12:20   ` Vinod Koul
  1 sibling, 1 reply; 183+ messages in thread
From: Guennadi Liakhovetski @ 2019-07-25 22:31 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, tiwai, gregkh, linux-kernel, vkoul, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale

On Thu, Jul 25, 2019 at 06:40:07PM -0500, Pierre-Louis Bossart wrote:
> When a Slave reports multiple status in the sticky bits, find the
> latest configuration from the mirror of the PING frame status and
> update the status directly.
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/cadence_master.c | 34 ++++++++++++++++++++++++------
>  1 file changed, 28 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
> index 889fa2cd49ae..25d5c7267c15 100644
> --- a/drivers/soundwire/cadence_master.c
> +++ b/drivers/soundwire/cadence_master.c
> @@ -643,13 +643,35 @@ static int cdns_update_slave_status(struct sdw_cdns *cdns,
>  
>  		/* first check if Slave reported multiple status */
>  		if (set_status > 1) {
> +			u32 val;
> +
>  			dev_warn_ratelimited(cdns->dev,
> -					     "Slave reported multiple Status: %d\n",
> -					     mask);
> -			/*
> -			 * TODO: we need to reread the status here by
> -			 * issuing a PING cmd
> -			 */
> +					     "Slave %d reported multiple Status: %d\n",
> +					     i, mask);
> +
> +			/* re-check latest status extracted from PING commands */
> +			val = cdns_readl(cdns, CDNS_MCP_SLAVE_STAT);
> +			val >>= (i * 2);

Superfluous parentheses.

> +
> +			switch (val & 0x3) {
> +			case 0:
> +				status[i] = SDW_SLAVE_UNATTACHED;
> +				break;
> +			case 1:
> +				status[i] = SDW_SLAVE_ATTACHED;
> +				break;
> +			case 2:
> +				status[i] = SDW_SLAVE_ALERT;
> +				break;
> +			default:

There aren't many values left for the "default" case :-) But I'm not sure whether
any of

+			case 3:

or

+			case 3:
+			default:

would improve readability.

Thanks
Guennadi

> +				status[i] = SDW_SLAVE_RESERVED;
> +				break;
> +			}
> +
> +			dev_warn_ratelimited(cdns->dev,
> +					     "Slave %d status updated to %d\n",
> +					     i, status[i]);
> +
>  		}
>  	}
>  
> -- 
> 2.20.1
> 
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 183+ messages in thread

* [RFC PATCH 00/40] soundwire: updates for 5.4
@ 2019-07-25 23:39 Pierre-Louis Bossart
  2019-07-25 23:39 ` [RFC PATCH 01/40] soundwire: add debugfs support Pierre-Louis Bossart
                   ` (40 more replies)
  0 siblings, 41 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:39 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart

The existing upstream code allows for SoundWire devices to be
enumerated and managed by the bus, but streaming is not currently
supported.

Bard Liao, Rander Wang and I did quite a bit of integration/validation
work to close this gap and we now have SoundWire streaming + basic
power managemement on Intel CometLake and IceLake reference
boards. These changes are still preliminary and should not be merged
as is, but it's time to start reviews. While the number of patches is
quite large, each of the changes is quite small.

SOF driver changes will be submitted shortly as well but are still
being validated.

ClockStop modes and synchronized playback on
multiple links are not supported for now and will likely be part of
the next cycle (dependencies on codec drivers and multi-cpu DAI
support).

Acknowledgements: This work would not have been possible without the
support of Slawomir Blauciak and Tomasz Lauda on the SOF side,
currently being reviewed, see
https://github.com/thesofproject/sof/pull/1638

Comments and feedback welcome!

Bard liao (1):
  soundwire: include mod_devicetable.h to avoid compiling warnings

Pierre-Louis Bossart (38):
  soundwire: add debugfs support
  soundwire: cadence_master: add debugfs register dump
  soundwire: cadence_master: align debugfs to 8 digits
  soundwire: intel: add debugfs register dump
  soundwire: intel: move interrupt enable after interrupt handler
    registration
  soundwire: intel: prevent possible dereference in hw_params
  soundwire: intel: fix channel number reported by hardware
  soundwire: intel: remove BIOS work-arounds
  soundwire: cadence_master: fix usage of CONFIG_UPDATE
  soundwire: cadence_master: remove useless wrapper
  soundwire: cadence_master: simplify bus clash interrupt clear
  soundwire: cadence_master: revisit interrupt settings
  soundwire: cadence_master: fix register definition for SLAVE_STATE
  soundwire: cadence_master: fix definitions for INTSTAT0/1
  soundwire: cadence_master: handle multiple status reports per Slave
  soundwire: cadence_master: improve startup sequence with link hw_reset
  soundwire: bus: use runtime_pm_get_sync/pm when enabled
  soundwire: bus: split handling of Device0 events
  soundwire: bus: improve dynamic debug comments for enumeration
  soundwire: prototypes for suspend/resume
  soundwire: export helpers to find row and column values
  soundwire: stream: fix disable sequence
  soundwire: cadence_master: use BIOS defaults for frame shape
  soundwire: intel: use BIOS information to set clock dividers
  soundwire: Add Intel resource management algorithm
  soundwire: intel: handle disabled links
  soundwire: intel_init: add kernel module parameter to filter out links
  soundwire: cadence_master: add kernel parameter to override interrupt
    mask
  soundwire: intel: move shutdown() callback and don't export symbol
  soundwire: intel: add helper for initialization
  soundwire: intel: Add basic power management support
  soundwire: intel: ignore disabled links for suspend/resume
  soundwire: intel: export helper to exit reset
  soundwire: intel: disable interrupts on suspend
  soundwire: cadence_master: add hw_reset capability in debugfs
  soundwire: cadence_master: make clock stop exit configurable on init
  soundwire: intel: add pm_runtime support
  soundwire: intel: add delay on restart for enumeration

Rander Wang (1):
  soundwire: cadence_master: fix divider setting in clock register

 drivers/soundwire/Makefile                  |   4 +-
 drivers/soundwire/algo_dynamic_allocation.c | 403 ++++++++++++++++++++
 drivers/soundwire/bus.c                     |  44 ++-
 drivers/soundwire/bus.h                     |  77 +++-
 drivers/soundwire/bus_type.c                |   3 +
 drivers/soundwire/cadence_master.c          | 365 ++++++++++++++----
 drivers/soundwire/cadence_master.h          |  12 +-
 drivers/soundwire/debugfs.c                 | 156 ++++++++
 drivers/soundwire/intel.c                   | 381 +++++++++++++++++-
 drivers/soundwire/intel_init.c              |  14 +
 drivers/soundwire/slave.c                   |   1 +
 drivers/soundwire/stream.c                  |  53 ++-
 include/linux/soundwire/sdw.h               |  15 +
 13 files changed, 1414 insertions(+), 114 deletions(-)
 create mode 100644 drivers/soundwire/algo_dynamic_allocation.c
 create mode 100644 drivers/soundwire/debugfs.c

-- 
2.20.1


^ permalink raw reply	[flat|nested] 183+ messages in thread

* [RFC PATCH 01/40] soundwire: add debugfs support
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
@ 2019-07-25 23:39 ` Pierre-Louis Bossart
  2019-07-25 22:15   ` [alsa-devel] " Guennadi Liakhovetski
                     ` (2 more replies)
  2019-07-25 23:39 ` [RFC PATCH 02/40] soundwire: cadence_master: add debugfs register dump Pierre-Louis Bossart
                   ` (39 subsequent siblings)
  40 siblings, 3 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:39 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

Add base debugfs mechanism for SoundWire bus by creating soundwire
root and master-N and slave-x hierarchy.

Also add SDW Slave SCP, DP0 and DP-N register debug file.

Registers not implemented will print as "XX"

Credits: this patch is based on an earlier internal contribution by
Vinod Koul, Sanyog Kale, Shreyas Nc and Hardik Shah. The main change
is the use of scnprintf to avoid known issues with snprintf.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/Makefile    |   4 +-
 drivers/soundwire/bus.c       |   6 ++
 drivers/soundwire/bus.h       |  24 ++++++
 drivers/soundwire/bus_type.c  |   3 +
 drivers/soundwire/debugfs.c   | 156 ++++++++++++++++++++++++++++++++++
 drivers/soundwire/slave.c     |   1 +
 include/linux/soundwire/sdw.h |   4 +
 7 files changed, 197 insertions(+), 1 deletion(-)
 create mode 100644 drivers/soundwire/debugfs.c

diff --git a/drivers/soundwire/Makefile b/drivers/soundwire/Makefile
index fd99a831b92a..88990cac48a7 100644
--- a/drivers/soundwire/Makefile
+++ b/drivers/soundwire/Makefile
@@ -4,7 +4,9 @@
 #
 
 #Bus Objs
-soundwire-bus-objs := bus_type.o bus.o slave.o mipi_disco.o stream.o
+soundwire-bus-objs := bus_type.o bus.o slave.o mipi_disco.o stream.o \
+			debugfs.o
+
 obj-$(CONFIG_SOUNDWIRE_BUS) += soundwire-bus.o
 
 #Cadence Objs
diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
index fe745830a261..5ad4109dc72f 100644
--- a/drivers/soundwire/bus.c
+++ b/drivers/soundwire/bus.c
@@ -49,6 +49,8 @@ int sdw_add_bus_master(struct sdw_bus *bus)
 		}
 	}
 
+	bus->debugfs = sdw_bus_debugfs_init(bus);
+
 	/*
 	 * Device numbers in SoundWire are 0 through 15. Enumeration device
 	 * number (0), Broadcast device number (15), Group numbers (12 and
@@ -109,6 +111,8 @@ static int sdw_delete_slave(struct device *dev, void *data)
 	struct sdw_slave *slave = dev_to_sdw_dev(dev);
 	struct sdw_bus *bus = slave->bus;
 
+	sdw_slave_debugfs_exit(slave->debugfs);
+
 	mutex_lock(&bus->bus_lock);
 
 	if (slave->dev_num) /* clear dev_num if assigned */
@@ -130,6 +134,8 @@ static int sdw_delete_slave(struct device *dev, void *data)
 void sdw_delete_bus_master(struct sdw_bus *bus)
 {
 	device_for_each_child(bus->dev, NULL, sdw_delete_slave);
+
+	sdw_bus_debugfs_exit(bus->debugfs);
 }
 EXPORT_SYMBOL(sdw_delete_bus_master);
 
diff --git a/drivers/soundwire/bus.h b/drivers/soundwire/bus.h
index 3048ca153f22..06ac4adb0074 100644
--- a/drivers/soundwire/bus.h
+++ b/drivers/soundwire/bus.h
@@ -18,6 +18,30 @@ static inline int sdw_acpi_find_slaves(struct sdw_bus *bus)
 void sdw_extract_slave_id(struct sdw_bus *bus,
 			  u64 addr, struct sdw_slave_id *id);
 
+#ifdef CONFIG_DEBUG_FS
+struct dentry *sdw_bus_debugfs_init(struct sdw_bus *bus);
+void sdw_bus_debugfs_exit(struct dentry *d);
+struct dentry *sdw_slave_debugfs_init(struct sdw_slave *slave);
+void sdw_slave_debugfs_exit(struct dentry *d);
+void sdw_debugfs_init(void);
+void sdw_debugfs_exit(void);
+#else
+struct dentry *sdw_bus_debugfs_init(struct sdw_bus *bus)
+{ return NULL; }
+
+void sdw_bus_debugfs_exit(struct dentry *d) {}
+
+struct dentry *sdw_slave_debugfs_init(struct sdw_slave *slave)
+{ return NULL; }
+
+void sdw_slave_debugfs_exit(struct dentry *d) {}
+
+void sdw_debugfs_init(void) {}
+
+void sdw_debugfs_exit(void) {}
+
+#endif
+
 enum {
 	SDW_MSG_FLAG_READ = 0,
 	SDW_MSG_FLAG_WRITE,
diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c
index 2655602f0cfb..4a465f55039f 100644
--- a/drivers/soundwire/bus_type.c
+++ b/drivers/soundwire/bus_type.c
@@ -6,6 +6,7 @@
 #include <linux/pm_domain.h>
 #include <linux/soundwire/sdw.h>
 #include <linux/soundwire/sdw_type.h>
+#include "bus.h"
 
 /**
  * sdw_get_device_id - find the matching SoundWire device id
@@ -177,11 +178,13 @@ EXPORT_SYMBOL_GPL(sdw_unregister_driver);
 
 static int __init sdw_bus_init(void)
 {
+	sdw_debugfs_init();
 	return bus_register(&sdw_bus_type);
 }
 
 static void __exit sdw_bus_exit(void)
 {
+	sdw_debugfs_exit();
 	bus_unregister(&sdw_bus_type);
 }
 
diff --git a/drivers/soundwire/debugfs.c b/drivers/soundwire/debugfs.c
new file mode 100644
index 000000000000..8d86e100516e
--- /dev/null
+++ b/drivers/soundwire/debugfs.c
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
+// Copyright(c) 2017-19 Intel Corporation.
+
+#include <linux/device.h>
+#include <linux/debugfs.h>
+#include <linux/mod_devicetable.h>
+#include <linux/slab.h>
+#include <linux/soundwire/sdw.h>
+#include <linux/soundwire/sdw_registers.h>
+#include "bus.h"
+
+#ifdef CONFIG_DEBUG_FS
+struct dentry *sdw_debugfs_root;
+#endif
+
+struct dentry *sdw_bus_debugfs_init(struct sdw_bus *bus)
+{
+	struct dentry *d;
+	char name[16];
+
+	if (!sdw_debugfs_root)
+		return NULL;
+
+	/* create the debugfs master-N */
+	snprintf(name, sizeof(name), "master-%d", bus->link_id);
+	d = debugfs_create_dir(name, sdw_debugfs_root);
+
+	return d;
+}
+
+void sdw_bus_debugfs_exit(struct dentry *d)
+{
+	debugfs_remove_recursive(d);
+}
+
+#define RD_BUF (3 * PAGE_SIZE)
+
+static ssize_t sdw_sprintf(struct sdw_slave *slave,
+			   char *buf, size_t pos, unsigned int reg)
+{
+	int value;
+
+	value = sdw_read(slave, reg);
+
+	if (value < 0)
+		return scnprintf(buf + pos, RD_BUF - pos, "%3x\tXX\n", reg);
+	else
+		return scnprintf(buf + pos, RD_BUF - pos,
+				"%3x\t%2x\n", reg, value);
+}
+
+static ssize_t sdw_slave_reg_read(struct file *file, char __user *user_buf,
+				  size_t count, loff_t *ppos)
+{
+	struct sdw_slave *slave = file->private_data;
+	unsigned int reg;
+	char *buf;
+	ssize_t ret;
+	int i, j;
+
+	buf = kzalloc(RD_BUF, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	ret = scnprintf(buf, RD_BUF, "Register  Value\n");
+	ret += scnprintf(buf + ret, RD_BUF - ret, "\nDP0\n");
+
+	for (i = 0; i < 6; i++)
+		ret += sdw_sprintf(slave, buf, ret, i);
+
+	ret += scnprintf(buf + ret, RD_BUF - ret, "Bank0\n");
+	ret += sdw_sprintf(slave, buf, ret, SDW_DP0_CHANNELEN);
+	for (i = SDW_DP0_SAMPLECTRL1; i <= SDW_DP0_LANECTRL; i++)
+		ret += sdw_sprintf(slave, buf, ret, i);
+
+	ret += scnprintf(buf + ret, RD_BUF - ret, "Bank1\n");
+	ret += sdw_sprintf(slave, buf, ret,
+			SDW_DP0_CHANNELEN + SDW_BANK1_OFFSET);
+	for (i = SDW_DP0_SAMPLECTRL1 + SDW_BANK1_OFFSET;
+			i <= SDW_DP0_LANECTRL + SDW_BANK1_OFFSET; i++)
+		ret += sdw_sprintf(slave, buf, ret, i);
+
+	ret += scnprintf(buf + ret, RD_BUF - ret, "\nSCP\n");
+	for (i = SDW_SCP_INT1; i <= SDW_SCP_BANKDELAY; i++)
+		ret += sdw_sprintf(slave, buf, ret, i);
+	for (i = SDW_SCP_DEVID_0; i <= SDW_SCP_DEVID_5; i++)
+		ret += sdw_sprintf(slave, buf, ret, i);
+
+	ret += scnprintf(buf + ret, RD_BUF - ret, "Bank0\n");
+	ret += sdw_sprintf(slave, buf, ret, SDW_SCP_FRAMECTRL_B0);
+	ret += sdw_sprintf(slave, buf, ret, SDW_SCP_NEXTFRAME_B0);
+
+	ret += scnprintf(buf + ret, RD_BUF - ret, "Bank1\n");
+	ret += sdw_sprintf(slave, buf, ret, SDW_SCP_FRAMECTRL_B1);
+	ret += sdw_sprintf(slave, buf, ret, SDW_SCP_NEXTFRAME_B1);
+
+	for (i = 1; i < 14; i++) {
+		ret += scnprintf(buf + ret, RD_BUF - ret, "\nDP%d\n", i);
+		reg = SDW_DPN_INT(i);
+		for (j = 0; j < 6; j++)
+			ret += sdw_sprintf(slave, buf, ret, reg + j);
+
+		ret += scnprintf(buf + ret, RD_BUF - ret, "Bank0\n");
+		reg = SDW_DPN_CHANNELEN_B0(i);
+		for (j = 0; j < 9; j++)
+			ret += sdw_sprintf(slave, buf, ret, reg + j);
+
+		ret += scnprintf(buf + ret, RD_BUF - ret, "Bank1\n");
+		reg = SDW_DPN_CHANNELEN_B1(i);
+		for (j = 0; j < 9; j++)
+			ret += sdw_sprintf(slave, buf, ret, reg + j);
+	}
+
+	ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
+	kfree(buf);
+
+	return ret;
+}
+
+static const struct file_operations sdw_slave_reg_fops = {
+	.open = simple_open,
+	.read = sdw_slave_reg_read,
+	.llseek = default_llseek,
+};
+
+struct dentry *sdw_slave_debugfs_init(struct sdw_slave *slave)
+{
+	struct dentry *master;
+	struct dentry *d;
+	char name[32];
+
+	master = slave->bus->debugfs;
+
+	/* create the debugfs slave-name */
+	snprintf(name, sizeof(name), "%s", dev_name(&slave->dev));
+	d = debugfs_create_dir(name, master);
+
+	debugfs_create_file("registers", 0400, d, slave, &sdw_slave_reg_fops);
+
+	return d;
+}
+
+void sdw_slave_debugfs_exit(struct dentry *d)
+{
+	debugfs_remove_recursive(d);
+}
+
+void sdw_debugfs_init(void)
+{
+	sdw_debugfs_root = debugfs_create_dir("soundwire", NULL);
+}
+
+void sdw_debugfs_exit(void)
+{
+	debugfs_remove_recursive(sdw_debugfs_root);
+}
diff --git a/drivers/soundwire/slave.c b/drivers/soundwire/slave.c
index f39a5815e25d..34d8bb995f45 100644
--- a/drivers/soundwire/slave.c
+++ b/drivers/soundwire/slave.c
@@ -56,6 +56,7 @@ static int sdw_slave_add(struct sdw_bus *bus,
 		mutex_unlock(&bus->bus_lock);
 		put_device(&slave->dev);
 	}
+	slave->debugfs = sdw_slave_debugfs_init(slave);
 
 	return ret;
 }
diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
index 3b231472464a..a49028e9d666 100644
--- a/include/linux/soundwire/sdw.h
+++ b/include/linux/soundwire/sdw.h
@@ -544,6 +544,7 @@ struct sdw_slave_ops {
  * @bus: Bus handle
  * @ops: Slave callback ops
  * @prop: Slave properties
+ * @debugfs: Slave debugfs
  * @node: node for bus list
  * @port_ready: Port ready completion flag for each Slave port
  * @dev_num: Device Number assigned by Bus
@@ -555,6 +556,7 @@ struct sdw_slave {
 	struct sdw_bus *bus;
 	const struct sdw_slave_ops *ops;
 	struct sdw_slave_prop prop;
+	struct dentry *debugfs;
 	struct list_head node;
 	struct completion *port_ready;
 	u16 dev_num;
@@ -731,6 +733,7 @@ struct sdw_master_ops {
  * @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
+ * @debugfs: Bus debugfs
  * @defer_msg: Defer message
  * @clk_stop_timeout: Clock stop timeout computed
  * @bank_switch_timeout: Bank switch timeout computed
@@ -750,6 +753,7 @@ struct sdw_bus {
 	struct sdw_bus_params params;
 	struct sdw_master_prop prop;
 	struct list_head m_rt_list;
+	struct dentry *debugfs;
 	struct sdw_defer defer_msg;
 	unsigned int clk_stop_timeout;
 	u32 bank_switch_timeout;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 02/40] soundwire: cadence_master: add debugfs register dump
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
  2019-07-25 23:39 ` [RFC PATCH 01/40] soundwire: add debugfs support Pierre-Louis Bossart
@ 2019-07-25 23:39 ` Pierre-Louis Bossart
  2019-07-26 14:09   ` Greg KH
  2019-08-05  7:55   ` Sanyog Kale
  2019-07-25 23:39 ` [RFC PATCH 03/40] soundwire: cadence_master: align debugfs to 8 digits Pierre-Louis Bossart
                   ` (38 subsequent siblings)
  40 siblings, 2 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:39 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

Add debugfs file to dump the Cadence master registers

Credits: this patch is based on an earlier internal contribution by
Vinod Koul, Sanyog Kale, Shreyas Nc and Hardik Shah. The main change
is the use of scnprintf to avoid known issues with snprintf.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/cadence_master.c | 98 ++++++++++++++++++++++++++++++
 drivers/soundwire/cadence_master.h |  2 +
 2 files changed, 100 insertions(+)

diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
index ff4badc9b3de..91e8bacb83e3 100644
--- a/drivers/soundwire/cadence_master.c
+++ b/drivers/soundwire/cadence_master.c
@@ -8,6 +8,7 @@
 
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/debugfs.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/module.h>
@@ -223,6 +224,103 @@ static int cdns_clear_bit(struct sdw_cdns *cdns, int offset, u32 value)
 	return -EAGAIN;
 }
 
+/*
+ * debugfs
+ */
+
+#define RD_BUF (2 * PAGE_SIZE)
+
+static ssize_t cdns_sprintf(struct sdw_cdns *cdns,
+			    char *buf, size_t pos, unsigned int reg)
+{
+	return scnprintf(buf + pos, RD_BUF - pos,
+			 "%4x\t%4x\n", reg, cdns_readl(cdns, reg));
+}
+
+static ssize_t cdns_reg_read(struct file *file, char __user *user_buf,
+			     size_t count, loff_t *ppos)
+{
+	struct sdw_cdns *cdns = file->private_data;
+	char *buf;
+	ssize_t ret;
+	int i, j;
+
+	buf = kzalloc(RD_BUF, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	ret = scnprintf(buf, RD_BUF, "Register  Value\n");
+	ret += scnprintf(buf + ret, RD_BUF - ret, "\nMCP Registers\n");
+	for (i = 0; i < 8; i++) /* 8 MCP registers */
+		ret += cdns_sprintf(cdns, buf, ret, i * 4);
+
+	ret += scnprintf(buf + ret, RD_BUF - ret,
+			 "\nStatus & Intr Registers\n");
+	for (i = 0; i < 13; i++) /* 13 Status & Intr registers */
+		ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_STAT + i * 4);
+
+	ret += scnprintf(buf + ret, RD_BUF - ret,
+			 "\nSSP & Clk ctrl Registers\n");
+	ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_SSP_CTRL0);
+	ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_SSP_CTRL1);
+	ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_CLK_CTRL0);
+	ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_CLK_CTRL1);
+
+	ret += scnprintf(buf + ret, RD_BUF - ret,
+			 "\nDPn B0 Registers\n");
+	for (i = 0; i < 7; i++) {
+		ret += scnprintf(buf + ret, RD_BUF - ret,
+				 "\nDP-%d\n", i);
+		for (j = 0; j < 6; j++)
+			ret += cdns_sprintf(cdns, buf, ret,
+					CDNS_DPN_B0_CONFIG(i) + j * 4);
+	}
+
+	ret += scnprintf(buf + ret, RD_BUF - ret,
+			 "\nDPn B1 Registers\n");
+	for (i = 0; i < 7; i++) {
+		ret += scnprintf(buf + ret, RD_BUF - ret,
+				 "\nDP-%d\n", i);
+
+		for (j = 0; j < 6; j++)
+			ret += cdns_sprintf(cdns, buf, ret,
+					CDNS_DPN_B1_CONFIG(i) + j * 4);
+	}
+
+	ret += scnprintf(buf + ret, RD_BUF - ret,
+			 "\nDPn Control Registers\n");
+	for (i = 0; i < 7; i++)
+		ret += cdns_sprintf(cdns, buf, ret,
+				CDNS_PORTCTRL + i * CDNS_PORT_OFFSET);
+
+	ret += scnprintf(buf + ret, RD_BUF - ret,
+			 "\nPDIn Config Registers\n");
+	for (i = 0; i < 7; i++)
+		ret += cdns_sprintf(cdns, buf, ret, CDNS_PDI_CONFIG(i));
+
+	ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
+	kfree(buf);
+
+	return ret;
+}
+
+static const struct file_operations cdns_reg_fops = {
+	.open = simple_open,
+	.read = cdns_reg_read,
+	.llseek = default_llseek,
+};
+
+/**
+ * sdw_cdns_debugfs_init() - Cadence debugfs init
+ * @cdns: Cadence instance
+ * @root: debugfs root
+ */
+void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root)
+{
+	debugfs_create_file("cdns-registers", 0400, root, cdns, &cdns_reg_fops);
+}
+EXPORT_SYMBOL_GPL(sdw_cdns_debugfs_init);
+
 /*
  * IO Calls
  */
diff --git a/drivers/soundwire/cadence_master.h b/drivers/soundwire/cadence_master.h
index fe2af62958b1..c0bf6ff00a44 100644
--- a/drivers/soundwire/cadence_master.h
+++ b/drivers/soundwire/cadence_master.h
@@ -163,6 +163,8 @@ int sdw_cdns_pdi_init(struct sdw_cdns *cdns,
 		      struct sdw_cdns_stream_config config);
 int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns);
 
+void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root);
+
 int sdw_cdns_get_stream(struct sdw_cdns *cdns,
 			struct sdw_cdns_streams *stream,
 			u32 ch, u32 dir);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 03/40] soundwire: cadence_master: align debugfs to 8 digits
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
  2019-07-25 23:39 ` [RFC PATCH 01/40] soundwire: add debugfs support Pierre-Louis Bossart
  2019-07-25 23:39 ` [RFC PATCH 02/40] soundwire: cadence_master: add debugfs register dump Pierre-Louis Bossart
@ 2019-07-25 23:39 ` Pierre-Louis Bossart
  2019-07-26  9:38   ` Cezary Rojewski
  2019-08-02 11:50   ` Vinod Koul
  2019-07-25 23:39 ` [RFC PATCH 04/40] soundwire: intel: add debugfs register dump Pierre-Louis Bossart
                   ` (37 subsequent siblings)
  40 siblings, 2 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:39 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

SQUASHME

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/cadence_master.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
index 91e8bacb83e3..9f611a1fff0a 100644
--- a/drivers/soundwire/cadence_master.c
+++ b/drivers/soundwire/cadence_master.c
@@ -234,7 +234,7 @@ static ssize_t cdns_sprintf(struct sdw_cdns *cdns,
 			    char *buf, size_t pos, unsigned int reg)
 {
 	return scnprintf(buf + pos, RD_BUF - pos,
-			 "%4x\t%4x\n", reg, cdns_readl(cdns, reg));
+			 "%4x\t%8x\n", reg, cdns_readl(cdns, reg));
 }
 
 static ssize_t cdns_reg_read(struct file *file, char __user *user_buf,
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 04/40] soundwire: intel: add debugfs register dump
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (2 preceding siblings ...)
  2019-07-25 23:39 ` [RFC PATCH 03/40] soundwire: cadence_master: align debugfs to 8 digits Pierre-Louis Bossart
@ 2019-07-25 23:39 ` Pierre-Louis Bossart
  2019-07-26  9:35   ` Cezary Rojewski
  2019-07-26 14:06   ` Greg KH
  2019-07-25 23:39 ` [RFC PATCH 05/40] soundwire: intel: move interrupt enable after interrupt handler registration Pierre-Louis Bossart
                   ` (36 subsequent siblings)
  40 siblings, 2 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:39 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

Add debugfs file to dump the Intel SoundWire registers

Credits: this patch is based on an earlier internal contribution by
Vinod Koul, Sanyog Kale, Shreyas Nc and Hardik Shah. The main change
is the use of scnprintf to avoid known issues with snprintf.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/intel.c | 115 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 115 insertions(+)

diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
index 317873bc0555..aeadc341c0a3 100644
--- a/drivers/soundwire/intel.c
+++ b/drivers/soundwire/intel.c
@@ -6,6 +6,7 @@
  */
 
 #include <linux/acpi.h>
+#include <linux/debugfs.h>
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
@@ -16,6 +17,7 @@
 #include <linux/soundwire/sdw.h>
 #include <linux/soundwire/sdw_intel.h>
 #include "cadence_master.h"
+#include "bus.h"
 #include "intel.h"
 
 /* Intel SHIM Registers Definition */
@@ -98,6 +100,7 @@ struct sdw_intel {
 	struct sdw_cdns cdns;
 	int instance;
 	struct sdw_intel_link_res *res;
+	struct dentry *fs;
 };
 
 #define cdns_to_intel(_cdns) container_of(_cdns, struct sdw_intel, cdns)
@@ -161,6 +164,115 @@ static int intel_set_bit(void __iomem *base, int offset, u32 value, u32 mask)
 	return -EAGAIN;
 }
 
+/*
+ * debugfs
+ */
+
+#define RD_BUF (2 * PAGE_SIZE)
+
+static ssize_t intel_sprintf(void __iomem *mem, bool l,
+			     char *buf, size_t pos, unsigned int reg)
+{
+	int value;
+
+	if (l)
+		value = intel_readl(mem, reg);
+	else
+		value = intel_readw(mem, reg);
+
+	return scnprintf(buf + pos, RD_BUF - pos, "%4x\t%4x\n", reg, value);
+}
+
+static ssize_t intel_reg_read(struct file *file, char __user *user_buf,
+			      size_t count, loff_t *ppos)
+{
+	struct sdw_intel *sdw = file->private_data;
+	void __iomem *s = sdw->res->shim;
+	void __iomem *a = sdw->res->alh;
+	char *buf;
+	ssize_t ret;
+	int i, j;
+	unsigned int links, reg;
+
+	buf = kzalloc(RD_BUF, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	links = intel_readl(s, SDW_SHIM_LCAP) & GENMASK(2, 0);
+
+	ret = scnprintf(buf, RD_BUF, "Register  Value\n");
+	ret += scnprintf(buf + ret, RD_BUF - ret, "\nShim\n");
+
+	for (i = 0; i < 4; i++) {
+		reg = SDW_SHIM_LCAP + i * 4;
+		ret += intel_sprintf(s, true, buf, ret, reg);
+	}
+
+	for (i = 0; i < links; i++) {
+		ret += scnprintf(buf + ret, RD_BUF - ret, "\nLink%d\n", i);
+		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTLSCAP(i));
+		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTLS0CM(i));
+		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTLS1CM(i));
+		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTLS2CM(i));
+		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTLS3CM(i));
+		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_PCMSCAP(i));
+
+		for (j = 0; j < 8; j++) {
+			ret += intel_sprintf(s, false, buf, ret,
+					SDW_SHIM_PCMSYCHM(i, j));
+			ret += intel_sprintf(s, false, buf, ret,
+					SDW_SHIM_PCMSYCHC(i, j));
+		}
+
+		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_PDMSCAP(i));
+		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_IOCTL(i));
+		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTMCTL(i));
+	}
+
+	ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_WAKEEN);
+	ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_WAKESTS);
+
+	ret += scnprintf(buf + ret, RD_BUF - ret, "\nALH\n");
+	for (i = 0; i < 8; i++)
+		ret += intel_sprintf(a, true, buf, ret, SDW_ALH_STRMZCFG(i));
+
+	ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
+	kfree(buf);
+
+	return ret;
+}
+
+static const struct file_operations intel_reg_fops = {
+	.open = simple_open,
+	.read = intel_reg_read,
+	.llseek = default_llseek,
+};
+
+static void intel_debugfs_init(struct sdw_intel *sdw)
+{
+	struct dentry *root = sdw->cdns.bus.debugfs;
+
+	if (!root)
+		return;
+
+	sdw->fs = debugfs_create_dir("intel-sdw", root);
+	if (IS_ERR_OR_NULL(sdw->fs)) {
+		dev_err(sdw->cdns.dev, "debugfs root creation failed\n");
+		sdw->fs = NULL;
+		return;
+	}
+
+	debugfs_create_file("intel-registers", 0400, sdw->fs, sdw,
+			    &intel_reg_fops);
+
+	sdw_cdns_debugfs_init(&sdw->cdns, sdw->fs);
+}
+
+static void intel_debugfs_exit(struct sdw_intel *sdw)
+{
+	debugfs_remove_recursive(sdw->fs);
+}
+
 /*
  * shim ops
  */
@@ -896,6 +1008,8 @@ static int intel_probe(struct platform_device *pdev)
 		goto err_dai;
 	}
 
+	intel_debugfs_init(sdw);
+
 	return 0;
 
 err_dai:
@@ -912,6 +1026,7 @@ static int intel_remove(struct platform_device *pdev)
 
 	sdw = platform_get_drvdata(pdev);
 
+	intel_debugfs_exit(sdw);
 	free_irq(sdw->res->irq, sdw);
 	snd_soc_unregister_component(sdw->cdns.dev);
 	sdw_delete_bus_master(&sdw->cdns.bus);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 05/40] soundwire: intel: move interrupt enable after interrupt handler registration
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (3 preceding siblings ...)
  2019-07-25 23:39 ` [RFC PATCH 04/40] soundwire: intel: add debugfs register dump Pierre-Louis Bossart
@ 2019-07-25 23:39 ` Pierre-Louis Bossart
  2019-08-02 11:53   ` Vinod Koul
  2019-07-25 23:39 ` [RFC PATCH 06/40] soundwire: intel: prevent possible dereference in hw_params Pierre-Louis Bossart
                   ` (35 subsequent siblings)
  40 siblings, 1 reply; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:39 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

Not sure why the existing code would enable interrupts without the
ability to deal with them.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/intel.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
index aeadc341c0a3..68832e613b1e 100644
--- a/drivers/soundwire/intel.c
+++ b/drivers/soundwire/intel.c
@@ -981,8 +981,6 @@ static int intel_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_init;
 
-	ret = sdw_cdns_enable_interrupt(&sdw->cdns);
-
 	/* Read the PDI config and initialize cadence PDI */
 	intel_pdi_init(sdw, &config);
 	ret = sdw_cdns_pdi_init(&sdw->cdns, config);
@@ -1000,6 +998,8 @@ static int intel_probe(struct platform_device *pdev)
 		goto err_init;
 	}
 
+	ret = sdw_cdns_enable_interrupt(&sdw->cdns);
+
 	/* Register DAIs */
 	ret = intel_register_dai(sdw);
 	if (ret) {
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 06/40] soundwire: intel: prevent possible dereference in hw_params
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (4 preceding siblings ...)
  2019-07-25 23:39 ` [RFC PATCH 05/40] soundwire: intel: move interrupt enable after interrupt handler registration Pierre-Louis Bossart
@ 2019-07-25 23:39 ` Pierre-Louis Bossart
  2019-07-26  9:45   ` Cezary Rojewski
  2019-08-02 11:55   ` Vinod Koul
  2019-07-25 23:39 ` [RFC PATCH 07/40] soundwire: intel: fix channel number reported by hardware Pierre-Louis Bossart
                   ` (34 subsequent siblings)
  40 siblings, 2 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:39 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

This should not happen in production systems but we should test for
all callback arguments before invoking the config_stream callback.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/intel.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
index 68832e613b1e..497879dd9c0d 100644
--- a/drivers/soundwire/intel.c
+++ b/drivers/soundwire/intel.c
@@ -509,7 +509,7 @@ static int intel_config_stream(struct sdw_intel *sdw,
 			       struct snd_soc_dai *dai,
 			       struct snd_pcm_hw_params *hw_params, int link_id)
 {
-	if (sdw->res->ops && sdw->res->ops->config_stream)
+	if (sdw->res->ops && sdw->res->ops->config_stream && sdw->res->arg)
 		return sdw->res->ops->config_stream(sdw->res->arg,
 				substream, dai, hw_params, link_id);
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 07/40] soundwire: intel: fix channel number reported by hardware
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (5 preceding siblings ...)
  2019-07-25 23:39 ` [RFC PATCH 06/40] soundwire: intel: prevent possible dereference in hw_params Pierre-Louis Bossart
@ 2019-07-25 23:39 ` Pierre-Louis Bossart
  2019-08-02 11:57   ` Vinod Koul
  2019-07-25 23:40 ` [RFC PATCH 08/40] soundwire: intel: remove BIOS work-arounds Pierre-Louis Bossart
                   ` (33 subsequent siblings)
  40 siblings, 1 reply; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:39 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

PDI2 reports an invalid count, force the correct hardware-supported
value

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/intel.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
index 497879dd9c0d..51990b192dc0 100644
--- a/drivers/soundwire/intel.c
+++ b/drivers/soundwire/intel.c
@@ -401,6 +401,15 @@ intel_pdi_get_ch_cap(struct sdw_intel *sdw, unsigned int pdi_num, bool pcm)
 
 	if (pcm) {
 		count = intel_readw(shim, SDW_SHIM_PCMSYCHC(link_id, pdi_num));
+
+		/*
+		 * TODO: pdi number 2 reports channel count as 1 even though
+		 * it supports 8 channel. Performing hardcoding for pdi
+		 * number 2.
+		 */
+		if (pdi_num == 2)
+			count = 7;
+
 	} else {
 		count = intel_readw(shim, SDW_SHIM_PDMSCAP(link_id));
 		count = ((count & SDW_SHIM_PDMSCAP_CPSS) >>
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 08/40] soundwire: intel: remove BIOS work-arounds
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (6 preceding siblings ...)
  2019-07-25 23:39 ` [RFC PATCH 07/40] soundwire: intel: fix channel number reported by hardware Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-08-02 11:58   ` Vinod Koul
  2019-07-25 23:40 ` [RFC PATCH 09/40] soundwire: cadence_master: fix usage of CONFIG_UPDATE Pierre-Louis Bossart
                   ` (32 subsequent siblings)
  40 siblings, 1 reply; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

the values passed by all existing BIOS are fine, let's use them as is.
The existing code must have been needed only on early prototypes.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/intel.c | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
index 51990b192dc0..c718c9c67a37 100644
--- a/drivers/soundwire/intel.c
+++ b/drivers/soundwire/intel.c
@@ -922,17 +922,6 @@ static int intel_prop_read(struct sdw_bus *bus)
 	/* Initialize with default handler to read all DisCo properties */
 	sdw_master_read_prop(bus);
 
-	/* BIOS is not giving some values correctly. So, lets override them */
-	bus->prop.num_clk_freq = 1;
-	bus->prop.clk_freq = devm_kcalloc(bus->dev, bus->prop.num_clk_freq,
-					  sizeof(*bus->prop.clk_freq),
-					  GFP_KERNEL);
-	if (!bus->prop.clk_freq)
-		return -ENOMEM;
-
-	bus->prop.clk_freq[0] = bus->prop.max_clk_freq;
-	bus->prop.err_threshold = 5;
-
 	return 0;
 }
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 09/40] soundwire: cadence_master: fix usage of CONFIG_UPDATE
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (7 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 08/40] soundwire: intel: remove BIOS work-arounds Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-07-25 22:23   ` [alsa-devel] " Guennadi Liakhovetski
                     ` (4 more replies)
  2019-07-25 23:40 ` [RFC PATCH 10/40] soundwire: cadence_master: remove useless wrapper Pierre-Louis Bossart
                   ` (31 subsequent siblings)
  40 siblings, 5 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

Per the hardware documentation, all changes to MCP_CONFIG,
MCP_CONTROL, MCP_CMDCTRL and MCP_PHYCTRL need to be validated with a
self-clearing write to MCP_CONFIG_UPDATE.

For some reason, the existing code only does this write to
CONFIG_UPDATE when enabling interrupts. Add a helper and do the update
when the CONFIG is changed.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/cadence_master.c | 29 +++++++++++++++++++++--------
 1 file changed, 21 insertions(+), 8 deletions(-)

diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
index 9f611a1fff0a..eb46cf651d62 100644
--- a/drivers/soundwire/cadence_master.c
+++ b/drivers/soundwire/cadence_master.c
@@ -224,6 +224,22 @@ static int cdns_clear_bit(struct sdw_cdns *cdns, int offset, u32 value)
 	return -EAGAIN;
 }
 
+/*
+ * all changes to the MCP_CONFIG, MCP_CONTROL, MCP_CMDCTRL and MCP_PHYCTRL
+ * need to be confirmed with a write to MCP_CONFIG_UPDATE
+ */
+static int cdns_update_config(struct sdw_cdns *cdns)
+{
+	int ret;
+
+	ret = cdns_clear_bit(cdns, CDNS_MCP_CONFIG_UPDATE,
+			     CDNS_MCP_CONFIG_UPDATE_BIT);
+	if (ret < 0)
+		dev_err(cdns->dev, "Config update timedout\n");
+
+	return ret;
+}
+
 /*
  * debugfs
  */
@@ -758,15 +774,9 @@ static int _cdns_enable_interrupt(struct sdw_cdns *cdns)
  */
 int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
 {
-	int ret;
-
 	_cdns_enable_interrupt(cdns);
-	ret = cdns_clear_bit(cdns, CDNS_MCP_CONFIG_UPDATE,
-			     CDNS_MCP_CONFIG_UPDATE_BIT);
-	if (ret < 0)
-		dev_err(cdns->dev, "Config update timedout\n");
 
-	return ret;
+	return 0;
 }
 EXPORT_SYMBOL(sdw_cdns_enable_interrupt);
 
@@ -943,7 +953,10 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
 
 	cdns_writel(cdns, CDNS_MCP_CONFIG, val);
 
-	return 0;
+	/* commit changes */
+	ret = cdns_update_config(cdns);
+
+	return ret;
 }
 EXPORT_SYMBOL(sdw_cdns_init);
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 10/40] soundwire: cadence_master: remove useless wrapper
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (8 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 09/40] soundwire: cadence_master: fix usage of CONFIG_UPDATE Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-07-25 23:40 ` [RFC PATCH 11/40] soundwire: cadence_master: simplify bus clash interrupt clear Pierre-Louis Bossart
                   ` (30 subsequent siblings)
  40 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

Now that we've removed the update config, there's no need for a wrapper.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/cadence_master.c | 18 ++++++------------
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
index eb46cf651d62..e85e49340986 100644
--- a/drivers/soundwire/cadence_master.c
+++ b/drivers/soundwire/cadence_master.c
@@ -749,7 +749,12 @@ EXPORT_SYMBOL(sdw_cdns_thread);
 /*
  * init routines
  */
-static int _cdns_enable_interrupt(struct sdw_cdns *cdns)
+
+/**
+ * sdw_cdns_enable_interrupt() - Enable SDW interrupts and update config
+ * @cdns: Cadence instance
+ */
+int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
 {
 	u32 mask;
 
@@ -767,17 +772,6 @@ static int _cdns_enable_interrupt(struct sdw_cdns *cdns)
 
 	return 0;
 }
-
-/**
- * sdw_cdns_enable_interrupt() - Enable SDW interrupts and update config
- * @cdns: Cadence instance
- */
-int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
-{
-	_cdns_enable_interrupt(cdns);
-
-	return 0;
-}
 EXPORT_SYMBOL(sdw_cdns_enable_interrupt);
 
 static int cdns_allocate_pdi(struct sdw_cdns *cdns,
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 11/40] soundwire: cadence_master: simplify bus clash interrupt clear
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (9 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 10/40] soundwire: cadence_master: remove useless wrapper Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-08-02 12:07   ` Vinod Koul
  2019-07-25 23:40 ` [RFC PATCH 12/40] soundwire: cadence_master: revisit interrupt settings Pierre-Louis Bossart
                   ` (29 subsequent siblings)
  40 siblings, 1 reply; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

The bus clash interrupts are generated when the status is one, and
also cleared by writing a one. It's overkill/useless to use an OR when
the bit is already set.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/cadence_master.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
index e85e49340986..bdc3ed844829 100644
--- a/drivers/soundwire/cadence_master.c
+++ b/drivers/soundwire/cadence_master.c
@@ -692,7 +692,6 @@ irqreturn_t sdw_cdns_irq(int irq, void *dev_id)
 	if (int_status & CDNS_MCP_INT_CTRL_CLASH) {
 		/* Slave is driving bit slot during control word */
 		dev_err_ratelimited(cdns->dev, "Bus clash for control word\n");
-		int_status |= CDNS_MCP_INT_CTRL_CLASH;
 	}
 
 	if (int_status & CDNS_MCP_INT_DATA_CLASH) {
@@ -701,7 +700,6 @@ irqreturn_t sdw_cdns_irq(int irq, void *dev_id)
 		 * ownership of data bits or Slave gone bonkers
 		 */
 		dev_err_ratelimited(cdns->dev, "Bus clash for data word\n");
-		int_status |= CDNS_MCP_INT_DATA_CLASH;
 	}
 
 	if (int_status & CDNS_MCP_INT_SLAVE_MASK) {
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 12/40] soundwire: cadence_master: revisit interrupt settings
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (10 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 11/40] soundwire: cadence_master: simplify bus clash interrupt clear Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-08-02 12:10   ` Vinod Koul
  2019-07-25 23:40 ` [RFC PATCH 13/40] soundwire: cadence_master: fix register definition for SLAVE_STATE Pierre-Louis Bossart
                   ` (28 subsequent siblings)
  40 siblings, 1 reply; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Bard Liao, Sanyog Kale

Adding missing interrupt masks (parity, etc) and missing checks.
Clarify which masks are for which usage.

Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/cadence_master.c | 25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
index bdc3ed844829..0f3b9c160b01 100644
--- a/drivers/soundwire/cadence_master.c
+++ b/drivers/soundwire/cadence_master.c
@@ -76,9 +76,12 @@
 #define CDNS_MCP_INT_DPINT			BIT(11)
 #define CDNS_MCP_INT_CTRL_CLASH			BIT(10)
 #define CDNS_MCP_INT_DATA_CLASH			BIT(9)
+#define CDNS_MCP_INT_PARITY			BIT(8)
 #define CDNS_MCP_INT_CMD_ERR			BIT(7)
+#define CDNS_MCP_INT_RX_NE			BIT(3)
 #define CDNS_MCP_INT_RX_WL			BIT(2)
 #define CDNS_MCP_INT_TXE			BIT(1)
+#define CDNS_MCP_INT_TXF			BIT(0)
 
 #define CDNS_MCP_INTSET				0x4C
 
@@ -689,6 +692,11 @@ irqreturn_t sdw_cdns_irq(int irq, void *dev_id)
 		}
 	}
 
+	if (int_status & CDNS_MCP_INT_PARITY) {
+		/* Parity error detected by Master */
+		dev_err_ratelimited(cdns->dev, "Parity error\n");
+	}
+
 	if (int_status & CDNS_MCP_INT_CTRL_CLASH) {
 		/* Slave is driving bit slot during control word */
 		dev_err_ratelimited(cdns->dev, "Bus clash for control word\n");
@@ -761,10 +769,21 @@ int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
 	cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK1,
 		    CDNS_MCP_SLAVE_INTMASK1_MASK);
 
+	/* enable detection of slave state changes */
 	mask = CDNS_MCP_INT_SLAVE_RSVD | CDNS_MCP_INT_SLAVE_ALERT |
-		CDNS_MCP_INT_SLAVE_ATTACH | CDNS_MCP_INT_SLAVE_NATTACH |
-		CDNS_MCP_INT_CTRL_CLASH | CDNS_MCP_INT_DATA_CLASH |
-		CDNS_MCP_INT_RX_WL | CDNS_MCP_INT_IRQ | CDNS_MCP_INT_DPINT;
+		CDNS_MCP_INT_SLAVE_ATTACH | CDNS_MCP_INT_SLAVE_NATTACH;
+
+	/* enable detection of bus issues */
+	mask |= CDNS_MCP_INT_CTRL_CLASH | CDNS_MCP_INT_DATA_CLASH |
+		CDNS_MCP_INT_PARITY;
+
+	/* no detection of port interrupts for now */
+
+	/* enable detection of RX fifo level */
+	mask |= CDNS_MCP_INT_RX_WL;
+
+	/* now enable all of the above */
+	mask |= CDNS_MCP_INT_IRQ;
 
 	cdns_writel(cdns, CDNS_MCP_INTMASK, mask);
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 13/40] soundwire: cadence_master: fix register definition for SLAVE_STATE
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (11 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 12/40] soundwire: cadence_master: revisit interrupt settings Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-08-02 12:12   ` Vinod Koul
  2019-07-25 23:40 ` [RFC PATCH 14/40] soundwire: cadence_master: fix definitions for INTSTAT0/1 Pierre-Louis Bossart
                   ` (27 subsequent siblings)
  40 siblings, 1 reply; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

wrong prefix and wrong macro.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/cadence_master.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
index 0f3b9c160b01..d9d9e3d964dd 100644
--- a/drivers/soundwire/cadence_master.c
+++ b/drivers/soundwire/cadence_master.c
@@ -85,8 +85,8 @@
 
 #define CDNS_MCP_INTSET				0x4C
 
-#define CDNS_SDW_SLAVE_STAT			0x50
-#define CDNS_MCP_SLAVE_STAT_MASK		BIT(1, 0)
+#define CDNS_MCP_SLAVE_STAT			0x50
+#define CDNS_MCP_SLAVE_STAT_MASK		GENMASK(1, 0)
 
 #define CDNS_MCP_SLAVE_INTSTAT0			0x54
 #define CDNS_MCP_SLAVE_INTSTAT1			0x58
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 14/40] soundwire: cadence_master: fix definitions for INTSTAT0/1
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (12 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 13/40] soundwire: cadence_master: fix register definition for SLAVE_STATE Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-08-02 12:13   ` Vinod Koul
  2019-07-25 23:40 ` [RFC PATCH 15/40] soundwire: cadence_master: handle multiple status reports per Slave Pierre-Louis Bossart
                   ` (26 subsequent siblings)
  40 siblings, 1 reply; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

Two off-by-one errors: INTSTAT0 missed BIT(31) and INTSTAT1 is only
defined on first 16 bits.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/cadence_master.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
index d9d9e3d964dd..889fa2cd49ae 100644
--- a/drivers/soundwire/cadence_master.c
+++ b/drivers/soundwire/cadence_master.c
@@ -100,8 +100,8 @@
 #define CDNS_MCP_SLAVE_INTMASK0			0x5C
 #define CDNS_MCP_SLAVE_INTMASK1			0x60
 
-#define CDNS_MCP_SLAVE_INTMASK0_MASK		GENMASK(30, 0)
-#define CDNS_MCP_SLAVE_INTMASK1_MASK		GENMASK(16, 0)
+#define CDNS_MCP_SLAVE_INTMASK0_MASK		GENMASK(31, 0)
+#define CDNS_MCP_SLAVE_INTMASK1_MASK		GENMASK(15, 0)
 
 #define CDNS_MCP_PORT_INTSTAT			0x64
 #define CDNS_MCP_PDI_STAT			0x6C
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 15/40] soundwire: cadence_master: handle multiple status reports per Slave
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (13 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 14/40] soundwire: cadence_master: fix definitions for INTSTAT0/1 Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-07-25 22:31   ` [alsa-devel] " Guennadi Liakhovetski
  2019-08-02 12:20   ` Vinod Koul
  2019-07-25 23:40 ` [RFC PATCH 16/40] soundwire: cadence_master: improve startup sequence with link hw_reset Pierre-Louis Bossart
                   ` (25 subsequent siblings)
  40 siblings, 2 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

When a Slave reports multiple status in the sticky bits, find the
latest configuration from the mirror of the PING frame status and
update the status directly.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/cadence_master.c | 34 ++++++++++++++++++++++++------
 1 file changed, 28 insertions(+), 6 deletions(-)

diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
index 889fa2cd49ae..25d5c7267c15 100644
--- a/drivers/soundwire/cadence_master.c
+++ b/drivers/soundwire/cadence_master.c
@@ -643,13 +643,35 @@ static int cdns_update_slave_status(struct sdw_cdns *cdns,
 
 		/* first check if Slave reported multiple status */
 		if (set_status > 1) {
+			u32 val;
+
 			dev_warn_ratelimited(cdns->dev,
-					     "Slave reported multiple Status: %d\n",
-					     mask);
-			/*
-			 * TODO: we need to reread the status here by
-			 * issuing a PING cmd
-			 */
+					     "Slave %d reported multiple Status: %d\n",
+					     i, mask);
+
+			/* re-check latest status extracted from PING commands */
+			val = cdns_readl(cdns, CDNS_MCP_SLAVE_STAT);
+			val >>= (i * 2);
+
+			switch (val & 0x3) {
+			case 0:
+				status[i] = SDW_SLAVE_UNATTACHED;
+				break;
+			case 1:
+				status[i] = SDW_SLAVE_ATTACHED;
+				break;
+			case 2:
+				status[i] = SDW_SLAVE_ALERT;
+				break;
+			default:
+				status[i] = SDW_SLAVE_RESERVED;
+				break;
+			}
+
+			dev_warn_ratelimited(cdns->dev,
+					     "Slave %d status updated to %d\n",
+					     i, status[i]);
+
 		}
 	}
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 16/40] soundwire: cadence_master: improve startup sequence with link hw_reset
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (14 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 15/40] soundwire: cadence_master: handle multiple status reports per Slave Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-07-26  7:22   ` [alsa-devel] " Guennadi Liakhovetski
  2019-07-25 23:40 ` [RFC PATCH 17/40] soundwire: bus: use runtime_pm_get_sync/pm when enabled Pierre-Louis Bossart
                   ` (24 subsequent siblings)
  40 siblings, 1 reply; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

Enable interrupts first, then engage hardware bus reset with maximum
duration to make sure the Slave(s) correctly detect the reset pattern
and to ensure electrical conflicts can be resolved.

Without these changes the initialization is randomly corrupted by bus
clashes, parity errors and Slave attachment does not generate any
interrupt, despite the status showing them being attached.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/cadence_master.c | 35 +++++++++++++++++++++++++-----
 1 file changed, 30 insertions(+), 5 deletions(-)

diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
index 25d5c7267c15..442f78c00f09 100644
--- a/drivers/soundwire/cadence_master.c
+++ b/drivers/soundwire/cadence_master.c
@@ -778,6 +778,31 @@ EXPORT_SYMBOL(sdw_cdns_thread);
  * init routines
  */
 
+static int do_reset(struct sdw_cdns *cdns)
+{
+	int ret;
+
+	/* program maximum length reset to be safe */
+	cdns_updatel(cdns, CDNS_MCP_CONTROL,
+		     CDNS_MCP_CONTROL_RST_DELAY,
+		     CDNS_MCP_CONTROL_RST_DELAY);
+
+	/* use hardware generated reset */
+	cdns_updatel(cdns, CDNS_MCP_CONTROL,
+		     CDNS_MCP_CONTROL_HW_RST,
+		     CDNS_MCP_CONTROL_HW_RST);
+
+	/* enable bus operations with clock and data */
+	cdns_updatel(cdns, CDNS_MCP_CONFIG,
+		     CDNS_MCP_CONFIG_OP,
+		     CDNS_MCP_CONFIG_OP_NORMAL);
+
+	/* commit changes */
+	ret = cdns_update_config(cdns);
+
+	return ret;
+}
+
 /**
  * sdw_cdns_enable_interrupt() - Enable SDW interrupts and update config
  * @cdns: Cadence instance
@@ -809,7 +834,7 @@ int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
 
 	cdns_writel(cdns, CDNS_MCP_INTMASK, mask);
 
-	return 0;
+	return do_reset(cdns);
 }
 EXPORT_SYMBOL(sdw_cdns_enable_interrupt);
 
@@ -958,6 +983,10 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
 	cdns_writel(cdns, CDNS_MCP_SSP_CTRL0, CDNS_DEFAULT_SSP_INTERVAL);
 	cdns_writel(cdns, CDNS_MCP_SSP_CTRL1, CDNS_DEFAULT_SSP_INTERVAL);
 
+	/* flush command FIFOs */
+	cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_CMD_RST,
+		     CDNS_MCP_CONTROL_CMD_RST);
+
 	/* Set cmd accept mode */
 	cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_CMD_ACCEPT,
 		     CDNS_MCP_CONTROL_CMD_ACCEPT);
@@ -980,10 +1009,6 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
 	/* Set cmd mode for Tx and Rx cmds */
 	val &= ~CDNS_MCP_CONFIG_CMD;
 
-	/* Set operation to normal */
-	val &= ~CDNS_MCP_CONFIG_OP;
-	val |= CDNS_MCP_CONFIG_OP_NORMAL;
-
 	cdns_writel(cdns, CDNS_MCP_CONFIG, val);
 
 	/* commit changes */
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 17/40] soundwire: bus: use runtime_pm_get_sync/pm when enabled
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (15 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 16/40] soundwire: cadence_master: improve startup sequence with link hw_reset Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-07-26  7:39   ` [alsa-devel] " Guennadi Liakhovetski
                     ` (2 more replies)
  2019-07-25 23:40 ` [RFC PATCH 18/40] soundwire: bus: split handling of Device0 events Pierre-Louis Bossart
                   ` (23 subsequent siblings)
  40 siblings, 3 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

Not all platforms support runtime_pm for now, let's use runtime_pm
only when enabled.

Suggested-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/bus.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
index 5ad4109dc72f..0a45dc5713df 100644
--- a/drivers/soundwire/bus.c
+++ b/drivers/soundwire/bus.c
@@ -332,12 +332,16 @@ int sdw_nread(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
 	if (ret < 0)
 		return ret;
 
-	ret = pm_runtime_get_sync(slave->bus->dev);
-	if (ret < 0)
-		return ret;
+	if (pm_runtime_enabled(slave->bus->dev)) {
+		ret = pm_runtime_get_sync(slave->bus->dev);
+		if (ret < 0)
+			return ret;
+	}
 
 	ret = sdw_transfer(slave->bus, &msg);
-	pm_runtime_put(slave->bus->dev);
+
+	if (pm_runtime_enabled(slave->bus->dev))
+		pm_runtime_put(slave->bus->dev);
 
 	return ret;
 }
@@ -359,13 +363,16 @@ int sdw_nwrite(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
 			   slave->dev_num, SDW_MSG_FLAG_WRITE, val);
 	if (ret < 0)
 		return ret;
-
-	ret = pm_runtime_get_sync(slave->bus->dev);
-	if (ret < 0)
-		return ret;
+	if (pm_runtime_enabled(slave->bus->dev)) {
+		ret = pm_runtime_get_sync(slave->bus->dev);
+		if (ret < 0)
+			return ret;
+	}
 
 	ret = sdw_transfer(slave->bus, &msg);
-	pm_runtime_put(slave->bus->dev);
+
+	if (pm_runtime_enabled(slave->bus->dev))
+		pm_runtime_put(slave->bus->dev);
 
 	return ret;
 }
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 18/40] soundwire: bus: split handling of Device0 events
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (16 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 17/40] soundwire: bus: use runtime_pm_get_sync/pm when enabled Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-08-02 16:59   ` Vinod Koul
  2019-07-25 23:40 ` [RFC PATCH 19/40] soundwire: bus: improve dynamic debug comments for enumeration Pierre-Louis Bossart
                   ` (22 subsequent siblings)
  40 siblings, 1 reply; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

Assigning a device number to a Slave will result in additional events
when it reports its status in a PING frame. There is no point in
dealing with all the other devices in a loop, this can be done when a
non-device0 event happens.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/bus.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
index 0a45dc5713df..bca378806d00 100644
--- a/drivers/soundwire/bus.c
+++ b/drivers/soundwire/bus.c
@@ -985,6 +985,11 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
 		ret = sdw_program_device_num(bus);
 		if (ret)
 			dev_err(bus->dev, "Slave attach failed: %d\n", ret);
+		/*
+		 * programming a device number will have side effects,
+		 * so we deal with other devices at a later time
+		 */
+		return ret;
 	}
 
 	/* Continue to check other slave statuses */
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 19/40] soundwire: bus: improve dynamic debug comments for enumeration
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (17 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 18/40] soundwire: bus: split handling of Device0 events Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-08-02 17:00   ` Vinod Koul
  2019-07-25 23:40 ` [RFC PATCH 20/40] soundwire: prototypes for suspend/resume Pierre-Louis Bossart
                   ` (21 subsequent siblings)
  40 siblings, 1 reply; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

update comments to provide better understanding of enumeration flows.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/bus.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
index bca378806d00..2354675ef104 100644
--- a/drivers/soundwire/bus.c
+++ b/drivers/soundwire/bus.c
@@ -483,7 +483,8 @@ static int sdw_assign_device_num(struct sdw_slave *slave)
 
 	ret = sdw_write(slave, SDW_SCP_DEVNUMBER, dev_num);
 	if (ret < 0) {
-		dev_err(&slave->dev, "Program device_num failed: %d\n", ret);
+		dev_err(&slave->dev, "Program device_num %d failed: %d\n",
+			dev_num, ret);
 		return ret;
 	}
 
@@ -540,6 +541,7 @@ static int sdw_program_device_num(struct sdw_bus *bus)
 	do {
 		ret = sdw_transfer(bus, &msg);
 		if (ret == -ENODATA) { /* end of device id reads */
+			dev_dbg(bus->dev, "No more devices to enumerate\n");
 			ret = 0;
 			break;
 		}
@@ -982,6 +984,7 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
 	int i, ret = 0;
 
 	if (status[0] == SDW_SLAVE_ATTACHED) {
+		dev_err(bus->dev, "Slave attached, programming device number\n");
 		ret = sdw_program_device_num(bus);
 		if (ret)
 			dev_err(bus->dev, "Slave attach failed: %d\n", ret);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 20/40] soundwire: prototypes for suspend/resume
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (18 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 19/40] soundwire: bus: improve dynamic debug comments for enumeration Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-07-26 10:04   ` Cezary Rojewski
  2019-08-02 17:03   ` Vinod Koul
  2019-07-25 23:40 ` [RFC PATCH 21/40] soundwire: export helpers to find row and column values Pierre-Louis Bossart
                   ` (20 subsequent siblings)
  40 siblings, 2 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/cadence_master.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/soundwire/cadence_master.h b/drivers/soundwire/cadence_master.h
index c0bf6ff00a44..d375bbfead18 100644
--- a/drivers/soundwire/cadence_master.h
+++ b/drivers/soundwire/cadence_master.h
@@ -165,6 +165,9 @@ int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns);
 
 void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root);
 
+int sdw_cdns_suspend(struct sdw_cdns *cdns);
+bool sdw_cdns_check_resume_status(struct sdw_cdns *cdns);
+
 int sdw_cdns_get_stream(struct sdw_cdns *cdns,
 			struct sdw_cdns_streams *stream,
 			u32 ch, u32 dir);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 21/40] soundwire: export helpers to find row and column values
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (19 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 20/40] soundwire: prototypes for suspend/resume Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-07-26 14:43   ` [alsa-devel] " Guennadi Liakhovetski
  2019-08-05  9:39   ` Sanyog Kale
  2019-07-25 23:40 ` [RFC PATCH 22/40] soundwire: include mod_devicetable.h to avoid compiling warnings Pierre-Louis Bossart
                   ` (19 subsequent siblings)
  40 siblings, 2 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

Add a prefix for common tables and export 2 helpers to set the frame
shapes based on row/col values.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/bus.h    |  7 +++++--
 drivers/soundwire/stream.c | 14 ++++++++------
 2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/soundwire/bus.h b/drivers/soundwire/bus.h
index 06ac4adb0074..c57c9c23f6ca 100644
--- a/drivers/soundwire/bus.h
+++ b/drivers/soundwire/bus.h
@@ -73,8 +73,11 @@ struct sdw_msg {
 
 #define SDW_DOUBLE_RATE_FACTOR		2
 
-extern int rows[SDW_FRAME_ROWS];
-extern int cols[SDW_FRAME_COLS];
+extern int sdw_rows[SDW_FRAME_ROWS];
+extern int sdw_cols[SDW_FRAME_COLS];
+
+int sdw_find_row_index(int row);
+int sdw_find_col_index(int col);
 
 /**
  * sdw_port_runtime: Runtime port parameters for Master or Slave
diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c
index a0476755a459..53f5e790fcd7 100644
--- a/drivers/soundwire/stream.c
+++ b/drivers/soundwire/stream.c
@@ -21,37 +21,39 @@
  * The rows are arranged as per the array index value programmed
  * in register. The index 15 has dummy value 0 in order to fill hole.
  */
-int rows[SDW_FRAME_ROWS] = {48, 50, 60, 64, 75, 80, 125, 147,
+int sdw_rows[SDW_FRAME_ROWS] = {48, 50, 60, 64, 75, 80, 125, 147,
 			96, 100, 120, 128, 150, 160, 250, 0,
 			192, 200, 240, 256, 72, 144, 90, 180};
 
-int cols[SDW_FRAME_COLS] = {2, 4, 6, 8, 10, 12, 14, 16};
+int sdw_cols[SDW_FRAME_COLS] = {2, 4, 6, 8, 10, 12, 14, 16};
 
-static int sdw_find_col_index(int col)
+int sdw_find_col_index(int col)
 {
 	int i;
 
 	for (i = 0; i < SDW_FRAME_COLS; i++) {
-		if (cols[i] == col)
+		if (sdw_cols[i] == col)
 			return i;
 	}
 
 	pr_warn("Requested column not found, selecting lowest column no: 2\n");
 	return 0;
 }
+EXPORT_SYMBOL(sdw_find_col_index);
 
-static int sdw_find_row_index(int row)
+int sdw_find_row_index(int row)
 {
 	int i;
 
 	for (i = 0; i < SDW_FRAME_ROWS; i++) {
-		if (rows[i] == row)
+		if (sdw_rows[i] == row)
 			return i;
 	}
 
 	pr_warn("Requested row not found, selecting lowest row no: 48\n");
 	return 0;
 }
+EXPORT_SYMBOL(sdw_find_row_index);
 
 static int _sdw_program_slave_port_params(struct sdw_bus *bus,
 					  struct sdw_slave *slave,
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 22/40] soundwire: include mod_devicetable.h to avoid compiling warnings
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (20 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 21/40] soundwire: export helpers to find row and column values Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-07-25 23:40 ` [RFC PATCH 23/40] soundwire: stream: fix disable sequence Pierre-Louis Bossart
                   ` (18 subsequent siblings)
  40 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Bard liao,
	kbuild test robot, Pierre-Louis Bossart, Sanyog Kale

From: Bard liao <yung-chuan.liao@linux.intel.com>

Reported-by: kbuild test robot <lkp@intel.com>
Signed-off-by: Bard liao <yung-chuan.liao@linux.intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 include/linux/soundwire/sdw.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
index a49028e9d666..31d1e8acf25b 100644
--- a/include/linux/soundwire/sdw.h
+++ b/include/linux/soundwire/sdw.h
@@ -4,6 +4,8 @@
 #ifndef __SOUNDWIRE_H
 #define __SOUNDWIRE_H
 
+#include <linux/mod_devicetable.h>
+
 struct sdw_bus;
 struct sdw_slave;
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 23/40] soundwire: stream: fix disable sequence
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (21 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 22/40] soundwire: include mod_devicetable.h to avoid compiling warnings Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-07-26 10:14   ` Cezary Rojewski
                     ` (2 more replies)
  2019-07-25 23:40 ` [RFC PATCH 24/40] soundwire: cadence_master: use BIOS defaults for frame shape Pierre-Louis Bossart
                   ` (17 subsequent siblings)
  40 siblings, 3 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

When we disable the stream and then call hw_free, two bank switches
will be handled and as a result we re-enable the stream on hw_free.

Make sure the stream is disabled on both banks.

TODO: we need to completely revisit all this and make sure we have a
mirroring mechanism between current and alternate banks.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/stream.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c
index 53f5e790fcd7..75b9ad1fb1a6 100644
--- a/drivers/soundwire/stream.c
+++ b/drivers/soundwire/stream.c
@@ -1637,7 +1637,24 @@ static int _sdw_disable_stream(struct sdw_stream_runtime *stream)
 		}
 	}
 
-	return do_bank_switch(stream);
+	ret = do_bank_switch(stream);
+	if (ret < 0) {
+		dev_err(bus->dev, "Bank switch failed: %d\n", ret);
+		return ret;
+	}
+
+	/* make sure alternate bank (previous current) is also disabled */
+	list_for_each_entry(m_rt, &stream->master_list, stream_node) {
+		bus = m_rt->bus;
+		/* Disable port(s) */
+		ret = sdw_enable_disable_ports(m_rt, false);
+		if (ret < 0) {
+			dev_err(bus->dev, "Disable port(s) failed: %d\n", ret);
+			return ret;
+		}
+	}
+
+	return 0;
 }
 
 /**
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 24/40] soundwire: cadence_master: use BIOS defaults for frame shape
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (22 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 23/40] soundwire: stream: fix disable sequence Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-07-26 10:20   ` Cezary Rojewski
                     ` (2 more replies)
  2019-07-25 23:40 ` [RFC PATCH 25/40] soundwire: intel: use BIOS information to set clock dividers Pierre-Louis Bossart
                   ` (16 subsequent siblings)
  40 siblings, 3 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

Remove hard-coding and use BIOS values. If they are wrong use default
48x2 frame shape.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/cadence_master.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
index 442f78c00f09..d84344e29f71 100644
--- a/drivers/soundwire/cadence_master.c
+++ b/drivers/soundwire/cadence_master.c
@@ -175,7 +175,6 @@
 /* Driver defaults */
 
 #define CDNS_DEFAULT_CLK_DIVIDER		0
-#define CDNS_DEFAULT_FRAME_SHAPE		0x30
 #define CDNS_DEFAULT_SSP_INTERVAL		0x18
 #define CDNS_TX_TIMEOUT				2000
 
@@ -954,6 +953,20 @@ int sdw_cdns_pdi_init(struct sdw_cdns *cdns,
 }
 EXPORT_SYMBOL(sdw_cdns_pdi_init);
 
+static u32 cdns_set_default_frame_shape(int n_rows, int n_cols)
+{
+	u32 val;
+	int c;
+	int r;
+
+	r = sdw_find_row_index(n_rows);
+	c = sdw_find_col_index(n_cols);
+
+	val = (r << 3) | c;
+
+	return val;
+}
+
 /**
  * sdw_cdns_init() - Cadence initialization
  * @cdns: Cadence instance
@@ -977,7 +990,9 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
 	cdns_writel(cdns, CDNS_MCP_CLK_CTRL0, val);
 
 	/* Set the default frame shape */
-	cdns_writel(cdns, CDNS_MCP_FRAME_SHAPE_INIT, CDNS_DEFAULT_FRAME_SHAPE);
+	val = cdns_set_default_frame_shape(prop->default_row,
+					   prop->default_col);
+	cdns_writel(cdns, CDNS_MCP_FRAME_SHAPE_INIT, val);
 
 	/* Set SSP interval to default value */
 	cdns_writel(cdns, CDNS_MCP_SSP_CTRL0, CDNS_DEFAULT_SSP_INTERVAL);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 25/40] soundwire: intel: use BIOS information to set clock dividers
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (23 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 24/40] soundwire: cadence_master: use BIOS defaults for frame shape Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-08-02 17:17   ` Vinod Koul
  2019-08-05 10:28   ` Sanyog Kale
  2019-07-25 23:40 ` [RFC PATCH 26/40] soundwire: cadence_master: fix divider setting in clock register Pierre-Louis Bossart
                   ` (15 subsequent siblings)
  40 siblings, 2 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

The BIOS provides an Intel-specific property, let's use it to avoid
hard-coded clock dividers.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/cadence_master.c | 26 ++++++++++++++++++++++----
 drivers/soundwire/intel.c          | 26 ++++++++++++++++++++++++++
 include/linux/soundwire/sdw.h      |  2 ++
 3 files changed, 50 insertions(+), 4 deletions(-)

diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
index d84344e29f71..10ebcef2e84e 100644
--- a/drivers/soundwire/cadence_master.c
+++ b/drivers/soundwire/cadence_master.c
@@ -173,8 +173,6 @@
 #define CDNS_PDI_CONFIG_PORT			GENMASK(4, 0)
 
 /* Driver defaults */
-
-#define CDNS_DEFAULT_CLK_DIVIDER		0
 #define CDNS_DEFAULT_SSP_INTERVAL		0x18
 #define CDNS_TX_TIMEOUT				2000
 
@@ -973,7 +971,10 @@ static u32 cdns_set_default_frame_shape(int n_rows, int n_cols)
  */
 int sdw_cdns_init(struct sdw_cdns *cdns)
 {
+	struct sdw_bus *bus = &cdns->bus;
+	struct sdw_master_prop *prop = &bus->prop;
 	u32 val;
+	int divider;
 	int ret;
 
 	/* Exit clock stop */
@@ -985,9 +986,17 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
 	}
 
 	/* Set clock divider */
+	divider	= (prop->mclk_freq / prop->max_clk_freq) - 1;
 	val = cdns_readl(cdns, CDNS_MCP_CLK_CTRL0);
-	val |= CDNS_DEFAULT_CLK_DIVIDER;
+	val |= divider;
 	cdns_writel(cdns, CDNS_MCP_CLK_CTRL0, val);
+	cdns_writel(cdns, CDNS_MCP_CLK_CTRL1, val);
+
+	pr_err("plb: mclk %d max_freq %d divider %d register %x\n",
+	       prop->mclk_freq,
+	       prop->max_clk_freq,
+	       divider,
+	       val);
 
 	/* Set the default frame shape */
 	val = cdns_set_default_frame_shape(prop->default_row,
@@ -1035,6 +1044,7 @@ EXPORT_SYMBOL(sdw_cdns_init);
 
 int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params)
 {
+	struct sdw_master_prop *prop = &bus->prop;
 	struct sdw_cdns *cdns = bus_to_cdns(bus);
 	int mcp_clkctrl_off, mcp_clkctrl;
 	int divider;
@@ -1044,7 +1054,9 @@ int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params)
 		return -EINVAL;
 	}
 
-	divider	= (params->max_dr_freq / params->curr_dr_freq) - 1;
+	divider	= prop->mclk_freq * SDW_DOUBLE_RATE_FACTOR /
+		params->curr_dr_freq;
+	divider--; /* divider is 1/(N+1) */
 
 	if (params->next_bank)
 		mcp_clkctrl_off = CDNS_MCP_CLK_CTRL1;
@@ -1055,6 +1067,12 @@ int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params)
 	mcp_clkctrl |= divider;
 	cdns_writel(cdns, mcp_clkctrl_off, mcp_clkctrl);
 
+	pr_err("plb: mclk * 2 %d curr_dr_freq %d divider %d register %x\n",
+	       prop->mclk_freq * SDW_DOUBLE_RATE_FACTOR,
+	       params->curr_dr_freq,
+	       divider,
+	       mcp_clkctrl);
+
 	return 0;
 }
 EXPORT_SYMBOL(cdns_bus_conf);
diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
index c718c9c67a37..796ac2bc8cea 100644
--- a/drivers/soundwire/intel.c
+++ b/drivers/soundwire/intel.c
@@ -917,11 +917,37 @@ static int intel_register_dai(struct sdw_intel *sdw)
 					  dais, num_dai);
 }
 
+static int sdw_master_read_intel_prop(struct sdw_bus *bus)
+{
+	struct sdw_master_prop *prop = &bus->prop;
+	struct fwnode_handle *link;
+	char name[32];
+	int nval, i;
+
+	/* Find master handle */
+	snprintf(name, sizeof(name),
+		 "mipi-sdw-link-%d-subproperties", bus->link_id);
+
+	link = device_get_named_child_node(bus->dev, name);
+	if (!link) {
+		dev_err(bus->dev, "Master node %s not found\n", name);
+		return -EIO;
+	}
+
+	fwnode_property_read_u32(link,
+				 "intel-sdw-ip-clock",
+				 &prop->mclk_freq);
+	return 0;
+}
+
 static int intel_prop_read(struct sdw_bus *bus)
 {
 	/* Initialize with default handler to read all DisCo properties */
 	sdw_master_read_prop(bus);
 
+	/* read Intel-specific properties */
+	sdw_master_read_intel_prop(bus);
+
 	return 0;
 }
 
diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
index 31d1e8acf25b..b6acc436ac80 100644
--- a/include/linux/soundwire/sdw.h
+++ b/include/linux/soundwire/sdw.h
@@ -379,6 +379,7 @@ struct sdw_slave_prop {
  * @dynamic_frame: Dynamic frame shape supported
  * @err_threshold: Number of times that software may retry sending a single
  * command
+ * @mclk_freq: clock reference passed to SoundWire Master, in Hz.
  */
 struct sdw_master_prop {
 	u32 revision;
@@ -393,6 +394,7 @@ struct sdw_master_prop {
 	u32 default_col;
 	bool dynamic_frame;
 	u32 err_threshold;
+	u32 mclk_freq;
 };
 
 int sdw_master_read_prop(struct sdw_bus *bus);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 26/40] soundwire: cadence_master: fix divider setting in clock register
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (24 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 25/40] soundwire: intel: use BIOS information to set clock dividers Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-07-26  5:19   ` [alsa-devel] " Bard liao
                     ` (2 more replies)
  2019-07-25 23:40 ` [RFC PATCH 27/40] soundwire: Add Intel resource management algorithm Pierre-Louis Bossart
                   ` (14 subsequent siblings)
  40 siblings, 3 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Rander Wang,
	Pierre-Louis Bossart, Sanyog Kale

From: Rander Wang <rander.wang@linux.intel.com>

The existing code uses an OR operation which would mix the original
divider setting with the new one, resulting in an invalid
configuration that can make codecs hang.

Add the mask definition and use cdns_updatel to update divider

Signed-off-by: Rander Wang <rander.wang@linux.intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/cadence_master.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
index 10ebcef2e84e..18c6ac026e85 100644
--- a/drivers/soundwire/cadence_master.c
+++ b/drivers/soundwire/cadence_master.c
@@ -57,6 +57,7 @@
 #define CDNS_MCP_SSP_CTRL1			0x28
 #define CDNS_MCP_CLK_CTRL0			0x30
 #define CDNS_MCP_CLK_CTRL1			0x38
+#define CDNS_MCP_CLK_MCLKD_MASK		GENMASK(7, 0)
 
 #define CDNS_MCP_STAT				0x40
 
@@ -988,9 +989,11 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
 	/* Set clock divider */
 	divider	= (prop->mclk_freq / prop->max_clk_freq) - 1;
 	val = cdns_readl(cdns, CDNS_MCP_CLK_CTRL0);
-	val |= divider;
-	cdns_writel(cdns, CDNS_MCP_CLK_CTRL0, val);
-	cdns_writel(cdns, CDNS_MCP_CLK_CTRL1, val);
+
+	cdns_updatel(cdns, CDNS_MCP_CLK_CTRL0,
+		     CDNS_MCP_CLK_MCLKD_MASK, divider);
+	cdns_updatel(cdns, CDNS_MCP_CLK_CTRL1,
+		     CDNS_MCP_CLK_MCLKD_MASK, divider);
 
 	pr_err("plb: mclk %d max_freq %d divider %d register %x\n",
 	       prop->mclk_freq,
@@ -1064,8 +1067,7 @@ int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params)
 		mcp_clkctrl_off = CDNS_MCP_CLK_CTRL0;
 
 	mcp_clkctrl = cdns_readl(cdns, mcp_clkctrl_off);
-	mcp_clkctrl |= divider;
-	cdns_writel(cdns, mcp_clkctrl_off, mcp_clkctrl);
+	cdns_updatel(cdns, mcp_clkctrl_off, CDNS_MCP_CLK_MCLKD_MASK, divider);
 
 	pr_err("plb: mclk * 2 %d curr_dr_freq %d divider %d register %x\n",
 	       prop->mclk_freq * SDW_DOUBLE_RATE_FACTOR,
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 27/40] soundwire: Add Intel resource management algorithm
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (25 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 26/40] soundwire: cadence_master: fix divider setting in clock register Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-07-26 11:07   ` Cezary Rojewski
                     ` (2 more replies)
  2019-07-25 23:40 ` [RFC PATCH 28/40] soundwire: intel: handle disabled links Pierre-Louis Bossart
                   ` (13 subsequent siblings)
  40 siblings, 3 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

This algorithm computes bus parameters like clock frequency, frame
shape and port transport parameters based on active stream(s) running
on the bus.

This implementation is optimal for Intel platforms. Developers can
also implement their own .compute_params() callback for specific
resource management algorithm.

Credits: this patch is based on an earlier internal contribution by
Vinod Koul, Sanyog Kale, Shreyas Nc and Hardik Shah. All hard-coded
values were removed from the initial contribution to use BIOS
information instead.

FIXME: remove checkpatch report
WARNING: Reusing the krealloc arg is almost always a bug
+			group->rates = krealloc(group->rates,

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/Makefile                  |   2 +-
 drivers/soundwire/algo_dynamic_allocation.c | 403 ++++++++++++++++++++
 drivers/soundwire/bus.c                     |   3 +
 drivers/soundwire/bus.h                     |  46 ++-
 drivers/soundwire/stream.c                  |  20 +
 include/linux/soundwire/sdw.h               |   5 +
 6 files changed, 476 insertions(+), 3 deletions(-)
 create mode 100644 drivers/soundwire/algo_dynamic_allocation.c

diff --git a/drivers/soundwire/Makefile b/drivers/soundwire/Makefile
index 88990cac48a7..f59a9d4a28fd 100644
--- a/drivers/soundwire/Makefile
+++ b/drivers/soundwire/Makefile
@@ -5,7 +5,7 @@
 
 #Bus Objs
 soundwire-bus-objs := bus_type.o bus.o slave.o mipi_disco.o stream.o \
-			debugfs.o
+			debugfs.o algo_dynamic_allocation.o
 
 obj-$(CONFIG_SOUNDWIRE_BUS) += soundwire-bus.o
 
diff --git a/drivers/soundwire/algo_dynamic_allocation.c b/drivers/soundwire/algo_dynamic_allocation.c
new file mode 100644
index 000000000000..89edb39162b8
--- /dev/null
+++ b/drivers/soundwire/algo_dynamic_allocation.c
@@ -0,0 +1,403 @@
+// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
+// Copyright(c) 2015-18 Intel Corporation.
+
+/*
+ * Bandwidth management algorithm based on 2^n gears
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/mod_devicetable.h>
+#include <linux/slab.h>
+#include <linux/soundwire/sdw.h>
+#include "bus.h"
+
+#define SDW_STRM_RATE_GROUPING		1
+
+struct sdw_group_params {
+	unsigned int rate;
+	int full_bw;
+	int payload_bw;
+	int hwidth;
+};
+
+struct sdw_group {
+	unsigned int count;
+	unsigned int max_size;
+	unsigned int *rates;
+};
+
+struct sdw_transport_data {
+	int hstart;
+	int hstop;
+	int block_offset;
+	int sub_block_offset;
+};
+
+static void sdw_compute_slave_ports(struct sdw_master_runtime *m_rt,
+				    struct sdw_transport_data *t_data)
+{
+	struct sdw_slave_runtime *s_rt = NULL;
+	struct sdw_port_runtime *p_rt;
+	int port_bo, sample_int;
+	unsigned int rate, bps, ch = 0;
+
+	port_bo = t_data->block_offset;
+
+	list_for_each_entry(s_rt, &m_rt->slave_rt_list, m_rt_node) {
+		rate = m_rt->stream->params.rate;
+		bps = m_rt->stream->params.bps;
+		sample_int = (m_rt->bus->params.curr_dr_freq / rate);
+
+		list_for_each_entry(p_rt, &s_rt->port_list, port_node) {
+			ch = sdw_ch_mask_to_ch(p_rt->ch_mask);
+
+			sdw_fill_xport_params(&p_rt->transport_params,
+					      p_rt->num, true,
+					      SDW_BLK_GRP_CNT_1,
+					      sample_int, port_bo, port_bo >> 8,
+					      t_data->hstart,
+					      t_data->hstop,
+					      (SDW_BLK_GRP_CNT_1 * ch), 0x0);
+
+			sdw_fill_port_params(&p_rt->port_params,
+					     p_rt->num, bps,
+					     SDW_PORT_FLOW_MODE_ISOCH,
+					     SDW_PORT_DATA_MODE_NORMAL);
+
+			port_bo += bps * ch;
+		}
+	}
+}
+
+static void sdw_compute_master_ports(struct sdw_master_runtime *m_rt,
+				     struct sdw_group_params *params,
+				     int port_bo, int hstop)
+{
+	struct sdw_transport_data t_data = {0};
+	struct sdw_port_runtime *p_rt;
+	struct sdw_bus *bus = m_rt->bus;
+	int sample_int, hstart = 0;
+	unsigned int rate, bps, ch, no_ch;
+
+	rate = m_rt->stream->params.rate;
+	bps = m_rt->stream->params.bps;
+	ch = m_rt->ch_count;
+	sample_int = (bus->params.curr_dr_freq / rate);
+
+	if (rate != params->rate)
+		return;
+
+	t_data.hstop = hstop;
+	hstart = hstop - params->hwidth + 1;
+	t_data.hstart = hstart;
+
+	list_for_each_entry(p_rt, &m_rt->port_list, port_node) {
+		no_ch = sdw_ch_mask_to_ch(p_rt->ch_mask);
+
+		sdw_fill_xport_params(&p_rt->transport_params, p_rt->num,
+				      true, SDW_BLK_GRP_CNT_1, sample_int,
+				      port_bo, port_bo >> 8, hstart, hstop,
+				      (SDW_BLK_GRP_CNT_1 * no_ch), 0x0);
+
+		sdw_fill_port_params(&p_rt->port_params,
+				     p_rt->num, bps,
+				     SDW_PORT_FLOW_MODE_ISOCH,
+				     SDW_PORT_DATA_MODE_NORMAL);
+
+		/* Check for first entry */
+		if (!(p_rt == list_first_entry(&m_rt->port_list,
+					       struct sdw_port_runtime,
+					       port_node))) {
+			port_bo += bps * ch;
+			continue;
+		}
+
+		t_data.hstart = hstart;
+		t_data.hstop = hstop;
+		t_data.block_offset = port_bo;
+		t_data.sub_block_offset = 0;
+		port_bo += bps * ch;
+	}
+
+	sdw_compute_slave_ports(m_rt, &t_data);
+}
+
+static void _sdw_compute_port_params(struct sdw_bus *bus,
+				     struct sdw_group_params *params, int count)
+{
+	struct sdw_master_runtime *m_rt = NULL;
+	int hstop = bus->params.col - 1;
+	int block_offset, port_bo, i;
+
+	/* Run loop for all groups to compute transport parameters */
+	for (i = 0; i < count; i++) {
+		port_bo = 1;
+		block_offset = 1;
+
+		list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
+			sdw_compute_master_ports(m_rt, &params[i],
+						 port_bo, hstop);
+
+			block_offset += m_rt->ch_count *
+					m_rt->stream->params.bps;
+			port_bo = block_offset;
+		}
+
+		hstop = hstop - params[i].hwidth;
+	}
+}
+
+static int sdw_compute_group_params(struct sdw_bus *bus,
+				    struct sdw_group_params *params,
+				    int *rates, int count)
+{
+	struct sdw_master_runtime *m_rt = NULL;
+	int sel_col = bus->params.col;
+	unsigned int rate, bps, ch;
+	int i, column_needed = 0;
+
+	/* Calculate bandwidth per group */
+	for (i = 0; i < count; i++) {
+		params[i].rate = rates[i];
+		params[i].full_bw = bus->params.curr_dr_freq / params[i].rate;
+	}
+
+	list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
+		rate = m_rt->stream->params.rate;
+		bps = m_rt->stream->params.bps;
+		ch = m_rt->ch_count;
+
+		for (i = 0; i < count; i++) {
+			if (rate == params[i].rate)
+				params[i].payload_bw += bps * ch;
+		}
+	}
+
+	for (i = 0; i < count; i++) {
+		params[i].hwidth = (sel_col *
+			params[i].payload_bw + params[i].full_bw - 1) /
+			params[i].full_bw;
+
+		column_needed += params[i].hwidth;
+	}
+
+	if (column_needed > sel_col - 1)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int sdw_add_element_group_count(struct sdw_group *group,
+				       unsigned int rate)
+{
+	int num = group->count;
+	int i;
+
+	for (i = 0; i <= num; i++) {
+		if (rate == group->rates[i])
+			break;
+
+		if (i != num)
+			continue;
+
+		if (group->count >= group->max_size) {
+			group->max_size += 1;
+			group->rates = krealloc(group->rates,
+						(sizeof(int) * group->max_size),
+						GFP_KERNEL);
+			if (!group->rates)
+				return -ENOMEM;
+		}
+
+		group->rates[group->count++] = rate;
+	}
+
+	return 0;
+}
+
+static int sdw_get_group_count(struct sdw_bus *bus,
+			       struct sdw_group *group)
+{
+	struct sdw_master_runtime *m_rt;
+	unsigned int rate;
+	int ret = 0;
+
+	group->count = 0;
+	group->max_size = SDW_STRM_RATE_GROUPING;
+	group->rates = kcalloc(group->max_size, sizeof(int), GFP_KERNEL);
+	if (!group->rates)
+		return -ENOMEM;
+
+	list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
+		rate = m_rt->stream->params.rate;
+		if (m_rt == list_first_entry(&bus->m_rt_list,
+					     struct sdw_master_runtime,
+					     bus_node)) {
+			group->rates[group->count++] = rate;
+
+		} else {
+			ret = sdw_add_element_group_count(group, rate);
+			if (ret < 0)
+				return ret;
+		}
+	}
+
+	return ret;
+}
+
+/**
+ * sdw_compute_port_params: Compute transport and port parameters
+ *
+ * @bus: SDW Bus instance
+ */
+static int sdw_compute_port_params(struct sdw_bus *bus)
+{
+	struct sdw_group_params *params = NULL;
+	struct sdw_group group;
+	int ret;
+
+	ret = sdw_get_group_count(bus, &group);
+	if (ret < 0)
+		goto out;
+
+	if (group.count == 0)
+		goto out;
+
+	params = kcalloc(group.count, sizeof(*params), GFP_KERNEL);
+	if (!params) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* Compute transport parameters for grouped streams */
+	ret = sdw_compute_group_params(bus, params,
+				       &group.rates[0], group.count);
+	if (ret < 0)
+		goto out;
+
+	_sdw_compute_port_params(bus, params, group.count);
+
+out:
+	kfree(params);
+	kfree(group.rates);
+
+	return ret;
+}
+
+static int sdw_select_row_col(struct sdw_bus *bus, int clk_freq)
+{
+	struct sdw_master_prop *prop = &bus->prop;
+	int frame_int, frame_freq;
+	int r, c;
+
+	for (c = 0; c < SDW_FRAME_COLS; c++) {
+		for (r = 0; r < SDW_FRAME_ROWS; r++) {
+			if (sdw_rows[r] != prop->default_row ||
+			    sdw_cols[c] != prop->default_col)
+				continue;
+
+			frame_int = sdw_rows[r] * sdw_cols[c];
+			frame_freq = clk_freq / frame_int;
+
+			if ((clk_freq - (frame_freq * SDW_FRAME_CTRL_BITS)) <
+			    bus->params.bandwidth)
+				continue;
+
+			bus->params.row = sdw_rows[r];
+			bus->params.col = sdw_cols[c];
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
+/**
+ * sdw_compute_bus_params: Compute bus parameters
+ *
+ * @bus: SDW Bus instance
+ */
+static int sdw_compute_bus_params(struct sdw_bus *bus)
+{
+	unsigned int max_dr_freq, curr_dr_freq = 0;
+	struct sdw_master_prop *mstr_prop = NULL;
+	int i, clk_values, ret;
+	bool is_gear = false;
+	u32 *clk_buf;
+
+	mstr_prop = &bus->prop;
+	if (!mstr_prop)
+		return -EINVAL;
+
+	if (mstr_prop->num_clk_gears) {
+		clk_values = mstr_prop->num_clk_gears;
+		clk_buf = mstr_prop->clk_gears;
+		is_gear = true;
+	} else if (mstr_prop->num_clk_freq) {
+		clk_values = mstr_prop->num_clk_freq;
+		clk_buf = mstr_prop->clk_freq;
+	} else {
+		clk_values = 1;
+		clk_buf = NULL;
+	}
+
+	max_dr_freq = mstr_prop->max_clk_freq * SDW_DOUBLE_RATE_FACTOR;
+
+	for (i = 0; i < clk_values; i++) {
+		if (!clk_buf)
+			curr_dr_freq = max_dr_freq;
+		else
+			curr_dr_freq = (is_gear) ?
+				(max_dr_freq >>  clk_buf[i]) :
+				clk_buf[i] * SDW_DOUBLE_RATE_FACTOR;
+
+		if (curr_dr_freq <= bus->params.bandwidth)
+			continue;
+
+		break;
+
+		/*
+		 * TODO: Check all the Slave(s) port(s) audio modes and find
+		 * whether given clock rate is supported with glitchless
+		 * transition.
+		 */
+	}
+
+	if (i == clk_values)
+		return -EINVAL;
+
+	ret = sdw_select_row_col(bus, curr_dr_freq);
+	if (ret < 0)
+		return -EINVAL;
+
+	bus->params.curr_dr_freq = curr_dr_freq;
+	return 0;
+}
+
+/**
+ * sdw_compute_params: Compute bus, transport and port parameters
+ *
+ * @bus: SDW Bus instance
+ */
+int sdw_compute_params(struct sdw_bus *bus)
+{
+	int ret;
+
+	/* Computes clock frequency, frame shape and frame frequency */
+	ret = sdw_compute_bus_params(bus);
+	if (ret < 0) {
+		dev_err(bus->dev, "Compute bus params failed: %d", ret);
+		return ret;
+	}
+
+	/* Compute transport and port params */
+	ret = sdw_compute_port_params(bus);
+	if (ret < 0) {
+		dev_err(bus->dev, "Compute transport params failed: %d", ret);
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(sdw_compute_params);
diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
index 2354675ef104..76a180578712 100644
--- a/drivers/soundwire/bus.c
+++ b/drivers/soundwire/bus.c
@@ -51,6 +51,9 @@ int sdw_add_bus_master(struct sdw_bus *bus)
 
 	bus->debugfs = sdw_bus_debugfs_init(bus);
 
+	if (!bus->compute_params)
+		bus->compute_params = &sdw_compute_params;
+
 	/*
 	 * Device numbers in SoundWire are 0 through 15. Enumeration device
 	 * number (0), Broadcast device number (15), Group numbers (12 and
diff --git a/drivers/soundwire/bus.h b/drivers/soundwire/bus.h
index c57c9c23f6ca..fdb7ce034fdf 100644
--- a/drivers/soundwire/bus.h
+++ b/drivers/soundwire/bus.h
@@ -72,6 +72,7 @@ struct sdw_msg {
 };
 
 #define SDW_DOUBLE_RATE_FACTOR		2
+#define SDW_STRM_RATE_GROUPING		1
 
 extern int sdw_rows[SDW_FRAME_ROWS];
 extern int sdw_cols[SDW_FRAME_COLS];
@@ -157,9 +158,50 @@ int sdw_transfer_defer(struct sdw_bus *bus, struct sdw_msg *msg,
 int sdw_fill_msg(struct sdw_msg *msg, struct sdw_slave *slave,
 		 u32 addr, size_t count, u16 dev_num, u8 flags, u8 *buf);
 
+/* Retrieve and return channel count from channel mask */
+static inline int sdw_ch_mask_to_ch(int ch_mask)
+{
+	int c = 0;
+
+	for (c = 0; ch_mask; ch_mask >>= 1)
+		c += ch_mask & 1;
+
+	return c;
+}
+
+/* Fill transport parameter data structure */
+static inline void sdw_fill_xport_params(struct sdw_transport_params *params,
+					 int port_num, bool grp_ctrl_valid,
+					 int grp_ctrl, int sample_int,
+					 int off1, int off2,
+					 int hstart, int hstop,
+					 int pack_mode, int lane_ctrl)
+{
+	params->port_num = port_num;
+	params->blk_grp_ctrl_valid = grp_ctrl_valid;
+	params->blk_grp_ctrl = grp_ctrl;
+	params->sample_interval = sample_int;
+	params->offset1 = off1;
+	params->offset2 = off2;
+	params->hstart = hstart;
+	params->hstop = hstop;
+	params->blk_pkg_mode = pack_mode;
+	params->lane_ctrl = lane_ctrl;
+}
+
+/* Fill port parameter data structure */
+static inline void sdw_fill_port_params(struct sdw_port_params *params,
+					int port_num, int bps,
+					int flow_mode, int data_mode)
+{
+	params->num = port_num;
+	params->bps = bps;
+	params->flow_mode = flow_mode;
+	params->data_mode = data_mode;
+}
+
 /* Read-Modify-Write Slave register */
-static inline int
-sdw_update(struct sdw_slave *slave, u32 addr, u8 mask, u8 val)
+static inline int sdw_update(struct sdw_slave *slave, u32 addr, u8 mask, u8 val)
 {
 	int tmp;
 
diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c
index 75b9ad1fb1a6..add7c121d084 100644
--- a/drivers/soundwire/stream.c
+++ b/drivers/soundwire/stream.c
@@ -1485,6 +1485,16 @@ static int _sdw_prepare_stream(struct sdw_stream_runtime *stream)
 		bus->params.bandwidth += m_rt->stream->params.rate *
 			m_rt->ch_count * m_rt->stream->params.bps;
 
+		/* Compute params */
+		if (bus->compute_params) {
+			ret = bus->compute_params(bus);
+			if (ret < 0) {
+				dev_err(bus->dev,
+					"Compute params failed: %d", ret);
+				return ret;
+			}
+		}
+
 		/* Program params */
 		ret = sdw_program_params(bus);
 		if (ret < 0) {
@@ -1704,6 +1714,16 @@ static int _sdw_deprepare_stream(struct sdw_stream_runtime *stream)
 		bus->params.bandwidth -= m_rt->stream->params.rate *
 			m_rt->ch_count * m_rt->stream->params.bps;
 
+		/* Compute params */
+		if (bus->compute_params) {
+			ret = bus->compute_params(bus);
+			if (ret < 0) {
+				dev_err(bus->dev,
+					"Compute params failed: %d", ret);
+				return ret;
+			}
+		}
+
 		/* Program params */
 		ret = sdw_program_params(bus);
 		if (ret < 0) {
diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
index b6acc436ac80..c7dfc824be80 100644
--- a/include/linux/soundwire/sdw.h
+++ b/include/linux/soundwire/sdw.h
@@ -730,6 +730,7 @@ struct sdw_master_ops {
  * Bit set implies used number, bit clear implies unused number.
  * @bus_lock: bus lock
  * @msg_lock: message lock
+ * @compute_params: points to Bus resource management implementation
  * @ops: Master callback ops
  * @port_ops: Master port callback ops
  * @params: Current bus parameters
@@ -752,6 +753,7 @@ struct sdw_bus {
 	DECLARE_BITMAP(assigned, SDW_MAX_DEVICES);
 	struct mutex bus_lock;
 	struct mutex msg_lock;
+	int (*compute_params)(struct sdw_bus *bus);
 	const struct sdw_master_ops *ops;
 	const struct sdw_master_port_ops *port_ops;
 	struct sdw_bus_params params;
@@ -852,6 +854,9 @@ struct sdw_stream_runtime {
 
 struct sdw_stream_runtime *sdw_alloc_stream(char *stream_name);
 void sdw_release_stream(struct sdw_stream_runtime *stream);
+
+int sdw_compute_params(struct sdw_bus *bus);
+
 int sdw_stream_add_master(struct sdw_bus *bus,
 		struct sdw_stream_config *stream_config,
 		struct sdw_port_config *port_config,
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 28/40] soundwire: intel: handle disabled links
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (26 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 27/40] soundwire: Add Intel resource management algorithm Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-08-05 16:57   ` Sanyog Kale
  2019-07-25 23:40 ` [RFC PATCH 29/40] soundwire: intel_init: add kernel module parameter to filter out links Pierre-Louis Bossart
                   ` (12 subsequent siblings)
  40 siblings, 1 reply; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

On most hardware platforms, SoundWire interfaces are pin-muxed with
other interfaces (typically DMIC or I2S) and the status of each link
needs to be checked at boot time.

For Intel platforms, the BIOS provides a menu to enable/disable the
links separately, and the information is provided to the OS with an
Intel-specific _DSD property. The same capability will be added to
revisions of the MIPI DisCo specification.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/intel.c     | 26 ++++++++++++++++++++++----
 include/linux/soundwire/sdw.h |  2 ++
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
index 796ac2bc8cea..5947fa8e840b 100644
--- a/drivers/soundwire/intel.c
+++ b/drivers/soundwire/intel.c
@@ -90,6 +90,8 @@
 #define SDW_ALH_STRMZCFG_DMAT		GENMASK(7, 0)
 #define SDW_ALH_STRMZCFG_CHN		GENMASK(19, 16)
 
+#define SDW_INTEL_QUIRK_MASK_BUS_DISABLE	BIT(1)
+
 enum intel_pdi_type {
 	INTEL_PDI_IN = 0,
 	INTEL_PDI_OUT = 1,
@@ -922,7 +924,7 @@ static int sdw_master_read_intel_prop(struct sdw_bus *bus)
 	struct sdw_master_prop *prop = &bus->prop;
 	struct fwnode_handle *link;
 	char name[32];
-	int nval, i;
+	u32 quirk_mask;
 
 	/* Find master handle */
 	snprintf(name, sizeof(name),
@@ -937,6 +939,14 @@ static int sdw_master_read_intel_prop(struct sdw_bus *bus)
 	fwnode_property_read_u32(link,
 				 "intel-sdw-ip-clock",
 				 &prop->mclk_freq);
+
+	fwnode_property_read_u32(link,
+				 "intel-quirk-mask",
+				 &quirk_mask);
+
+	if (quirk_mask & SDW_INTEL_QUIRK_MASK_BUS_DISABLE)
+		prop->hw_disabled = true;
+
 	return 0;
 }
 
@@ -997,6 +1007,12 @@ static int intel_probe(struct platform_device *pdev)
 		goto err_master_reg;
 	}
 
+	if (sdw->cdns.bus.prop.hw_disabled) {
+		dev_info(&pdev->dev, "SoundWire master %d is disabled, ignoring\n",
+			 sdw->cdns.bus.link_id);
+		return 0;
+	}
+
 	/* Initialize shim and controller */
 	intel_link_power_up(sdw);
 	intel_shim_init(sdw);
@@ -1050,9 +1066,11 @@ static int intel_remove(struct platform_device *pdev)
 
 	sdw = platform_get_drvdata(pdev);
 
-	intel_debugfs_exit(sdw);
-	free_irq(sdw->res->irq, sdw);
-	snd_soc_unregister_component(sdw->cdns.dev);
+	if (!sdw->cdns.bus.prop.hw_disabled) {
+		intel_debugfs_exit(sdw);
+		free_irq(sdw->res->irq, sdw);
+		snd_soc_unregister_component(sdw->cdns.dev);
+	}
 	sdw_delete_bus_master(&sdw->cdns.bus);
 
 	return 0;
diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
index c7dfc824be80..f78b076a8782 100644
--- a/include/linux/soundwire/sdw.h
+++ b/include/linux/soundwire/sdw.h
@@ -380,6 +380,7 @@ struct sdw_slave_prop {
  * @err_threshold: Number of times that software may retry sending a single
  * command
  * @mclk_freq: clock reference passed to SoundWire Master, in Hz.
+ * @hw_disabled: if true, the Master is not functional, typically due to pin-mux
  */
 struct sdw_master_prop {
 	u32 revision;
@@ -395,6 +396,7 @@ struct sdw_master_prop {
 	bool dynamic_frame;
 	u32 err_threshold;
 	u32 mclk_freq;
+	bool hw_disabled;
 };
 
 int sdw_master_read_prop(struct sdw_bus *bus);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 29/40] soundwire: intel_init: add kernel module parameter to filter out links
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (27 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 28/40] soundwire: intel: handle disabled links Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-07-26 10:30   ` Cezary Rojewski
  2019-07-25 23:40 ` [RFC PATCH 30/40] soundwire: cadence_master: add kernel parameter to override interrupt mask Pierre-Louis Bossart
                   ` (11 subsequent siblings)
  40 siblings, 1 reply; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

The hardware and ACPI info may report the presence of links that are
not physically enabled (e.g. due to pin-muxing or hardware reworks),
which in turn can result in errors being thrown. This shouldn't be the
case for production devices but will happen a lot on development
devices - even more so when they expose a connector.

Add a module parameter to filter out such links, e.g. adding the
following config to a file in /etc/modprobe.d will select the second
and third links only.

options soundwire_intel_init sdw_link_mask=0x6

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/intel_init.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/soundwire/intel_init.c b/drivers/soundwire/intel_init.c
index 70637a0383d2..6ae8bb13f907 100644
--- a/drivers/soundwire/intel_init.c
+++ b/drivers/soundwire/intel_init.c
@@ -22,6 +22,10 @@
 #define SDW_LINK_BASE		0x30000
 #define SDW_LINK_SIZE		0x10000
 
+static int link_mask;
+module_param_named(sdw_link_mask, link_mask, int, 0444);
+MODULE_PARM_DESC(sdw_link_mask, "Intel link mask (one bit per link)");
+
 struct sdw_link_data {
 	struct sdw_intel_link_res res;
 	struct platform_device *pdev;
@@ -83,6 +87,9 @@ static struct sdw_intel_ctx
 	caps = ioread32(res->mmio_base + SDW_SHIM_BASE + SDW_SHIM_LCAP);
 	caps &= GENMASK(2, 0);
 
+	dev_dbg(&adev->dev, "SoundWire links: BIOS count %d hardware caps %d\n",
+		count, caps);
+
 	/* Check HW supported vs property value and use min of two */
 	count = min_t(u8, caps, count);
 
@@ -111,6 +118,13 @@ static struct sdw_intel_ctx
 
 	/* Create SDW Master devices */
 	for (i = 0; i < count; i++) {
+		if (link_mask && !(link_mask & BIT(i))) {
+			dev_dbg(&adev->dev,
+				"Link %d masked, will not be enabled\n", i);
+			link++;
+			continue;
+		}
+
 		link->res.irq = res->irq;
 		link->res.registers = res->mmio_base + SDW_LINK_BASE
 					+ (SDW_LINK_SIZE * i);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 30/40] soundwire: cadence_master: add kernel parameter to override interrupt mask
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (28 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 29/40] soundwire: intel_init: add kernel module parameter to filter out links Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-07-25 23:40 ` [RFC PATCH 31/40] soundwire: intel: move shutdown() callback and don't export symbol Pierre-Louis Bossart
                   ` (10 subsequent siblings)
  40 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

The code has a set of defaults which may not be relevant in all cases,
add kernel parameter as a helper - mostly for early board bring-up.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/cadence_master.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
index 18c6ac026e85..dede55072191 100644
--- a/drivers/soundwire/cadence_master.c
+++ b/drivers/soundwire/cadence_master.c
@@ -20,6 +20,10 @@
 #include "bus.h"
 #include "cadence_master.h"
 
+static int interrupt_mask;
+module_param_named(cnds_mcp_int_mask, interrupt_mask, int, 0444);
+MODULE_PARM_DESC(cdns_mcp_int_mask, "Cadence MCP IntMask");
+
 #define CDNS_MCP_CONFIG				0x0
 
 #define CDNS_MCP_CONFIG_MCMD_RETRY		GENMASK(27, 24)
@@ -830,6 +834,9 @@ int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
 	/* now enable all of the above */
 	mask |= CDNS_MCP_INT_IRQ;
 
+	if (interrupt_mask) /* parameter override */
+		mask = interrupt_mask;
+
 	cdns_writel(cdns, CDNS_MCP_INTMASK, mask);
 
 	return do_reset(cdns);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 31/40] soundwire: intel: move shutdown() callback and don't export symbol
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (29 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 30/40] soundwire: cadence_master: add kernel parameter to override interrupt mask Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-07-26 10:38   ` Cezary Rojewski
  2019-07-25 23:40 ` [RFC PATCH 32/40] soundwire: intel: add helper for initialization Pierre-Louis Bossart
                   ` (9 subsequent siblings)
  40 siblings, 1 reply; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

All DAI callbacks are in intel.c except for shutdown. Move and remove
export symbol

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/cadence_master.c | 14 --------------
 drivers/soundwire/cadence_master.h |  2 --
 drivers/soundwire/intel.c          | 17 +++++++++++++++--
 3 files changed, 15 insertions(+), 18 deletions(-)

diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
index dede55072191..4a189e487830 100644
--- a/drivers/soundwire/cadence_master.c
+++ b/drivers/soundwire/cadence_master.c
@@ -1381,19 +1381,5 @@ int sdw_cdns_alloc_stream(struct sdw_cdns *cdns,
 }
 EXPORT_SYMBOL(sdw_cdns_alloc_stream);
 
-void sdw_cdns_shutdown(struct snd_pcm_substream *substream,
-		       struct snd_soc_dai *dai)
-{
-	struct sdw_cdns_dma_data *dma;
-
-	dma = snd_soc_dai_get_dma_data(dai, substream);
-	if (!dma)
-		return;
-
-	snd_soc_dai_set_dma_data(dai, substream, NULL);
-	kfree(dma);
-}
-EXPORT_SYMBOL(sdw_cdns_shutdown);
-
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_DESCRIPTION("Cadence Soundwire Library");
diff --git a/drivers/soundwire/cadence_master.h b/drivers/soundwire/cadence_master.h
index d375bbfead18..de97bc22acb7 100644
--- a/drivers/soundwire/cadence_master.h
+++ b/drivers/soundwire/cadence_master.h
@@ -177,8 +177,6 @@ int sdw_cdns_alloc_stream(struct sdw_cdns *cdns,
 void sdw_cdns_config_stream(struct sdw_cdns *cdns, struct sdw_cdns_port *port,
 			    u32 ch, u32 dir, struct sdw_cdns_pdi *pdi);
 
-void sdw_cdns_shutdown(struct snd_pcm_substream *substream,
-		       struct snd_soc_dai *dai);
 int sdw_cdns_pcm_set_stream(struct snd_soc_dai *dai,
 			    void *stream, int direction);
 int sdw_cdns_pdm_set_stream(struct snd_soc_dai *dai,
diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
index 5947fa8e840b..c40ab443e723 100644
--- a/drivers/soundwire/intel.c
+++ b/drivers/soundwire/intel.c
@@ -772,6 +772,19 @@ intel_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 	return ret;
 }
 
+void intel_shutdown(struct snd_pcm_substream *substream,
+		    struct snd_soc_dai *dai)
+{
+	struct sdw_cdns_dma_data *dma;
+
+	dma = snd_soc_dai_get_dma_data(dai, substream);
+	if (!dma)
+		return;
+
+	snd_soc_dai_set_dma_data(dai, substream, NULL);
+	kfree(dma);
+}
+
 static int intel_pcm_set_sdw_stream(struct snd_soc_dai *dai,
 				    void *stream, int direction)
 {
@@ -787,14 +800,14 @@ static int intel_pdm_set_sdw_stream(struct snd_soc_dai *dai,
 static const struct snd_soc_dai_ops intel_pcm_dai_ops = {
 	.hw_params = intel_hw_params,
 	.hw_free = intel_hw_free,
-	.shutdown = sdw_cdns_shutdown,
+	.shutdown = intel_shutdown,
 	.set_sdw_stream = intel_pcm_set_sdw_stream,
 };
 
 static const struct snd_soc_dai_ops intel_pdm_dai_ops = {
 	.hw_params = intel_hw_params,
 	.hw_free = intel_hw_free,
-	.shutdown = sdw_cdns_shutdown,
+	.shutdown = intel_shutdown,
 	.set_sdw_stream = intel_pdm_set_sdw_stream,
 };
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 32/40] soundwire: intel: add helper for initialization
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (30 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 31/40] soundwire: intel: move shutdown() callback and don't export symbol Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-07-26 10:42   ` Cezary Rojewski
  2019-07-25 23:40 ` [RFC PATCH 33/40] soundwire: intel: Add basic power management support Pierre-Louis Bossart
                   ` (8 subsequent siblings)
  40 siblings, 1 reply; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

Move code to helper for reuse in power management routines

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/intel.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
index c40ab443e723..215dc81cdf73 100644
--- a/drivers/soundwire/intel.c
+++ b/drivers/soundwire/intel.c
@@ -984,6 +984,15 @@ static struct sdw_master_ops sdw_intel_ops = {
 	.post_bank_switch = intel_post_bank_switch,
 };
 
+static int intel_init(struct sdw_intel *sdw)
+{
+	/* Initialize shim and controller */
+	intel_link_power_up(sdw);
+	intel_shim_init(sdw);
+
+	return sdw_cdns_init(&sdw->cdns);
+}
+
 /*
  * probe and init
  */
@@ -1026,11 +1035,8 @@ static int intel_probe(struct platform_device *pdev)
 		return 0;
 	}
 
-	/* Initialize shim and controller */
-	intel_link_power_up(sdw);
-	intel_shim_init(sdw);
-
-	ret = sdw_cdns_init(&sdw->cdns);
+	/* Initialize shim, controller and Cadence IP */
+	ret = intel_init(sdw);
 	if (ret)
 		goto err_init;
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 33/40] soundwire: intel: Add basic power management support
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (31 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 32/40] soundwire: intel: add helper for initialization Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-07-26 10:50   ` Cezary Rojewski
  2019-07-25 23:40 ` [RFC PATCH 34/40] soundwire: intel: ignore disabled links for suspend/resume Pierre-Louis Bossart
                   ` (7 subsequent siblings)
  40 siblings, 1 reply; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

Implement suspend/resume capabilities (not runtime_pm for now)

Credits: this patch is based on an earlier internal contribution by
Vinod Koul, Sanyog Kale, Shreyas Nc and Hardik Shah.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/intel.c | 102 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 102 insertions(+)

diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
index 215dc81cdf73..1477c35f616f 100644
--- a/drivers/soundwire/intel.c
+++ b/drivers/soundwire/intel.c
@@ -12,6 +12,7 @@
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <sound/pcm_params.h>
+#include <linux/pm_runtime.h>
 #include <sound/soc.h>
 #include <linux/soundwire/sdw_registers.h>
 #include <linux/soundwire/sdw.h>
@@ -278,6 +279,35 @@ static void intel_debugfs_exit(struct sdw_intel *sdw)
 /*
  * shim ops
  */
+static int intel_link_power_down(struct sdw_intel *sdw)
+{
+	int link_control, spa_mask, cpa_mask, ret;
+	unsigned int link_id = sdw->instance;
+	void __iomem *shim = sdw->res->shim;
+	u16 ioctl;
+
+	/* Glue logic */
+	ioctl = intel_readw(shim, SDW_SHIM_IOCTL(link_id));
+	ioctl |= SDW_SHIM_IOCTL_BKE;
+	ioctl |= SDW_SHIM_IOCTL_COE;
+	intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
+
+	ioctl &= ~(SDW_SHIM_IOCTL_MIF);
+	intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
+
+	/* Link power down sequence */
+	link_control = intel_readl(shim, SDW_SHIM_LCTL);
+	spa_mask = ~(SDW_SHIM_LCTL_SPA << link_id);
+	cpa_mask = (SDW_SHIM_LCTL_CPA << link_id);
+	link_control &=  spa_mask;
+
+	ret = intel_clear_bit(shim, SDW_SHIM_LCTL, link_control, cpa_mask);
+	if (ret < 0)
+		return ret;
+
+	sdw->cdns.link_up = false;
+	return 0;
+}
 
 static int intel_link_power_up(struct sdw_intel *sdw)
 {
@@ -300,6 +330,29 @@ static int intel_link_power_up(struct sdw_intel *sdw)
 	return 0;
 }
 
+static void intel_shim_wake(struct sdw_intel *sdw, bool wake_enable)
+{
+	void __iomem *shim = sdw->res->shim;
+	unsigned int link_id = sdw->instance;
+	u16 wake_en, wake_sts;
+
+	if (wake_enable) {
+		/* Enable the wakeup */
+		intel_writew(shim, SDW_SHIM_WAKEEN,
+			     (SDW_SHIM_WAKEEN_ENABLE << link_id));
+	} else {
+		/* Disable the wake up interrupt */
+		wake_en = intel_readw(shim, SDW_SHIM_WAKEEN);
+		wake_en &= ~(SDW_SHIM_WAKEEN_ENABLE << link_id);
+		intel_writew(shim, SDW_SHIM_WAKEEN, wake_en);
+
+		/* Clear wake status */
+		wake_sts = intel_readw(shim, SDW_SHIM_WAKESTS);
+		wake_sts |= (SDW_SHIM_WAKEEN_ENABLE << link_id);
+		intel_writew(shim, SDW_SHIM_WAKESTS_STATUS, wake_sts);
+	}
+}
+
 static int intel_shim_init(struct sdw_intel *sdw)
 {
 	void __iomem *shim = sdw->res->shim;
@@ -1095,11 +1148,60 @@ static int intel_remove(struct platform_device *pdev)
 	return 0;
 }
 
+/*
+ * PM calls
+ */
+
+#ifdef CONFIG_PM
+
+static int intel_suspend(struct device *dev)
+{
+	struct sdw_intel *sdw;
+	int ret;
+
+	sdw = dev_get_drvdata(dev);
+
+	ret = intel_link_power_down(sdw);
+	if (ret) {
+		dev_err(dev, "Link power down failed: %d", ret);
+		return ret;
+	}
+
+	intel_shim_wake(sdw, false);
+
+	return 0;
+}
+
+static int intel_resume(struct device *dev)
+{
+	struct sdw_intel *sdw;
+	int ret;
+
+	sdw = dev_get_drvdata(dev);
+
+	ret = intel_init(sdw);
+	if (ret) {
+		dev_err(dev, "%s failed: %d", __func__, ret);
+		return ret;
+	}
+
+	sdw_cdns_enable_interrupt(&sdw->cdns);
+
+	return ret;
+}
+
+#endif
+
+static const struct dev_pm_ops intel_pm = {
+	SET_SYSTEM_SLEEP_PM_OPS(intel_suspend, intel_resume)
+};
+
 static struct platform_driver sdw_intel_drv = {
 	.probe = intel_probe,
 	.remove = intel_remove,
 	.driver = {
 		.name = "int-sdw",
+		.pm = &intel_pm,
 
 	},
 };
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 34/40] soundwire: intel: ignore disabled links for suspend/resume
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (32 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 33/40] soundwire: intel: Add basic power management support Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-08-02 17:30   ` Vinod Koul
  2019-07-25 23:40 ` [RFC PATCH 35/40] soundwire: intel: export helper to exit reset Pierre-Louis Bossart
                   ` (6 subsequent siblings)
  40 siblings, 1 reply; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/intel.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
index 1477c35f616f..a976480d6f36 100644
--- a/drivers/soundwire/intel.c
+++ b/drivers/soundwire/intel.c
@@ -1161,6 +1161,12 @@ static int intel_suspend(struct device *dev)
 
 	sdw = dev_get_drvdata(dev);
 
+	if (sdw->cdns.bus.prop.hw_disabled) {
+		dev_dbg(dev, "SoundWire master %d is disabled, ignoring\n",
+			sdw->cdns.bus.link_id);
+		return 0;
+	}
+
 	ret = intel_link_power_down(sdw);
 	if (ret) {
 		dev_err(dev, "Link power down failed: %d", ret);
@@ -1179,6 +1185,12 @@ static int intel_resume(struct device *dev)
 
 	sdw = dev_get_drvdata(dev);
 
+	if (sdw->cdns.bus.prop.hw_disabled) {
+		dev_dbg(dev, "SoundWire master %d is disabled, ignoring\n",
+			sdw->cdns.bus.link_id);
+		return 0;
+	}
+
 	ret = intel_init(sdw);
 	if (ret) {
 		dev_err(dev, "%s failed: %d", __func__, ret);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 35/40] soundwire: intel: export helper to exit reset
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (33 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 34/40] soundwire: intel: ignore disabled links for suspend/resume Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-07-26 15:52   ` [alsa-devel] " Guennadi Liakhovetski
  2019-08-02 17:31   ` Vinod Koul
  2019-07-25 23:40 ` [RFC PATCH 36/40] soundwire: intel: disable interrupts on suspend Pierre-Louis Bossart
                   ` (5 subsequent siblings)
  40 siblings, 2 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/cadence_master.c | 9 +++++++--
 drivers/soundwire/cadence_master.h | 1 +
 drivers/soundwire/intel.c          | 4 ++++
 3 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
index 4a189e487830..f486fe15fb46 100644
--- a/drivers/soundwire/cadence_master.c
+++ b/drivers/soundwire/cadence_master.c
@@ -780,7 +780,11 @@ EXPORT_SYMBOL(sdw_cdns_thread);
  * init routines
  */
 
-static int do_reset(struct sdw_cdns *cdns)
+/**
+ * sdw_cdns_exit_reset() - Program reset parameters and start bus operations
+ * @cdns: Cadence instance
+ */
+int sdw_cdns_exit_reset(struct sdw_cdns *cdns)
 {
 	int ret;
 
@@ -804,6 +808,7 @@ static int do_reset(struct sdw_cdns *cdns)
 
 	return ret;
 }
+EXPORT_SYMBOL(sdw_cdns_exit_reset);
 
 /**
  * sdw_cdns_enable_interrupt() - Enable SDW interrupts and update config
@@ -839,7 +844,7 @@ int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
 
 	cdns_writel(cdns, CDNS_MCP_INTMASK, mask);
 
-	return do_reset(cdns);
+	return 0;
 }
 EXPORT_SYMBOL(sdw_cdns_enable_interrupt);
 
diff --git a/drivers/soundwire/cadence_master.h b/drivers/soundwire/cadence_master.h
index de97bc22acb7..2b551f9226f3 100644
--- a/drivers/soundwire/cadence_master.h
+++ b/drivers/soundwire/cadence_master.h
@@ -161,6 +161,7 @@ irqreturn_t sdw_cdns_thread(int irq, void *dev_id);
 int sdw_cdns_init(struct sdw_cdns *cdns);
 int sdw_cdns_pdi_init(struct sdw_cdns *cdns,
 		      struct sdw_cdns_stream_config config);
+int sdw_cdns_exit_reset(struct sdw_cdns *cdns);
 int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns);
 
 void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root);
diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
index a976480d6f36..9ebe38e4d979 100644
--- a/drivers/soundwire/intel.c
+++ b/drivers/soundwire/intel.c
@@ -1112,6 +1112,8 @@ static int intel_probe(struct platform_device *pdev)
 
 	ret = sdw_cdns_enable_interrupt(&sdw->cdns);
 
+	ret = sdw_cdns_exit_reset(&sdw->cdns);
+
 	/* Register DAIs */
 	ret = intel_register_dai(sdw);
 	if (ret) {
@@ -1199,6 +1201,8 @@ static int intel_resume(struct device *dev)
 
 	sdw_cdns_enable_interrupt(&sdw->cdns);
 
+	ret = sdw_cdns_exit_reset(&sdw->cdns);
+
 	return ret;
 }
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 36/40] soundwire: intel: disable interrupts on suspend
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (34 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 35/40] soundwire: intel: export helper to exit reset Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-07-26 15:55   ` [alsa-devel] " Guennadi Liakhovetski
  2019-07-25 23:40 ` [RFC PATCH 37/40] soundwire: cadence_master: add hw_reset capability in debugfs Pierre-Louis Bossart
                   ` (4 subsequent siblings)
  40 siblings, 1 reply; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/cadence_master.c | 42 +++++++++++++++++-------------
 drivers/soundwire/cadence_master.h |  2 +-
 drivers/soundwire/intel.c          |  6 +++--
 3 files changed, 29 insertions(+), 21 deletions(-)

diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
index f486fe15fb46..fa7230b0f200 100644
--- a/drivers/soundwire/cadence_master.c
+++ b/drivers/soundwire/cadence_master.c
@@ -814,33 +814,39 @@ EXPORT_SYMBOL(sdw_cdns_exit_reset);
  * sdw_cdns_enable_interrupt() - Enable SDW interrupts and update config
  * @cdns: Cadence instance
  */
-int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
+int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns, bool state)
 {
 	u32 mask;
 
-	cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK0,
-		    CDNS_MCP_SLAVE_INTMASK0_MASK);
-	cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK1,
-		    CDNS_MCP_SLAVE_INTMASK1_MASK);
+	if (state) {
+		cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK0,
+			    CDNS_MCP_SLAVE_INTMASK0_MASK);
+		cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK1,
+			    CDNS_MCP_SLAVE_INTMASK1_MASK);
 
-	/* enable detection of slave state changes */
-	mask = CDNS_MCP_INT_SLAVE_RSVD | CDNS_MCP_INT_SLAVE_ALERT |
-		CDNS_MCP_INT_SLAVE_ATTACH | CDNS_MCP_INT_SLAVE_NATTACH;
+		/* enable detection of slave state changes */
+		mask = CDNS_MCP_INT_SLAVE_RSVD | CDNS_MCP_INT_SLAVE_ALERT |
+			CDNS_MCP_INT_SLAVE_ATTACH | CDNS_MCP_INT_SLAVE_NATTACH;
 
-	/* enable detection of bus issues */
-	mask |= CDNS_MCP_INT_CTRL_CLASH | CDNS_MCP_INT_DATA_CLASH |
-		CDNS_MCP_INT_PARITY;
+		/* enable detection of bus issues */
+		mask |= CDNS_MCP_INT_CTRL_CLASH | CDNS_MCP_INT_DATA_CLASH |
+			CDNS_MCP_INT_PARITY;
 
-	/* no detection of port interrupts for now */
+		/* no detection of port interrupts for now */
 
-	/* enable detection of RX fifo level */
-	mask |= CDNS_MCP_INT_RX_WL;
+		/* enable detection of RX fifo level */
+		mask |= CDNS_MCP_INT_RX_WL;
 
-	/* now enable all of the above */
-	mask |= CDNS_MCP_INT_IRQ;
+		/* now enable all of the above */
+		mask |= CDNS_MCP_INT_IRQ;
 
-	if (interrupt_mask) /* parameter override */
-		mask = interrupt_mask;
+		if (interrupt_mask) /* parameter override */
+			mask = interrupt_mask;
+	} else {
+		cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK0, 0);
+		cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK1, 0);
+		mask = 0;
+	}
 
 	cdns_writel(cdns, CDNS_MCP_INTMASK, mask);
 
diff --git a/drivers/soundwire/cadence_master.h b/drivers/soundwire/cadence_master.h
index 2b551f9226f3..1a0ba36dd78f 100644
--- a/drivers/soundwire/cadence_master.h
+++ b/drivers/soundwire/cadence_master.h
@@ -162,7 +162,7 @@ int sdw_cdns_init(struct sdw_cdns *cdns);
 int sdw_cdns_pdi_init(struct sdw_cdns *cdns,
 		      struct sdw_cdns_stream_config config);
 int sdw_cdns_exit_reset(struct sdw_cdns *cdns);
-int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns);
+int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns, bool state);
 
 void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root);
 
diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
index 9ebe38e4d979..1192d5775484 100644
--- a/drivers/soundwire/intel.c
+++ b/drivers/soundwire/intel.c
@@ -1110,7 +1110,7 @@ static int intel_probe(struct platform_device *pdev)
 		goto err_init;
 	}
 
-	ret = sdw_cdns_enable_interrupt(&sdw->cdns);
+	ret = sdw_cdns_enable_interrupt(&sdw->cdns, true);
 
 	ret = sdw_cdns_exit_reset(&sdw->cdns);
 
@@ -1169,6 +1169,8 @@ static int intel_suspend(struct device *dev)
 		return 0;
 	}
 
+	sdw_cdns_enable_interrupt(&sdw->cdns, false);
+
 	ret = intel_link_power_down(sdw);
 	if (ret) {
 		dev_err(dev, "Link power down failed: %d", ret);
@@ -1199,7 +1201,7 @@ static int intel_resume(struct device *dev)
 		return ret;
 	}
 
-	sdw_cdns_enable_interrupt(&sdw->cdns);
+	sdw_cdns_enable_interrupt(&sdw->cdns, true);
 
 	ret = sdw_cdns_exit_reset(&sdw->cdns);
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 37/40] soundwire: cadence_master: add hw_reset capability in debugfs
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (35 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 36/40] soundwire: intel: disable interrupts on suspend Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-07-26 14:07   ` Greg KH
  2019-07-26 15:57   ` Guennadi Liakhovetski
  2019-07-25 23:40 ` [RFC PATCH 38/40] soundwire: cadence_master: make clock stop exit configurable on init Pierre-Louis Bossart
                   ` (3 subsequent siblings)
  40 siblings, 2 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

This is to kick devices into reset and see what software does

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/cadence_master.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
index fa7230b0f200..53278aa2436f 100644
--- a/drivers/soundwire/cadence_master.c
+++ b/drivers/soundwire/cadence_master.c
@@ -331,6 +331,25 @@ static const struct file_operations cdns_reg_fops = {
 	.llseek = default_llseek,
 };
 
+static int cdns_hw_reset(void *data, u64 value)
+{
+	struct sdw_cdns *cdns = data;
+	int ret;
+
+	if (value != 1)
+		return 0;
+
+	dev_info(cdns->dev, "starting link hw_reset\n");
+
+	ret = sdw_cdns_exit_reset(cdns);
+
+	dev_info(cdns->dev, "link hw_reset done\n");
+
+	return ret;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(cdns_hw_reset_fops, NULL, cdns_hw_reset, "%llu\n");
+
 /**
  * sdw_cdns_debugfs_init() - Cadence debugfs init
  * @cdns: Cadence instance
@@ -339,6 +358,9 @@ static const struct file_operations cdns_reg_fops = {
 void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root)
 {
 	debugfs_create_file("cdns-registers", 0400, root, cdns, &cdns_reg_fops);
+
+	debugfs_create_file_unsafe("cdns-hw-reset", 0200, root, cdns,
+				   &cdns_hw_reset_fops);
 }
 EXPORT_SYMBOL_GPL(sdw_cdns_debugfs_init);
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 38/40] soundwire: cadence_master: make clock stop exit configurable on init
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (36 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 37/40] soundwire: cadence_master: add hw_reset capability in debugfs Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-07-26 16:02   ` [alsa-devel] " Guennadi Liakhovetski
  2019-07-25 23:40 ` [RFC PATCH 39/40] soundwire: intel: add pm_runtime support Pierre-Louis Bossart
                   ` (2 subsequent siblings)
  40 siblings, 1 reply; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

The use of clock stop is not a requirement, the IP can e.g. be
completely power gated and not detect any wakes while in s2idle/deep
sleep.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/cadence_master.c | 15 ++++++++-------
 drivers/soundwire/cadence_master.h |  2 +-
 drivers/soundwire/intel.c          |  2 +-
 3 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
index 53278aa2436f..4ab6f70d7705 100644
--- a/drivers/soundwire/cadence_master.c
+++ b/drivers/soundwire/cadence_master.c
@@ -1010,7 +1010,7 @@ static u32 cdns_set_default_frame_shape(int n_rows, int n_cols)
  * sdw_cdns_init() - Cadence initialization
  * @cdns: Cadence instance
  */
-int sdw_cdns_init(struct sdw_cdns *cdns)
+int sdw_cdns_init(struct sdw_cdns *cdns, bool clock_stop_exit)
 {
 	struct sdw_bus *bus = &cdns->bus;
 	struct sdw_master_prop *prop = &bus->prop;
@@ -1018,12 +1018,13 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
 	int divider;
 	int ret;
 
-	/* Exit clock stop */
-	ret = cdns_clear_bit(cdns, CDNS_MCP_CONTROL,
-			     CDNS_MCP_CONTROL_CLK_STOP_CLR);
-	if (ret < 0) {
-		dev_err(cdns->dev, "Couldn't exit from clock stop\n");
-		return ret;
+	if (clock_stop_exit) {
+		ret = cdns_clear_bit(cdns, CDNS_MCP_CONTROL,
+				     CDNS_MCP_CONTROL_CLK_STOP_CLR);
+		if (ret < 0) {
+			dev_err(cdns->dev, "Couldn't exit from clock stop\n");
+			return ret;
+		}
 	}
 
 	/* Set clock divider */
diff --git a/drivers/soundwire/cadence_master.h b/drivers/soundwire/cadence_master.h
index 1a0ba36dd78f..091b771b570d 100644
--- a/drivers/soundwire/cadence_master.h
+++ b/drivers/soundwire/cadence_master.h
@@ -158,7 +158,7 @@ extern struct sdw_master_ops sdw_cdns_master_ops;
 irqreturn_t sdw_cdns_irq(int irq, void *dev_id);
 irqreturn_t sdw_cdns_thread(int irq, void *dev_id);
 
-int sdw_cdns_init(struct sdw_cdns *cdns);
+int sdw_cdns_init(struct sdw_cdns *cdns, bool clock_stop_exit);
 int sdw_cdns_pdi_init(struct sdw_cdns *cdns,
 		      struct sdw_cdns_stream_config config);
 int sdw_cdns_exit_reset(struct sdw_cdns *cdns);
diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
index 1192d5775484..db7bf2912767 100644
--- a/drivers/soundwire/intel.c
+++ b/drivers/soundwire/intel.c
@@ -1043,7 +1043,7 @@ static int intel_init(struct sdw_intel *sdw)
 	intel_link_power_up(sdw);
 	intel_shim_init(sdw);
 
-	return sdw_cdns_init(&sdw->cdns);
+	return sdw_cdns_init(&sdw->cdns, false);
 }
 
 /*
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 39/40] soundwire: intel: add pm_runtime support
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (37 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 38/40] soundwire: cadence_master: make clock stop exit configurable on init Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-07-25 23:40 ` [RFC PATCH 40/40] soundwire: intel: add delay on restart for enumeration Pierre-Louis Bossart
  2019-07-26 11:14 ` [RFC PATCH 00/40] soundwire: updates for 5.4 Cezary Rojewski
  40 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

Add basic hooks in DAI .startup and .shutdown callbacks. The SoundWire
IP should be powered between those two calls.

By default the platform_device is in SUSPENDED mode, it is required to
call pm_runtime_set_active() before _enable()

FIXME: do we need to use mark_last_busy()?

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/intel.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
index db7bf2912767..1394a2322553 100644
--- a/drivers/soundwire/intel.c
+++ b/drivers/soundwire/intel.c
@@ -707,6 +707,23 @@ static void intel_port_cleanup(struct sdw_cdns_dma_data *dma)
 	}
 }
 
+static int intel_startup(struct snd_pcm_substream *substream,
+			 struct snd_soc_dai *dai)
+{
+	struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
+	int ret;
+
+	ret = pm_runtime_get_sync(cdns->dev);
+	if (ret < 0) {
+		dev_err_ratelimited(cdns->dev,
+				    "pm_runtime_get_sync failed in %s, ret %d\n",
+				    __func__, ret);
+		pm_runtime_put_noidle(cdns->dev);
+	}
+
+	return ret;
+}
+
 static int intel_hw_params(struct snd_pcm_substream *substream,
 			   struct snd_pcm_hw_params *params,
 			   struct snd_soc_dai *dai)
@@ -829,6 +846,8 @@ void intel_shutdown(struct snd_pcm_substream *substream,
 		    struct snd_soc_dai *dai)
 {
 	struct sdw_cdns_dma_data *dma;
+	struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
+	int ret;
 
 	dma = snd_soc_dai_get_dma_data(dai, substream);
 	if (!dma)
@@ -836,6 +855,13 @@ void intel_shutdown(struct snd_pcm_substream *substream,
 
 	snd_soc_dai_set_dma_data(dai, substream, NULL);
 	kfree(dma);
+
+	pm_runtime_mark_last_busy(cdns->dev);
+	ret = pm_runtime_put_autosuspend(cdns->dev);
+	if (ret < 0)
+		dev_err_ratelimited(cdns->dev,
+				    "pM_runtime_put_autosuspend failed in %s:, ret %d\n",
+				    __func__, ret);
 }
 
 static int intel_pcm_set_sdw_stream(struct snd_soc_dai *dai,
@@ -851,6 +877,7 @@ static int intel_pdm_set_sdw_stream(struct snd_soc_dai *dai,
 }
 
 static const struct snd_soc_dai_ops intel_pcm_dai_ops = {
+	.startup = intel_startup,
 	.hw_params = intel_hw_params,
 	.hw_free = intel_hw_free,
 	.shutdown = intel_shutdown,
@@ -1124,6 +1151,15 @@ static int intel_probe(struct platform_device *pdev)
 
 	intel_debugfs_init(sdw);
 
+	/* Enable PM */
+	pm_runtime_set_autosuspend_delay(&pdev->dev, 3000);
+	pm_runtime_use_autosuspend(&pdev->dev);
+
+	pm_runtime_mark_last_busy(&pdev->dev); /* FIXME: needed? */
+
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+
 	return 0;
 
 err_dai:
@@ -1141,6 +1177,7 @@ static int intel_remove(struct platform_device *pdev)
 	sdw = platform_get_drvdata(pdev);
 
 	if (!sdw->cdns.bus.prop.hw_disabled) {
+		pm_runtime_disable(&pdev->dev);
 		intel_debugfs_exit(sdw);
 		free_irq(sdw->res->irq, sdw);
 		snd_soc_unregister_component(sdw->cdns.dev);
@@ -1212,6 +1249,7 @@ static int intel_resume(struct device *dev)
 
 static const struct dev_pm_ops intel_pm = {
 	SET_SYSTEM_SLEEP_PM_OPS(intel_suspend, intel_resume)
+	SET_RUNTIME_PM_OPS(intel_suspend, intel_resume, NULL)
 };
 
 static struct platform_driver sdw_intel_drv = {
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* [RFC PATCH 40/40] soundwire: intel: add delay on restart for enumeration
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (38 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 39/40] soundwire: intel: add pm_runtime support Pierre-Louis Bossart
@ 2019-07-25 23:40 ` Pierre-Louis Bossart
  2019-07-26 11:14 ` [RFC PATCH 00/40] soundwire: updates for 5.4 Cezary Rojewski
  40 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-25 23:40 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Pierre-Louis Bossart,
	Sanyog Kale

We have a conceptual issue on restart: the interaction with the slaves
can start before (re) enumeration is complete. Add a delay for now but
we will need to have an async notification that all devices are back
on the bus.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 drivers/soundwire/intel.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
index 1394a2322553..e4ea430b5a8e 100644
--- a/drivers/soundwire/intel.c
+++ b/drivers/soundwire/intel.c
@@ -1242,6 +1242,11 @@ static int intel_resume(struct device *dev)
 
 	ret = sdw_cdns_exit_reset(&sdw->cdns);
 
+	/* add delay to let Slaves re-enumerate */
+	usleep_range(20000, 30000);
+
+	dev_dbg(dev, "%s done\n", __func__);
+
 	return ret;
 }
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 09/40] soundwire: cadence_master: fix usage of CONFIG_UPDATE
  2019-07-25 23:40 ` [RFC PATCH 09/40] soundwire: cadence_master: fix usage of CONFIG_UPDATE Pierre-Louis Bossart
  2019-07-25 22:23   ` [alsa-devel] " Guennadi Liakhovetski
@ 2019-07-26  2:11   ` Bard liao
  2019-07-26 13:33     ` Pierre-Louis Bossart
  2019-07-26  9:53   ` Cezary Rojewski
                     ` (2 subsequent siblings)
  4 siblings, 1 reply; 183+ messages in thread
From: Bard liao @ 2019-07-26  2:11 UTC (permalink / raw)
  To: Pierre-Louis Bossart, alsa-devel
  Cc: tiwai, gregkh, linux-kernel, vkoul, broonie, srinivas.kandagatla,
	jank, slawomir.blauciak, Sanyog Kale

On 7/26/2019 7:40 AM, Pierre-Louis Bossart wrote:
> Per the hardware documentation, all changes to MCP_CONFIG,
> MCP_CONTROL, MCP_CMDCTRL and MCP_PHYCTRL need to be validated with a
> self-clearing write to MCP_CONFIG_UPDATE.
>
> For some reason, the existing code only does this write to
> CONFIG_UPDATE when enabling interrupts. Add a helper and do the update
> when the CONFIG is changed.
>
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>   drivers/soundwire/cadence_master.c | 29 +++++++++++++++++++++--------
>   1 file changed, 21 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
> index 9f611a1fff0a..eb46cf651d62 100644
> --- a/drivers/soundwire/cadence_master.c
> +++ b/drivers/soundwire/cadence_master.c
> @@ -224,6 +224,22 @@ static int cdns_clear_bit(struct sdw_cdns *cdns, int offset, u32 value)
>   	return -EAGAIN;
>   }
>   
> +/*
> + * all changes to the MCP_CONFIG, MCP_CONTROL, MCP_CMDCTRL and MCP_PHYCTRL
> + * need to be confirmed with a write to MCP_CONFIG_UPDATE
> + */
> +static int cdns_update_config(struct sdw_cdns *cdns)
> +{
> +	int ret;
> +
> +	ret = cdns_clear_bit(cdns, CDNS_MCP_CONFIG_UPDATE,
> +			     CDNS_MCP_CONFIG_UPDATE_BIT);
> +	if (ret < 0)
> +		dev_err(cdns->dev, "Config update timedout\n");
> +
> +	return ret;
> +}
> +
>   /*
>    * debugfs
>    */
> @@ -758,15 +774,9 @@ static int _cdns_enable_interrupt(struct sdw_cdns *cdns)
>    */
>   int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
>   {
> -	int ret;
> -
>   	_cdns_enable_interrupt(cdns);
> -	ret = cdns_clear_bit(cdns, CDNS_MCP_CONFIG_UPDATE,
> -			     CDNS_MCP_CONFIG_UPDATE_BIT);
> -	if (ret < 0)
> -		dev_err(cdns->dev, "Config update timedout\n");
>   
> -	return ret;
Should we add cdns_update_config() here?
> +	return 0;
>   }
>   EXPORT_SYMBOL(sdw_cdns_enable_interrupt);
>   
> @@ -943,7 +953,10 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
>   
>   	cdns_writel(cdns, CDNS_MCP_CONFIG, val);
>   
> -	return 0;
> +	/* commit changes */
> +	ret = cdns_update_config(cdns);
> +
> +	return ret;
>   }
>   EXPORT_SYMBOL(sdw_cdns_init);
>   

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 26/40] soundwire: cadence_master: fix divider setting in clock register
  2019-07-25 23:40 ` [RFC PATCH 26/40] soundwire: cadence_master: fix divider setting in clock register Pierre-Louis Bossart
@ 2019-07-26  5:19   ` Bard liao
  2019-07-26  5:56     ` rander.wang
  2019-07-26 14:24     ` Pierre-Louis Bossart
  2019-08-02 17:19   ` Vinod Koul
  2019-08-05 10:40   ` Sanyog Kale
  2 siblings, 2 replies; 183+ messages in thread
From: Bard liao @ 2019-07-26  5:19 UTC (permalink / raw)
  To: Pierre-Louis Bossart, alsa-devel
  Cc: tiwai, gregkh, linux-kernel, vkoul, broonie, srinivas.kandagatla,
	jank, slawomir.blauciak, Sanyog Kale, Rander Wang


On 7/26/2019 7:40 AM, Pierre-Louis Bossart wrote:
> From: Rander Wang <rander.wang@linux.intel.com>
>
> The existing code uses an OR operation which would mix the original
> divider setting with the new one, resulting in an invalid
> configuration that can make codecs hang.
>
> Add the mask definition and use cdns_updatel to update divider
>
> Signed-off-by: Rander Wang <rander.wang@linux.intel.com>
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>   drivers/soundwire/cadence_master.c | 12 +++++++-----
>   1 file changed, 7 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
> index 10ebcef2e84e..18c6ac026e85 100644
> --- a/drivers/soundwire/cadence_master.c
> +++ b/drivers/soundwire/cadence_master.c
> @@ -57,6 +57,7 @@
>   #define CDNS_MCP_SSP_CTRL1			0x28
>   #define CDNS_MCP_CLK_CTRL0			0x30
>   #define CDNS_MCP_CLK_CTRL1			0x38
> +#define CDNS_MCP_CLK_MCLKD_MASK		GENMASK(7, 0)
>   
>   #define CDNS_MCP_STAT				0x40
>   
> @@ -988,9 +989,11 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
>   	/* Set clock divider */
>   	divider	= (prop->mclk_freq / prop->max_clk_freq) - 1;
>   	val = cdns_readl(cdns, CDNS_MCP_CLK_CTRL0);


Do we still need to read cdns_readl(cdns, CDNS_MCP_CLK_CTRL0)

after this change?


> -	val |= divider;
> -	cdns_writel(cdns, CDNS_MCP_CLK_CTRL0, val);
> -	cdns_writel(cdns, CDNS_MCP_CLK_CTRL1, val);
> +
> +	cdns_updatel(cdns, CDNS_MCP_CLK_CTRL0,
> +		     CDNS_MCP_CLK_MCLKD_MASK, divider);
> +	cdns_updatel(cdns, CDNS_MCP_CLK_CTRL1,
> +		     CDNS_MCP_CLK_MCLKD_MASK, divider);
>   
>   	pr_err("plb: mclk %d max_freq %d divider %d register %x\n",
>   	       prop->mclk_freq,
> @@ -1064,8 +1067,7 @@ int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params)
>   		mcp_clkctrl_off = CDNS_MCP_CLK_CTRL0;
>   
>   	mcp_clkctrl = cdns_readl(cdns, mcp_clkctrl_off);


Same here.


> -	mcp_clkctrl |= divider;
> -	cdns_writel(cdns, mcp_clkctrl_off, mcp_clkctrl);
> +	cdns_updatel(cdns, mcp_clkctrl_off, CDNS_MCP_CLK_MCLKD_MASK, divider);
>   
>   	pr_err("plb: mclk * 2 %d curr_dr_freq %d divider %d register %x\n",
>   	       prop->mclk_freq * SDW_DOUBLE_RATE_FACTOR,

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 26/40] soundwire: cadence_master: fix divider setting in clock register
  2019-07-26  5:19   ` [alsa-devel] " Bard liao
@ 2019-07-26  5:56     ` rander.wang
  2019-07-26 14:24     ` Pierre-Louis Bossart
  1 sibling, 0 replies; 183+ messages in thread
From: rander.wang @ 2019-07-26  5:56 UTC (permalink / raw)
  To: Bard liao, Pierre-Louis Bossart, alsa-devel
  Cc: tiwai, gregkh, linux-kernel, vkoul, broonie, srinivas.kandagatla,
	jank, slawomir.blauciak, Sanyog Kale


在 7/26/2019 1:19 PM, Bard liao 写道:
>
> On 7/26/2019 7:40 AM, Pierre-Louis Bossart wrote:
>> From: Rander Wang <rander.wang@linux.intel.com>
>>
>> The existing code uses an OR operation which would mix the original
>> divider setting with the new one, resulting in an invalid
>> configuration that can make codecs hang.
>>
>> Add the mask definition and use cdns_updatel to update divider
>>
>> Signed-off-by: Rander Wang <rander.wang@linux.intel.com>
>> Signed-off-by: Pierre-Louis Bossart 
>> <pierre-louis.bossart@linux.intel.com>
>> ---
>>   drivers/soundwire/cadence_master.c | 12 +++++++-----
>>   1 file changed, 7 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/soundwire/cadence_master.c 
>> b/drivers/soundwire/cadence_master.c
>> index 10ebcef2e84e..18c6ac026e85 100644
>> --- a/drivers/soundwire/cadence_master.c
>> +++ b/drivers/soundwire/cadence_master.c
>> @@ -57,6 +57,7 @@
>>   #define CDNS_MCP_SSP_CTRL1            0x28
>>   #define CDNS_MCP_CLK_CTRL0            0x30
>>   #define CDNS_MCP_CLK_CTRL1            0x38
>> +#define CDNS_MCP_CLK_MCLKD_MASK        GENMASK(7, 0)
>>     #define CDNS_MCP_STAT                0x40
>>   @@ -988,9 +989,11 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
>>       /* Set clock divider */
>>       divider    = (prop->mclk_freq / prop->max_clk_freq) - 1;
>>       val = cdns_readl(cdns, CDNS_MCP_CLK_CTRL0);
>
>
> Do we still need to read cdns_readl(cdns, CDNS_MCP_CLK_CTRL0)
>
> after this change?
>
The val is used to print debug message,  and my opinion is to change the log

from pr_err("plb: ........") to dev_dbg(bus->dev, "........") to follow 
the dev_dbg

usage in this file.

>
>> -    val |= divider;
>> -    cdns_writel(cdns, CDNS_MCP_CLK_CTRL0, val);
>> -    cdns_writel(cdns, CDNS_MCP_CLK_CTRL1, val);
>> +
>> +    cdns_updatel(cdns, CDNS_MCP_CLK_CTRL0,
>> +             CDNS_MCP_CLK_MCLKD_MASK, divider);
>> +    cdns_updatel(cdns, CDNS_MCP_CLK_CTRL1,
>> +             CDNS_MCP_CLK_MCLKD_MASK, divider);
>>         pr_err("plb: mclk %d max_freq %d divider %d register %x\n",
>>              prop->mclk_freq,
>> @@ -1064,8 +1067,7 @@ int cdns_bus_conf(struct sdw_bus *bus, struct 
>> sdw_bus_params *params)
>>           mcp_clkctrl_off = CDNS_MCP_CLK_CTRL0;
>>         mcp_clkctrl = cdns_readl(cdns, mcp_clkctrl_off);
>
>
> Same here.
>
Also refine the debug log.
>
>> -    mcp_clkctrl |= divider;
>> -    cdns_writel(cdns, mcp_clkctrl_off, mcp_clkctrl);
>> +    cdns_updatel(cdns, mcp_clkctrl_off, CDNS_MCP_CLK_MCLKD_MASK, 
>> divider);
>>         pr_err("plb: mclk * 2 %d curr_dr_freq %d divider %d register 
>> %x\n",
>>              prop->mclk_freq * SDW_DOUBLE_RATE_FACTOR,

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 16/40] soundwire: cadence_master: improve startup sequence with link hw_reset
  2019-07-25 23:40 ` [RFC PATCH 16/40] soundwire: cadence_master: improve startup sequence with link hw_reset Pierre-Louis Bossart
@ 2019-07-26  7:22   ` Guennadi Liakhovetski
  2019-07-26 14:11     ` Pierre-Louis Bossart
  0 siblings, 1 reply; 183+ messages in thread
From: Guennadi Liakhovetski @ 2019-07-26  7:22 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, tiwai, gregkh, linux-kernel, vkoul, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale

On Thu, Jul 25, 2019 at 06:40:08PM -0500, Pierre-Louis Bossart wrote:
> Enable interrupts first, then engage hardware bus reset with maximum
> duration to make sure the Slave(s) correctly detect the reset pattern
> and to ensure electrical conflicts can be resolved.
> 
> Without these changes the initialization is randomly corrupted by bus
> clashes, parity errors and Slave attachment does not generate any
> interrupt, despite the status showing them being attached.
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/cadence_master.c | 35 +++++++++++++++++++++++++-----
>  1 file changed, 30 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
> index 25d5c7267c15..442f78c00f09 100644
> --- a/drivers/soundwire/cadence_master.c
> +++ b/drivers/soundwire/cadence_master.c
> @@ -778,6 +778,31 @@ EXPORT_SYMBOL(sdw_cdns_thread);
>   * init routines
>   */
>  
> +static int do_reset(struct sdw_cdns *cdns)
> +{
> +	int ret;
> +
> +	/* program maximum length reset to be safe */
> +	cdns_updatel(cdns, CDNS_MCP_CONTROL,
> +		     CDNS_MCP_CONTROL_RST_DELAY,
> +		     CDNS_MCP_CONTROL_RST_DELAY);
> +
> +	/* use hardware generated reset */
> +	cdns_updatel(cdns, CDNS_MCP_CONTROL,
> +		     CDNS_MCP_CONTROL_HW_RST,
> +		     CDNS_MCP_CONTROL_HW_RST);
> +
> +	/* enable bus operations with clock and data */
> +	cdns_updatel(cdns, CDNS_MCP_CONFIG,
> +		     CDNS_MCP_CONFIG_OP,
> +		     CDNS_MCP_CONFIG_OP_NORMAL);
> +
> +	/* commit changes */
> +	ret = cdns_update_config(cdns);
> +
> +	return ret;

+	return cdns_update_config(cdns);

and remove the "ret" variable.

Thanks
Guennadi

> +}
> +
>  /**
>   * sdw_cdns_enable_interrupt() - Enable SDW interrupts and update config
>   * @cdns: Cadence instance
> @@ -809,7 +834,7 @@ int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
>  
>  	cdns_writel(cdns, CDNS_MCP_INTMASK, mask);
>  
> -	return 0;
> +	return do_reset(cdns);
>  }
>  EXPORT_SYMBOL(sdw_cdns_enable_interrupt);
>  
> @@ -958,6 +983,10 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
>  	cdns_writel(cdns, CDNS_MCP_SSP_CTRL0, CDNS_DEFAULT_SSP_INTERVAL);
>  	cdns_writel(cdns, CDNS_MCP_SSP_CTRL1, CDNS_DEFAULT_SSP_INTERVAL);
>  
> +	/* flush command FIFOs */
> +	cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_CMD_RST,
> +		     CDNS_MCP_CONTROL_CMD_RST);
> +
>  	/* Set cmd accept mode */
>  	cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_CMD_ACCEPT,
>  		     CDNS_MCP_CONTROL_CMD_ACCEPT);
> @@ -980,10 +1009,6 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
>  	/* Set cmd mode for Tx and Rx cmds */
>  	val &= ~CDNS_MCP_CONFIG_CMD;
>  
> -	/* Set operation to normal */
> -	val &= ~CDNS_MCP_CONFIG_OP;
> -	val |= CDNS_MCP_CONFIG_OP_NORMAL;
> -
>  	cdns_writel(cdns, CDNS_MCP_CONFIG, val);
>  
>  	/* commit changes */
> -- 
> 2.20.1
> 
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 17/40] soundwire: bus: use runtime_pm_get_sync/pm when enabled
  2019-07-25 23:40 ` [RFC PATCH 17/40] soundwire: bus: use runtime_pm_get_sync/pm when enabled Pierre-Louis Bossart
@ 2019-07-26  7:39   ` Guennadi Liakhovetski
  2019-07-26  7:47     ` Jan Kotas
  2019-07-26 18:08   ` Pierre-Louis Bossart
  2019-08-02 16:58   ` Vinod Koul
  2 siblings, 1 reply; 183+ messages in thread
From: Guennadi Liakhovetski @ 2019-07-26  7:39 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, tiwai, gregkh, linux-kernel, vkoul, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale

Hi Pierre,

I might be wrong but this doesn't seem right to me. (Supposedly) all RT-PM
functions check for "enabled" internally. The only thing that can happen is
that if RT-PM isn't enabled some of those functions will return an error.
So, in those cases where the return value of RT-PM functions isn't checked,
I don't think you need to do anything. Where it is checked maybe do

+	if (ret < 0 && pm_runtime_enabled(slave->bus->dev))

Thanks
Guennadi

On Thu, Jul 25, 2019 at 06:40:09PM -0500, Pierre-Louis Bossart wrote:
> Not all platforms support runtime_pm for now, let's use runtime_pm
> only when enabled.
> 
> Suggested-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/bus.c | 25 ++++++++++++++++---------
>  1 file changed, 16 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
> index 5ad4109dc72f..0a45dc5713df 100644
> --- a/drivers/soundwire/bus.c
> +++ b/drivers/soundwire/bus.c
> @@ -332,12 +332,16 @@ int sdw_nread(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
>  	if (ret < 0)
>  		return ret;
>  
> -	ret = pm_runtime_get_sync(slave->bus->dev);
> -	if (ret < 0)
> -		return ret;
> +	if (pm_runtime_enabled(slave->bus->dev)) {
> +		ret = pm_runtime_get_sync(slave->bus->dev);
> +		if (ret < 0)
> +			return ret;
> +	}
>  
>  	ret = sdw_transfer(slave->bus, &msg);
> -	pm_runtime_put(slave->bus->dev);
> +
> +	if (pm_runtime_enabled(slave->bus->dev))
> +		pm_runtime_put(slave->bus->dev);
>  
>  	return ret;
>  }
> @@ -359,13 +363,16 @@ int sdw_nwrite(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
>  			   slave->dev_num, SDW_MSG_FLAG_WRITE, val);
>  	if (ret < 0)
>  		return ret;
> -
> -	ret = pm_runtime_get_sync(slave->bus->dev);
> -	if (ret < 0)
> -		return ret;
> +	if (pm_runtime_enabled(slave->bus->dev)) {
> +		ret = pm_runtime_get_sync(slave->bus->dev);
> +		if (ret < 0)
> +			return ret;
> +	}
>  
>  	ret = sdw_transfer(slave->bus, &msg);
> -	pm_runtime_put(slave->bus->dev);
> +
> +	if (pm_runtime_enabled(slave->bus->dev))
> +		pm_runtime_put(slave->bus->dev);
>  
>  	return ret;
>  }
> -- 
> 2.20.1
> 
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 17/40] soundwire: bus: use runtime_pm_get_sync/pm when enabled
  2019-07-26  7:39   ` [alsa-devel] " Guennadi Liakhovetski
@ 2019-07-26  7:47     ` Jan Kotas
  2019-07-26  8:22       ` Guennadi Liakhovetski
  0 siblings, 1 reply; 183+ messages in thread
From: Jan Kotas @ 2019-07-26  7:47 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: Pierre-Louis Bossart, alsa-devel, tiwai, gregkh, LKML,
	Vinod Koul, Mark Brown, Srinivas Kandagatla, Jan Kotas,
	slawomir.blauciak, Sanyog Kale

Hello,

I while back I proposed a patch for this, but it went nowhere.

https://patchwork.kernel.org/patch/10887405/
Maybe something similar can be implemented?

Jan

> On 26 Jul 2019, at 09:39, Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com> wrote:
> 
> EXTERNAL MAIL
> 
> 
> Hi Pierre,
> 
> I might be wrong but this doesn't seem right to me. (Supposedly) all RT-PM
> functions check for "enabled" internally. The only thing that can happen is
> that if RT-PM isn't enabled some of those functions will return an error.
> So, in those cases where the return value of RT-PM functions isn't checked,
> I don't think you need to do anything. Where it is checked maybe do
> 
> +	if (ret < 0 && pm_runtime_enabled(slave->bus->dev))
> 
> Thanks
> Guennadi
> 
> On Thu, Jul 25, 2019 at 06:40:09PM -0500, Pierre-Louis Bossart wrote:
>> Not all platforms support runtime_pm for now, let's use runtime_pm
>> only when enabled.
>> 
>> Suggested-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
>> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
>> ---
>> drivers/soundwire/bus.c | 25 ++++++++++++++++---------
>> 1 file changed, 16 insertions(+), 9 deletions(-)
>> 
>> diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
>> index 5ad4109dc72f..0a45dc5713df 100644
>> --- a/drivers/soundwire/bus.c
>> +++ b/drivers/soundwire/bus.c
>> @@ -332,12 +332,16 @@ int sdw_nread(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
>> 	if (ret < 0)
>> 		return ret;
>> 
>> -	ret = pm_runtime_get_sync(slave->bus->dev);
>> -	if (ret < 0)
>> -		return ret;
>> +	if (pm_runtime_enabled(slave->bus->dev)) {
>> +		ret = pm_runtime_get_sync(slave->bus->dev);
>> +		if (ret < 0)
>> +			return ret;
>> +	}
>> 
>> 	ret = sdw_transfer(slave->bus, &msg);
>> -	pm_runtime_put(slave->bus->dev);
>> +
>> +	if (pm_runtime_enabled(slave->bus->dev))
>> +		pm_runtime_put(slave->bus->dev);
>> 
>> 	return ret;
>> }
>> @@ -359,13 +363,16 @@ int sdw_nwrite(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
>> 			   slave->dev_num, SDW_MSG_FLAG_WRITE, val);
>> 	if (ret < 0)
>> 		return ret;
>> -
>> -	ret = pm_runtime_get_sync(slave->bus->dev);
>> -	if (ret < 0)
>> -		return ret;
>> +	if (pm_runtime_enabled(slave->bus->dev)) {
>> +		ret = pm_runtime_get_sync(slave->bus->dev);
>> +		if (ret < 0)
>> +			return ret;
>> +	}
>> 
>> 	ret = sdw_transfer(slave->bus, &msg);
>> -	pm_runtime_put(slave->bus->dev);
>> +
>> +	if (pm_runtime_enabled(slave->bus->dev))
>> +		pm_runtime_put(slave->bus->dev);
>> 
>> 	return ret;
>> }
>> -- 
>> 2.20.1
>> 
>> _______________________________________________
>> Alsa-devel mailing list
>> Alsa-devel@alsa-project.org
>> https://urldefense.proofpoint.com/v2/url?u=https-3A__mailman.alsa-2Dproject.org_mailman_listinfo_alsa-2Ddevel&d=DwIBAg&c=aUq983L2pue2FqKFoP6PGHMJQyoJ7kl3s3GZ-_haXqY&r=g7GAQENVXx_RQdyXHInPMg&m=vETGQLSPeGb7K_ZsXv4Tl3VFfdXzyummTDga97ozJcg&s=LiW4SToh5U0zhnkox54oRhJ1u3vFNbBB9nmzRDuCDjI&e=


^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 17/40] soundwire: bus: use runtime_pm_get_sync/pm when enabled
  2019-07-26  7:47     ` Jan Kotas
@ 2019-07-26  8:22       ` Guennadi Liakhovetski
  2019-07-26  8:33         ` Jan Kotas
  0 siblings, 1 reply; 183+ messages in thread
From: Guennadi Liakhovetski @ 2019-07-26  8:22 UTC (permalink / raw)
  To: Jan Kotas
  Cc: alsa-devel, tiwai, gregkh, Pierre-Louis Bossart, LKML,
	Vinod Koul, Mark Brown, Srinivas Kandagatla, slawomir.blauciak,
	Sanyog Kale

Hi Jan,

On Fri, Jul 26, 2019 at 07:47:04AM +0000, Jan Kotas wrote:
> Hello,
> 
> I while back I proposed a patch for this, but it went nowhere.
> 
> https://patchwork.kernel.org/patch/10887405/
> Maybe something similar can be implemented?

Yes, I was thinking about checkint -EACCESS too, but then I noticed this code
in rpm_resume():

	else if (dev->power.disable_depth == 1 && dev->power.is_suspended
	    && dev->power.runtime_status == RPM_ACTIVE)
		retval = 1;

i.e. if RT-PM is disabled on the device (but only exactly once?..) and it's
active and the device is suspended for a system suspend, the function will
return 1. I don't understand the logic of this code, but it seems to me it
could break the -EACCESS check?

Thanks
Guennadi

> Jan
> 
> > On 26 Jul 2019, at 09:39, Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com> wrote:
> > 
> > EXTERNAL MAIL
> > 
> > 
> > Hi Pierre,
> > 
> > I might be wrong but this doesn't seem right to me. (Supposedly) all RT-PM
> > functions check for "enabled" internally. The only thing that can happen is
> > that if RT-PM isn't enabled some of those functions will return an error.
> > So, in those cases where the return value of RT-PM functions isn't checked,
> > I don't think you need to do anything. Where it is checked maybe do
> > 
> > +	if (ret < 0 && pm_runtime_enabled(slave->bus->dev))
> > 
> > Thanks
> > Guennadi
> > 
> > On Thu, Jul 25, 2019 at 06:40:09PM -0500, Pierre-Louis Bossart wrote:
> >> Not all platforms support runtime_pm for now, let's use runtime_pm
> >> only when enabled.
> >> 
> >> Suggested-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> >> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> >> ---
> >> drivers/soundwire/bus.c | 25 ++++++++++++++++---------
> >> 1 file changed, 16 insertions(+), 9 deletions(-)
> >> 
> >> diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
> >> index 5ad4109dc72f..0a45dc5713df 100644
> >> --- a/drivers/soundwire/bus.c
> >> +++ b/drivers/soundwire/bus.c
> >> @@ -332,12 +332,16 @@ int sdw_nread(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
> >> 	if (ret < 0)
> >> 		return ret;
> >> 
> >> -	ret = pm_runtime_get_sync(slave->bus->dev);
> >> -	if (ret < 0)
> >> -		return ret;
> >> +	if (pm_runtime_enabled(slave->bus->dev)) {
> >> +		ret = pm_runtime_get_sync(slave->bus->dev);
> >> +		if (ret < 0)
> >> +			return ret;
> >> +	}
> >> 
> >> 	ret = sdw_transfer(slave->bus, &msg);
> >> -	pm_runtime_put(slave->bus->dev);
> >> +
> >> +	if (pm_runtime_enabled(slave->bus->dev))
> >> +		pm_runtime_put(slave->bus->dev);
> >> 
> >> 	return ret;
> >> }
> >> @@ -359,13 +363,16 @@ int sdw_nwrite(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
> >> 			   slave->dev_num, SDW_MSG_FLAG_WRITE, val);
> >> 	if (ret < 0)
> >> 		return ret;
> >> -
> >> -	ret = pm_runtime_get_sync(slave->bus->dev);
> >> -	if (ret < 0)
> >> -		return ret;
> >> +	if (pm_runtime_enabled(slave->bus->dev)) {
> >> +		ret = pm_runtime_get_sync(slave->bus->dev);
> >> +		if (ret < 0)
> >> +			return ret;
> >> +	}
> >> 
> >> 	ret = sdw_transfer(slave->bus, &msg);
> >> -	pm_runtime_put(slave->bus->dev);
> >> +
> >> +	if (pm_runtime_enabled(slave->bus->dev))
> >> +		pm_runtime_put(slave->bus->dev);
> >> 
> >> 	return ret;
> >> }
> >> -- 
> >> 2.20.1
> >> 
> >> _______________________________________________
> >> Alsa-devel mailing list
> >> Alsa-devel@alsa-project.org
> >> https://urldefense.proofpoint.com/v2/url?u=https-3A__mailman.alsa-2Dproject.org_mailman_listinfo_alsa-2Ddevel&d=DwIBAg&c=aUq983L2pue2FqKFoP6PGHMJQyoJ7kl3s3GZ-_haXqY&r=g7GAQENVXx_RQdyXHInPMg&m=vETGQLSPeGb7K_ZsXv4Tl3VFfdXzyummTDga97ozJcg&s=LiW4SToh5U0zhnkox54oRhJ1u3vFNbBB9nmzRDuCDjI&e=
> 
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 17/40] soundwire: bus: use runtime_pm_get_sync/pm when enabled
  2019-07-26  8:22       ` Guennadi Liakhovetski
@ 2019-07-26  8:33         ` Jan Kotas
  2019-07-26  8:42           ` Guennadi Liakhovetski
  0 siblings, 1 reply; 183+ messages in thread
From: Jan Kotas @ 2019-07-26  8:33 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: Jan Kotas, alsa-devel, tiwai, gregkh, Pierre-Louis Bossart, LKML,
	Vinod Koul, Mark Brown, Srinivas Kandagatla, slawomir.blauciak,
	Sanyog Kale



> On 26 Jul 2019, at 10:22, Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com> wrote:
> 
> EXTERNAL MAIL
> 
> 
> Hi Jan,
> 
> On Fri, Jul 26, 2019 at 07:47:04AM +0000, Jan Kotas wrote:
>> Hello,
>> 
>> I while back I proposed a patch for this, but it went nowhere.
>> 
>> https://urldefense.proofpoint.com/v2/url?u=https-3A__patchwork.kernel.org_patch_10887405_&d=DwIBAg&c=aUq983L2pue2FqKFoP6PGHMJQyoJ7kl3s3GZ-_haXqY&r=g7GAQENVXx_RQdyXHInPMg&m=i_0S359hFIVqNgv3fR5_MNzDOHP99trdXszZ-FMiQEE&s=ddktFZYlePh-bC7kXeoKWt4QomupzHATK4FLY4oSWKA&e= 
>> Maybe something similar can be implemented?
> 
> Yes, I was thinking about checkint -EACCESS too, but then I noticed this code
> in rpm_resume():
> 
> 	else if (dev->power.disable_depth == 1 && dev->power.is_suspended
> 	    && dev->power.runtime_status == RPM_ACTIVE)
> 		retval = 1;
> 
> i.e. if RT-PM is disabled on the device (but only exactly once?..) and it's
> active and the device is suspended for a system suspend, the function will
> return 1. I don't understand the logic of this code, but it seems to me it
> could break the -EACCESS check?
> 

Hi,

In such case ret < 0 will not be true, which I think is fine,
if I’m understanding you correctly.

Regards,
Jan


> Thanks
> Guennadi
> 
>> Jan
>> 
>>> On 26 Jul 2019, at 09:39, Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com> wrote:
>>> 
>>> EXTERNAL MAIL
>>> 
>>> 
>>> Hi Pierre,
>>> 
>>> I might be wrong but this doesn't seem right to me. (Supposedly) all RT-PM
>>> functions check for "enabled" internally. The only thing that can happen is
>>> that if RT-PM isn't enabled some of those functions will return an error.
>>> So, in those cases where the return value of RT-PM functions isn't checked,
>>> I don't think you need to do anything. Where it is checked maybe do
>>> 
>>> +	if (ret < 0 && pm_runtime_enabled(slave->bus->dev))
>>> 
>>> Thanks
>>> Guennadi
>>> 
>>> On Thu, Jul 25, 2019 at 06:40:09PM -0500, Pierre-Louis Bossart wrote:
>>>> Not all platforms support runtime_pm for now, let's use runtime_pm
>>>> only when enabled.
>>>> 
>>>> Suggested-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
>>>> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
>>>> ---
>>>> drivers/soundwire/bus.c | 25 ++++++++++++++++---------
>>>> 1 file changed, 16 insertions(+), 9 deletions(-)
>>>> 
>>>> diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
>>>> index 5ad4109dc72f..0a45dc5713df 100644
>>>> --- a/drivers/soundwire/bus.c
>>>> +++ b/drivers/soundwire/bus.c
>>>> @@ -332,12 +332,16 @@ int sdw_nread(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
>>>> 	if (ret < 0)
>>>> 		return ret;
>>>> 
>>>> -	ret = pm_runtime_get_sync(slave->bus->dev);
>>>> -	if (ret < 0)
>>>> -		return ret;
>>>> +	if (pm_runtime_enabled(slave->bus->dev)) {
>>>> +		ret = pm_runtime_get_sync(slave->bus->dev);
>>>> +		if (ret < 0)
>>>> +			return ret;
>>>> +	}
>>>> 
>>>> 	ret = sdw_transfer(slave->bus, &msg);
>>>> -	pm_runtime_put(slave->bus->dev);
>>>> +
>>>> +	if (pm_runtime_enabled(slave->bus->dev))
>>>> +		pm_runtime_put(slave->bus->dev);
>>>> 
>>>> 	return ret;
>>>> }
>>>> @@ -359,13 +363,16 @@ int sdw_nwrite(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
>>>> 			   slave->dev_num, SDW_MSG_FLAG_WRITE, val);
>>>> 	if (ret < 0)
>>>> 		return ret;
>>>> -
>>>> -	ret = pm_runtime_get_sync(slave->bus->dev);
>>>> -	if (ret < 0)
>>>> -		return ret;
>>>> +	if (pm_runtime_enabled(slave->bus->dev)) {
>>>> +		ret = pm_runtime_get_sync(slave->bus->dev);
>>>> +		if (ret < 0)
>>>> +			return ret;
>>>> +	}
>>>> 
>>>> 	ret = sdw_transfer(slave->bus, &msg);
>>>> -	pm_runtime_put(slave->bus->dev);
>>>> +
>>>> +	if (pm_runtime_enabled(slave->bus->dev))
>>>> +		pm_runtime_put(slave->bus->dev);
>>>> 
>>>> 	return ret;
>>>> }
>>>> -- 
>>>> 2.20.1
>>>> 
>>>> _______________________________________________
>>>> Alsa-devel mailing list
>>>> Alsa-devel@alsa-project.org
>>>> https://urldefense.proofpoint.com/v2/url?u=https-3A__mailman.alsa-2Dproject.org_mailman_listinfo_alsa-2Ddevel&d=DwIBAg&c=aUq983L2pue2FqKFoP6PGHMJQyoJ7kl3s3GZ-_haXqY&r=g7GAQENVXx_RQdyXHInPMg&m=vETGQLSPeGb7K_ZsXv4Tl3VFfdXzyummTDga97ozJcg&s=LiW4SToh5U0zhnkox54oRhJ1u3vFNbBB9nmzRDuCDjI&e=
>> 
>> _______________________________________________
>> Alsa-devel mailing list
>> Alsa-devel@alsa-project.org
>> https://urldefense.proofpoint.com/v2/url?u=https-3A__mailman.alsa-2Dproject.org_mailman_listinfo_alsa-2Ddevel&d=DwIBAg&c=aUq983L2pue2FqKFoP6PGHMJQyoJ7kl3s3GZ-_haXqY&r=g7GAQENVXx_RQdyXHInPMg&m=i_0S359hFIVqNgv3fR5_MNzDOHP99trdXszZ-FMiQEE&s=RxPHxKfI3v6Fkh7qzKjq8sNi-5QMoY8XfyMDSquA38o&e= 


^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 17/40] soundwire: bus: use runtime_pm_get_sync/pm when enabled
  2019-07-26  8:33         ` Jan Kotas
@ 2019-07-26  8:42           ` Guennadi Liakhovetski
  0 siblings, 0 replies; 183+ messages in thread
From: Guennadi Liakhovetski @ 2019-07-26  8:42 UTC (permalink / raw)
  To: Jan Kotas
  Cc: alsa-devel, tiwai, gregkh, Pierre-Louis Bossart, LKML,
	Vinod Koul, Mark Brown, Srinivas Kandagatla, slawomir.blauciak,
	Sanyog Kale

On Fri, Jul 26, 2019 at 08:33:35AM +0000, Jan Kotas wrote:
> 
> 
> > On 26 Jul 2019, at 10:22, Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com> wrote:
> > 
> > EXTERNAL MAIL
> > 
> > 
> > Hi Jan,
> > 
> > On Fri, Jul 26, 2019 at 07:47:04AM +0000, Jan Kotas wrote:
> >> Hello,
> >> 
> >> I while back I proposed a patch for this, but it went nowhere.
> >> 
> >> https://urldefense.proofpoint.com/v2/url?u=https-3A__patchwork.kernel.org_patch_10887405_&d=DwIBAg&c=aUq983L2pue2FqKFoP6PGHMJQyoJ7kl3s3GZ-_haXqY&r=g7GAQENVXx_RQdyXHInPMg&m=i_0S359hFIVqNgv3fR5_MNzDOHP99trdXszZ-FMiQEE&s=ddktFZYlePh-bC7kXeoKWt4QomupzHATK4FLY4oSWKA&e= 
> >> Maybe something similar can be implemented?
> > 
> > Yes, I was thinking about checkint -EACCESS too, but then I noticed this code
> > in rpm_resume():
> > 
> > 	else if (dev->power.disable_depth == 1 && dev->power.is_suspended
> > 	    && dev->power.runtime_status == RPM_ACTIVE)
> > 		retval = 1;
> > 
> > i.e. if RT-PM is disabled on the device (but only exactly once?..) and it's
> > active and the device is suspended for a system suspend, the function will
> > return 1. I don't understand the logic of this code, but it seems to me it
> > could break the -EACCESS check?
> > 
> 
> Hi,
> 
> In such case ret < 0 will not be true, which I think is fine,
> if I’m understanding you correctly.

Yes, if we just have to distinguish a single case "RT-PM is enabled and it failed."
Which is indeed the case here, it seems. However if we want to check whether RT-PM
is disabled after a call to, say, pm_runtime_get_sync(), then just checking
-EACCESS isn't always enough - there can be cases when RT-PM is disabled and the
return code is 1. But yes, just for checking for failures, like here, it should be
fine.

Thanks
Guennadi

> >> Jan
> >> 
> >>> On 26 Jul 2019, at 09:39, Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com> wrote:
> >>> 
> >>> EXTERNAL MAIL
> >>> 
> >>> 
> >>> Hi Pierre,
> >>> 
> >>> I might be wrong but this doesn't seem right to me. (Supposedly) all RT-PM
> >>> functions check for "enabled" internally. The only thing that can happen is
> >>> that if RT-PM isn't enabled some of those functions will return an error.
> >>> So, in those cases where the return value of RT-PM functions isn't checked,
> >>> I don't think you need to do anything. Where it is checked maybe do
> >>> 
> >>> +	if (ret < 0 && pm_runtime_enabled(slave->bus->dev))
> >>> 
> >>> Thanks
> >>> Guennadi
> >>> 
> >>> On Thu, Jul 25, 2019 at 06:40:09PM -0500, Pierre-Louis Bossart wrote:
> >>>> Not all platforms support runtime_pm for now, let's use runtime_pm
> >>>> only when enabled.
> >>>> 
> >>>> Suggested-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> >>>> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> >>>> ---
> >>>> drivers/soundwire/bus.c | 25 ++++++++++++++++---------
> >>>> 1 file changed, 16 insertions(+), 9 deletions(-)
> >>>> 
> >>>> diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
> >>>> index 5ad4109dc72f..0a45dc5713df 100644
> >>>> --- a/drivers/soundwire/bus.c
> >>>> +++ b/drivers/soundwire/bus.c
> >>>> @@ -332,12 +332,16 @@ int sdw_nread(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
> >>>> 	if (ret < 0)
> >>>> 		return ret;
> >>>> 
> >>>> -	ret = pm_runtime_get_sync(slave->bus->dev);
> >>>> -	if (ret < 0)
> >>>> -		return ret;
> >>>> +	if (pm_runtime_enabled(slave->bus->dev)) {
> >>>> +		ret = pm_runtime_get_sync(slave->bus->dev);
> >>>> +		if (ret < 0)
> >>>> +			return ret;
> >>>> +	}
> >>>> 
> >>>> 	ret = sdw_transfer(slave->bus, &msg);
> >>>> -	pm_runtime_put(slave->bus->dev);
> >>>> +
> >>>> +	if (pm_runtime_enabled(slave->bus->dev))
> >>>> +		pm_runtime_put(slave->bus->dev);
> >>>> 
> >>>> 	return ret;
> >>>> }
> >>>> @@ -359,13 +363,16 @@ int sdw_nwrite(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
> >>>> 			   slave->dev_num, SDW_MSG_FLAG_WRITE, val);
> >>>> 	if (ret < 0)
> >>>> 		return ret;
> >>>> -
> >>>> -	ret = pm_runtime_get_sync(slave->bus->dev);
> >>>> -	if (ret < 0)
> >>>> -		return ret;
> >>>> +	if (pm_runtime_enabled(slave->bus->dev)) {
> >>>> +		ret = pm_runtime_get_sync(slave->bus->dev);
> >>>> +		if (ret < 0)
> >>>> +			return ret;
> >>>> +	}
> >>>> 
> >>>> 	ret = sdw_transfer(slave->bus, &msg);
> >>>> -	pm_runtime_put(slave->bus->dev);
> >>>> +
> >>>> +	if (pm_runtime_enabled(slave->bus->dev))
> >>>> +		pm_runtime_put(slave->bus->dev);
> >>>> 
> >>>> 	return ret;
> >>>> }
> >>>> -- 
> >>>> 2.20.1
> >>>> 
> >>>> _______________________________________________
> >>>> Alsa-devel mailing list
> >>>> Alsa-devel@alsa-project.org
> >>>> https://urldefense.proofpoint.com/v2/url?u=https-3A__mailman.alsa-2Dproject.org_mailman_listinfo_alsa-2Ddevel&d=DwIBAg&c=aUq983L2pue2FqKFoP6PGHMJQyoJ7kl3s3GZ-_haXqY&r=g7GAQENVXx_RQdyXHInPMg&m=vETGQLSPeGb7K_ZsXv4Tl3VFfdXzyummTDga97ozJcg&s=LiW4SToh5U0zhnkox54oRhJ1u3vFNbBB9nmzRDuCDjI&e=
> >> 
> >> _______________________________________________
> >> Alsa-devel mailing list
> >> Alsa-devel@alsa-project.org
> >> https://urldefense.proofpoint.com/v2/url?u=https-3A__mailman.alsa-2Dproject.org_mailman_listinfo_alsa-2Ddevel&d=DwIBAg&c=aUq983L2pue2FqKFoP6PGHMJQyoJ7kl3s3GZ-_haXqY&r=g7GAQENVXx_RQdyXHInPMg&m=i_0S359hFIVqNgv3fR5_MNzDOHP99trdXszZ-FMiQEE&s=RxPHxKfI3v6Fkh7qzKjq8sNi-5QMoY8XfyMDSquA38o&e= 
> 
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 01/40] soundwire: add debugfs support
  2019-07-25 23:39 ` [RFC PATCH 01/40] soundwire: add debugfs support Pierre-Louis Bossart
  2019-07-25 22:15   ` [alsa-devel] " Guennadi Liakhovetski
@ 2019-07-26  9:22   ` Cezary Rojewski
  2019-07-26 13:57     ` [alsa-devel] " Pierre-Louis Bossart
  2019-07-26 14:04   ` Greg KH
  2 siblings, 1 reply; 183+ messages in thread
From: Cezary Rojewski @ 2019-07-26  9:22 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 2019-07-26 01:39, Pierre-Louis Bossart wrote:
> +static ssize_t sdw_slave_reg_read(struct file *file, char __user *user_buf,
> +				  size_t count, loff_t *ppos)
> +{
> +	struct sdw_slave *slave = file->private_data;
> +	unsigned int reg;
> +	char *buf;
> +	ssize_t ret;
> +	int i, j;
> +
> +	buf = kzalloc(RD_BUF, GFP_KERNEL);
> +	if (!buf)
> +		return -ENOMEM;
> +
> +	ret = scnprintf(buf, RD_BUF, "Register  Value\n");
> +	ret += scnprintf(buf + ret, RD_BUF - ret, "\nDP0\n");
> +
> +	for (i = 0; i < 6; i++)
> +		ret += sdw_sprintf(slave, buf, ret, i);

In most cases explicit reg macro is used, here it's implicit. Align with 
the rest?

> +
> +	ret += scnprintf(buf + ret, RD_BUF - ret, "Bank0\n");
> +	ret += sdw_sprintf(slave, buf, ret, SDW_DP0_CHANNELEN);
> +	for (i = SDW_DP0_SAMPLECTRL1; i <= SDW_DP0_LANECTRL; i++)
> +		ret += sdw_sprintf(slave, buf, ret, i);
> +
> +	ret += scnprintf(buf + ret, RD_BUF - ret, "Bank1\n");
> +	ret += sdw_sprintf(slave, buf, ret,
> +			SDW_DP0_CHANNELEN + SDW_BANK1_OFFSET);
> +	for (i = SDW_DP0_SAMPLECTRL1 + SDW_BANK1_OFFSET;
> +			i <= SDW_DP0_LANECTRL + SDW_BANK1_OFFSET; i++)
> +		ret += sdw_sprintf(slave, buf, ret, i);

I'd advice to revisit macros declarations first.
There should be SDW_DP0_SAMPLECTRL1_B(bank) declared. In general all 
macros for SDW should be "bank-less" (name wise). Additionally, 
SDW_BANK_OFFSET(bank) could be provided for convenience i.e.: return 0 
for bank0.
Yeah, there might be some speed loss in terms of operation count but in 
most cases it is negligible.

Would simplify this entire reg dump greatly.
const array on top with {0, 1} elements and replacing explicit "bank0/1" 
strings with "bank%d" gets code size reduced while not losing on 
readability.

> +
> +	ret += scnprintf(buf + ret, RD_BUF - ret, "\nSCP\n");
> +	for (i = SDW_SCP_INT1; i <= SDW_SCP_BANKDELAY; i++)
> +		ret += sdw_sprintf(slave, buf, ret, i);
> +	for (i = SDW_SCP_DEVID_0; i <= SDW_SCP_DEVID_5; i++)
> +		ret += sdw_sprintf(slave, buf, ret, i);
> +
> +	ret += scnprintf(buf + ret, RD_BUF - ret, "Bank0\n");
> +	ret += sdw_sprintf(slave, buf, ret, SDW_SCP_FRAMECTRL_B0);
> +	ret += sdw_sprintf(slave, buf, ret, SDW_SCP_NEXTFRAME_B0);
> +
> +	ret += scnprintf(buf + ret, RD_BUF - ret, "Bank1\n");
> +	ret += sdw_sprintf(slave, buf, ret, SDW_SCP_FRAMECTRL_B1);
> +	ret += sdw_sprintf(slave, buf, ret, SDW_SCP_NEXTFRAME_B1);
> +
> +	for (i = 1; i < 14; i++) {

Explicit valid slave addresses would be preferred.

> +		ret += scnprintf(buf + ret, RD_BUF - ret, "\nDP%d\n", i);
> +		reg = SDW_DPN_INT(i);
> +		for (j = 0; j < 6; j++)
> +			ret += sdw_sprintf(slave, buf, ret, reg + j);
> +
> +		ret += scnprintf(buf + ret, RD_BUF - ret, "Bank0\n");
> +		reg = SDW_DPN_CHANNELEN_B0(i);
> +		for (j = 0; j < 9; j++)
> +			ret += sdw_sprintf(slave, buf, ret, reg + j);
> +
> +		ret += scnprintf(buf + ret, RD_BUF - ret, "Bank1\n");
> +		reg = SDW_DPN_CHANNELEN_B1(i);
> +		for (j = 0; j < 9; j++)
> +			ret += sdw_sprintf(slave, buf, ret, reg + j);

Some sort of MAX_CHANNELS would be nice here too.

> +	}
> +
> +	ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
> +	kfree(buf);
> +
> +	return ret;
> +}
> +
> +static const struct file_operations sdw_slave_reg_fops = {
> +	.open = simple_open,
> +	.read = sdw_slave_reg_read,
> +	.llseek = default_llseek,
> +};
> +
> +struct dentry *sdw_slave_debugfs_init(struct sdw_slave *slave)
> +{
> +	struct dentry *master;
> +	struct dentry *d;
> +	char name[32];
> +
> +	master = slave->bus->debugfs;
> +
> +	/* create the debugfs slave-name */
> +	snprintf(name, sizeof(name), "%s", dev_name(&slave->dev));
> +	d = debugfs_create_dir(name, master);
> +
> +	debugfs_create_file("registers", 0400, d, slave, &sdw_slave_reg_fops);

Pointer returned by _create_file gets completely ignored here. At least 
dbg msg would be nice if it fails.

> +	return d;
> +}
> +

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 04/40] soundwire: intel: add debugfs register dump
  2019-07-25 23:39 ` [RFC PATCH 04/40] soundwire: intel: add debugfs register dump Pierre-Louis Bossart
@ 2019-07-26  9:35   ` Cezary Rojewski
  2019-07-26 14:00     ` [alsa-devel] " Pierre-Louis Bossart
  2019-07-26 14:06   ` Greg KH
  1 sibling, 1 reply; 183+ messages in thread
From: Cezary Rojewski @ 2019-07-26  9:35 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 2019-07-26 01:39, Pierre-Louis Bossart wrote:
> +static void intel_debugfs_init(struct sdw_intel *sdw)
> +{
> +	struct dentry *root = sdw->cdns.bus.debugfs;
> +
> +	if (!root)
> +		return;
> +
> +	sdw->fs = debugfs_create_dir("intel-sdw", root);
> +	if (IS_ERR_OR_NULL(sdw->fs)) {
> +		dev_err(sdw->cdns.dev, "debugfs root creation failed\n");
> +		sdw->fs = NULL;
> +		return;
> +	}
> +
> +	debugfs_create_file("intel-registers", 0400, sdw->fs, sdw,
> +			    &intel_reg_fops);
> +
> +	sdw_cdns_debugfs_init(&sdw->cdns, sdw->fs);
> +}

I believe there should be dummy equivalent of _init and _exit if debugfs 
is not enabled (if these are defined already and I've missed it, please 
ignore).

> +static void intel_debugfs_exit(struct sdw_intel *sdw)
> +{
> +	debugfs_remove_recursive(sdw->fs);
> +}

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 03/40] soundwire: cadence_master: align debugfs to 8 digits
  2019-07-25 23:39 ` [RFC PATCH 03/40] soundwire: cadence_master: align debugfs to 8 digits Pierre-Louis Bossart
@ 2019-07-26  9:38   ` Cezary Rojewski
  2019-07-26 13:58     ` [alsa-devel] " Pierre-Louis Bossart
  2019-08-02 11:50   ` Vinod Koul
  1 sibling, 1 reply; 183+ messages in thread
From: Cezary Rojewski @ 2019-07-26  9:38 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 2019-07-26 01:39, Pierre-Louis Bossart wrote:
> SQUASHME
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>   drivers/soundwire/cadence_master.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
> index 91e8bacb83e3..9f611a1fff0a 100644
> --- a/drivers/soundwire/cadence_master.c
> +++ b/drivers/soundwire/cadence_master.c
> @@ -234,7 +234,7 @@ static ssize_t cdns_sprintf(struct sdw_cdns *cdns,
>   			    char *buf, size_t pos, unsigned int reg)
>   {
>   	return scnprintf(buf + pos, RD_BUF - pos,
> -			 "%4x\t%4x\n", reg, cdns_readl(cdns, reg));
> +			 "%4x\t%8x\n", reg, cdns_readl(cdns, reg));
>   }
>   
>   static ssize_t cdns_reg_read(struct file *file, char __user *user_buf,
> 

Should just be merged together with the introducing commit. Guess it's 
posted unintentionally.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 06/40] soundwire: intel: prevent possible dereference in hw_params
  2019-07-25 23:39 ` [RFC PATCH 06/40] soundwire: intel: prevent possible dereference in hw_params Pierre-Louis Bossart
@ 2019-07-26  9:45   ` Cezary Rojewski
  2019-07-26 14:02     ` [alsa-devel] " Pierre-Louis Bossart
  2019-08-02 11:55   ` Vinod Koul
  1 sibling, 1 reply; 183+ messages in thread
From: Cezary Rojewski @ 2019-07-26  9:45 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 2019-07-26 01:39, Pierre-Louis Bossart wrote:
> This should not happen in production systems but we should test for
> all callback arguments before invoking the config_stream callback.
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>   drivers/soundwire/intel.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
> index 68832e613b1e..497879dd9c0d 100644
> --- a/drivers/soundwire/intel.c
> +++ b/drivers/soundwire/intel.c
> @@ -509,7 +509,7 @@ static int intel_config_stream(struct sdw_intel *sdw,
>   			       struct snd_soc_dai *dai,
>   			       struct snd_pcm_hw_params *hw_params, int link_id)
>   {
> -	if (sdw->res->ops && sdw->res->ops->config_stream)
> +	if (sdw->res->ops && sdw->res->ops->config_stream && sdw->res->arg)
>   		return sdw->res->ops->config_stream(sdw->res->arg,
>   				substream, dai, hw_params, link_id);
>   
> 

Hmm, declaring local for sdw->res should prove useful here after 
addition of 4th sdw->res dereference.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 09/40] soundwire: cadence_master: fix usage of CONFIG_UPDATE
  2019-07-25 23:40 ` [RFC PATCH 09/40] soundwire: cadence_master: fix usage of CONFIG_UPDATE Pierre-Louis Bossart
  2019-07-25 22:23   ` [alsa-devel] " Guennadi Liakhovetski
  2019-07-26  2:11   ` Bard liao
@ 2019-07-26  9:53   ` Cezary Rojewski
  2019-07-26  9:54     ` Cezary Rojewski
  2019-08-02 12:03   ` Vinod Koul
  2019-08-05  8:51   ` Sanyog Kale
  4 siblings, 1 reply; 183+ messages in thread
From: Cezary Rojewski @ 2019-07-26  9:53 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 2019-07-26 01:40, Pierre-Louis Bossart wrote:
>   /*
>    * debugfs
>    */
> @@ -758,15 +774,9 @@ static int _cdns_enable_interrupt(struct sdw_cdns *cdns)
>    */
>   int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
>   {
> -	int ret;
> -
>   	_cdns_enable_interrupt(cdns);
> -	ret = cdns_clear_bit(cdns, CDNS_MCP_CONFIG_UPDATE,
> -			     CDNS_MCP_CONFIG_UPDATE_BIT);
> -	if (ret < 0)
> -		dev_err(cdns->dev, "Config update timedout\n");
>   
> -	return ret;
> +	return 0;
>   }
>   EXPORT_SYMBOL(sdw_cdns_enable_interrupt);

Rather than ignoring _cdns_enable_interrupt - despite said func always 
returning 0 - simply do: return _cnds_enable_interrupt(cdns) and flag 
caller with inline.

Afterwards, one can think if such encapsulation is even required - 
remove existing sdw_cdns_enable_interrupt and rename _cnds_enable_interrupt?

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 09/40] soundwire: cadence_master: fix usage of CONFIG_UPDATE
  2019-07-26  9:53   ` Cezary Rojewski
@ 2019-07-26  9:54     ` Cezary Rojewski
  0 siblings, 0 replies; 183+ messages in thread
From: Cezary Rojewski @ 2019-07-26  9:54 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale



On 2019-07-26 11:53, Cezary Rojewski wrote:
> On 2019-07-26 01:40, Pierre-Louis Bossart wrote:
>>   /*
>>    * debugfs
>>    */
>> @@ -758,15 +774,9 @@ static int _cdns_enable_interrupt(struct sdw_cdns 
>> *cdns)
>>    */
>>   int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
>>   {
>> -    int ret;
>> -
>>       _cdns_enable_interrupt(cdns);
>> -    ret = cdns_clear_bit(cdns, CDNS_MCP_CONFIG_UPDATE,
>> -                 CDNS_MCP_CONFIG_UPDATE_BIT);
>> -    if (ret < 0)
>> -        dev_err(cdns->dev, "Config update timedout\n");
>> -    return ret;
>> +    return 0;
>>   }
>>   EXPORT_SYMBOL(sdw_cdns_enable_interrupt);
> 
> Rather than ignoring _cdns_enable_interrupt - despite said func always 
> returning 0 - simply do: return _cnds_enable_interrupt(cdns) and flag 
> caller with inline.
> 
> Afterwards, one can think if such encapsulation is even required - 
> remove existing sdw_cdns_enable_interrupt and rename 
> _cnds_enable_interrupt?

Nevermind, I see you simplified it in the next patch..

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 20/40] soundwire: prototypes for suspend/resume
  2019-07-25 23:40 ` [RFC PATCH 20/40] soundwire: prototypes for suspend/resume Pierre-Louis Bossart
@ 2019-07-26 10:04   ` Cezary Rojewski
  2019-07-26 14:15     ` [alsa-devel] " Pierre-Louis Bossart
  2019-08-02 17:03   ` Vinod Koul
  1 sibling, 1 reply; 183+ messages in thread
From: Cezary Rojewski @ 2019-07-26 10:04 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 2019-07-26 01:40, Pierre-Louis Bossart wrote:
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>   drivers/soundwire/cadence_master.h | 3 +++
>   1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/soundwire/cadence_master.h b/drivers/soundwire/cadence_master.h
> index c0bf6ff00a44..d375bbfead18 100644
> --- a/drivers/soundwire/cadence_master.h
> +++ b/drivers/soundwire/cadence_master.h
> @@ -165,6 +165,9 @@ int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns);
>   
>   void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root);
>   
> +int sdw_cdns_suspend(struct sdw_cdns *cdns);
> +bool sdw_cdns_check_resume_status(struct sdw_cdns *cdns);
> +
>   int sdw_cdns_get_stream(struct sdw_cdns *cdns,
>   			struct sdw_cdns_streams *stream,
>   			u32 ch, u32 dir);
> 

No commit message, guess it's SQUASHME commit and shouldn't be part of 
overall series.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 23/40] soundwire: stream: fix disable sequence
  2019-07-25 23:40 ` [RFC PATCH 23/40] soundwire: stream: fix disable sequence Pierre-Louis Bossart
@ 2019-07-26 10:14   ` Cezary Rojewski
  2019-07-26 14:17     ` [alsa-devel] " Pierre-Louis Bossart
  2019-07-26 14:51   ` Guennadi Liakhovetski
  2019-08-05  9:56   ` Sanyog Kale
  2 siblings, 1 reply; 183+ messages in thread
From: Cezary Rojewski @ 2019-07-26 10:14 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 2019-07-26 01:40, Pierre-Louis Bossart wrote:
>   
> -	return do_bank_switch(stream);
> +	ret = do_bank_switch(stream);
> +	if (ret < 0) {
> +		dev_err(bus->dev, "Bank switch failed: %d\n", ret);
> +		return ret;
> +	}
> +
> +	/* make sure alternate bank (previous current) is also disabled */
> +	list_for_each_entry(m_rt, &stream->master_list, stream_node) {
> +		bus = m_rt->bus;
> +		/* Disable port(s) */
> +		ret = sdw_enable_disable_ports(m_rt, false);
> +		if (ret < 0) {
> +			dev_err(bus->dev, "Disable port(s) failed: %d\n", ret);
> +			return ret;
> +		}
> +	}
> +
> +	return 0;
>   }
>   
>   /**
> 

While not directly connected to this commit, I see that you do:
link_for_each_entry(m_rt, &stream->master_list, stream_node)

quite often in /stream.c code. Helpful macro would prove useful.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 24/40] soundwire: cadence_master: use BIOS defaults for frame shape
  2019-07-25 23:40 ` [RFC PATCH 24/40] soundwire: cadence_master: use BIOS defaults for frame shape Pierre-Louis Bossart
@ 2019-07-26 10:20   ` Cezary Rojewski
  2019-07-26 14:22     ` [alsa-devel] " Pierre-Louis Bossart
  2019-08-02 17:10   ` Vinod Koul
  2019-08-05 10:01   ` Sanyog Kale
  2 siblings, 1 reply; 183+ messages in thread
From: Cezary Rojewski @ 2019-07-26 10:20 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 2019-07-26 01:40, Pierre-Louis Bossart wrote:
> +static u32 cdns_set_default_frame_shape(int n_rows, int n_cols)
> +{
> +	u32 val;
> +	int c;
> +	int r;
> +
> +	r = sdw_find_row_index(n_rows);
> +	c = sdw_find_col_index(n_cols);
> +
> +	val = (r << 3) | c;
> +
> +	return val;
> +}
> +
>   /**
>    * sdw_cdns_init() - Cadence initialization
>    * @cdns: Cadence instance
> @@ -977,7 +990,9 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
>   	cdns_writel(cdns, CDNS_MCP_CLK_CTRL0, val);
>   
>   	/* Set the default frame shape */
> -	cdns_writel(cdns, CDNS_MCP_FRAME_SHAPE_INIT, CDNS_DEFAULT_FRAME_SHAPE);
> +	val = cdns_set_default_frame_shape(prop->default_row,
> +					   prop->default_col);
> +	cdns_writel(cdns, CDNS_MCP_FRAME_SHAPE_INIT, val);
>   
>   	/* Set SSP interval to default value */
>   	cdns_writel(cdns, CDNS_MCP_SSP_CTRL0, CDNS_DEFAULT_SSP_INTERVAL);
> 

Suggestion:
declare "generic" _get_frame_frame(rows, cols) instead and let it do the 
bitwise operations for you. Pretty sure this won't be the only place in 
code where reg value for frame_shape needs to be prepared.

Said function could be as simple as:
return (row << 3) | cols;
+inline flag

i.e. could be even a macro..

Otherwise modify _set_default_frame_shape to simply:
return (r << 3) | c

without involving additional local val variable (I don't really see the 
point for any locals there though).

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 29/40] soundwire: intel_init: add kernel module parameter to filter out links
  2019-07-25 23:40 ` [RFC PATCH 29/40] soundwire: intel_init: add kernel module parameter to filter out links Pierre-Louis Bossart
@ 2019-07-26 10:30   ` Cezary Rojewski
  2019-07-26 14:43     ` [alsa-devel] " Pierre-Louis Bossart
  0 siblings, 1 reply; 183+ messages in thread
From: Cezary Rojewski @ 2019-07-26 10:30 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 2019-07-26 01:40, Pierre-Louis Bossart wrote:
> @@ -83,6 +87,9 @@ static struct sdw_intel_ctx
>   	caps = ioread32(res->mmio_base + SDW_SHIM_BASE + SDW_SHIM_LCAP);
>   	caps &= GENMASK(2, 0);
>   
> +	dev_dbg(&adev->dev, "SoundWire links: BIOS count %d hardware caps %d\n",
> +		count, caps);
> +
>   	/* Check HW supported vs property value and use min of two */
>   	count = min_t(u8, caps, count);
>   

This message does not look like it belongs to current patch - no 
link_mask dependency whatsoever. There have been couple "informative" 
patches in your series, maybe schedule it with them instead (as a 
separate series)?


^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 31/40] soundwire: intel: move shutdown() callback and don't export symbol
  2019-07-25 23:40 ` [RFC PATCH 31/40] soundwire: intel: move shutdown() callback and don't export symbol Pierre-Louis Bossart
@ 2019-07-26 10:38   ` Cezary Rojewski
  2019-07-26 14:46     ` [alsa-devel] " Pierre-Louis Bossart
  0 siblings, 1 reply; 183+ messages in thread
From: Cezary Rojewski @ 2019-07-26 10:38 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 2019-07-26 01:40, Pierre-Louis Bossart wrote:
> +void intel_shutdown(struct snd_pcm_substream *substream,
> +		    struct snd_soc_dai *dai)
> +{
> +	struct sdw_cdns_dma_data *dma;
> +
> +	dma = snd_soc_dai_get_dma_data(dai, substream);
> +	if (!dma)
> +		return;
> +
> +	snd_soc_dai_set_dma_data(dai, substream, NULL);
> +	kfree(dma);
> +}

Correct me if I'm wrong, but do we really need to _get_dma_ here?
_set_dma_ seems bulletproof, same for kfree.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 32/40] soundwire: intel: add helper for initialization
  2019-07-25 23:40 ` [RFC PATCH 32/40] soundwire: intel: add helper for initialization Pierre-Louis Bossart
@ 2019-07-26 10:42   ` Cezary Rojewski
  2019-07-26 14:55     ` [alsa-devel] " Pierre-Louis Bossart
  0 siblings, 1 reply; 183+ messages in thread
From: Cezary Rojewski @ 2019-07-26 10:42 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 2019-07-26 01:40, Pierre-Louis Bossart wrote:
> Move code to helper for reuse in power management routines
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>   drivers/soundwire/intel.c | 16 +++++++++++-----
>   1 file changed, 11 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
> index c40ab443e723..215dc81cdf73 100644
> --- a/drivers/soundwire/intel.c
> +++ b/drivers/soundwire/intel.c
> @@ -984,6 +984,15 @@ static struct sdw_master_ops sdw_intel_ops = {
>   	.post_bank_switch = intel_post_bank_switch,
>   };
>   
> +static int intel_init(struct sdw_intel *sdw)
> +{
> +	/* Initialize shim and controller */
> +	intel_link_power_up(sdw);
> +	intel_shim_init(sdw);
> +
> +	return sdw_cdns_init(&sdw->cdns);
> +}

Why don't we check polling status for _link_power_up? I've already met 
slow starting devices in the past. If polling fails and -EAGAIN is 
returned, flow of initialization should react appropriately e.g. poll 
till MAX_TIMEOUT of some sort -or- collapse.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 33/40] soundwire: intel: Add basic power management support
  2019-07-25 23:40 ` [RFC PATCH 33/40] soundwire: intel: Add basic power management support Pierre-Louis Bossart
@ 2019-07-26 10:50   ` Cezary Rojewski
  2019-07-26 14:57     ` [alsa-devel] " Pierre-Louis Bossart
  0 siblings, 1 reply; 183+ messages in thread
From: Cezary Rojewski @ 2019-07-26 10:50 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 2019-07-26 01:40, Pierre-Louis Bossart wrote:
> +static int intel_resume(struct device *dev)
> +{
> +	struct sdw_intel *sdw;
> +	int ret;
> +
> +	sdw = dev_get_drvdata(dev);
> +
> +	ret = intel_init(sdw);
> +	if (ret) {
> +		dev_err(dev, "%s failed: %d", __func__, ret);
> +		return ret;
> +	}
> +
> +	sdw_cdns_enable_interrupt(&sdw->cdns);
> +
> +	return ret;
> +}
> +
> +#endif

Suggestion: the local declaration + initialization via dev_get_drvdata() 
are usually combined.

Given the upstream declaration of _enable_interrupt, it does return 
error code/ success. Given current flow, if function gets to 
_enable_interrupt call, ret is already set to 0. Returning 
sdw_cds_enable_interrupt() directly would both simplify the definition 
and prevent status loss.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 27/40] soundwire: Add Intel resource management algorithm
  2019-07-25 23:40 ` [RFC PATCH 27/40] soundwire: Add Intel resource management algorithm Pierre-Louis Bossart
@ 2019-07-26 11:07   ` Cezary Rojewski
  2019-07-26 14:41     ` [alsa-devel] " Pierre-Louis Bossart
  2019-07-26 15:43   ` Guennadi Liakhovetski
  2019-08-05 16:54   ` Sanyog Kale
  2 siblings, 1 reply; 183+ messages in thread
From: Cezary Rojewski @ 2019-07-26 11:07 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 2019-07-26 01:40, Pierre-Louis Bossart wrote:
> This algorithm computes bus parameters like clock frequency, frame
> shape and port transport parameters based on active stream(s) running
> on the bus.
> 
> This implementation is optimal for Intel platforms. Developers can
> also implement their own .compute_params() callback for specific
> resource management algorithm.
> 
> Credits: this patch is based on an earlier internal contribution by
> Vinod Koul, Sanyog Kale, Shreyas Nc and Hardik Shah. All hard-coded
> values were removed from the initial contribution to use BIOS
> information instead.
> 
> FIXME: remove checkpatch report
> WARNING: Reusing the krealloc arg is almost always a bug
> +			group->rates = krealloc(group->rates,
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>

Could you specify the requirements and limitations for this algorithm? 
Last year I written calc for Linux based on Windows (please don't burn 
me here) equivalent though said requirements/ limitiations might have 
changed and nothing is valid any longer.

I remember that some parts of specification overcomplicated the 
calculator and due to actual, realtime usecases it could be greatly 
simplified (that's why I mention that my work is probably no longer 
valid). However, these details would help me in reviewing your 
implementation and providing suggestions.

And yes, "Frame shape calculator" probably suits this better.
Though this might be just a preference thingy : )

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 00/40] soundwire: updates for 5.4
  2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
                   ` (39 preceding siblings ...)
  2019-07-25 23:40 ` [RFC PATCH 40/40] soundwire: intel: add delay on restart for enumeration Pierre-Louis Bossart
@ 2019-07-26 11:14 ` Cezary Rojewski
  2019-07-26 15:23   ` [alsa-devel] " Pierre-Louis Bossart
  40 siblings, 1 reply; 183+ messages in thread
From: Cezary Rojewski @ 2019-07-26 11:14 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak

On 2019-07-26 01:39, Pierre-Louis Bossart wrote:
> The existing upstream code allows for SoundWire devices to be
> enumerated and managed by the bus, but streaming is not currently
> supported.
> 
> Bard Liao, Rander Wang and I did quite a bit of integration/validation
> work to close this gap and we now have SoundWire streaming + basic
> power managemement on Intel CometLake and IceLake reference
> boards. These changes are still preliminary and should not be merged
> as is, but it's time to start reviews. While the number of patches is
> quite large, each of the changes is quite small.
> 
> SOF driver changes will be submitted shortly as well but are still
> being validated.
> 
> ClockStop modes and synchronized playback on
> multiple links are not supported for now and will likely be part of
> the next cycle (dependencies on codec drivers and multi-cpu DAI
> support).
> 
> Acknowledgements: This work would not have been possible without the
> support of Slawomir Blauciak and Tomasz Lauda on the SOF side,
> currently being reviewed, see
> https://github.com/thesofproject/sof/pull/1638
> 
> Comments and feedback welcome!

Hello Pierre,

This patchset is pretty large - I'd suggest dividing next RFC into 
segments: debugfs, info, power-management, basic flow corrections and 
frame shape calculator.
Some commits have no messages and others lack additional info - tried to 
provide feedback wherever I could, though, especially for the last one, 
it would be vital to post additional info so in-depth feedback can be 
provided.

Maybe nothing for calculator will come up, maybe something will. In 
general I remember it being an essential part of SDW and one where many 
bugs where found during the initial verification phase.

Thanks for your contribution and have a good day!
Czarek

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 09/40] soundwire: cadence_master: fix usage of CONFIG_UPDATE
  2019-07-26  2:11   ` Bard liao
@ 2019-07-26 13:33     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 13:33 UTC (permalink / raw)
  To: Bard liao, alsa-devel
  Cc: tiwai, gregkh, linux-kernel, vkoul, broonie, srinivas.kandagatla,
	jank, slawomir.blauciak, Sanyog Kale


>> @@ -758,15 +774,9 @@ static int _cdns_enable_interrupt(struct sdw_cdns 
>> *cdns)
>>    */
>>   int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
>>   {
>> -    int ret;
>> -
>>       _cdns_enable_interrupt(cdns);
>> -    ret = cdns_clear_bit(cdns, CDNS_MCP_CONFIG_UPDATE,
>> -                 CDNS_MCP_CONFIG_UPDATE_BIT);
>> -    if (ret < 0)
>> -        dev_err(cdns->dev, "Config update timedout\n");
>> -    return ret;
> Should we add cdns_update_config() here?

indeed, this would be a good improvement. The code works because we 
added the exit_reset() sequence which does call cdns_update_config(), 
but better make this function self-contained. When we enable the 
clock-stop mode we will not do this reset sequence.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 01/40] soundwire: add debugfs support
  2019-07-25 22:15   ` [alsa-devel] " Guennadi Liakhovetski
@ 2019-07-26 13:43     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 13:43 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: alsa-devel, tiwai, gregkh, linux-kernel, vkoul, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale



On 7/25/19 5:15 PM, Guennadi Liakhovetski wrote:
> Hi Pierre,
> 
> A couple of nitpicks:

Thanks for the feedback!

>>   create mode 100644 drivers/soundwire/debugfs.c
> 
> [snip]
> 
>> diff --git a/drivers/soundwire/bus.h b/drivers/soundwire/bus.h
>> index 3048ca153f22..06ac4adb0074 100644
>> --- a/drivers/soundwire/bus.h
>> +++ b/drivers/soundwire/bus.h
>> @@ -18,6 +18,30 @@ static inline int sdw_acpi_find_slaves(struct sdw_bus *bus)
>>   void sdw_extract_slave_id(struct sdw_bus *bus,
>>   			  u64 addr, struct sdw_slave_id *id);
>>   
>> +#ifdef CONFIG_DEBUG_FS
>> +struct dentry *sdw_bus_debugfs_init(struct sdw_bus *bus);
>> +void sdw_bus_debugfs_exit(struct dentry *d);
>> +struct dentry *sdw_slave_debugfs_init(struct sdw_slave *slave);
>> +void sdw_slave_debugfs_exit(struct dentry *d);
>> +void sdw_debugfs_init(void);
>> +void sdw_debugfs_exit(void);
>> +#else
>> +struct dentry *sdw_bus_debugfs_init(struct sdw_bus *bus)
>> +{ return NULL; }
> 
> static?
> 
>> +
>> +void sdw_bus_debugfs_exit(struct dentry *d) {}
>> +
>> +struct dentry *sdw_slave_debugfs_init(struct sdw_slave *slave)
>> +{ return NULL; }
>> +
>> +void sdw_slave_debugfs_exit(struct dentry *d) {}
>> +
>> +void sdw_debugfs_init(void) {}
>> +
>> +void sdw_debugfs_exit(void) {}
> 
> Same for all the above. You could also declare them inline, but I really hope
> the compiler will be smart enough to do that itself.

yes, I'll add static inline for all this.

>> +struct dentry *sdw_bus_debugfs_init(struct sdw_bus *bus)
>> +{
>> +	struct dentry *d;
> 
> I would remove the above
> 
>> +	char name[16];
>> +
>> +	if (!sdw_debugfs_root)
>> +		return NULL;
>> +
>> +	/* create the debugfs master-N */
>> +	snprintf(name, sizeof(name), "master-%d", bus->link_id);
>> +	d = debugfs_create_dir(name, sdw_debugfs_root);
>> +
>> +	return d;
> 
> And just do
> 
> +	return debugfs_create_dir(name, sdw_debugfs_root);

yep, will do.

>> +static ssize_t sdw_sprintf(struct sdw_slave *slave,
>> +			   char *buf, size_t pos, unsigned int reg)
>> +{
>> +	int value;
>> +
>> +	value = sdw_read(slave, reg);
> 
> I personally would join the two lines above, but that's just a personal
> preference.

I prefer splitting variables and code, I just can't mentally split the two.

> 
>> +
>> +	if (value < 0)
>> +		return scnprintf(buf + pos, RD_BUF - pos, "%3x\tXX\n", reg);
>> +	else
> 
> I think it's advised to not use an else in such cases.
> 
> Thanks
> Guennadi
> 
>> +		return scnprintf(buf + pos, RD_BUF - pos,
>> +				"%3x\t%2x\n", reg, value);
>> +}

The intent was to provide a visual cue that the register is not 
implemented, which is quite useful. Not all registers are mandatory and 
not all vendors document the entire set of registers, so it's a good way 
to figure things out. The value is not used for any functional purpose, 
it's just a register dump for the integrator to look at. I'll add a note 
to explain the idea.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 01/40] soundwire: add debugfs support
  2019-07-26  9:22   ` Cezary Rojewski
@ 2019-07-26 13:57     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 13:57 UTC (permalink / raw)
  To: Cezary Rojewski
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

Thanks for the feedback Cezary.

>> +static ssize_t sdw_slave_reg_read(struct file *file, char __user 
>> *user_buf,
>> +                  size_t count, loff_t *ppos)
>> +{
>> +    struct sdw_slave *slave = file->private_data;
>> +    unsigned int reg;
>> +    char *buf;
>> +    ssize_t ret;
>> +    int i, j;
>> +
>> +    buf = kzalloc(RD_BUF, GFP_KERNEL);
>> +    if (!buf)
>> +        return -ENOMEM;
>> +
>> +    ret = scnprintf(buf, RD_BUF, "Register  Value\n");
>> +    ret += scnprintf(buf + ret, RD_BUF - ret, "\nDP0\n");
>> +
>> +    for (i = 0; i < 6; i++)
>> +        ret += sdw_sprintf(slave, buf, ret, i);
> 
> In most cases explicit reg macro is used, here it's implicit. Align with 
> the rest?

I don't see what you are referring to, or I need more coffee.
we use this function sdw_printf in a number of places. Or are you 
referring to the magic value 6? That should indeed be a macro.

>> +
>> +    ret += scnprintf(buf + ret, RD_BUF - ret, "Bank0\n");
>> +    ret += sdw_sprintf(slave, buf, ret, SDW_DP0_CHANNELEN);
>> +    for (i = SDW_DP0_SAMPLECTRL1; i <= SDW_DP0_LANECTRL; i++)
>> +        ret += sdw_sprintf(slave, buf, ret, i);
>> +
>> +    ret += scnprintf(buf + ret, RD_BUF - ret, "Bank1\n");
>> +    ret += sdw_sprintf(slave, buf, ret,
>> +            SDW_DP0_CHANNELEN + SDW_BANK1_OFFSET);
>> +    for (i = SDW_DP0_SAMPLECTRL1 + SDW_BANK1_OFFSET;
>> +            i <= SDW_DP0_LANECTRL + SDW_BANK1_OFFSET; i++)
>> +        ret += sdw_sprintf(slave, buf, ret, i);
> 
> I'd advice to revisit macros declarations first.
> There should be SDW_DP0_SAMPLECTRL1_B(bank) declared. In general all 
> macros for SDW should be "bank-less" (name wise). Additionally, 
> SDW_BANK_OFFSET(bank) could be provided for convenience i.e.: return 0 
> for bank0.
> Yeah, there might be some speed loss in terms of operation count but in 
> most cases it is negligible.
> 
> Would simplify this entire reg dump greatly.
> const array on top with {0, 1} elements and replacing explicit "bank0/1" 
> strings with "bank%d" gets code size reduced while not losing on 
> readability.

This could require a lot of changes in other parts of the code, and I 
don't want to do this just for debugfs. It's valid point that maybe the 
code can be simplified, but the changes are an across-the-board change 
to be done when we don't add new functionality. I'll keep this on the 
todo list.

> 
>> +
>> +    ret += scnprintf(buf + ret, RD_BUF - ret, "\nSCP\n");
>> +    for (i = SDW_SCP_INT1; i <= SDW_SCP_BANKDELAY; i++)
>> +        ret += sdw_sprintf(slave, buf, ret, i);
>> +    for (i = SDW_SCP_DEVID_0; i <= SDW_SCP_DEVID_5; i++)
>> +        ret += sdw_sprintf(slave, buf, ret, i);
>> +
>> +    ret += scnprintf(buf + ret, RD_BUF - ret, "Bank0\n");
>> +    ret += sdw_sprintf(slave, buf, ret, SDW_SCP_FRAMECTRL_B0);
>> +    ret += sdw_sprintf(slave, buf, ret, SDW_SCP_NEXTFRAME_B0);
>> +
>> +    ret += scnprintf(buf + ret, RD_BUF - ret, "Bank1\n");
>> +    ret += sdw_sprintf(slave, buf, ret, SDW_SCP_FRAMECTRL_B1);
>> +    ret += sdw_sprintf(slave, buf, ret, SDW_SCP_NEXTFRAME_B1);
>> +
>> +    for (i = 1; i < 14; i++) {
> 
> Explicit valid slave addresses would be preferred.

no, these are ports. we should use a macro instead of the magic 14 but 
it's fine to try and read all ports. As I explained it's a good way to 
figure out how many ports the Slave device supports even in the absence 
of documentation. This also helps figure out if the DisCo properties 
make sense.

> 
>> +        ret += scnprintf(buf + ret, RD_BUF - ret, "\nDP%d\n", i);
>> +        reg = SDW_DPN_INT(i);
>> +        for (j = 0; j < 6; j++)
>> +            ret += sdw_sprintf(slave, buf, ret, reg + j);
>> +
>> +        ret += scnprintf(buf + ret, RD_BUF - ret, "Bank0\n");
>> +        reg = SDW_DPN_CHANNELEN_B0(i);
>> +        for (j = 0; j < 9; j++)
>> +            ret += sdw_sprintf(slave, buf, ret, reg + j);
>> +
>> +        ret += scnprintf(buf + ret, RD_BUF - ret, "Bank1\n");
>> +        reg = SDW_DPN_CHANNELEN_B1(i);
>> +        for (j = 0; j < 9; j++)
>> +            ret += sdw_sprintf(slave, buf, ret, reg + j);
> 
> Some sort of MAX_CHANNELS would be nice here too.

Yes, need to use macros indeed.

>> +struct dentry *sdw_slave_debugfs_init(struct sdw_slave *slave)
>> +{
>> +    struct dentry *master;
>> +    struct dentry *d;
>> +    char name[32];
>> +
>> +    master = slave->bus->debugfs;
>> +
>> +    /* create the debugfs slave-name */
>> +    snprintf(name, sizeof(name), "%s", dev_name(&slave->dev));
>> +    d = debugfs_create_dir(name, master);
>> +
>> +    debugfs_create_file("registers", 0400, d, slave, 
>> &sdw_slave_reg_fops);
> 
> Pointer returned by _create_file gets completely ignored here. At least 
> dbg msg would be nice if it fails.
> 
>> +    return d;

I understood that Greg KH doesn't want us to depend on the result of 
debugfs calls, but a dev_dbg is likely ok.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 03/40] soundwire: cadence_master: align debugfs to 8 digits
  2019-07-26  9:38   ` Cezary Rojewski
@ 2019-07-26 13:58     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 13:58 UTC (permalink / raw)
  To: Cezary Rojewski
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale



On 7/26/19 4:38 AM, Cezary Rojewski wrote:
> On 2019-07-26 01:39, Pierre-Louis Bossart wrote:
>> SQUASHME
>>
>> Signed-off-by: Pierre-Louis Bossart 
>> <pierre-louis.bossart@linux.intel.com>
>> ---
>>   drivers/soundwire/cadence_master.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/soundwire/cadence_master.c 
>> b/drivers/soundwire/cadence_master.c
>> index 91e8bacb83e3..9f611a1fff0a 100644
>> --- a/drivers/soundwire/cadence_master.c
>> +++ b/drivers/soundwire/cadence_master.c
>> @@ -234,7 +234,7 @@ static ssize_t cdns_sprintf(struct sdw_cdns *cdns,
>>                   char *buf, size_t pos, unsigned int reg)
>>   {
>>       return scnprintf(buf + pos, RD_BUF - pos,
>> -             "%4x\t%4x\n", reg, cdns_readl(cdns, reg));
>> +             "%4x\t%8x\n", reg, cdns_readl(cdns, reg));
>>   }
>>   static ssize_t cdns_reg_read(struct file *file, char __user *user_buf,
>>
> 
> Should just be merged together with the introducing commit. Guess it's 
> posted unintentionally.

Yep, I missed this, will squash in the updates as intended.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 04/40] soundwire: intel: add debugfs register dump
  2019-07-26  9:35   ` Cezary Rojewski
@ 2019-07-26 14:00     ` Pierre-Louis Bossart
  2019-07-26 14:11       ` Greg KH
  0 siblings, 1 reply; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 14:00 UTC (permalink / raw)
  To: Cezary Rojewski
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale



On 7/26/19 4:35 AM, Cezary Rojewski wrote:
> On 2019-07-26 01:39, Pierre-Louis Bossart wrote:
>> +static void intel_debugfs_init(struct sdw_intel *sdw)
>> +{
>> +    struct dentry *root = sdw->cdns.bus.debugfs;
>> +
>> +    if (!root)
>> +        return;
>> +
>> +    sdw->fs = debugfs_create_dir("intel-sdw", root);
>> +    if (IS_ERR_OR_NULL(sdw->fs)) {
>> +        dev_err(sdw->cdns.dev, "debugfs root creation failed\n");
>> +        sdw->fs = NULL;
>> +        return;
>> +    }
>> +
>> +    debugfs_create_file("intel-registers", 0400, sdw->fs, sdw,
>> +                &intel_reg_fops);
>> +
>> +    sdw_cdns_debugfs_init(&sdw->cdns, sdw->fs);
>> +}
> 
> I believe there should be dummy equivalent of _init and _exit if debugfs 
> is not enabled (if these are defined already and I've missed it, please 
> ignore).

I think the direction is just to keep going if there is an error or 
debufs is not enabled.

> 
>> +static void intel_debugfs_exit(struct sdw_intel *sdw)
>> +{
>> +    debugfs_remove_recursive(sdw->fs);
>> +}

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 06/40] soundwire: intel: prevent possible dereference in hw_params
  2019-07-26  9:45   ` Cezary Rojewski
@ 2019-07-26 14:02     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 14:02 UTC (permalink / raw)
  To: Cezary Rojewski
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale


>> diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
>> index 68832e613b1e..497879dd9c0d 100644
>> --- a/drivers/soundwire/intel.c
>> +++ b/drivers/soundwire/intel.c
>> @@ -509,7 +509,7 @@ static int intel_config_stream(struct sdw_intel *sdw,
>>                      struct snd_soc_dai *dai,
>>                      struct snd_pcm_hw_params *hw_params, int link_id)
>>   {
>> -    if (sdw->res->ops && sdw->res->ops->config_stream)
>> +    if (sdw->res->ops && sdw->res->ops->config_stream && sdw->res->arg)
>>           return sdw->res->ops->config_stream(sdw->res->arg,
>>                   substream, dai, hw_params, link_id);
>>
> 
> Hmm, declaring local for sdw->res should prove useful here after 
> addition of 4th sdw->res dereference.

yes, it's an eyesore. I added this to quickly fix a kernel oops while 
debugging, will simplify. thanks for the note.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 01/40] soundwire: add debugfs support
  2019-07-25 23:39 ` [RFC PATCH 01/40] soundwire: add debugfs support Pierre-Louis Bossart
  2019-07-25 22:15   ` [alsa-devel] " Guennadi Liakhovetski
  2019-07-26  9:22   ` Cezary Rojewski
@ 2019-07-26 14:04   ` Greg KH
  2019-07-26 15:29     ` Pierre-Louis Bossart
  2 siblings, 1 reply; 183+ messages in thread
From: Greg KH @ 2019-07-26 14:04 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On Thu, Jul 25, 2019 at 06:39:53PM -0500, Pierre-Louis Bossart wrote:
> Add base debugfs mechanism for SoundWire bus by creating soundwire
> root and master-N and slave-x hierarchy.
> 
> Also add SDW Slave SCP, DP0 and DP-N register debug file.
> 
> Registers not implemented will print as "XX"
> 
> Credits: this patch is based on an earlier internal contribution by
> Vinod Koul, Sanyog Kale, Shreyas Nc and Hardik Shah. The main change
> is the use of scnprintf to avoid known issues with snprintf.
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/Makefile    |   4 +-
>  drivers/soundwire/bus.c       |   6 ++
>  drivers/soundwire/bus.h       |  24 ++++++
>  drivers/soundwire/bus_type.c  |   3 +
>  drivers/soundwire/debugfs.c   | 156 ++++++++++++++++++++++++++++++++++
>  drivers/soundwire/slave.c     |   1 +
>  include/linux/soundwire/sdw.h |   4 +
>  7 files changed, 197 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/soundwire/debugfs.c
> 
> diff --git a/drivers/soundwire/Makefile b/drivers/soundwire/Makefile
> index fd99a831b92a..88990cac48a7 100644
> --- a/drivers/soundwire/Makefile
> +++ b/drivers/soundwire/Makefile
> @@ -4,7 +4,9 @@
>  #
>  
>  #Bus Objs
> -soundwire-bus-objs := bus_type.o bus.o slave.o mipi_disco.o stream.o
> +soundwire-bus-objs := bus_type.o bus.o slave.o mipi_disco.o stream.o \
> +			debugfs.o
> +
>  obj-$(CONFIG_SOUNDWIRE_BUS) += soundwire-bus.o
>  
>  #Cadence Objs
> diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
> index fe745830a261..5ad4109dc72f 100644
> --- a/drivers/soundwire/bus.c
> +++ b/drivers/soundwire/bus.c
> @@ -49,6 +49,8 @@ int sdw_add_bus_master(struct sdw_bus *bus)
>  		}
>  	}
>  
> +	bus->debugfs = sdw_bus_debugfs_init(bus);
> +
>  	/*
>  	 * Device numbers in SoundWire are 0 through 15. Enumeration device
>  	 * number (0), Broadcast device number (15), Group numbers (12 and
> @@ -109,6 +111,8 @@ static int sdw_delete_slave(struct device *dev, void *data)
>  	struct sdw_slave *slave = dev_to_sdw_dev(dev);
>  	struct sdw_bus *bus = slave->bus;
>  
> +	sdw_slave_debugfs_exit(slave->debugfs);
> +
>  	mutex_lock(&bus->bus_lock);
>  
>  	if (slave->dev_num) /* clear dev_num if assigned */
> @@ -130,6 +134,8 @@ static int sdw_delete_slave(struct device *dev, void *data)
>  void sdw_delete_bus_master(struct sdw_bus *bus)
>  {
>  	device_for_each_child(bus->dev, NULL, sdw_delete_slave);
> +
> +	sdw_bus_debugfs_exit(bus->debugfs);
>  }
>  EXPORT_SYMBOL(sdw_delete_bus_master);
>  
> diff --git a/drivers/soundwire/bus.h b/drivers/soundwire/bus.h
> index 3048ca153f22..06ac4adb0074 100644
> --- a/drivers/soundwire/bus.h
> +++ b/drivers/soundwire/bus.h
> @@ -18,6 +18,30 @@ static inline int sdw_acpi_find_slaves(struct sdw_bus *bus)
>  void sdw_extract_slave_id(struct sdw_bus *bus,
>  			  u64 addr, struct sdw_slave_id *id);
>  
> +#ifdef CONFIG_DEBUG_FS
> +struct dentry *sdw_bus_debugfs_init(struct sdw_bus *bus);
> +void sdw_bus_debugfs_exit(struct dentry *d);
> +struct dentry *sdw_slave_debugfs_init(struct sdw_slave *slave);
> +void sdw_slave_debugfs_exit(struct dentry *d);
> +void sdw_debugfs_init(void);
> +void sdw_debugfs_exit(void);
> +#else
> +struct dentry *sdw_bus_debugfs_init(struct sdw_bus *bus)
> +{ return NULL; }
> +
> +void sdw_bus_debugfs_exit(struct dentry *d) {}
> +
> +struct dentry *sdw_slave_debugfs_init(struct sdw_slave *slave)
> +{ return NULL; }
> +
> +void sdw_slave_debugfs_exit(struct dentry *d) {}
> +
> +void sdw_debugfs_init(void) {}
> +
> +void sdw_debugfs_exit(void) {}
> +
> +#endif
> +
>  enum {
>  	SDW_MSG_FLAG_READ = 0,
>  	SDW_MSG_FLAG_WRITE,
> diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c
> index 2655602f0cfb..4a465f55039f 100644
> --- a/drivers/soundwire/bus_type.c
> +++ b/drivers/soundwire/bus_type.c
> @@ -6,6 +6,7 @@
>  #include <linux/pm_domain.h>
>  #include <linux/soundwire/sdw.h>
>  #include <linux/soundwire/sdw_type.h>
> +#include "bus.h"
>  
>  /**
>   * sdw_get_device_id - find the matching SoundWire device id
> @@ -177,11 +178,13 @@ EXPORT_SYMBOL_GPL(sdw_unregister_driver);
>  
>  static int __init sdw_bus_init(void)
>  {
> +	sdw_debugfs_init();
>  	return bus_register(&sdw_bus_type);
>  }
>  
>  static void __exit sdw_bus_exit(void)
>  {
> +	sdw_debugfs_exit();
>  	bus_unregister(&sdw_bus_type);
>  }
>  
> diff --git a/drivers/soundwire/debugfs.c b/drivers/soundwire/debugfs.c
> new file mode 100644
> index 000000000000..8d86e100516e
> --- /dev/null
> +++ b/drivers/soundwire/debugfs.c
> @@ -0,0 +1,156 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)

No, for debugfs-specific code, that dual license makes no sense, right?
Don't cargo-cult SPDX identifiers please.

> +// Copyright(c) 2017-19 Intel Corporation.

Spell the year out fully unless you want lawyers knocking on your door :)

> +
> +#include <linux/device.h>
> +#include <linux/debugfs.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/slab.h>
> +#include <linux/soundwire/sdw.h>
> +#include <linux/soundwire/sdw_registers.h>
> +#include "bus.h"
> +
> +#ifdef CONFIG_DEBUG_FS
> +struct dentry *sdw_debugfs_root;
> +#endif

This whole file is not built if that option is not enabled, so why the
#ifdef?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 09/40] soundwire: cadence_master: fix usage of CONFIG_UPDATE
  2019-07-25 22:23   ` [alsa-devel] " Guennadi Liakhovetski
@ 2019-07-26 14:05     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 14:05 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: alsa-devel, tiwai, gregkh, linux-kernel, vkoul, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale


>> @@ -943,7 +953,10 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
>>   
>>   	cdns_writel(cdns, CDNS_MCP_CONFIG, val);
>>   
>> -	return 0;
>> +	/* commit changes */
>> +	ret = cdns_update_config(cdns);
>> +
>> +	return ret;
> 
> +	return cdns_update_config(cdns);

yes, will fix. thanks!

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 04/40] soundwire: intel: add debugfs register dump
  2019-07-25 23:39 ` [RFC PATCH 04/40] soundwire: intel: add debugfs register dump Pierre-Louis Bossart
  2019-07-26  9:35   ` Cezary Rojewski
@ 2019-07-26 14:06   ` Greg KH
  2019-07-26 14:09     ` Greg KH
  2019-07-26 15:34     ` Pierre-Louis Bossart
  1 sibling, 2 replies; 183+ messages in thread
From: Greg KH @ 2019-07-26 14:06 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On Thu, Jul 25, 2019 at 06:39:56PM -0500, Pierre-Louis Bossart wrote:
> Add debugfs file to dump the Intel SoundWire registers
> 
> Credits: this patch is based on an earlier internal contribution by
> Vinod Koul, Sanyog Kale, Shreyas Nc and Hardik Shah. The main change
> is the use of scnprintf to avoid known issues with snprintf.
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/intel.c | 115 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 115 insertions(+)
> 
> diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
> index 317873bc0555..aeadc341c0a3 100644
> --- a/drivers/soundwire/intel.c
> +++ b/drivers/soundwire/intel.c
> @@ -6,6 +6,7 @@
>   */
>  
>  #include <linux/acpi.h>
> +#include <linux/debugfs.h>
>  #include <linux/delay.h>
>  #include <linux/module.h>
>  #include <linux/interrupt.h>
> @@ -16,6 +17,7 @@
>  #include <linux/soundwire/sdw.h>
>  #include <linux/soundwire/sdw_intel.h>
>  #include "cadence_master.h"
> +#include "bus.h"
>  #include "intel.h"
>  
>  /* Intel SHIM Registers Definition */
> @@ -98,6 +100,7 @@ struct sdw_intel {
>  	struct sdw_cdns cdns;
>  	int instance;
>  	struct sdw_intel_link_res *res;
> +	struct dentry *fs;
>  };
>  
>  #define cdns_to_intel(_cdns) container_of(_cdns, struct sdw_intel, cdns)
> @@ -161,6 +164,115 @@ static int intel_set_bit(void __iomem *base, int offset, u32 value, u32 mask)
>  	return -EAGAIN;
>  }
>  
> +/*
> + * debugfs
> + */
> +
> +#define RD_BUF (2 * PAGE_SIZE)
> +
> +static ssize_t intel_sprintf(void __iomem *mem, bool l,
> +			     char *buf, size_t pos, unsigned int reg)
> +{
> +	int value;
> +
> +	if (l)
> +		value = intel_readl(mem, reg);
> +	else
> +		value = intel_readw(mem, reg);
> +
> +	return scnprintf(buf + pos, RD_BUF - pos, "%4x\t%4x\n", reg, value);
> +}
> +
> +static ssize_t intel_reg_read(struct file *file, char __user *user_buf,
> +			      size_t count, loff_t *ppos)
> +{
> +	struct sdw_intel *sdw = file->private_data;
> +	void __iomem *s = sdw->res->shim;
> +	void __iomem *a = sdw->res->alh;
> +	char *buf;
> +	ssize_t ret;
> +	int i, j;
> +	unsigned int links, reg;
> +
> +	buf = kzalloc(RD_BUF, GFP_KERNEL);
> +	if (!buf)
> +		return -ENOMEM;
> +
> +	links = intel_readl(s, SDW_SHIM_LCAP) & GENMASK(2, 0);
> +
> +	ret = scnprintf(buf, RD_BUF, "Register  Value\n");
> +	ret += scnprintf(buf + ret, RD_BUF - ret, "\nShim\n");
> +
> +	for (i = 0; i < 4; i++) {
> +		reg = SDW_SHIM_LCAP + i * 4;
> +		ret += intel_sprintf(s, true, buf, ret, reg);
> +	}
> +
> +	for (i = 0; i < links; i++) {
> +		ret += scnprintf(buf + ret, RD_BUF - ret, "\nLink%d\n", i);
> +		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTLSCAP(i));
> +		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTLS0CM(i));
> +		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTLS1CM(i));
> +		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTLS2CM(i));
> +		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTLS3CM(i));
> +		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_PCMSCAP(i));
> +
> +		for (j = 0; j < 8; j++) {
> +			ret += intel_sprintf(s, false, buf, ret,
> +					SDW_SHIM_PCMSYCHM(i, j));
> +			ret += intel_sprintf(s, false, buf, ret,
> +					SDW_SHIM_PCMSYCHC(i, j));
> +		}
> +
> +		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_PDMSCAP(i));
> +		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_IOCTL(i));
> +		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTMCTL(i));
> +	}
> +
> +	ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_WAKEEN);
> +	ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_WAKESTS);
> +
> +	ret += scnprintf(buf + ret, RD_BUF - ret, "\nALH\n");
> +	for (i = 0; i < 8; i++)
> +		ret += intel_sprintf(a, true, buf, ret, SDW_ALH_STRMZCFG(i));
> +
> +	ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
> +	kfree(buf);
> +
> +	return ret;
> +}
> +
> +static const struct file_operations intel_reg_fops = {
> +	.open = simple_open,
> +	.read = intel_reg_read,
> +	.llseek = default_llseek,
> +};

DEFINE_SIMPLE_ATTRIBUTE()?

> +
> +static void intel_debugfs_init(struct sdw_intel *sdw)
> +{
> +	struct dentry *root = sdw->cdns.bus.debugfs;
> +
> +	if (!root)
> +		return;
> +
> +	sdw->fs = debugfs_create_dir("intel-sdw", root);
> +	if (IS_ERR_OR_NULL(sdw->fs)) {
> +		dev_err(sdw->cdns.dev, "debugfs root creation failed\n");

No, come on, don't do that.  I've been sweeping the kernel tree to
remove this anti-pattern.

The debugfs core will print an error if you got something wrong, just
call the function and move on, you NEVER need to check the return value
of a debugfs call.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 37/40] soundwire: cadence_master: add hw_reset capability in debugfs
  2019-07-25 23:40 ` [RFC PATCH 37/40] soundwire: cadence_master: add hw_reset capability in debugfs Pierre-Louis Bossart
@ 2019-07-26 14:07   ` Greg KH
  2019-07-26 15:01     ` [alsa-devel] " Pierre-Louis Bossart
  2019-07-26 15:57   ` Guennadi Liakhovetski
  1 sibling, 1 reply; 183+ messages in thread
From: Greg KH @ 2019-07-26 14:07 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On Thu, Jul 25, 2019 at 06:40:29PM -0500, Pierre-Louis Bossart wrote:
> This is to kick devices into reset and see what software does
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/cadence_master.c | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
> 
> diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
> index fa7230b0f200..53278aa2436f 100644
> --- a/drivers/soundwire/cadence_master.c
> +++ b/drivers/soundwire/cadence_master.c
> @@ -331,6 +331,25 @@ static const struct file_operations cdns_reg_fops = {
>  	.llseek = default_llseek,
>  };
>  
> +static int cdns_hw_reset(void *data, u64 value)
> +{
> +	struct sdw_cdns *cdns = data;
> +	int ret;
> +
> +	if (value != 1)
> +		return 0;
> +
> +	dev_info(cdns->dev, "starting link hw_reset\n");
> +
> +	ret = sdw_cdns_exit_reset(cdns);
> +
> +	dev_info(cdns->dev, "link hw_reset done\n");

Do not be noisy for when things always go right.  This looks like
debuggging code, please remove.

> +
> +	return ret;
> +}
> +
> +DEFINE_DEBUGFS_ATTRIBUTE(cdns_hw_reset_fops, NULL, cdns_hw_reset, "%llu\n");
> +
>  /**
>   * sdw_cdns_debugfs_init() - Cadence debugfs init
>   * @cdns: Cadence instance
> @@ -339,6 +358,9 @@ static const struct file_operations cdns_reg_fops = {
>  void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root)
>  {
>  	debugfs_create_file("cdns-registers", 0400, root, cdns, &cdns_reg_fops);
> +
> +	debugfs_create_file_unsafe("cdns-hw-reset", 0200, root, cdns,
> +				   &cdns_hw_reset_fops);

Why unsafe?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 02/40] soundwire: cadence_master: add debugfs register dump
  2019-07-25 23:39 ` [RFC PATCH 02/40] soundwire: cadence_master: add debugfs register dump Pierre-Louis Bossart
@ 2019-07-26 14:09   ` Greg KH
  2019-07-26 15:32     ` Pierre-Louis Bossart
  2019-08-05  7:55   ` Sanyog Kale
  1 sibling, 1 reply; 183+ messages in thread
From: Greg KH @ 2019-07-26 14:09 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On Thu, Jul 25, 2019 at 06:39:54PM -0500, Pierre-Louis Bossart wrote:
> Add debugfs file to dump the Cadence master registers
> 
> Credits: this patch is based on an earlier internal contribution by
> Vinod Koul, Sanyog Kale, Shreyas Nc and Hardik Shah. The main change
> is the use of scnprintf to avoid known issues with snprintf.
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/cadence_master.c | 98 ++++++++++++++++++++++++++++++
>  drivers/soundwire/cadence_master.h |  2 +
>  2 files changed, 100 insertions(+)
> 
> diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
> index ff4badc9b3de..91e8bacb83e3 100644
> --- a/drivers/soundwire/cadence_master.c
> +++ b/drivers/soundwire/cadence_master.c
> @@ -8,6 +8,7 @@
>  
>  #include <linux/delay.h>
>  #include <linux/device.h>
> +#include <linux/debugfs.h>
>  #include <linux/interrupt.h>
>  #include <linux/io.h>
>  #include <linux/module.h>
> @@ -223,6 +224,103 @@ static int cdns_clear_bit(struct sdw_cdns *cdns, int offset, u32 value)
>  	return -EAGAIN;
>  }
>  
> +/*
> + * debugfs
> + */
> +
> +#define RD_BUF (2 * PAGE_SIZE)
> +
> +static ssize_t cdns_sprintf(struct sdw_cdns *cdns,
> +			    char *buf, size_t pos, unsigned int reg)
> +{
> +	return scnprintf(buf + pos, RD_BUF - pos,
> +			 "%4x\t%4x\n", reg, cdns_readl(cdns, reg));
> +}
> +
> +static ssize_t cdns_reg_read(struct file *file, char __user *user_buf,
> +			     size_t count, loff_t *ppos)
> +{
> +	struct sdw_cdns *cdns = file->private_data;
> +	char *buf;
> +	ssize_t ret;
> +	int i, j;
> +
> +	buf = kzalloc(RD_BUF, GFP_KERNEL);
> +	if (!buf)
> +		return -ENOMEM;
> +
> +	ret = scnprintf(buf, RD_BUF, "Register  Value\n");
> +	ret += scnprintf(buf + ret, RD_BUF - ret, "\nMCP Registers\n");
> +	for (i = 0; i < 8; i++) /* 8 MCP registers */
> +		ret += cdns_sprintf(cdns, buf, ret, i * 4);
> +
> +	ret += scnprintf(buf + ret, RD_BUF - ret,
> +			 "\nStatus & Intr Registers\n");
> +	for (i = 0; i < 13; i++) /* 13 Status & Intr registers */
> +		ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_STAT + i * 4);
> +
> +	ret += scnprintf(buf + ret, RD_BUF - ret,
> +			 "\nSSP & Clk ctrl Registers\n");
> +	ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_SSP_CTRL0);
> +	ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_SSP_CTRL1);
> +	ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_CLK_CTRL0);
> +	ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_CLK_CTRL1);
> +
> +	ret += scnprintf(buf + ret, RD_BUF - ret,
> +			 "\nDPn B0 Registers\n");
> +	for (i = 0; i < 7; i++) {
> +		ret += scnprintf(buf + ret, RD_BUF - ret,
> +				 "\nDP-%d\n", i);
> +		for (j = 0; j < 6; j++)
> +			ret += cdns_sprintf(cdns, buf, ret,
> +					CDNS_DPN_B0_CONFIG(i) + j * 4);
> +	}
> +
> +	ret += scnprintf(buf + ret, RD_BUF - ret,
> +			 "\nDPn B1 Registers\n");
> +	for (i = 0; i < 7; i++) {
> +		ret += scnprintf(buf + ret, RD_BUF - ret,
> +				 "\nDP-%d\n", i);
> +
> +		for (j = 0; j < 6; j++)
> +			ret += cdns_sprintf(cdns, buf, ret,
> +					CDNS_DPN_B1_CONFIG(i) + j * 4);
> +	}
> +
> +	ret += scnprintf(buf + ret, RD_BUF - ret,
> +			 "\nDPn Control Registers\n");
> +	for (i = 0; i < 7; i++)
> +		ret += cdns_sprintf(cdns, buf, ret,
> +				CDNS_PORTCTRL + i * CDNS_PORT_OFFSET);
> +
> +	ret += scnprintf(buf + ret, RD_BUF - ret,
> +			 "\nPDIn Config Registers\n");
> +	for (i = 0; i < 7; i++)
> +		ret += cdns_sprintf(cdns, buf, ret, CDNS_PDI_CONFIG(i));
> +
> +	ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
> +	kfree(buf);
> +
> +	return ret;
> +}
> +
> +static const struct file_operations cdns_reg_fops = {
> +	.open = simple_open,
> +	.read = cdns_reg_read,
> +	.llseek = default_llseek,
> +};

DEFINE_SHOW_ATTRIBUTE()?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 04/40] soundwire: intel: add debugfs register dump
  2019-07-26 14:06   ` Greg KH
@ 2019-07-26 14:09     ` Greg KH
  2019-07-26 15:34     ` Pierre-Louis Bossart
  1 sibling, 0 replies; 183+ messages in thread
From: Greg KH @ 2019-07-26 14:09 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On Fri, Jul 26, 2019 at 04:06:35PM +0200, Greg KH wrote:
> On Thu, Jul 25, 2019 at 06:39:56PM -0500, Pierre-Louis Bossart wrote:
> > Add debugfs file to dump the Intel SoundWire registers
> > 
> > Credits: this patch is based on an earlier internal contribution by
> > Vinod Koul, Sanyog Kale, Shreyas Nc and Hardik Shah. The main change
> > is the use of scnprintf to avoid known issues with snprintf.
> > 
> > Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> > ---
> >  drivers/soundwire/intel.c | 115 ++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 115 insertions(+)
> > 
> > diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
> > index 317873bc0555..aeadc341c0a3 100644
> > --- a/drivers/soundwire/intel.c
> > +++ b/drivers/soundwire/intel.c
> > @@ -6,6 +6,7 @@
> >   */
> >  
> >  #include <linux/acpi.h>
> > +#include <linux/debugfs.h>
> >  #include <linux/delay.h>
> >  #include <linux/module.h>
> >  #include <linux/interrupt.h>
> > @@ -16,6 +17,7 @@
> >  #include <linux/soundwire/sdw.h>
> >  #include <linux/soundwire/sdw_intel.h>
> >  #include "cadence_master.h"
> > +#include "bus.h"
> >  #include "intel.h"
> >  
> >  /* Intel SHIM Registers Definition */
> > @@ -98,6 +100,7 @@ struct sdw_intel {
> >  	struct sdw_cdns cdns;
> >  	int instance;
> >  	struct sdw_intel_link_res *res;
> > +	struct dentry *fs;
> >  };
> >  
> >  #define cdns_to_intel(_cdns) container_of(_cdns, struct sdw_intel, cdns)
> > @@ -161,6 +164,115 @@ static int intel_set_bit(void __iomem *base, int offset, u32 value, u32 mask)
> >  	return -EAGAIN;
> >  }
> >  
> > +/*
> > + * debugfs
> > + */
> > +
> > +#define RD_BUF (2 * PAGE_SIZE)
> > +
> > +static ssize_t intel_sprintf(void __iomem *mem, bool l,
> > +			     char *buf, size_t pos, unsigned int reg)
> > +{
> > +	int value;
> > +
> > +	if (l)
> > +		value = intel_readl(mem, reg);
> > +	else
> > +		value = intel_readw(mem, reg);
> > +
> > +	return scnprintf(buf + pos, RD_BUF - pos, "%4x\t%4x\n", reg, value);
> > +}
> > +
> > +static ssize_t intel_reg_read(struct file *file, char __user *user_buf,
> > +			      size_t count, loff_t *ppos)
> > +{
> > +	struct sdw_intel *sdw = file->private_data;
> > +	void __iomem *s = sdw->res->shim;
> > +	void __iomem *a = sdw->res->alh;
> > +	char *buf;
> > +	ssize_t ret;
> > +	int i, j;
> > +	unsigned int links, reg;
> > +
> > +	buf = kzalloc(RD_BUF, GFP_KERNEL);
> > +	if (!buf)
> > +		return -ENOMEM;
> > +
> > +	links = intel_readl(s, SDW_SHIM_LCAP) & GENMASK(2, 0);
> > +
> > +	ret = scnprintf(buf, RD_BUF, "Register  Value\n");
> > +	ret += scnprintf(buf + ret, RD_BUF - ret, "\nShim\n");
> > +
> > +	for (i = 0; i < 4; i++) {
> > +		reg = SDW_SHIM_LCAP + i * 4;
> > +		ret += intel_sprintf(s, true, buf, ret, reg);
> > +	}
> > +
> > +	for (i = 0; i < links; i++) {
> > +		ret += scnprintf(buf + ret, RD_BUF - ret, "\nLink%d\n", i);
> > +		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTLSCAP(i));
> > +		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTLS0CM(i));
> > +		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTLS1CM(i));
> > +		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTLS2CM(i));
> > +		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTLS3CM(i));
> > +		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_PCMSCAP(i));
> > +
> > +		for (j = 0; j < 8; j++) {
> > +			ret += intel_sprintf(s, false, buf, ret,
> > +					SDW_SHIM_PCMSYCHM(i, j));
> > +			ret += intel_sprintf(s, false, buf, ret,
> > +					SDW_SHIM_PCMSYCHC(i, j));
> > +		}
> > +
> > +		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_PDMSCAP(i));
> > +		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_IOCTL(i));
> > +		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTMCTL(i));
> > +	}
> > +
> > +	ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_WAKEEN);
> > +	ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_WAKESTS);
> > +
> > +	ret += scnprintf(buf + ret, RD_BUF - ret, "\nALH\n");
> > +	for (i = 0; i < 8; i++)
> > +		ret += intel_sprintf(a, true, buf, ret, SDW_ALH_STRMZCFG(i));
> > +
> > +	ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
> > +	kfree(buf);
> > +
> > +	return ret;
> > +}
> > +
> > +static const struct file_operations intel_reg_fops = {
> > +	.open = simple_open,
> > +	.read = intel_reg_read,
> > +	.llseek = default_llseek,
> > +};
> 
> DEFINE_SIMPLE_ATTRIBUTE()?

Oops, I mean DEFINE_SHOW_ATTRIBUTE()?

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 15/40] soundwire: cadence_master: handle multiple status reports per Slave
  2019-07-25 22:31   ` [alsa-devel] " Guennadi Liakhovetski
@ 2019-07-26 14:09     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 14:09 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: alsa-devel, tiwai, gregkh, linux-kernel, vkoul, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale


>> diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
>> index 889fa2cd49ae..25d5c7267c15 100644
>> --- a/drivers/soundwire/cadence_master.c
>> +++ b/drivers/soundwire/cadence_master.c
>> @@ -643,13 +643,35 @@ static int cdns_update_slave_status(struct sdw_cdns *cdns,
>>   
>>   		/* first check if Slave reported multiple status */
>>   		if (set_status > 1) {
>> +			u32 val;
>> +
>>   			dev_warn_ratelimited(cdns->dev,
>> -					     "Slave reported multiple Status: %d\n",
>> -					     mask);
>> -			/*
>> -			 * TODO: we need to reread the status here by
>> -			 * issuing a PING cmd
>> -			 */
>> +					     "Slave %d reported multiple Status: %d\n",
>> +					     i, mask);
>> +
>> +			/* re-check latest status extracted from PING commands */
>> +			val = cdns_readl(cdns, CDNS_MCP_SLAVE_STAT);
>> +			val >>= (i * 2);
> 
> Superfluous parentheses.

Humm, I don't know my left from my right and I can't remember operator 
precedence, so i'd rather make it explicit...

> 
>> +
>> +			switch (val & 0x3) {
>> +			case 0:
>> +				status[i] = SDW_SLAVE_UNATTACHED;
>> +				break;
>> +			case 1:
>> +				status[i] = SDW_SLAVE_ATTACHED;
>> +				break;
>> +			case 2:
>> +				status[i] = SDW_SLAVE_ALERT;
>> +				break;
>> +			default:
> 
> There aren't many values left for the "default" case :-) But I'm not sure whether
> any of
> 
> +			case 3:
> 
> or
> 
> +			case 3:
> +			default:
> 
> would improve readability.
> 
> Thanks
> Guennadi
> 
>> +				status[i] = SDW_SLAVE_RESERVED;
>> +				break;

Yes, those defaults are annoying. Some tools complain so I tend to leave 
them.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 16/40] soundwire: cadence_master: improve startup sequence with link hw_reset
  2019-07-26  7:22   ` [alsa-devel] " Guennadi Liakhovetski
@ 2019-07-26 14:11     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 14:11 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: alsa-devel, tiwai, gregkh, linux-kernel, vkoul, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale


>> +static int do_reset(struct sdw_cdns *cdns)
>> +{
>> +	int ret;
>> +
>> +	/* program maximum length reset to be safe */
>> +	cdns_updatel(cdns, CDNS_MCP_CONTROL,
>> +		     CDNS_MCP_CONTROL_RST_DELAY,
>> +		     CDNS_MCP_CONTROL_RST_DELAY);
>> +
>> +	/* use hardware generated reset */
>> +	cdns_updatel(cdns, CDNS_MCP_CONTROL,
>> +		     CDNS_MCP_CONTROL_HW_RST,
>> +		     CDNS_MCP_CONTROL_HW_RST);
>> +
>> +	/* enable bus operations with clock and data */
>> +	cdns_updatel(cdns, CDNS_MCP_CONFIG,
>> +		     CDNS_MCP_CONFIG_OP,
>> +		     CDNS_MCP_CONFIG_OP_NORMAL);
>> +
>> +	/* commit changes */
>> +	ret = cdns_update_config(cdns);
>> +
>> +	return ret;
> 
> +	return cdns_update_config(cdns);
> 
> and remove the "ret" variable.

Yes, it's the same issue as previously reported. will fix.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 04/40] soundwire: intel: add debugfs register dump
  2019-07-26 14:00     ` [alsa-devel] " Pierre-Louis Bossart
@ 2019-07-26 14:11       ` Greg KH
  0 siblings, 0 replies; 183+ messages in thread
From: Greg KH @ 2019-07-26 14:11 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: Cezary Rojewski, alsa-devel, linux-kernel, tiwai, broonie, vkoul,
	jank, srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On Fri, Jul 26, 2019 at 09:00:28AM -0500, Pierre-Louis Bossart wrote:
> 
> 
> On 7/26/19 4:35 AM, Cezary Rojewski wrote:
> > On 2019-07-26 01:39, Pierre-Louis Bossart wrote:
> > > +static void intel_debugfs_init(struct sdw_intel *sdw)
> > > +{
> > > +    struct dentry *root = sdw->cdns.bus.debugfs;
> > > +
> > > +    if (!root)
> > > +        return;
> > > +
> > > +    sdw->fs = debugfs_create_dir("intel-sdw", root);
> > > +    if (IS_ERR_OR_NULL(sdw->fs)) {
> > > +        dev_err(sdw->cdns.dev, "debugfs root creation failed\n");
> > > +        sdw->fs = NULL;
> > > +        return;
> > > +    }
> > > +
> > > +    debugfs_create_file("intel-registers", 0400, sdw->fs, sdw,
> > > +                &intel_reg_fops);
> > > +
> > > +    sdw_cdns_debugfs_init(&sdw->cdns, sdw->fs);
> > > +}
> > 
> > I believe there should be dummy equivalent of _init and _exit if debugfs
> > is not enabled (if these are defined already and I've missed it, please
> > ignore).
> 
> I think the direction is just to keep going if there is an error or debufs
> is not enabled.

You should not care either way :)

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 20/40] soundwire: prototypes for suspend/resume
  2019-07-26 10:04   ` Cezary Rojewski
@ 2019-07-26 14:15     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 14:15 UTC (permalink / raw)
  To: Cezary Rojewski
  Cc: alsa-devel, tiwai, gregkh, linux-kernel, vkoul, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale



On 7/26/19 5:04 AM, Cezary Rojewski wrote:
> On 2019-07-26 01:40, Pierre-Louis Bossart wrote:
>> Signed-off-by: Pierre-Louis Bossart 
>> <pierre-louis.bossart@linux.intel.com>
>> ---
>>   drivers/soundwire/cadence_master.h | 3 +++
>>   1 file changed, 3 insertions(+)
>>
>> diff --git a/drivers/soundwire/cadence_master.h 
>> b/drivers/soundwire/cadence_master.h
>> index c0bf6ff00a44..d375bbfead18 100644
>> --- a/drivers/soundwire/cadence_master.h
>> +++ b/drivers/soundwire/cadence_master.h
>> @@ -165,6 +165,9 @@ int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns);
>>   void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root);
>> +int sdw_cdns_suspend(struct sdw_cdns *cdns);
>> +bool sdw_cdns_check_resume_status(struct sdw_cdns *cdns);
>> +
>>   int sdw_cdns_get_stream(struct sdw_cdns *cdns,
>>               struct sdw_cdns_streams *stream,
>>               u32 ch, u32 dir);
>>
> 
> No commit message, guess it's SQUASHME commit and shouldn't be part of 
> overall series.

I can't recall why it's separate, will look into this. Thanks.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 23/40] soundwire: stream: fix disable sequence
  2019-07-26 10:14   ` Cezary Rojewski
@ 2019-07-26 14:17     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 14:17 UTC (permalink / raw)
  To: Cezary Rojewski
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale



On 7/26/19 5:14 AM, Cezary Rojewski wrote:
> On 2019-07-26 01:40, Pierre-Louis Bossart wrote:
>> -    return do_bank_switch(stream);
>> +    ret = do_bank_switch(stream);
>> +    if (ret < 0) {
>> +        dev_err(bus->dev, "Bank switch failed: %d\n", ret);
>> +        return ret;
>> +    }
>> +
>> +    /* make sure alternate bank (previous current) is also disabled */
>> +    list_for_each_entry(m_rt, &stream->master_list, stream_node) {
>> +        bus = m_rt->bus;
>> +        /* Disable port(s) */
>> +        ret = sdw_enable_disable_ports(m_rt, false);
>> +        if (ret < 0) {
>> +            dev_err(bus->dev, "Disable port(s) failed: %d\n", ret);
>> +            return ret;
>> +        }
>> +    }
>> +
>> +    return 0;
>>   }
>>   /**
>>
> 
> While not directly connected to this commit, I see that you do:
> link_for_each_entry(m_rt, &stream->master_list, stream_node)
> 
> quite often in /stream.c code. Helpful macro would prove useful.

Yes, but the flip side is that people need to look at what the macro 
does to figure it out, while everyone knows what list_for_each_entry() 
means. Not sure about this one.
And on top of this we'll probably have to rework this code to have a 
background copy of the current bank in the alternate bank so it'd rather 
leave it simple for now.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 24/40] soundwire: cadence_master: use BIOS defaults for frame shape
  2019-07-26 10:20   ` Cezary Rojewski
@ 2019-07-26 14:22     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 14:22 UTC (permalink / raw)
  To: Cezary Rojewski
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale



On 7/26/19 5:20 AM, Cezary Rojewski wrote:
> On 2019-07-26 01:40, Pierre-Louis Bossart wrote:
>> +static u32 cdns_set_default_frame_shape(int n_rows, int n_cols)
>> +{
>> +    u32 val;
>> +    int c;
>> +    int r;
>> +
>> +    r = sdw_find_row_index(n_rows);
>> +    c = sdw_find_col_index(n_cols);
>> +
>> +    val = (r << 3) | c;
>> +
>> +    return val;
>> +}
>> +
>>   /**
>>    * sdw_cdns_init() - Cadence initialization
>>    * @cdns: Cadence instance
>> @@ -977,7 +990,9 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
>>       cdns_writel(cdns, CDNS_MCP_CLK_CTRL0, val);
>>       /* Set the default frame shape */
>> -    cdns_writel(cdns, CDNS_MCP_FRAME_SHAPE_INIT, 
>> CDNS_DEFAULT_FRAME_SHAPE);
>> +    val = cdns_set_default_frame_shape(prop->default_row,
>> +                       prop->default_col);
>> +    cdns_writel(cdns, CDNS_MCP_FRAME_SHAPE_INIT, val);
>>       /* Set SSP interval to default value */
>>       cdns_writel(cdns, CDNS_MCP_SSP_CTRL0, CDNS_DEFAULT_SSP_INTERVAL);
>>
> 
> Suggestion:
> declare "generic" _get_frame_frame(rows, cols) instead and let it do the 
> bitwise operations for you. Pretty sure this won't be the only place in 
> code where reg value for frame_shape needs to be prepared.
> 
> Said function could be as simple as:
> return (row << 3) | cols;
> +inline flag
> 
> i.e. could be even a macro..
> 
> Otherwise modify _set_default_frame_shape to simply:
> return (r << 3) | c
> 
> without involving additional local val variable (I don't really see the 
> point for any locals there though).

what this function does is take the standard-defined offsets for row and 
column and stores them in a Cadence-defined register. I think we can 
probably use a macro to remove the magic '3' value, but there are limits 
to what we can simplify. I should probably add comments so that people 
figure it out.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 26/40] soundwire: cadence_master: fix divider setting in clock register
  2019-07-26  5:19   ` [alsa-devel] " Bard liao
  2019-07-26  5:56     ` rander.wang
@ 2019-07-26 14:24     ` Pierre-Louis Bossart
  1 sibling, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 14:24 UTC (permalink / raw)
  To: Bard liao, alsa-devel
  Cc: tiwai, gregkh, linux-kernel, vkoul, broonie, srinivas.kandagatla,
	jank, slawomir.blauciak, Sanyog Kale, Rander Wang



On 7/26/19 12:19 AM, Bard liao wrote:
> 
> On 7/26/2019 7:40 AM, Pierre-Louis Bossart wrote:
>> From: Rander Wang <rander.wang@linux.intel.com>
>>
>> The existing code uses an OR operation which would mix the original
>> divider setting with the new one, resulting in an invalid
>> configuration that can make codecs hang.
>>
>> Add the mask definition and use cdns_updatel to update divider
>>
>> Signed-off-by: Rander Wang <rander.wang@linux.intel.com>
>> Signed-off-by: Pierre-Louis Bossart 
>> <pierre-louis.bossart@linux.intel.com>
>> ---
>>   drivers/soundwire/cadence_master.c | 12 +++++++-----
>>   1 file changed, 7 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/soundwire/cadence_master.c 
>> b/drivers/soundwire/cadence_master.c
>> index 10ebcef2e84e..18c6ac026e85 100644
>> --- a/drivers/soundwire/cadence_master.c
>> +++ b/drivers/soundwire/cadence_master.c
>> @@ -57,6 +57,7 @@
>>   #define CDNS_MCP_SSP_CTRL1            0x28
>>   #define CDNS_MCP_CLK_CTRL0            0x30
>>   #define CDNS_MCP_CLK_CTRL1            0x38
>> +#define CDNS_MCP_CLK_MCLKD_MASK        GENMASK(7, 0)
>>   #define CDNS_MCP_STAT                0x40
>> @@ -988,9 +989,11 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
>>       /* Set clock divider */
>>       divider    = (prop->mclk_freq / prop->max_clk_freq) - 1;
>>       val = cdns_readl(cdns, CDNS_MCP_CLK_CTRL0);
> 
> 
> Do we still need to read cdns_readl(cdns, CDNS_MCP_CLK_CTRL0)
> 
> after this change?

no I don't think we do indeed.
> 
> 
>> -    val |= divider;
>> -    cdns_writel(cdns, CDNS_MCP_CLK_CTRL0, val);
>> -    cdns_writel(cdns, CDNS_MCP_CLK_CTRL1, val);
>> +
>> +    cdns_updatel(cdns, CDNS_MCP_CLK_CTRL0,
>> +             CDNS_MCP_CLK_MCLKD_MASK, divider);
>> +    cdns_updatel(cdns, CDNS_MCP_CLK_CTRL1,
>> +             CDNS_MCP_CLK_MCLKD_MASK, divider);
>>       pr_err("plb: mclk %d max_freq %d divider %d register %x\n",
>>              prop->mclk_freq,

and this log needs to go away or done in a better way, I missed this.

>> @@ -1064,8 +1067,7 @@ int cdns_bus_conf(struct sdw_bus *bus, struct 
>> sdw_bus_params *params)
>>           mcp_clkctrl_off = CDNS_MCP_CLK_CTRL0;
>>       mcp_clkctrl = cdns_readl(cdns, mcp_clkctrl_off);
> 
> 
> Same here.

yep.

> 
> 
>> -    mcp_clkctrl |= divider;
>> -    cdns_writel(cdns, mcp_clkctrl_off, mcp_clkctrl);
>> +    cdns_updatel(cdns, mcp_clkctrl_off, CDNS_MCP_CLK_MCLKD_MASK, 
>> divider);
>>       pr_err("plb: mclk * 2 %d curr_dr_freq %d divider %d register %x\n",
>>              prop->mclk_freq * SDW_DOUBLE_RATE_FACTOR,
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 27/40] soundwire: Add Intel resource management algorithm
  2019-07-26 11:07   ` Cezary Rojewski
@ 2019-07-26 14:41     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 14:41 UTC (permalink / raw)
  To: Cezary Rojewski
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale



On 7/26/19 6:07 AM, Cezary Rojewski wrote:
> On 2019-07-26 01:40, Pierre-Louis Bossart wrote:
>> This algorithm computes bus parameters like clock frequency, frame
>> shape and port transport parameters based on active stream(s) running
>> on the bus.
>>
>> This implementation is optimal for Intel platforms. Developers can
>> also implement their own .compute_params() callback for specific
>> resource management algorithm.
>>
>> Credits: this patch is based on an earlier internal contribution by
>> Vinod Koul, Sanyog Kale, Shreyas Nc and Hardik Shah. All hard-coded
>> values were removed from the initial contribution to use BIOS
>> information instead.
>>
>> FIXME: remove checkpatch report
>> WARNING: Reusing the krealloc arg is almost always a bug
>> +            group->rates = krealloc(group->rates,
>>
>> Signed-off-by: Pierre-Louis Bossart 
>> <pierre-louis.bossart@linux.intel.com>
> 
> Could you specify the requirements and limitations for this algorithm? 
> Last year I written calc for Linux based on Windows (please don't burn 
> me here) equivalent though said requirements/ limitiations might have 
> changed and nothing is valid any longer.

The frame shape typically only changes by doubling the number of 
columns, and the priority is given to PDM streams which use columns. 
It's hard to document this on a public mailing list, it'd require making 
references to a spec that's only available to MIPI members.

> 
> I remember that some parts of specification overcomplicated the 
> calculator and due to actual, realtime usecases it could be greatly 
> simplified (that's why I mention that my work is probably no longer 
> valid). However, these details would help me in reviewing your 
> implementation and providing suggestions.

To the best of my knowledge, the algorithm follows a script that is used 
for both Windows and Linux. The code was initially written by Vinod and 
team, and I am not aware of simplifications.
There a simplifications that are possible, e.g. we don't support PDM for 
now and the notion of grouping is not needed, but we have to carefully 
balance 'optimization' with 'introducing bugs'. if this algorithm craps 
out then the entire bus operation is in the weeds.

If we really want people to experiment and get a feel for the 
performance of the algorithm, we should really provide a UI where the 
stream parameters can be entered and visually check what the algorithm 
is doing. I have a solution that shows the bits based on the stream 
parameters (need to make it available e.g. in Python), if we connected 
it with the automatic bit allocation it'd be very useful.

> And yes, "Frame shape calculator" probably suits this better.
> Though this might be just a preference thingy : )

Resource management is indeed a bit vague. But frame shape calculator is 
not quite right. The algorithm will find the frame shape that is 
required for the current bandwidth, but will also allocate the bitSlots 
in that frame. In MIPI circles we talk about bitSlot allocation.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 21/40] soundwire: export helpers to find row and column values
  2019-07-25 23:40 ` [RFC PATCH 21/40] soundwire: export helpers to find row and column values Pierre-Louis Bossart
@ 2019-07-26 14:43   ` Guennadi Liakhovetski
  2019-07-26 15:26     ` Pierre-Louis Bossart
  2019-08-05  9:39   ` Sanyog Kale
  1 sibling, 1 reply; 183+ messages in thread
From: Guennadi Liakhovetski @ 2019-07-26 14:43 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, tiwai, gregkh, linux-kernel, vkoul, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale

On Thu, Jul 25, 2019 at 06:40:13PM -0500, Pierre-Louis Bossart wrote:
> Add a prefix for common tables and export 2 helpers to set the frame
> shapes based on row/col values.
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/bus.h    |  7 +++++--
>  drivers/soundwire/stream.c | 14 ++++++++------
>  2 files changed, 13 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/soundwire/bus.h b/drivers/soundwire/bus.h
> index 06ac4adb0074..c57c9c23f6ca 100644
> --- a/drivers/soundwire/bus.h
> +++ b/drivers/soundwire/bus.h
> @@ -73,8 +73,11 @@ struct sdw_msg {
>  
>  #define SDW_DOUBLE_RATE_FACTOR		2
>  
> -extern int rows[SDW_FRAME_ROWS];
> -extern int cols[SDW_FRAME_COLS];
> +extern int sdw_rows[SDW_FRAME_ROWS];
> +extern int sdw_cols[SDW_FRAME_COLS];

So these arrays actually have to be exported? In the current (5.2) sources they
seem to only be used in stream.c, maybe make them static there?

> +
> +int sdw_find_row_index(int row);
> +int sdw_find_col_index(int col);
>  
>  /**
>   * sdw_port_runtime: Runtime port parameters for Master or Slave
> diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c
> index a0476755a459..53f5e790fcd7 100644
> --- a/drivers/soundwire/stream.c
> +++ b/drivers/soundwire/stream.c
> @@ -21,37 +21,39 @@
>   * The rows are arranged as per the array index value programmed
>   * in register. The index 15 has dummy value 0 in order to fill hole.
>   */
> -int rows[SDW_FRAME_ROWS] = {48, 50, 60, 64, 75, 80, 125, 147,
> +int sdw_rows[SDW_FRAME_ROWS] = {48, 50, 60, 64, 75, 80, 125, 147,
>  			96, 100, 120, 128, 150, 160, 250, 0,
>  			192, 200, 240, 256, 72, 144, 90, 180};
>  
> -int cols[SDW_FRAME_COLS] = {2, 4, 6, 8, 10, 12, 14, 16};
> +int sdw_cols[SDW_FRAME_COLS] = {2, 4, 6, 8, 10, 12, 14, 16};
>  
> -static int sdw_find_col_index(int col)
> +int sdw_find_col_index(int col)
>  {
>  	int i;
>  
>  	for (i = 0; i < SDW_FRAME_COLS; i++) {
> -		if (cols[i] == col)
> +		if (sdw_cols[i] == col)
>  			return i;
>  	}
>  
>  	pr_warn("Requested column not found, selecting lowest column no: 2\n");
>  	return 0;
>  }
> +EXPORT_SYMBOL(sdw_find_col_index);
>  
> -static int sdw_find_row_index(int row)
> +int sdw_find_row_index(int row)
>  {
>  	int i;
>  
>  	for (i = 0; i < SDW_FRAME_ROWS; i++) {
> -		if (rows[i] == row)
> +		if (sdw_rows[i] == row)
>  			return i;
>  	}
>  
>  	pr_warn("Requested row not found, selecting lowest row no: 48\n");
>  	return 0;
>  }
> +EXPORT_SYMBOL(sdw_find_row_index);
>  
>  static int _sdw_program_slave_port_params(struct sdw_bus *bus,
>  					  struct sdw_slave *slave,
> -- 
> 2.20.1
> 
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 29/40] soundwire: intel_init: add kernel module parameter to filter out links
  2019-07-26 10:30   ` Cezary Rojewski
@ 2019-07-26 14:43     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 14:43 UTC (permalink / raw)
  To: Cezary Rojewski
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale



On 7/26/19 5:30 AM, Cezary Rojewski wrote:
> On 2019-07-26 01:40, Pierre-Louis Bossart wrote:
>> @@ -83,6 +87,9 @@ static struct sdw_intel_ctx
>>       caps = ioread32(res->mmio_base + SDW_SHIM_BASE + SDW_SHIM_LCAP);
>>       caps &= GENMASK(2, 0);
>> +    dev_dbg(&adev->dev, "SoundWire links: BIOS count %d hardware caps 
>> %d\n",
>> +        count, caps);
>> +
>>       /* Check HW supported vs property value and use min of two */
>>       count = min_t(u8, caps, count);
> 
> This message does not look like it belongs to current patch - no 
> link_mask dependency whatsoever. There have been couple "informative" 
> patches in your series, maybe schedule it with them instead (as a 
> separate series)?

You're right, this log should be in a different patch. it was added when 
I was debugging the DisCo properties a couple of months back and should 
be moved. thanks for noting this.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 31/40] soundwire: intel: move shutdown() callback and don't export symbol
  2019-07-26 10:38   ` Cezary Rojewski
@ 2019-07-26 14:46     ` Pierre-Louis Bossart
  2019-08-02 17:28       ` Vinod Koul
  0 siblings, 1 reply; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 14:46 UTC (permalink / raw)
  To: Cezary Rojewski
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale



On 7/26/19 5:38 AM, Cezary Rojewski wrote:
> On 2019-07-26 01:40, Pierre-Louis Bossart wrote:
>> +void intel_shutdown(struct snd_pcm_substream *substream,
>> +            struct snd_soc_dai *dai)
>> +{
>> +    struct sdw_cdns_dma_data *dma;
>> +
>> +    dma = snd_soc_dai_get_dma_data(dai, substream);
>> +    if (!dma)
>> +        return;
>> +
>> +    snd_soc_dai_set_dma_data(dai, substream, NULL);
>> +    kfree(dma);
>> +}
> 
> Correct me if I'm wrong, but do we really need to _get_dma_ here?
> _set_dma_ seems bulletproof, same for kfree.

I must admit I have no idea why we have a reference to DMAs here, this 
looks like an abuse to store a dai-specific context, and the initial 
test looks like copy-paste to detect invalid configs, as done in other 
callbacks. Vinod and Sanyog might have more history than me here.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 23/40] soundwire: stream: fix disable sequence
  2019-07-25 23:40 ` [RFC PATCH 23/40] soundwire: stream: fix disable sequence Pierre-Louis Bossart
  2019-07-26 10:14   ` Cezary Rojewski
@ 2019-07-26 14:51   ` Guennadi Liakhovetski
  2019-07-26 15:05     ` Pierre-Louis Bossart
  2019-08-05  9:56   ` Sanyog Kale
  2 siblings, 1 reply; 183+ messages in thread
From: Guennadi Liakhovetski @ 2019-07-26 14:51 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, tiwai, gregkh, linux-kernel, vkoul, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale

Unrelated to this specific patch, but I looked at _sdw_disable_stream()
and I see this there (again, maybe my version is outdated already):

	struct sdw_master_runtime *m_rt = NULL;
	struct sdw_bus *bus = NULL;

where both those initialisations are redundant. Moreover:

On Thu, Jul 25, 2019 at 06:40:15PM -0500, Pierre-Louis Bossart wrote:
> When we disable the stream and then call hw_free, two bank switches
> will be handled and as a result we re-enable the stream on hw_free.
> 
> Make sure the stream is disabled on both banks.
> 
> TODO: we need to completely revisit all this and make sure we have a
> mirroring mechanism between current and alternate banks.
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/stream.c | 19 ++++++++++++++++++-
>  1 file changed, 18 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c
> index 53f5e790fcd7..75b9ad1fb1a6 100644
> --- a/drivers/soundwire/stream.c
> +++ b/drivers/soundwire/stream.c
> @@ -1637,7 +1637,24 @@ static int _sdw_disable_stream(struct sdw_stream_runtime *stream)
>  		}
>  	}
>  
> -	return do_bank_switch(stream);
> +	ret = do_bank_switch(stream);
> +	if (ret < 0) {
> +		dev_err(bus->dev, "Bank switch failed: %d\n", ret);
> +		return ret;
> +	}
> +
> +	/* make sure alternate bank (previous current) is also disabled */
> +	list_for_each_entry(m_rt, &stream->master_list, stream_node) {
> +		bus = m_rt->bus;

"bus" is only used below, so at least take that line under "if (ret < 0)"
or even just do "dev_err(m_rt->bus->dev,...)" everywhere in this function
and remove the variable altogether...

Thanks
Guennadi

> +		/* Disable port(s) */
> +		ret = sdw_enable_disable_ports(m_rt, false);
> +		if (ret < 0) {
> +			dev_err(bus->dev, "Disable port(s) failed: %d\n", ret);
> +			return ret;
> +		}
> +	}
> +
> +	return 0;
>  }
>  
>  /**
> -- 
> 2.20.1
> 
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 32/40] soundwire: intel: add helper for initialization
  2019-07-26 10:42   ` Cezary Rojewski
@ 2019-07-26 14:55     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 14:55 UTC (permalink / raw)
  To: Cezary Rojewski
  Cc: alsa-devel, tiwai, gregkh, linux-kernel, vkoul, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale



On 7/26/19 5:42 AM, Cezary Rojewski wrote:
> On 2019-07-26 01:40, Pierre-Louis Bossart wrote:
>> Move code to helper for reuse in power management routines
>>
>> Signed-off-by: Pierre-Louis Bossart 
>> <pierre-louis.bossart@linux.intel.com>
>> ---
>>   drivers/soundwire/intel.c | 16 +++++++++++-----
>>   1 file changed, 11 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
>> index c40ab443e723..215dc81cdf73 100644
>> --- a/drivers/soundwire/intel.c
>> +++ b/drivers/soundwire/intel.c
>> @@ -984,6 +984,15 @@ static struct sdw_master_ops sdw_intel_ops = {
>>       .post_bank_switch = intel_post_bank_switch,
>>   };
>> +static int intel_init(struct sdw_intel *sdw)
>> +{
>> +    /* Initialize shim and controller */
>> +    intel_link_power_up(sdw);
>> +    intel_shim_init(sdw);
>> +
>> +    return sdw_cdns_init(&sdw->cdns);
>> +}
> 
> Why don't we check polling status for _link_power_up? I've already met 
> slow starting devices in the past. If polling fails and -EAGAIN is 
> returned, flow of initialization should react appropriately e.g. poll 
> till MAX_TIMEOUT of some sort -or- collapse.

The code does what it states, it initializes the Intel and Cadence IPs.

What you are referring to is a different problem: once the bus starts, 
then Slave devices will report as attached, and will be enumerated. This 
will take time. The devices I tested show up immediately and within a 
couple of ms the bus is operational. But MIPI allows to the sync to take 
up to 4096 frames, which is 85ms with a 48kHz frame rate, so yes we do 
need to look into this.

We currently do not have a notification that tells us the bus is back to 
normal, that's a design flaw - see the last patch of the series where I 
kicked the can down the road but adding an artificial delay.

So yes good point indeed but on the wrong patch :-)

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 33/40] soundwire: intel: Add basic power management support
  2019-07-26 10:50   ` Cezary Rojewski
@ 2019-07-26 14:57     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 14:57 UTC (permalink / raw)
  To: Cezary Rojewski
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale



On 7/26/19 5:50 AM, Cezary Rojewski wrote:
> On 2019-07-26 01:40, Pierre-Louis Bossart wrote:
>> +static int intel_resume(struct device *dev)
>> +{
>> +    struct sdw_intel *sdw;
>> +    int ret;
>> +
>> +    sdw = dev_get_drvdata(dev);
>> +
>> +    ret = intel_init(sdw);
>> +    if (ret) {
>> +        dev_err(dev, "%s failed: %d", __func__, ret);
>> +        return ret;
>> +    }
>> +
>> +    sdw_cdns_enable_interrupt(&sdw->cdns);
>> +
>> +    return ret;
>> +}
>> +
>> +#endif
> 
> Suggestion: the local declaration + initialization via dev_get_drvdata() 
> are usually combined.

yes, will do.

> 
> Given the upstream declaration of _enable_interrupt, it does return 
> error code/ success. Given current flow, if function gets to 
> _enable_interrupt call, ret is already set to 0. Returning 
> sdw_cds_enable_interrupt() directly would both simplify the definition 
> and prevent status loss.

sounds good, will do, thanks!

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 37/40] soundwire: cadence_master: add hw_reset capability in debugfs
  2019-07-26 14:07   ` Greg KH
@ 2019-07-26 15:01     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 15:01 UTC (permalink / raw)
  To: Greg KH
  Cc: alsa-devel, tiwai, linux-kernel, vkoul, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale

Thanks for the review Greg.

>> +static int cdns_hw_reset(void *data, u64 value)
>> +{
>> +	struct sdw_cdns *cdns = data;
>> +	int ret;
>> +
>> +	if (value != 1)
>> +		return 0;
>> +
>> +	dev_info(cdns->dev, "starting link hw_reset\n");
>> +
>> +	ret = sdw_cdns_exit_reset(cdns);
>> +
>> +	dev_info(cdns->dev, "link hw_reset done\n");
> 
> Do not be noisy for when things always go right.  This looks like
> debuggging code, please remove.

yes, missed this in the cleanup, will remove.

>> +DEFINE_DEBUGFS_ATTRIBUTE(cdns_hw_reset_fops, NULL, cdns_hw_reset, "%llu\n");
>> +
>>   /**
>>    * sdw_cdns_debugfs_init() - Cadence debugfs init
>>    * @cdns: Cadence instance
>> @@ -339,6 +358,9 @@ static const struct file_operations cdns_reg_fops = {
>>   void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root)
>>   {
>>   	debugfs_create_file("cdns-registers", 0400, root, cdns, &cdns_reg_fops);
>> +
>> +	debugfs_create_file_unsafe("cdns-hw-reset", 0200, root, cdns,
>> +				   &cdns_hw_reset_fops);
> 
> Why unsafe?

Dunno. I followed the documentation and my take-away, along with a 
number of examples, was to use _unsafe. I really have no idea if this is 
correct or not, I can remove this qualifier if that's not needed.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 23/40] soundwire: stream: fix disable sequence
  2019-07-26 14:51   ` Guennadi Liakhovetski
@ 2019-07-26 15:05     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 15:05 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: alsa-devel, tiwai, gregkh, linux-kernel, vkoul, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale


> Unrelated to this specific patch, but I looked at _sdw_disable_stream()
> and I see this there (again, maybe my version is outdated already):
> 
> 	struct sdw_master_runtime *m_rt = NULL;
> 	struct sdw_bus *bus = NULL;
> 
> where both those initialisations are redundant. Moreover:

will look at this, thanks.

> 
> On Thu, Jul 25, 2019 at 06:40:15PM -0500, Pierre-Louis Bossart wrote:
>> When we disable the stream and then call hw_free, two bank switches
>> will be handled and as a result we re-enable the stream on hw_free.
>>
>> Make sure the stream is disabled on both banks.
>>
>> TODO: we need to completely revisit all this and make sure we have a
>> mirroring mechanism between current and alternate banks.
>>
>> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
>> ---
>>   drivers/soundwire/stream.c | 19 ++++++++++++++++++-
>>   1 file changed, 18 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c
>> index 53f5e790fcd7..75b9ad1fb1a6 100644
>> --- a/drivers/soundwire/stream.c
>> +++ b/drivers/soundwire/stream.c
>> @@ -1637,7 +1637,24 @@ static int _sdw_disable_stream(struct sdw_stream_runtime *stream)
>>   		}
>>   	}
>>   
>> -	return do_bank_switch(stream);
>> +	ret = do_bank_switch(stream);
>> +	if (ret < 0) {
>> +		dev_err(bus->dev, "Bank switch failed: %d\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	/* make sure alternate bank (previous current) is also disabled */
>> +	list_for_each_entry(m_rt, &stream->master_list, stream_node) {
>> +		bus = m_rt->bus;
> 
> "bus" is only used below, so at least take that line under "if (ret < 0)"
> or even just do "dev_err(m_rt->bus->dev,...)" everywhere in this function
> and remove the variable altogether...

will look at this, thanks Guennadi

> 
> Thanks
> Guennadi
> 
>> +		/* Disable port(s) */
>> +		ret = sdw_enable_disable_ports(m_rt, false);
>> +		if (ret < 0) {
>> +			dev_err(bus->dev, "Disable port(s) failed: %d\n", ret);
>> +			return ret;

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 00/40] soundwire: updates for 5.4
  2019-07-26 11:14 ` [RFC PATCH 00/40] soundwire: updates for 5.4 Cezary Rojewski
@ 2019-07-26 15:23   ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 15:23 UTC (permalink / raw)
  To: Cezary Rojewski
  Cc: alsa-devel, tiwai, gregkh, linux-kernel, vkoul, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak


>> Comments and feedback welcome!
> 
> Hello Pierre,
> 
> This patchset is pretty large - I'd suggest dividing next RFC into 
> segments: debugfs, info, power-management, basic flow corrections and 
> frame shape calculator.

There was an intent to provide a logical progression...

First debugfs, since I believe it was reviewed before, and I wanted 
folks like Greg to double-check it without burrying it too deep.

Then all corrections, followed by the allocator.

And last all PM stuff, split by regular suspend/resume and pm_runtime.

The RFC state is precisely to gather feedback, if folks want a different 
order that's fine. I just wanted to be transparent and share what we have.

> Some commits have no messages and others lack additional info - tried to 
> provide feedback wherever I could, though, especially for the last one, 
> it would be vital to post additional info so in-depth feedback can be 
> provided.

The lack of commits is a miss, I went from 170 debug/integration patches 
to 40 yesterday and my brain was fried.

> Maybe nothing for calculator will come up, maybe something will. In 
> general I remember it being an essential part of SDW and one where many 
> bugs where found during the initial verification phase.

the frame allocation is a critical piece and it does need to be 
hardened. However we can do so in steps. The current setups we have 
support 1 Slave per link and a limited amount of bandwidth. The links 
themselves don't operate at the max frequency.
Also note that that the streams are 'statically' defined by the 
dailinks, and the allocation is not fully dynamic with random 
configurations being request. If you fail you fail fast.

Nevertheless I do plan to recheck the allocator with an additional 
scripting tool. It'd be very good to e.g. dump the current setup in a 
debugfs file and show to users what is happening (or not happening). I 
didn't recall you worked on SoundWire and I can use your practical 
knowledge to make the code and tools better :-)

> 
> Thanks for your contribution and have a good day!

Thanks for reviewing this long series and have a nice week-end.
-Pierre

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 21/40] soundwire: export helpers to find row and column values
  2019-07-26 14:43   ` [alsa-devel] " Guennadi Liakhovetski
@ 2019-07-26 15:26     ` Pierre-Louis Bossart
  2019-08-02 17:04       ` Vinod Koul
  0 siblings, 1 reply; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 15:26 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: alsa-devel, tiwai, gregkh, linux-kernel, vkoul, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale



On 7/26/19 9:43 AM, Guennadi Liakhovetski wrote:
> On Thu, Jul 25, 2019 at 06:40:13PM -0500, Pierre-Louis Bossart wrote:
>> Add a prefix for common tables and export 2 helpers to set the frame
>> shapes based on row/col values.
>>
>> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
>> ---
>>   drivers/soundwire/bus.h    |  7 +++++--
>>   drivers/soundwire/stream.c | 14 ++++++++------
>>   2 files changed, 13 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/soundwire/bus.h b/drivers/soundwire/bus.h
>> index 06ac4adb0074..c57c9c23f6ca 100644
>> --- a/drivers/soundwire/bus.h
>> +++ b/drivers/soundwire/bus.h
>> @@ -73,8 +73,11 @@ struct sdw_msg {
>>   
>>   #define SDW_DOUBLE_RATE_FACTOR		2
>>   
>> -extern int rows[SDW_FRAME_ROWS];
>> -extern int cols[SDW_FRAME_COLS];
>> +extern int sdw_rows[SDW_FRAME_ROWS];
>> +extern int sdw_cols[SDW_FRAME_COLS];
> 
> So these arrays actually have to be exported? In the current (5.2) sources they
> seem to only be used in stream.c, maybe make them static there?
> 
>> +
>> +int sdw_find_row_index(int row);
>> +int sdw_find_col_index(int col);

yes, they need to be exported, they are used by the allocation algorithm 
(in Patch 27).
Others will need this for non-Intel solutions, it's really a part of the 
standard definition and should be shared.
I can improve the commit message to make this explicit.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 01/40] soundwire: add debugfs support
  2019-07-26 14:04   ` Greg KH
@ 2019-07-26 15:29     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 15:29 UTC (permalink / raw)
  To: Greg KH
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale


>> diff --git a/drivers/soundwire/debugfs.c b/drivers/soundwire/debugfs.c
>> new file mode 100644
>> index 000000000000..8d86e100516e
>> --- /dev/null
>> +++ b/drivers/soundwire/debugfs.c
>> @@ -0,0 +1,156 @@
>> +// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
> 
> No, for debugfs-specific code, that dual license makes no sense, right?
> Don't cargo-cult SPDX identifiers please.

It's a miss, I used EXPORT_GPL and missed this line, will fix.

> 
>> +// Copyright(c) 2017-19 Intel Corporation.
> 
> Spell the year out fully unless you want lawyers knocking on your door :)

haha, will fix.

> 
>> +
>> +#include <linux/device.h>
>> +#include <linux/debugfs.h>
>> +#include <linux/mod_devicetable.h>
>> +#include <linux/slab.h>
>> +#include <linux/soundwire/sdw.h>
>> +#include <linux/soundwire/sdw_registers.h>
>> +#include "bus.h"
>> +
>> +#ifdef CONFIG_DEBUG_FS
>> +struct dentry *sdw_debugfs_root;
>> +#endif
> 
> This whole file is not built if that option is not enabled, so why the
> #ifdef?

Ah, will look into this, thanks!

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 02/40] soundwire: cadence_master: add debugfs register dump
  2019-07-26 14:09   ` Greg KH
@ 2019-07-26 15:32     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 15:32 UTC (permalink / raw)
  To: Greg KH
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale


>> +static const struct file_operations cdns_reg_fops = {
>> +	.open = simple_open,
>> +	.read = cdns_reg_read,
>> +	.llseek = default_llseek,
>> +};
> 
> DEFINE_SHOW_ATTRIBUTE()?

I remember looking at this but can't recall why I left it this way.
That was before my Summer break so will relook, thanks for suggesting this.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 04/40] soundwire: intel: add debugfs register dump
  2019-07-26 14:06   ` Greg KH
  2019-07-26 14:09     ` Greg KH
@ 2019-07-26 15:34     ` Pierre-Louis Bossart
  1 sibling, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 15:34 UTC (permalink / raw)
  To: Greg KH
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale


>> +static const struct file_operations intel_reg_fops = {
>> +	.open = simple_open,
>> +	.read = intel_reg_read,
>> +	.llseek = default_llseek,
>> +};
> 
> DEFINE_SIMPLE_ATTRIBUTE()?

yes

> 
>> +
>> +static void intel_debugfs_init(struct sdw_intel *sdw)
>> +{
>> +	struct dentry *root = sdw->cdns.bus.debugfs;
>> +
>> +	if (!root)
>> +		return;
>> +
>> +	sdw->fs = debugfs_create_dir("intel-sdw", root);
>> +	if (IS_ERR_OR_NULL(sdw->fs)) {
>> +		dev_err(sdw->cdns.dev, "debugfs root creation failed\n");
> 
> No, come on, don't do that.  I've been sweeping the kernel tree to
> remove this anti-pattern.
> 
> The debugfs core will print an error if you got something wrong, just
> call the function and move on, you NEVER need to check the return value
> of a debugfs call.

Yes, sorry to make your blood pressure go up... I missed this one in the 
cleanups yesterday. will fix.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 27/40] soundwire: Add Intel resource management algorithm
  2019-07-25 23:40 ` [RFC PATCH 27/40] soundwire: Add Intel resource management algorithm Pierre-Louis Bossart
  2019-07-26 11:07   ` Cezary Rojewski
@ 2019-07-26 15:43   ` Guennadi Liakhovetski
  2019-07-26 17:55     ` Pierre-Louis Bossart
  2019-08-05 16:54   ` Sanyog Kale
  2 siblings, 1 reply; 183+ messages in thread
From: Guennadi Liakhovetski @ 2019-07-26 15:43 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, tiwai, gregkh, linux-kernel, vkoul, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale

On Thu, Jul 25, 2019 at 06:40:19PM -0500, Pierre-Louis Bossart wrote:
> This algorithm computes bus parameters like clock frequency, frame
> shape and port transport parameters based on active stream(s) running
> on the bus.
> 
> This implementation is optimal for Intel platforms. Developers can
> also implement their own .compute_params() callback for specific
> resource management algorithm.
> 
> Credits: this patch is based on an earlier internal contribution by
> Vinod Koul, Sanyog Kale, Shreyas Nc and Hardik Shah. All hard-coded
> values were removed from the initial contribution to use BIOS
> information instead.
> 
> FIXME: remove checkpatch report
> WARNING: Reusing the krealloc arg is almost always a bug
> +			group->rates = krealloc(group->rates,
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/Makefile                  |   2 +-
>  drivers/soundwire/algo_dynamic_allocation.c | 403 ++++++++++++++++++++
>  drivers/soundwire/bus.c                     |   3 +
>  drivers/soundwire/bus.h                     |  46 ++-
>  drivers/soundwire/stream.c                  |  20 +
>  include/linux/soundwire/sdw.h               |   5 +
>  6 files changed, 476 insertions(+), 3 deletions(-)
>  create mode 100644 drivers/soundwire/algo_dynamic_allocation.c
> 
> diff --git a/drivers/soundwire/Makefile b/drivers/soundwire/Makefile
> index 88990cac48a7..f59a9d4a28fd 100644
> --- a/drivers/soundwire/Makefile
> +++ b/drivers/soundwire/Makefile
> @@ -5,7 +5,7 @@
>  
>  #Bus Objs
>  soundwire-bus-objs := bus_type.o bus.o slave.o mipi_disco.o stream.o \
> -			debugfs.o
> +			debugfs.o algo_dynamic_allocation.o
>  
>  obj-$(CONFIG_SOUNDWIRE_BUS) += soundwire-bus.o
>  
> diff --git a/drivers/soundwire/algo_dynamic_allocation.c b/drivers/soundwire/algo_dynamic_allocation.c
> new file mode 100644
> index 000000000000..89edb39162b8
> --- /dev/null
> +++ b/drivers/soundwire/algo_dynamic_allocation.c
> @@ -0,0 +1,403 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
> +// Copyright(c) 2015-18 Intel Corporation.
> +
> +/*
> + * Bandwidth management algorithm based on 2^n gears
> + *
> + */
> +
> +#include <linux/device.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/slab.h>
> +#include <linux/soundwire/sdw.h>
> +#include "bus.h"
> +
> +#define SDW_STRM_RATE_GROUPING		1
> +
> +struct sdw_group_params {
> +	unsigned int rate;
> +	int full_bw;
> +	int payload_bw;
> +	int hwidth;
> +};
> +
> +struct sdw_group {
> +	unsigned int count;
> +	unsigned int max_size;
> +	unsigned int *rates;
> +};
> +
> +struct sdw_transport_data {
> +	int hstart;
> +	int hstop;
> +	int block_offset;
> +	int sub_block_offset;
> +};
> +
> +static void sdw_compute_slave_ports(struct sdw_master_runtime *m_rt,
> +				    struct sdw_transport_data *t_data)
> +{
> +	struct sdw_slave_runtime *s_rt = NULL;

Superfluous initialisation.

> +	struct sdw_port_runtime *p_rt;
> +	int port_bo, sample_int;
> +	unsigned int rate, bps, ch = 0;

ditto for ch

> +
> +	port_bo = t_data->block_offset;
> +
> +	list_for_each_entry(s_rt, &m_rt->slave_rt_list, m_rt_node) {
> +		rate = m_rt->stream->params.rate;
> +		bps = m_rt->stream->params.bps;
> +		sample_int = (m_rt->bus->params.curr_dr_freq / rate);
> +
> +		list_for_each_entry(p_rt, &s_rt->port_list, port_node) {
> +			ch = sdw_ch_mask_to_ch(p_rt->ch_mask);
> +
> +			sdw_fill_xport_params(&p_rt->transport_params,
> +					      p_rt->num, true,
> +					      SDW_BLK_GRP_CNT_1,
> +					      sample_int, port_bo, port_bo >> 8,
> +					      t_data->hstart,
> +					      t_data->hstop,

I think the above two lines could fit in one

> +					      (SDW_BLK_GRP_CNT_1 * ch), 0x0);

superfluous parentheses

> +
> +			sdw_fill_port_params(&p_rt->port_params,
> +					     p_rt->num, bps,
> +					     SDW_PORT_FLOW_MODE_ISOCH,
> +					     SDW_PORT_DATA_MODE_NORMAL);
> +
> +			port_bo += bps * ch;
> +		}
> +	}
> +}
> +
> +static void sdw_compute_master_ports(struct sdw_master_runtime *m_rt,
> +				     struct sdw_group_params *params,
> +				     int port_bo, int hstop)
> +{
> +	struct sdw_transport_data t_data = {0};
> +	struct sdw_port_runtime *p_rt;
> +	struct sdw_bus *bus = m_rt->bus;
> +	int sample_int, hstart = 0;

superfluous initialisation

> +	unsigned int rate, bps, ch, no_ch;
> +
> +	rate = m_rt->stream->params.rate;
> +	bps = m_rt->stream->params.bps;
> +	ch = m_rt->ch_count;
> +	sample_int = (bus->params.curr_dr_freq / rate);

superfluous parentheses

> +
> +	if (rate != params->rate)
> +		return;
> +
> +	t_data.hstop = hstop;
> +	hstart = hstop - params->hwidth + 1;
> +	t_data.hstart = hstart;
> +
> +	list_for_each_entry(p_rt, &m_rt->port_list, port_node) {
> +		no_ch = sdw_ch_mask_to_ch(p_rt->ch_mask);
> +
> +		sdw_fill_xport_params(&p_rt->transport_params, p_rt->num,
> +				      true, SDW_BLK_GRP_CNT_1, sample_int,
> +				      port_bo, port_bo >> 8, hstart, hstop,
> +				      (SDW_BLK_GRP_CNT_1 * no_ch), 0x0);

superfluous parentheses

> +
> +		sdw_fill_port_params(&p_rt->port_params,
> +				     p_rt->num, bps,
> +				     SDW_PORT_FLOW_MODE_ISOCH,
> +				     SDW_PORT_DATA_MODE_NORMAL);
> +
> +		/* Check for first entry */
> +		if (!(p_rt == list_first_entry(&m_rt->port_list,
> +					       struct sdw_port_runtime,
> +					       port_node))) {

you wanted to write "if (p_rt != ...)"

> +			port_bo += bps * ch;
> +			continue;
> +		}
> +
> +		t_data.hstart = hstart;
> +		t_data.hstop = hstop;

You already set these two above

> +		t_data.block_offset = port_bo;
> +		t_data.sub_block_offset = 0;
> +		port_bo += bps * ch;
> +	}
> +
> +	sdw_compute_slave_ports(m_rt, &t_data);
> +}
> +
> +static void _sdw_compute_port_params(struct sdw_bus *bus,
> +				     struct sdw_group_params *params, int count)
> +{
> +	struct sdw_master_runtime *m_rt = NULL;

superfluous initialisation

> +	int hstop = bus->params.col - 1;
> +	int block_offset, port_bo, i;
> +
> +	/* Run loop for all groups to compute transport parameters */
> +	for (i = 0; i < count; i++) {
> +		port_bo = 1;
> +		block_offset = 1;
> +
> +		list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
> +			sdw_compute_master_ports(m_rt, &params[i],
> +						 port_bo, hstop);
> +
> +			block_offset += m_rt->ch_count *
> +					m_rt->stream->params.bps;
> +			port_bo = block_offset;
> +		}
> +
> +		hstop = hstop - params[i].hwidth;

hstop -= ...

> +	}
> +}
> +
> +static int sdw_compute_group_params(struct sdw_bus *bus,
> +				    struct sdw_group_params *params,
> +				    int *rates, int count)
> +{
> +	struct sdw_master_runtime *m_rt = NULL;

ditto

> +	int sel_col = bus->params.col;
> +	unsigned int rate, bps, ch;
> +	int i, column_needed = 0;
> +
> +	/* Calculate bandwidth per group */
> +	for (i = 0; i < count; i++) {
> +		params[i].rate = rates[i];
> +		params[i].full_bw = bus->params.curr_dr_freq / params[i].rate;
> +	}
> +
> +	list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
> +		rate = m_rt->stream->params.rate;
> +		bps = m_rt->stream->params.bps;
> +		ch = m_rt->ch_count;
> +
> +		for (i = 0; i < count; i++) {
> +			if (rate == params[i].rate)
> +				params[i].payload_bw += bps * ch;

I don't know about the algorithm, rates can repeat, right? So you cannot break
out of the loop here once you found one match?

> +		}
> +	}
> +
> +	for (i = 0; i < count; i++) {
> +		params[i].hwidth = (sel_col *
> +			params[i].payload_bw + params[i].full_bw - 1) /
> +			params[i].full_bw;
> +
> +		column_needed += params[i].hwidth;
> +	}
> +
> +	if (column_needed > sel_col - 1)
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
> +static int sdw_add_element_group_count(struct sdw_group *group,
> +				       unsigned int rate)
> +{
> +	int num = group->count;
> +	int i;
> +
> +	for (i = 0; i <= num; i++) {
> +		if (rate == group->rates[i])

Are you sure this is correct? You actually check count + 1 rates - from 0
to count inclusively. I think this isn't what you wanted to do, so my
proposal below only checks count rates.

> +			break;
> +
> +		if (i != num)
> +			continue;
> +
> +		if (group->count >= group->max_size) {
> +			group->max_size += 1;
> +			group->rates = krealloc(group->rates,
> +						(sizeof(int) * group->max_size),
> +						GFP_KERNEL);
> +			if (!group->rates)
> +				return -ENOMEM;
> +		}
> +
> +		group->rates[group->count++] = rate;
> +	}

How about this:

	for (i = 0; i < num; i++)
		if (rate == group->rates[i])
			return 0;

	if (group->count >= group->max_size) {
		group->max_size += 1;
		group->rates = krealloc(group->rates,
					(sizeof(int) * group->max_size),
					GFP_KERNEL);
		if (!group->rates)
			return -ENOMEM;
	}

	group->rates[group->count++] = rate;

	return 0;

> +
> +	return 0;
> +}
> +
> +static int sdw_get_group_count(struct sdw_bus *bus,
> +			       struct sdw_group *group)
> +{
> +	struct sdw_master_runtime *m_rt;
> +	unsigned int rate;
> +	int ret = 0;
> +
> +	group->count = 0;
> +	group->max_size = SDW_STRM_RATE_GROUPING;
> +	group->rates = kcalloc(group->max_size, sizeof(int), GFP_KERNEL);
> +	if (!group->rates)
> +		return -ENOMEM;
> +
> +	list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
> +		rate = m_rt->stream->params.rate;
> +		if (m_rt == list_first_entry(&bus->m_rt_list,
> +					     struct sdw_master_runtime,
> +					     bus_node)) {
> +			group->rates[group->count++] = rate;
> +
> +		} else {
> +			ret = sdw_add_element_group_count(group, rate);
> +			if (ret < 0)

Actually it looks like you should free rates here? I see that not doing this
makes the caller function below easier, but I'd say this is more error-
prone... Up to you but I'd go the "safe" way - if it fails, it frees itself,
if it succeeds - it's freed elsewhere.

> +				return ret;
> +		}
> +	}
> +
> +	return ret;

I think this will always return 0 here, so you don't need the "ret"
variable in the function scope, you only need it in the "else"
scope above.

> +}
> +
> +/**
> + * sdw_compute_port_params: Compute transport and port parameters
> + *
> + * @bus: SDW Bus instance
> + */
> +static int sdw_compute_port_params(struct sdw_bus *bus)
> +{
> +	struct sdw_group_params *params = NULL;
> +	struct sdw_group group;
> +	int ret;
> +
> +	ret = sdw_get_group_count(bus, &group);
> +	if (ret < 0)
> +		goto out;
> +
> +	if (group.count == 0)
> +		goto out;
> +
> +	params = kcalloc(group.count, sizeof(*params), GFP_KERNEL);
> +	if (!params) {
> +		ret = -ENOMEM;
> +		goto out;
> +	}
> +
> +	/* Compute transport parameters for grouped streams */
> +	ret = sdw_compute_group_params(bus, params,
> +				       &group.rates[0], group.count);
> +	if (ret < 0)
> +		goto out;
> +
> +	_sdw_compute_port_params(bus, params, group.count);
> +
> +out:
> +	kfree(params);
> +	kfree(group.rates);

Depending whether or not you change the code above, this might change
too.

> +
> +	return ret;
> +}
> +
> +static int sdw_select_row_col(struct sdw_bus *bus, int clk_freq)
> +{
> +	struct sdw_master_prop *prop = &bus->prop;
> +	int frame_int, frame_freq;
> +	int r, c;
> +
> +	for (c = 0; c < SDW_FRAME_COLS; c++) {
> +		for (r = 0; r < SDW_FRAME_ROWS; r++) {
> +			if (sdw_rows[r] != prop->default_row ||
> +			    sdw_cols[c] != prop->default_col)
> +				continue;
> +
> +			frame_int = sdw_rows[r] * sdw_cols[c];
> +			frame_freq = clk_freq / frame_int;
> +
> +			if ((clk_freq - (frame_freq * SDW_FRAME_CTRL_BITS)) <
> +			    bus->params.bandwidth)
> +				continue;
> +
> +			bus->params.row = sdw_rows[r];
> +			bus->params.col = sdw_cols[c];
> +			return 0;
> +		}
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +/**
> + * sdw_compute_bus_params: Compute bus parameters
> + *
> + * @bus: SDW Bus instance
> + */
> +static int sdw_compute_bus_params(struct sdw_bus *bus)
> +{
> +	unsigned int max_dr_freq, curr_dr_freq = 0;
> +	struct sdw_master_prop *mstr_prop = NULL;

superfluous initialisation

> +	int i, clk_values, ret;
> +	bool is_gear = false;
> +	u32 *clk_buf;
> +
> +	mstr_prop = &bus->prop;
> +	if (!mstr_prop)

this is impossible, it's an address of bus->prop...

> +		return -EINVAL;
> +
> +	if (mstr_prop->num_clk_gears) {
> +		clk_values = mstr_prop->num_clk_gears;
> +		clk_buf = mstr_prop->clk_gears;
> +		is_gear = true;
> +	} else if (mstr_prop->num_clk_freq) {
> +		clk_values = mstr_prop->num_clk_freq;
> +		clk_buf = mstr_prop->clk_freq;
> +	} else {
> +		clk_values = 1;
> +		clk_buf = NULL;
> +	}
> +
> +	max_dr_freq = mstr_prop->max_clk_freq * SDW_DOUBLE_RATE_FACTOR;
> +
> +	for (i = 0; i < clk_values; i++) {
> +		if (!clk_buf)
> +			curr_dr_freq = max_dr_freq;
> +		else
> +			curr_dr_freq = (is_gear) ?

superfluous parentheses

> +				(max_dr_freq >>  clk_buf[i]) :

ditto

> +				clk_buf[i] * SDW_DOUBLE_RATE_FACTOR;
> +
> +		if (curr_dr_freq <= bus->params.bandwidth)
> +			continue;
> +
> +		break;

I think this is raw code, you'd actually want to write this as

		if (curr_dr_freq > bus->params.bandwidth)
			break;

> +
> +		/*
> +		 * TODO: Check all the Slave(s) port(s) audio modes and find
> +		 * whether given clock rate is supported with glitchless
> +		 * transition.
> +		 */
> +	}
> +
> +	if (i == clk_values)
> +		return -EINVAL;
> +
> +	ret = sdw_select_row_col(bus, curr_dr_freq);
> +	if (ret < 0)
> +		return -EINVAL;
> +
> +	bus->params.curr_dr_freq = curr_dr_freq;
> +	return 0;
> +}
> +
> +/**
> + * sdw_compute_params: Compute bus, transport and port parameters
> + *
> + * @bus: SDW Bus instance
> + */
> +int sdw_compute_params(struct sdw_bus *bus)
> +{
> +	int ret;
> +
> +	/* Computes clock frequency, frame shape and frame frequency */
> +	ret = sdw_compute_bus_params(bus);
> +	if (ret < 0) {
> +		dev_err(bus->dev, "Compute bus params failed: %d", ret);
> +		return ret;
> +	}
> +
> +	/* Compute transport and port params */
> +	ret = sdw_compute_port_params(bus);
> +	if (ret < 0) {
> +		dev_err(bus->dev, "Compute transport params failed: %d", ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(sdw_compute_params);
> diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
> index 2354675ef104..76a180578712 100644
> --- a/drivers/soundwire/bus.c
> +++ b/drivers/soundwire/bus.c
> @@ -51,6 +51,9 @@ int sdw_add_bus_master(struct sdw_bus *bus)
>  
>  	bus->debugfs = sdw_bus_debugfs_init(bus);
>  
> +	if (!bus->compute_params)
> +		bus->compute_params = &sdw_compute_params;

I think it is more usual to not use "&" with functions, but it's valid too

> +
>  	/*
>  	 * Device numbers in SoundWire are 0 through 15. Enumeration device
>  	 * number (0), Broadcast device number (15), Group numbers (12 and
> diff --git a/drivers/soundwire/bus.h b/drivers/soundwire/bus.h
> index c57c9c23f6ca..fdb7ce034fdf 100644
> --- a/drivers/soundwire/bus.h
> +++ b/drivers/soundwire/bus.h
> @@ -72,6 +72,7 @@ struct sdw_msg {
>  };
>  
>  #define SDW_DOUBLE_RATE_FACTOR		2
> +#define SDW_STRM_RATE_GROUPING		1
>  
>  extern int sdw_rows[SDW_FRAME_ROWS];
>  extern int sdw_cols[SDW_FRAME_COLS];
> @@ -157,9 +158,50 @@ int sdw_transfer_defer(struct sdw_bus *bus, struct sdw_msg *msg,
>  int sdw_fill_msg(struct sdw_msg *msg, struct sdw_slave *slave,
>  		 u32 addr, size_t count, u16 dev_num, u8 flags, u8 *buf);
>  
> +/* Retrieve and return channel count from channel mask */
> +static inline int sdw_ch_mask_to_ch(int ch_mask)
> +{
> +	int c = 0;

superfluous initialisation

> +
> +	for (c = 0; ch_mask; ch_mask >>= 1)
> +		c += ch_mask & 1;

isn't there a built-in or something to count set bits... You could use ffs() to
at least not loop 31 times for 0x80000000

> +
> +	return c;
> +}
> +
> +/* Fill transport parameter data structure */
> +static inline void sdw_fill_xport_params(struct sdw_transport_params *params,
> +					 int port_num, bool grp_ctrl_valid,
> +					 int grp_ctrl, int sample_int,
> +					 int off1, int off2,
> +					 int hstart, int hstop,
> +					 int pack_mode, int lane_ctrl)
> +{
> +	params->port_num = port_num;
> +	params->blk_grp_ctrl_valid = grp_ctrl_valid;
> +	params->blk_grp_ctrl = grp_ctrl;
> +	params->sample_interval = sample_int;
> +	params->offset1 = off1;
> +	params->offset2 = off2;
> +	params->hstart = hstart;
> +	params->hstop = hstop;
> +	params->blk_pkg_mode = pack_mode;
> +	params->lane_ctrl = lane_ctrl;
> +}
> +
> +/* Fill port parameter data structure */
> +static inline void sdw_fill_port_params(struct sdw_port_params *params,
> +					int port_num, int bps,
> +					int flow_mode, int data_mode)
> +{
> +	params->num = port_num;
> +	params->bps = bps;
> +	params->flow_mode = flow_mode;
> +	params->data_mode = data_mode;
> +}
> +
>  /* Read-Modify-Write Slave register */
> -static inline int
> -sdw_update(struct sdw_slave *slave, u32 addr, u8 mask, u8 val)
> +static inline int sdw_update(struct sdw_slave *slave, u32 addr, u8 mask, u8 val)
>  {
>  	int tmp;
>  
> diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c
> index 75b9ad1fb1a6..add7c121d084 100644
> --- a/drivers/soundwire/stream.c
> +++ b/drivers/soundwire/stream.c
> @@ -1485,6 +1485,16 @@ static int _sdw_prepare_stream(struct sdw_stream_runtime *stream)
>  		bus->params.bandwidth += m_rt->stream->params.rate *
>  			m_rt->ch_count * m_rt->stream->params.bps;
>  
> +		/* Compute params */
> +		if (bus->compute_params) {
> +			ret = bus->compute_params(bus);
> +			if (ret < 0) {
> +				dev_err(bus->dev,
> +					"Compute params failed: %d", ret);
> +				return ret;
> +			}
> +		}
> +
>  		/* Program params */
>  		ret = sdw_program_params(bus);
>  		if (ret < 0) {
> @@ -1704,6 +1714,16 @@ static int _sdw_deprepare_stream(struct sdw_stream_runtime *stream)
>  		bus->params.bandwidth -= m_rt->stream->params.rate *
>  			m_rt->ch_count * m_rt->stream->params.bps;
>  
> +		/* Compute params */
> +		if (bus->compute_params) {
> +			ret = bus->compute_params(bus);
> +			if (ret < 0) {
> +				dev_err(bus->dev,
> +					"Compute params failed: %d", ret);
> +				return ret;
> +			}
> +		}
> +
>  		/* Program params */
>  		ret = sdw_program_params(bus);
>  		if (ret < 0) {
> diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
> index b6acc436ac80..c7dfc824be80 100644
> --- a/include/linux/soundwire/sdw.h
> +++ b/include/linux/soundwire/sdw.h
> @@ -730,6 +730,7 @@ struct sdw_master_ops {
>   * Bit set implies used number, bit clear implies unused number.
>   * @bus_lock: bus lock
>   * @msg_lock: message lock
> + * @compute_params: points to Bus resource management implementation
>   * @ops: Master callback ops
>   * @port_ops: Master port callback ops
>   * @params: Current bus parameters
> @@ -752,6 +753,7 @@ struct sdw_bus {
>  	DECLARE_BITMAP(assigned, SDW_MAX_DEVICES);
>  	struct mutex bus_lock;
>  	struct mutex msg_lock;
> +	int (*compute_params)(struct sdw_bus *bus);
>  	const struct sdw_master_ops *ops;
>  	const struct sdw_master_port_ops *port_ops;
>  	struct sdw_bus_params params;
> @@ -852,6 +854,9 @@ struct sdw_stream_runtime {
>  
>  struct sdw_stream_runtime *sdw_alloc_stream(char *stream_name);
>  void sdw_release_stream(struct sdw_stream_runtime *stream);
> +
> +int sdw_compute_params(struct sdw_bus *bus);
> +
>  int sdw_stream_add_master(struct sdw_bus *bus,
>  		struct sdw_stream_config *stream_config,
>  		struct sdw_port_config *port_config,
> -- 
> 2.20.1
> 
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 35/40] soundwire: intel: export helper to exit reset
  2019-07-25 23:40 ` [RFC PATCH 35/40] soundwire: intel: export helper to exit reset Pierre-Louis Bossart
@ 2019-07-26 15:52   ` Guennadi Liakhovetski
  2019-07-26 17:22     ` Pierre-Louis Bossart
  2019-08-02 17:31   ` Vinod Koul
  1 sibling, 1 reply; 183+ messages in thread
From: Guennadi Liakhovetski @ 2019-07-26 15:52 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, tiwai, gregkh, linux-kernel, vkoul, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale

On Thu, Jul 25, 2019 at 06:40:27PM -0500, Pierre-Louis Bossart wrote:
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/cadence_master.c | 9 +++++++--
>  drivers/soundwire/cadence_master.h | 1 +
>  drivers/soundwire/intel.c          | 4 ++++
>  3 files changed, 12 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
> index 4a189e487830..f486fe15fb46 100644
> --- a/drivers/soundwire/cadence_master.c
> +++ b/drivers/soundwire/cadence_master.c
> @@ -780,7 +780,11 @@ EXPORT_SYMBOL(sdw_cdns_thread);
>   * init routines
>   */
>  
> -static int do_reset(struct sdw_cdns *cdns)
> +/**
> + * sdw_cdns_exit_reset() - Program reset parameters and start bus operations
> + * @cdns: Cadence instance
> + */
> +int sdw_cdns_exit_reset(struct sdw_cdns *cdns)
>  {
>  	int ret;
>  
> @@ -804,6 +808,7 @@ static int do_reset(struct sdw_cdns *cdns)
>  
>  	return ret;
>  }
> +EXPORT_SYMBOL(sdw_cdns_exit_reset);
>  
>  /**
>   * sdw_cdns_enable_interrupt() - Enable SDW interrupts and update config
> @@ -839,7 +844,7 @@ int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
>  
>  	cdns_writel(cdns, CDNS_MCP_INTMASK, mask);
>  
> -	return do_reset(cdns);
> +	return 0;
>  }
>  EXPORT_SYMBOL(sdw_cdns_enable_interrupt);
>  
> diff --git a/drivers/soundwire/cadence_master.h b/drivers/soundwire/cadence_master.h
> index de97bc22acb7..2b551f9226f3 100644
> --- a/drivers/soundwire/cadence_master.h
> +++ b/drivers/soundwire/cadence_master.h
> @@ -161,6 +161,7 @@ irqreturn_t sdw_cdns_thread(int irq, void *dev_id);
>  int sdw_cdns_init(struct sdw_cdns *cdns);
>  int sdw_cdns_pdi_init(struct sdw_cdns *cdns,
>  		      struct sdw_cdns_stream_config config);
> +int sdw_cdns_exit_reset(struct sdw_cdns *cdns);
>  int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns);
>  
>  void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root);
> diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
> index a976480d6f36..9ebe38e4d979 100644
> --- a/drivers/soundwire/intel.c
> +++ b/drivers/soundwire/intel.c
> @@ -1112,6 +1112,8 @@ static int intel_probe(struct platform_device *pdev)
>  
>  	ret = sdw_cdns_enable_interrupt(&sdw->cdns);
>  
> +	ret = sdw_cdns_exit_reset(&sdw->cdns);

This isn't something, that this patch changes, but if the return value above is
ignored, maybe no need to assign it at all?

Thanks
Guennadi

> +
>  	/* Register DAIs */
>  	ret = intel_register_dai(sdw);
>  	if (ret) {
> @@ -1199,6 +1201,8 @@ static int intel_resume(struct device *dev)
>  
>  	sdw_cdns_enable_interrupt(&sdw->cdns);
>  
> +	ret = sdw_cdns_exit_reset(&sdw->cdns);
> +
>  	return ret;
>  }
>  
> -- 
> 2.20.1
> 
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 36/40] soundwire: intel: disable interrupts on suspend
  2019-07-25 23:40 ` [RFC PATCH 36/40] soundwire: intel: disable interrupts on suspend Pierre-Louis Bossart
@ 2019-07-26 15:55   ` Guennadi Liakhovetski
  2019-07-26 17:26     ` Pierre-Louis Bossart
  0 siblings, 1 reply; 183+ messages in thread
From: Guennadi Liakhovetski @ 2019-07-26 15:55 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, tiwai, gregkh, linux-kernel, vkoul, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale

On Thu, Jul 25, 2019 at 06:40:28PM -0500, Pierre-Louis Bossart wrote:
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/cadence_master.c | 42 +++++++++++++++++-------------
>  drivers/soundwire/cadence_master.h |  2 +-
>  drivers/soundwire/intel.c          |  6 +++--
>  3 files changed, 29 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
> index f486fe15fb46..fa7230b0f200 100644
> --- a/drivers/soundwire/cadence_master.c
> +++ b/drivers/soundwire/cadence_master.c
> @@ -814,33 +814,39 @@ EXPORT_SYMBOL(sdw_cdns_exit_reset);
>   * sdw_cdns_enable_interrupt() - Enable SDW interrupts and update config
>   * @cdns: Cadence instance
>   */
> -int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
> +int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns, bool state)
>  {
>  	u32 mask;
>  
> -	cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK0,
> -		    CDNS_MCP_SLAVE_INTMASK0_MASK);
> -	cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK1,
> -		    CDNS_MCP_SLAVE_INTMASK1_MASK);
> +	if (state) {
> +		cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK0,
> +			    CDNS_MCP_SLAVE_INTMASK0_MASK);
> +		cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK1,
> +			    CDNS_MCP_SLAVE_INTMASK1_MASK);
>  
> -	/* enable detection of slave state changes */
> -	mask = CDNS_MCP_INT_SLAVE_RSVD | CDNS_MCP_INT_SLAVE_ALERT |
> -		CDNS_MCP_INT_SLAVE_ATTACH | CDNS_MCP_INT_SLAVE_NATTACH;
> +		/* enable detection of slave state changes */
> +		mask = CDNS_MCP_INT_SLAVE_RSVD | CDNS_MCP_INT_SLAVE_ALERT |
> +			CDNS_MCP_INT_SLAVE_ATTACH | CDNS_MCP_INT_SLAVE_NATTACH;
>  
> -	/* enable detection of bus issues */
> -	mask |= CDNS_MCP_INT_CTRL_CLASH | CDNS_MCP_INT_DATA_CLASH |
> -		CDNS_MCP_INT_PARITY;
> +		/* enable detection of bus issues */
> +		mask |= CDNS_MCP_INT_CTRL_CLASH | CDNS_MCP_INT_DATA_CLASH |
> +			CDNS_MCP_INT_PARITY;
>  
> -	/* no detection of port interrupts for now */
> +		/* no detection of port interrupts for now */
>  
> -	/* enable detection of RX fifo level */
> -	mask |= CDNS_MCP_INT_RX_WL;
> +		/* enable detection of RX fifo level */
> +		mask |= CDNS_MCP_INT_RX_WL;
>  
> -	/* now enable all of the above */
> -	mask |= CDNS_MCP_INT_IRQ;
> +		/* now enable all of the above */
> +		mask |= CDNS_MCP_INT_IRQ;
>  
> -	if (interrupt_mask) /* parameter override */
> -		mask = interrupt_mask;
> +		if (interrupt_mask) /* parameter override */
> +			mask = interrupt_mask;
> +	} else {
> +		cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK0, 0);
> +		cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK1, 0);
> +		mask = 0;
> +	}

Looks like this should be two functions? Especially since "state" is always a constant
when it is called. If there is still a lot of common code below, maybe make it a helper
function.

Thanks
Guennadi

>  
>  	cdns_writel(cdns, CDNS_MCP_INTMASK, mask);
>  
> diff --git a/drivers/soundwire/cadence_master.h b/drivers/soundwire/cadence_master.h
> index 2b551f9226f3..1a0ba36dd78f 100644
> --- a/drivers/soundwire/cadence_master.h
> +++ b/drivers/soundwire/cadence_master.h
> @@ -162,7 +162,7 @@ int sdw_cdns_init(struct sdw_cdns *cdns);
>  int sdw_cdns_pdi_init(struct sdw_cdns *cdns,
>  		      struct sdw_cdns_stream_config config);
>  int sdw_cdns_exit_reset(struct sdw_cdns *cdns);
> -int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns);
> +int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns, bool state);
>  
>  void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root);
>  
> diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
> index 9ebe38e4d979..1192d5775484 100644
> --- a/drivers/soundwire/intel.c
> +++ b/drivers/soundwire/intel.c
> @@ -1110,7 +1110,7 @@ static int intel_probe(struct platform_device *pdev)
>  		goto err_init;
>  	}
>  
> -	ret = sdw_cdns_enable_interrupt(&sdw->cdns);
> +	ret = sdw_cdns_enable_interrupt(&sdw->cdns, true);
>  
>  	ret = sdw_cdns_exit_reset(&sdw->cdns);
>  
> @@ -1169,6 +1169,8 @@ static int intel_suspend(struct device *dev)
>  		return 0;
>  	}
>  
> +	sdw_cdns_enable_interrupt(&sdw->cdns, false);
> +
>  	ret = intel_link_power_down(sdw);
>  	if (ret) {
>  		dev_err(dev, "Link power down failed: %d", ret);
> @@ -1199,7 +1201,7 @@ static int intel_resume(struct device *dev)
>  		return ret;
>  	}
>  
> -	sdw_cdns_enable_interrupt(&sdw->cdns);
> +	sdw_cdns_enable_interrupt(&sdw->cdns, true);
>  
>  	ret = sdw_cdns_exit_reset(&sdw->cdns);
>  
> -- 
> 2.20.1
> 
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 37/40] soundwire: cadence_master: add hw_reset capability in debugfs
  2019-07-25 23:40 ` [RFC PATCH 37/40] soundwire: cadence_master: add hw_reset capability in debugfs Pierre-Louis Bossart
  2019-07-26 14:07   ` Greg KH
@ 2019-07-26 15:57   ` Guennadi Liakhovetski
  2019-07-26 17:31     ` Pierre-Louis Bossart
  1 sibling, 1 reply; 183+ messages in thread
From: Guennadi Liakhovetski @ 2019-07-26 15:57 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, tiwai, gregkh, linux-kernel, vkoul, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale

On Thu, Jul 25, 2019 at 06:40:29PM -0500, Pierre-Louis Bossart wrote:
> This is to kick devices into reset and see what software does
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/cadence_master.c | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
> 
> diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
> index fa7230b0f200..53278aa2436f 100644
> --- a/drivers/soundwire/cadence_master.c
> +++ b/drivers/soundwire/cadence_master.c
> @@ -331,6 +331,25 @@ static const struct file_operations cdns_reg_fops = {
>  	.llseek = default_llseek,
>  };
>  
> +static int cdns_hw_reset(void *data, u64 value)
> +{
> +	struct sdw_cdns *cdns = data;
> +	int ret;
> +
> +	if (value != 1)
> +		return 0;
> +
> +	dev_info(cdns->dev, "starting link hw_reset\n");
> +
> +	ret = sdw_cdns_exit_reset(cdns);
> +
> +	dev_info(cdns->dev, "link hw_reset done\n");

Both really should be dev_info()? Maybe at least one of them can be dev_dbg()?

Thanks
Guennadi

> +
> +	return ret;
> +}
> +
> +DEFINE_DEBUGFS_ATTRIBUTE(cdns_hw_reset_fops, NULL, cdns_hw_reset, "%llu\n");
> +
>  /**
>   * sdw_cdns_debugfs_init() - Cadence debugfs init
>   * @cdns: Cadence instance
> @@ -339,6 +358,9 @@ static const struct file_operations cdns_reg_fops = {
>  void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root)
>  {
>  	debugfs_create_file("cdns-registers", 0400, root, cdns, &cdns_reg_fops);
> +
> +	debugfs_create_file_unsafe("cdns-hw-reset", 0200, root, cdns,
> +				   &cdns_hw_reset_fops);
>  }
>  EXPORT_SYMBOL_GPL(sdw_cdns_debugfs_init);
>  
> -- 
> 2.20.1
> 
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 38/40] soundwire: cadence_master: make clock stop exit configurable on init
  2019-07-25 23:40 ` [RFC PATCH 38/40] soundwire: cadence_master: make clock stop exit configurable on init Pierre-Louis Bossart
@ 2019-07-26 16:02   ` Guennadi Liakhovetski
  2019-07-26 17:35     ` Pierre-Louis Bossart
  0 siblings, 1 reply; 183+ messages in thread
From: Guennadi Liakhovetski @ 2019-07-26 16:02 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, tiwai, gregkh, linux-kernel, vkoul, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale

On Thu, Jul 25, 2019 at 06:40:30PM -0500, Pierre-Louis Bossart wrote:
> The use of clock stop is not a requirement, the IP can e.g. be
> completely power gated and not detect any wakes while in s2idle/deep
> sleep.
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/cadence_master.c | 15 ++++++++-------
>  drivers/soundwire/cadence_master.h |  2 +-
>  drivers/soundwire/intel.c          |  2 +-
>  3 files changed, 10 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
> index 53278aa2436f..4ab6f70d7705 100644
> --- a/drivers/soundwire/cadence_master.c
> +++ b/drivers/soundwire/cadence_master.c
> @@ -1010,7 +1010,7 @@ static u32 cdns_set_default_frame_shape(int n_rows, int n_cols)
>   * sdw_cdns_init() - Cadence initialization
>   * @cdns: Cadence instance
>   */
> -int sdw_cdns_init(struct sdw_cdns *cdns)
> +int sdw_cdns_init(struct sdw_cdns *cdns, bool clock_stop_exit)
>  {
>  	struct sdw_bus *bus = &cdns->bus;
>  	struct sdw_master_prop *prop = &bus->prop;
> @@ -1018,12 +1018,13 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
>  	int divider;
>  	int ret;
>  
> -	/* Exit clock stop */
> -	ret = cdns_clear_bit(cdns, CDNS_MCP_CONTROL,
> -			     CDNS_MCP_CONTROL_CLK_STOP_CLR);
> -	if (ret < 0) {
> -		dev_err(cdns->dev, "Couldn't exit from clock stop\n");
> -		return ret;
> +	if (clock_stop_exit) {
> +		ret = cdns_clear_bit(cdns, CDNS_MCP_CONTROL,
> +				     CDNS_MCP_CONTROL_CLK_STOP_CLR);
> +		if (ret < 0) {
> +			dev_err(cdns->dev, "Couldn't exit from clock stop\n");
> +			return ret;
> +		}
>  	}
>  
>  	/* Set clock divider */
> diff --git a/drivers/soundwire/cadence_master.h b/drivers/soundwire/cadence_master.h
> index 1a0ba36dd78f..091b771b570d 100644
> --- a/drivers/soundwire/cadence_master.h
> +++ b/drivers/soundwire/cadence_master.h
> @@ -158,7 +158,7 @@ extern struct sdw_master_ops sdw_cdns_master_ops;
>  irqreturn_t sdw_cdns_irq(int irq, void *dev_id);
>  irqreturn_t sdw_cdns_thread(int irq, void *dev_id);
>  
> -int sdw_cdns_init(struct sdw_cdns *cdns);
> +int sdw_cdns_init(struct sdw_cdns *cdns, bool clock_stop_exit);
>  int sdw_cdns_pdi_init(struct sdw_cdns *cdns,
>  		      struct sdw_cdns_stream_config config);
>  int sdw_cdns_exit_reset(struct sdw_cdns *cdns);
> diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
> index 1192d5775484..db7bf2912767 100644
> --- a/drivers/soundwire/intel.c
> +++ b/drivers/soundwire/intel.c
> @@ -1043,7 +1043,7 @@ static int intel_init(struct sdw_intel *sdw)
>  	intel_link_power_up(sdw);
>  	intel_shim_init(sdw);
>  
> -	return sdw_cdns_init(&sdw->cdns);
> +	return sdw_cdns_init(&sdw->cdns, false);

This is the only caller of this function so far, so, it looks like
the second argument ATM is always "false." I assume you foresee other
uses with "true" in the future, otherwise maybe just fix it to false
in the function?

Thanks
Guennadi

>  }
>  
>  /*
> -- 
> 2.20.1
> 
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 35/40] soundwire: intel: export helper to exit reset
  2019-07-26 15:52   ` [alsa-devel] " Guennadi Liakhovetski
@ 2019-07-26 17:22     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 17:22 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: alsa-devel, tiwai, gregkh, linux-kernel, vkoul, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale


>> @@ -161,6 +161,7 @@ irqreturn_t sdw_cdns_thread(int irq, void *dev_id);
>>   int sdw_cdns_init(struct sdw_cdns *cdns);
>>   int sdw_cdns_pdi_init(struct sdw_cdns *cdns,
>>   		      struct sdw_cdns_stream_config config);
>> +int sdw_cdns_exit_reset(struct sdw_cdns *cdns);
>>   int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns);
>>   
>>   void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root);
>> diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
>> index a976480d6f36..9ebe38e4d979 100644
>> --- a/drivers/soundwire/intel.c
>> +++ b/drivers/soundwire/intel.c
>> @@ -1112,6 +1112,8 @@ static int intel_probe(struct platform_device *pdev)
>>   
>>   	ret = sdw_cdns_enable_interrupt(&sdw->cdns);
>>   
>> +	ret = sdw_cdns_exit_reset(&sdw->cdns);
> 
> This isn't something, that this patch changes, but if the return value above is
> ignored, maybe no need to assign it at all?

The return of these two functions was used with in some logs at some 
point but they obviously vanished.
I'll re-check if we care about the status, could be that it never fails
Thanks!


>> +
>>   	/* Register DAIs */
>>   	ret = intel_register_dai(sdw);
>>   	if (ret) {
>> @@ -1199,6 +1201,8 @@ static int intel_resume(struct device *dev)
>>   
>>   	sdw_cdns_enable_interrupt(&sdw->cdns);
>>   
>> +	ret = sdw_cdns_exit_reset(&sdw->cdns);
>> +
>>   	return ret;

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 36/40] soundwire: intel: disable interrupts on suspend
  2019-07-26 15:55   ` [alsa-devel] " Guennadi Liakhovetski
@ 2019-07-26 17:26     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 17:26 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: alsa-devel, tiwai, gregkh, linux-kernel, vkoul, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale


>> -int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
>> +int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns, bool state)
>>   {
>>   	u32 mask;
>>   
>> -	cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK0,
>> -		    CDNS_MCP_SLAVE_INTMASK0_MASK);
>> -	cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK1,
>> -		    CDNS_MCP_SLAVE_INTMASK1_MASK);
>> +	if (state) {
>> +		cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK0,
>> +			    CDNS_MCP_SLAVE_INTMASK0_MASK);
>> +		cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK1,
>> +			    CDNS_MCP_SLAVE_INTMASK1_MASK);
>>   
>> -	/* enable detection of slave state changes */
>> -	mask = CDNS_MCP_INT_SLAVE_RSVD | CDNS_MCP_INT_SLAVE_ALERT |
>> -		CDNS_MCP_INT_SLAVE_ATTACH | CDNS_MCP_INT_SLAVE_NATTACH;
>> +		/* enable detection of slave state changes */
>> +		mask = CDNS_MCP_INT_SLAVE_RSVD | CDNS_MCP_INT_SLAVE_ALERT |
>> +			CDNS_MCP_INT_SLAVE_ATTACH | CDNS_MCP_INT_SLAVE_NATTACH;
>>   
>> -	/* enable detection of bus issues */
>> -	mask |= CDNS_MCP_INT_CTRL_CLASH | CDNS_MCP_INT_DATA_CLASH |
>> -		CDNS_MCP_INT_PARITY;
>> +		/* enable detection of bus issues */
>> +		mask |= CDNS_MCP_INT_CTRL_CLASH | CDNS_MCP_INT_DATA_CLASH |
>> +			CDNS_MCP_INT_PARITY;
>>   
>> -	/* no detection of port interrupts for now */
>> +		/* no detection of port interrupts for now */
>>   
>> -	/* enable detection of RX fifo level */
>> -	mask |= CDNS_MCP_INT_RX_WL;
>> +		/* enable detection of RX fifo level */
>> +		mask |= CDNS_MCP_INT_RX_WL;
>>   
>> -	/* now enable all of the above */
>> -	mask |= CDNS_MCP_INT_IRQ;
>> +		/* now enable all of the above */
>> +		mask |= CDNS_MCP_INT_IRQ;
>>   
>> -	if (interrupt_mask) /* parameter override */
>> -		mask = interrupt_mask;
>> +		if (interrupt_mask) /* parameter override */
>> +			mask = interrupt_mask;
>> +	} else {
>> +		cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK0, 0);
>> +		cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK1, 0);
>> +		mask = 0;
>> +	}
> 
> Looks like this should be two functions? Especially since "state" is always a constant
> when it is called. If there is still a lot of common code below, maybe make it a helper
> function.

Yes, the code is a bit ugly. I could initialize all the masks to zero, 
have the if(state) block and write the masks.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 37/40] soundwire: cadence_master: add hw_reset capability in debugfs
  2019-07-26 15:57   ` Guennadi Liakhovetski
@ 2019-07-26 17:31     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 17:31 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: alsa-devel, tiwai, gregkh, linux-kernel, vkoul, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale


>> +static int cdns_hw_reset(void *data, u64 value)
>> +{
>> +	struct sdw_cdns *cdns = data;
>> +	int ret;
>> +
>> +	if (value != 1)
>> +		return 0;
>> +
>> +	dev_info(cdns->dev, "starting link hw_reset\n");
>> +
>> +	ret = sdw_cdns_exit_reset(cdns);
>> +
>> +	dev_info(cdns->dev, "link hw_reset done\n");
> 
> Both really should be dev_info()? Maybe at least one of them can be dev_dbg()?

I have to walk back on what I explained to Greg. The idea was to have a 
dmesg trace when this function as called when the user plays with 
debugfs, otherwise the dmesg log is difficult to interpret (devices can 
go off the bus on their own). I'll keep the first one only and demote it 
to dev_dbg.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 38/40] soundwire: cadence_master: make clock stop exit configurable on init
  2019-07-26 16:02   ` [alsa-devel] " Guennadi Liakhovetski
@ 2019-07-26 17:35     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 17:35 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: alsa-devel, tiwai, gregkh, linux-kernel, vkoul, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale


>> -int sdw_cdns_init(struct sdw_cdns *cdns);
>> +int sdw_cdns_init(struct sdw_cdns *cdns, bool clock_stop_exit);
>>   int sdw_cdns_pdi_init(struct sdw_cdns *cdns,
>>   		      struct sdw_cdns_stream_config config);
>>   int sdw_cdns_exit_reset(struct sdw_cdns *cdns);
>> diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
>> index 1192d5775484..db7bf2912767 100644
>> --- a/drivers/soundwire/intel.c
>> +++ b/drivers/soundwire/intel.c
>> @@ -1043,7 +1043,7 @@ static int intel_init(struct sdw_intel *sdw)
>>   	intel_link_power_up(sdw);
>>   	intel_shim_init(sdw);
>>   
>> -	return sdw_cdns_init(&sdw->cdns);
>> +	return sdw_cdns_init(&sdw->cdns, false);
> 
> This is the only caller of this function so far, so, it looks like
> the second argument ATM is always "false." I assume you foresee other
> uses with "true" in the future, otherwise maybe just fix it to false
> in the function?

Since we are at RFC level things are not set in stone, it's not fully 
clear if this test is required or not. I added it since Rander reported 
an error on one of the target platforms that I didn't see personally. 
We'll double-check if it's needed. And if indeed it's needed, yes it'll 
be set to true when we add clock stop.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 27/40] soundwire: Add Intel resource management algorithm
  2019-07-26 15:43   ` Guennadi Liakhovetski
@ 2019-07-26 17:55     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 17:55 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: alsa-devel, tiwai, gregkh, linux-kernel, vkoul, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale

Thanks Guennadi for looking at this code, it's hard to review and figure 
things out...
I replied to each, even trivial ones, to have a trace of all the issues.

>> +static void sdw_compute_slave_ports(struct sdw_master_runtime *m_rt,
>> +				    struct sdw_transport_data *t_data)
>> +{
>> +	struct sdw_slave_runtime *s_rt = NULL;
> 
> Superfluous initialisation.

ok

> 
>> +	struct sdw_port_runtime *p_rt;
>> +	int port_bo, sample_int;
>> +	unsigned int rate, bps, ch = 0;
> 
> ditto for ch

ok

>> +
>> +	port_bo = t_data->block_offset;
>> +
>> +	list_for_each_entry(s_rt, &m_rt->slave_rt_list, m_rt_node) {
>> +		rate = m_rt->stream->params.rate;
>> +		bps = m_rt->stream->params.bps;
>> +		sample_int = (m_rt->bus->params.curr_dr_freq / rate);
>> +
>> +		list_for_each_entry(p_rt, &s_rt->port_list, port_node) {
>> +			ch = sdw_ch_mask_to_ch(p_rt->ch_mask);
>> +
>> +			sdw_fill_xport_params(&p_rt->transport_params,
>> +					      p_rt->num, true,
>> +					      SDW_BLK_GRP_CNT_1,
>> +					      sample_int, port_bo, port_bo >> 8,
>> +					      t_data->hstart,
>> +					      t_data->hstop,
> 
> I think the above two lines could fit in one

likely yes.

> 
>> +					      (SDW_BLK_GRP_CNT_1 * ch), 0x0);
> 
> superfluous parentheses

yep


>> +static void sdw_compute_master_ports(struct sdw_master_runtime *m_rt,
>> +				     struct sdw_group_params *params,
>> +				     int port_bo, int hstop)
>> +{
>> +	struct sdw_transport_data t_data = {0};
>> +	struct sdw_port_runtime *p_rt;
>> +	struct sdw_bus *bus = m_rt->bus;
>> +	int sample_int, hstart = 0;
> 
> superfluous initialisation

yes

> 
>> +	unsigned int rate, bps, ch, no_ch;
>> +
>> +	rate = m_rt->stream->params.rate;
>> +	bps = m_rt->stream->params.bps;
>> +	ch = m_rt->ch_count;
>> +	sample_int = (bus->params.curr_dr_freq / rate);
> 
> superfluous parentheses

yes

>> +
>> +	if (rate != params->rate)
>> +		return;
>> +
>> +	t_data.hstop = hstop;
>> +	hstart = hstop - params->hwidth + 1;
>> +	t_data.hstart = hstart;
>> +
>> +	list_for_each_entry(p_rt, &m_rt->port_list, port_node) {
>> +		no_ch = sdw_ch_mask_to_ch(p_rt->ch_mask);
>> +
>> +		sdw_fill_xport_params(&p_rt->transport_params, p_rt->num,
>> +				      true, SDW_BLK_GRP_CNT_1, sample_int,
>> +				      port_bo, port_bo >> 8, hstart, hstop,
>> +				      (SDW_BLK_GRP_CNT_1 * no_ch), 0x0);
> 
> superfluous parentheses

yes

> 
>> +
>> +		sdw_fill_port_params(&p_rt->port_params,
>> +				     p_rt->num, bps,
>> +				     SDW_PORT_FLOW_MODE_ISOCH,
>> +				     SDW_PORT_DATA_MODE_NORMAL);
>> +
>> +		/* Check for first entry */
>> +		if (!(p_rt == list_first_entry(&m_rt->port_list,
>> +					       struct sdw_port_runtime,
>> +					       port_node))) {
> 
> you wanted to write "if (p_rt != ...)"

bad code indeed, thanks for spotting this. I need to double-check this 
one, now I don't trust the ==
it could also be that it was meant to be a NULL check on the first entry.

> 
>> +			port_bo += bps * ch;
>> +			continue;
>> +		}
>> +
>> +		t_data.hstart = hstart;
>> +		t_data.hstop = hstop;
> 
> You already set these two above

need to check this as well.

> 
>> +		t_data.block_offset = port_bo;
>> +		t_data.sub_block_offset = 0;
>> +		port_bo += bps * ch;
>> +	}
>> +
>> +	sdw_compute_slave_ports(m_rt, &t_data);
>> +}
>> +
>> +static void _sdw_compute_port_params(struct sdw_bus *bus,
>> +				     struct sdw_group_params *params, int count)
>> +{
>> +	struct sdw_master_runtime *m_rt = NULL;
> 
> superfluous initialisation

yes

> 
>> +	int hstop = bus->params.col - 1;
>> +	int block_offset, port_bo, i;
>> +
>> +	/* Run loop for all groups to compute transport parameters */
>> +	for (i = 0; i < count; i++) {
>> +		port_bo = 1;
>> +		block_offset = 1;
>> +
>> +		list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
>> +			sdw_compute_master_ports(m_rt, &params[i],
>> +						 port_bo, hstop);
>> +
>> +			block_offset += m_rt->ch_count *
>> +					m_rt->stream->params.bps;
>> +			port_bo = block_offset;
>> +		}
>> +
>> +		hstop = hstop - params[i].hwidth;
> 
> hstop -= ...

yes

> 
>> +	}
>> +}
>> +
>> +static int sdw_compute_group_params(struct sdw_bus *bus,
>> +				    struct sdw_group_params *params,
>> +				    int *rates, int count)
>> +{
>> +	struct sdw_master_runtime *m_rt = NULL;
> 
> ditto

yes

>> +	int sel_col = bus->params.col;
>> +	unsigned int rate, bps, ch;
>> +	int i, column_needed = 0;
>> +
>> +	/* Calculate bandwidth per group */
>> +	for (i = 0; i < count; i++) {
>> +		params[i].rate = rates[i];
>> +		params[i].full_bw = bus->params.curr_dr_freq / params[i].rate;
>> +	}
>> +
>> +	list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
>> +		rate = m_rt->stream->params.rate;
>> +		bps = m_rt->stream->params.bps;
>> +		ch = m_rt->ch_count;
>> +
>> +		for (i = 0; i < count; i++) {
>> +			if (rate == params[i].rate)
>> +				params[i].payload_bw += bps * ch;
> 
> I don't know about the algorithm, rates can repeat, right? So you cannot break
> out of the loop here once you found one match?

This code looks wrong. Need to get an intravenous caffeine injection.

> 
>> +		}
>> +	}
>> +
>> +	for (i = 0; i < count; i++) {
>> +		params[i].hwidth = (sel_col *
>> +			params[i].payload_bw + params[i].full_bw - 1) /
>> +			params[i].full_bw;
>> +
>> +		column_needed += params[i].hwidth;
>> +	}
>> +
>> +	if (column_needed > sel_col - 1)
>> +		return -EINVAL;
>> +
>> +	return 0;
>> +}
>> +
>> +static int sdw_add_element_group_count(struct sdw_group *group,
>> +				       unsigned int rate)
>> +{
>> +	int num = group->count;
>> +	int i;
>> +
>> +	for (i = 0; i <= num; i++) {
>> +		if (rate == group->rates[i])
> 
> Are you sure this is correct? You actually check count + 1 rates - from 0
> to count inclusively. I think this isn't what you wanted to do, so my
> proposal below only checks count rates.

I'll have to double check. There's already the warning on krealloc that 
looks suspicious as well.

> 
>> +			break;
>> +
>> +		if (i != num)
>> +			continue;
>> +
>> +		if (group->count >= group->max_size) {
>> +			group->max_size += 1;
>> +			group->rates = krealloc(group->rates,
>> +						(sizeof(int) * group->max_size),
>> +						GFP_KERNEL);
>> +			if (!group->rates)
>> +				return -ENOMEM;
>> +		}
>> +
>> +		group->rates[group->count++] = rate;
>> +	}
> 
> How about this:
> 
> 	for (i = 0; i < num; i++)
> 		if (rate == group->rates[i])
> 			return 0;
> 
> 	if (group->count >= group->max_size) {
> 		group->max_size += 1;
> 		group->rates = krealloc(group->rates,
> 					(sizeof(int) * group->max_size),
> 					GFP_KERNEL);
> 		if (!group->rates)
> 			return -ENOMEM;
> 	}
> 
> 	group->rates[group->count++] = rate;
> 
> 	return 0;

will check offline and see.

>> +
>> +	return 0;
>> +}
>> +
>> +static int sdw_get_group_count(struct sdw_bus *bus,
>> +			       struct sdw_group *group)
>> +{
>> +	struct sdw_master_runtime *m_rt;
>> +	unsigned int rate;
>> +	int ret = 0;
>> +
>> +	group->count = 0;
>> +	group->max_size = SDW_STRM_RATE_GROUPING;
>> +	group->rates = kcalloc(group->max_size, sizeof(int), GFP_KERNEL);
>> +	if (!group->rates)
>> +		return -ENOMEM;
>> +
>> +	list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
>> +		rate = m_rt->stream->params.rate;
>> +		if (m_rt == list_first_entry(&bus->m_rt_list,
>> +					     struct sdw_master_runtime,
>> +					     bus_node)) {
>> +			group->rates[group->count++] = rate;
>> +
>> +		} else {
>> +			ret = sdw_add_element_group_count(group, rate);
>> +			if (ret < 0)
> 
> Actually it looks like you should free rates here? I see that not doing this
> makes the caller function below easier, but I'd say this is more error-
> prone... Up to you but I'd go the "safe" way - if it fails, it frees itself,
> if it succeeds - it's freed elsewhere.

good catch, will look into this.

> 
>> +				return ret;
>> +		}
>> +	}
>> +
>> +	return ret;
> 
> I think this will always return 0 here, so you don't need the "ret"
> variable in the function scope, you only need it in the "else"
> scope above.

will check. In general I avoid per-scope declarations.

>> +}
>> +
>> +/**
>> + * sdw_compute_port_params: Compute transport and port parameters
>> + *
>> + * @bus: SDW Bus instance
>> + */
>> +static int sdw_compute_port_params(struct sdw_bus *bus)
>> +{
>> +	struct sdw_group_params *params = NULL;
>> +	struct sdw_group group;
>> +	int ret;
>> +
>> +	ret = sdw_get_group_count(bus, &group);
>> +	if (ret < 0)
>> +		goto out;
>> +
>> +	if (group.count == 0)
>> +		goto out;
>> +
>> +	params = kcalloc(group.count, sizeof(*params), GFP_KERNEL);
>> +	if (!params) {
>> +		ret = -ENOMEM;
>> +		goto out;
>> +	}
>> +
>> +	/* Compute transport parameters for grouped streams */
>> +	ret = sdw_compute_group_params(bus, params,
>> +				       &group.rates[0], group.count);
>> +	if (ret < 0)
>> +		goto out;
>> +
>> +	_sdw_compute_port_params(bus, params, group.count);
>> +
>> +out:
>> +	kfree(params);
>> +	kfree(group.rates);
> 
> Depending whether or not you change the code above, this might change
> too.

will check

>> +static int sdw_compute_bus_params(struct sdw_bus *bus)
>> +{
>> +	unsigned int max_dr_freq, curr_dr_freq = 0;
>> +	struct sdw_master_prop *mstr_prop = NULL;
> 
> superfluous initialisation

yes

>> +	int i, clk_values, ret;
>> +	bool is_gear = false;
>> +	u32 *clk_buf;
>> +
>> +	mstr_prop = &bus->prop;
>> +	if (!mstr_prop)
> 
> this is impossible, it's an address of bus->prop...

Gah, yes.

>> +		return -EINVAL;
>> +
>> +	if (mstr_prop->num_clk_gears) {
>> +		clk_values = mstr_prop->num_clk_gears;
>> +		clk_buf = mstr_prop->clk_gears;
>> +		is_gear = true;
>> +	} else if (mstr_prop->num_clk_freq) {
>> +		clk_values = mstr_prop->num_clk_freq;
>> +		clk_buf = mstr_prop->clk_freq;
>> +	} else {
>> +		clk_values = 1;
>> +		clk_buf = NULL;
>> +	}
>> +
>> +	max_dr_freq = mstr_prop->max_clk_freq * SDW_DOUBLE_RATE_FACTOR;
>> +
>> +	for (i = 0; i < clk_values; i++) {
>> +		if (!clk_buf)
>> +			curr_dr_freq = max_dr_freq;
>> +		else
>> +			curr_dr_freq = (is_gear) ?
> 
> superfluous parentheses
> 
>> +				(max_dr_freq >>  clk_buf[i]) :
> 
> ditto

yes and yes
> 
>> +				clk_buf[i] * SDW_DOUBLE_RATE_FACTOR;
>> +
>> +		if (curr_dr_freq <= bus->params.bandwidth)
>> +			continue;
>> +
>> +		break;
> 
> I think this is raw code, you'd actually want to write this as
> 
> 		if (curr_dr_freq > bus->params.bandwidth)
> 			break;

I saw this before my Summer break and forgot about it. yes it needs to 
be fixed.

>>   
>>   	bus->debugfs = sdw_bus_debugfs_init(bus);
>>   
>> +	if (!bus->compute_params)
>> +		bus->compute_params = &sdw_compute_params;
> 
> I think it is more usual to not use "&" with functions, but it's valid too

yes, will fix


>> +/* Retrieve and return channel count from channel mask */
>> +static inline int sdw_ch_mask_to_ch(int ch_mask)
>> +{
>> +	int c = 0;
> 
> superfluous initialisation

yes

> 
>> +
>> +	for (c = 0; ch_mask; ch_mask >>= 1)
>> +		c += ch_mask & 1;
> 
> isn't there a built-in or something to count set bits... You could use ffs() to
> at least not loop 31 times for 0x80000000

will check

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 17/40] soundwire: bus: use runtime_pm_get_sync/pm when enabled
  2019-07-25 23:40 ` [RFC PATCH 17/40] soundwire: bus: use runtime_pm_get_sync/pm when enabled Pierre-Louis Bossart
  2019-07-26  7:39   ` [alsa-devel] " Guennadi Liakhovetski
@ 2019-07-26 18:08   ` Pierre-Louis Bossart
  2019-07-26 18:25     ` [alsa-devel] " Guennadi Liakhovetski
  2019-07-26 19:08     ` Andy Shevchenko
  2019-08-02 16:58   ` Vinod Koul
  2 siblings, 2 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-26 18:08 UTC (permalink / raw)
  To: alsa-devel
  Cc: linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale,
	Rafael J. Wysocki, Andy Shevchenko, linux-pm

This thread became unreadable with interleaved top-posting, allow me 
restate the options and ask PM folks what they think

On 7/25/19 6:40 PM, Pierre-Louis Bossart wrote:
> Not all platforms support runtime_pm for now, let's use runtime_pm
> only when enabled.
> 
> Suggested-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>   drivers/soundwire/bus.c | 25 ++++++++++++++++---------
>   1 file changed, 16 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
> index 5ad4109dc72f..0a45dc5713df 100644
> --- a/drivers/soundwire/bus.c
> +++ b/drivers/soundwire/bus.c
> @@ -332,12 +332,16 @@ int sdw_nread(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
>   	if (ret < 0)
>   		return ret;
>   
> -	ret = pm_runtime_get_sync(slave->bus->dev);
> -	if (ret < 0)
> -		return ret;
> +	if (pm_runtime_enabled(slave->bus->dev)) {
> +		ret = pm_runtime_get_sync(slave->bus->dev);
> +		if (ret < 0)
> +			return ret;
> +	}
>   
>   	ret = sdw_transfer(slave->bus, &msg);
> -	pm_runtime_put(slave->bus->dev);
> +
> +	if (pm_runtime_enabled(slave->bus->dev))
> +		pm_runtime_put(slave->bus->dev);

This is option1: we explicitly test if pm_runtime is enabled before 
calling _get_sync() and _put()

option2 (suggested by Jan Kotas): catch the -EACCESS error code

  	ret = pm_runtime_get_sync(slave->bus->dev);
-	if (ret < 0)
+	if (ret < 0 && ret != -EACCES)
  		return ret;

option3: ignore the return value as done in quite a few drivers

Are there any other options? I am personally surprised this is not 
handled in the pm_runtime core, not sure why users need to test for this?

Thanks
Pierre

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 17/40] soundwire: bus: use runtime_pm_get_sync/pm when enabled
  2019-07-26 18:08   ` Pierre-Louis Bossart
@ 2019-07-26 18:25     ` Guennadi Liakhovetski
  2019-07-26 19:11       ` Andy Shevchenko
  2019-07-26 19:08     ` Andy Shevchenko
  1 sibling, 1 reply; 183+ messages in thread
From: Guennadi Liakhovetski @ 2019-07-26 18:25 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, Rafael J. Wysocki, tiwai, gregkh, linux-pm,
	linux-kernel, vkoul, broonie, srinivas.kandagatla, jank,
	slawomir.blauciak, Sanyog Kale, Andy Shevchenko

On Fri, Jul 26, 2019 at 01:08:57PM -0500, Pierre-Louis Bossart wrote:
> This thread became unreadable with interleaved top-posting, allow me restate
> the options and ask PM folks what they think
> 
> On 7/25/19 6:40 PM, Pierre-Louis Bossart wrote:
> > Not all platforms support runtime_pm for now, let's use runtime_pm
> > only when enabled.
> > 
> > Suggested-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> > Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> > ---
> >   drivers/soundwire/bus.c | 25 ++++++++++++++++---------
> >   1 file changed, 16 insertions(+), 9 deletions(-)
> > 
> > diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
> > index 5ad4109dc72f..0a45dc5713df 100644
> > --- a/drivers/soundwire/bus.c
> > +++ b/drivers/soundwire/bus.c
> > @@ -332,12 +332,16 @@ int sdw_nread(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
> >   	if (ret < 0)
> >   		return ret;
> > -	ret = pm_runtime_get_sync(slave->bus->dev);
> > -	if (ret < 0)
> > -		return ret;
> > +	if (pm_runtime_enabled(slave->bus->dev)) {
> > +		ret = pm_runtime_get_sync(slave->bus->dev);
> > +		if (ret < 0)
> > +			return ret;
> > +	}
> >   	ret = sdw_transfer(slave->bus, &msg);
> > -	pm_runtime_put(slave->bus->dev);
> > +
> > +	if (pm_runtime_enabled(slave->bus->dev))
> > +		pm_runtime_put(slave->bus->dev);
> 
> This is option1: we explicitly test if pm_runtime is enabled before calling
> _get_sync() and _put()
> 
> option2 (suggested by Jan Kotas): catch the -EACCESS error code
> 
>  	ret = pm_runtime_get_sync(slave->bus->dev);
> -	if (ret < 0)
> +	if (ret < 0 && ret != -EACCES)
>  		return ret;
> 
> option3: ignore the return value as done in quite a few drivers
> 
> Are there any other options? I am personally surprised this is not handled
> in the pm_runtime core, not sure why users need to test for this?

option 4: fix this in runtime PM :-) This seems like the best option to me,
but probably not the easiest one. Otherwise I'd go with (2), I think, since
that's also the official purpose of the -EACCESS return code:

https://lists.linuxfoundation.org/pipermail/linux-pm/2011-June/031930.html

Thanks
Guennadi

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 17/40] soundwire: bus: use runtime_pm_get_sync/pm when enabled
  2019-07-26 18:08   ` Pierre-Louis Bossart
  2019-07-26 18:25     ` [alsa-devel] " Guennadi Liakhovetski
@ 2019-07-26 19:08     ` Andy Shevchenko
  2019-07-29 22:07       ` [alsa-devel] " Pierre-Louis Bossart
  1 sibling, 1 reply; 183+ messages in thread
From: Andy Shevchenko @ 2019-07-26 19:08 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale,
	Rafael J. Wysocki, linux-pm

On Fri, Jul 26, 2019 at 01:08:57PM -0500, Pierre-Louis Bossart wrote:
> This thread became unreadable with interleaved top-posting, allow me restate
> the options and ask PM folks what they think
> 
> On 7/25/19 6:40 PM, Pierre-Louis Bossart wrote:
> > Not all platforms support runtime_pm for now, let's use runtime_pm
> > only when enabled.

Just a side note below...

> > -	ret = pm_runtime_get_sync(slave->bus->dev);
> > -	if (ret < 0)

Here...

> > -		return ret;
> > +	if (pm_runtime_enabled(slave->bus->dev)) {
> > +		ret = pm_runtime_get_sync(slave->bus->dev);
> > +		if (ret < 0)

...and thus here...

> > +			return ret;
> > +	}
> >   	ret = sdw_transfer(slave->bus, &msg);
> > -	pm_runtime_put(slave->bus->dev);
> > +
> > +	if (pm_runtime_enabled(slave->bus->dev))
> > +		pm_runtime_put(slave->bus->dev);
> 
> This is option1: we explicitly test if pm_runtime is enabled before calling
> _get_sync() and _put()
> 
> option2 (suggested by Jan Kotas): catch the -EACCESS error code
> 
>  	ret = pm_runtime_get_sync(slave->bus->dev);
> -	if (ret < 0)
> +	if (ret < 0 && ret != -EACCES)

...and here, the pm_runtime_put_noidle() call is missed.

>  		return ret;
> 
> option3: ignore the return value as done in quite a few drivers
> 
> Are there any other options? I am personally surprised this is not handled
> in the pm_runtime core, not sure why users need to test for this?

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 17/40] soundwire: bus: use runtime_pm_get_sync/pm when enabled
  2019-07-26 18:25     ` [alsa-devel] " Guennadi Liakhovetski
@ 2019-07-26 19:11       ` Andy Shevchenko
  0 siblings, 0 replies; 183+ messages in thread
From: Andy Shevchenko @ 2019-07-26 19:11 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: Pierre-Louis Bossart, alsa-devel, Rafael J. Wysocki, tiwai,
	gregkh, linux-pm, linux-kernel, vkoul, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale

On Fri, Jul 26, 2019 at 08:25:35PM +0200, Guennadi Liakhovetski wrote:
> On Fri, Jul 26, 2019 at 01:08:57PM -0500, Pierre-Louis Bossart wrote:
> > On 7/25/19 6:40 PM, Pierre-Louis Bossart wrote:
> > > Not all platforms support runtime_pm for now, let's use runtime_pm
> > > only when enabled.

> > option2 (suggested by Jan Kotas): catch the -EACCESS error code
> > 
> >  	ret = pm_runtime_get_sync(slave->bus->dev);
> > -	if (ret < 0)
> > +	if (ret < 0 && ret != -EACCES)
> >  		return ret;

> Otherwise I'd go with (2), I think, since
> that's also the official purpose of the -EACCESS return code:
> 
> https://lists.linuxfoundation.org/pipermail/linux-pm/2011-June/031930.html

And at least we have examples in the kernel

drivers/gpu/drm/radeon/radeon_fb.c:57:  if (ret < 0 && ret != -EACCES) {

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 17/40] soundwire: bus: use runtime_pm_get_sync/pm when enabled
  2019-07-26 19:08     ` Andy Shevchenko
@ 2019-07-29 22:07       ` Pierre-Louis Bossart
  2019-07-30 11:21         ` Andy Shevchenko
  0 siblings, 1 reply; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-29 22:07 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: alsa-devel, Rafael J. Wysocki, tiwai, gregkh, linux-pm,
	linux-kernel, vkoul, broonie, srinivas.kandagatla, jank,
	slawomir.blauciak, Sanyog Kale



On 7/26/19 2:08 PM, Andy Shevchenko wrote:
> On Fri, Jul 26, 2019 at 01:08:57PM -0500, Pierre-Louis Bossart wrote:
>> This thread became unreadable with interleaved top-posting, allow me restate
>> the options and ask PM folks what they think
>>
>> On 7/25/19 6:40 PM, Pierre-Louis Bossart wrote:
>>> Not all platforms support runtime_pm for now, let's use runtime_pm
>>> only when enabled.
> 
> Just a side note below...
> 
>>> -	ret = pm_runtime_get_sync(slave->bus->dev);
>>> -	if (ret < 0)
> 
> Here...
> 
>>> -		return ret;
>>> +	if (pm_runtime_enabled(slave->bus->dev)) {
>>> +		ret = pm_runtime_get_sync(slave->bus->dev);
>>> +		if (ret < 0)
> 
> ...and thus here...
> 
>>> +			return ret;
>>> +	}
>>>    	ret = sdw_transfer(slave->bus, &msg);
>>> -	pm_runtime_put(slave->bus->dev);
>>> +
>>> +	if (pm_runtime_enabled(slave->bus->dev))
>>> +		pm_runtime_put(slave->bus->dev);
>>
>> This is option1: we explicitly test if pm_runtime is enabled before calling
>> _get_sync() and _put()
>>
>> option2 (suggested by Jan Kotas): catch the -EACCESS error code
>>
>>   	ret = pm_runtime_get_sync(slave->bus->dev);
>> -	if (ret < 0)
>> +	if (ret < 0 && ret != -EACCES)
> 
> ...and here, the pm_runtime_put_noidle() call is missed.

yes but in the example you provided, they actually do more work than 
just decrement the device usage counter:

static int
radeonfb_open(struct fb_info *info, int user)
{
	struct radeon_fbdev *rfbdev = info->par;
	struct radeon_device *rdev = rfbdev->rdev;
	int ret = pm_runtime_get_sync(rdev->ddev->dev);
	if (ret < 0 && ret != -EACCES) {
		pm_runtime_mark_last_busy(rdev->ddev->dev);
		pm_runtime_put_autosuspend(rdev->ddev->dev);
		return ret;
	}
	return 0;
}

unless I am missing something pm_runtime_put_noidle() and 
_put_autosuspend() are not equivalent, are they?

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 17/40] soundwire: bus: use runtime_pm_get_sync/pm when enabled
  2019-07-29 22:07       ` [alsa-devel] " Pierre-Louis Bossart
@ 2019-07-30 11:21         ` Andy Shevchenko
  2019-07-30 12:57           ` Pierre-Louis Bossart
  0 siblings, 1 reply; 183+ messages in thread
From: Andy Shevchenko @ 2019-07-30 11:21 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, Rafael J. Wysocki, tiwai, gregkh, linux-pm,
	linux-kernel, vkoul, broonie, srinivas.kandagatla, jank,
	slawomir.blauciak, Sanyog Kale

On Mon, Jul 29, 2019 at 05:07:39PM -0500, Pierre-Louis Bossart wrote:
> On 7/26/19 2:08 PM, Andy Shevchenko wrote:
> > On Fri, Jul 26, 2019 at 01:08:57PM -0500, Pierre-Louis Bossart wrote:

> > > -	if (ret < 0)
> > > +	if (ret < 0 && ret != -EACCES)
> > 
> > ...and here, the pm_runtime_put_noidle() call is missed.
> 
> yes but in the example you provided, they actually do more work than just
> decrement the device usage counter:

In their case they would like to do that. You decide what is appropriate call
in your case.

My point is, that reference counter in case of error handling should be
returned back to its value.

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 17/40] soundwire: bus: use runtime_pm_get_sync/pm when enabled
  2019-07-30 11:21         ` Andy Shevchenko
@ 2019-07-30 12:57           ` Pierre-Louis Bossart
  2019-07-30 15:58             ` Andy Shevchenko
  0 siblings, 1 reply; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-07-30 12:57 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: alsa-devel, linux-pm, tiwai, gregkh, Rafael J. Wysocki,
	linux-kernel, vkoul, broonie, srinivas.kandagatla, jank,
	slawomir.blauciak, Sanyog Kale



On 7/30/19 6:21 AM, Andy Shevchenko wrote:
> On Mon, Jul 29, 2019 at 05:07:39PM -0500, Pierre-Louis Bossart wrote:
>> On 7/26/19 2:08 PM, Andy Shevchenko wrote:
>>> On Fri, Jul 26, 2019 at 01:08:57PM -0500, Pierre-Louis Bossart wrote:
> 
>>>> -	if (ret < 0)
>>>> +	if (ret < 0 && ret != -EACCES)
>>>
>>> ...and here, the pm_runtime_put_noidle() call is missed.
>>
>> yes but in the example you provided, they actually do more work than just
>> decrement the device usage counter:
> 
> In their case they would like to do that. You decide what is appropriate call
> in your case.
> 
> My point is, that reference counter in case of error handling should be
> returned back to its value.

Agree on the reference count.
I am however not clear on the next step and 'what is appropriate'.

If pm_runtime_get_sync() failed, then technically the device was not 
resumed so marking it as last_busy+autosuspend, or using a plain vanilla 
put() will not result in any action. I must be missing something here.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 17/40] soundwire: bus: use runtime_pm_get_sync/pm when enabled
  2019-07-30 12:57           ` Pierre-Louis Bossart
@ 2019-07-30 15:58             ` Andy Shevchenko
  2019-07-30 15:59               ` Andy Shevchenko
  0 siblings, 1 reply; 183+ messages in thread
From: Andy Shevchenko @ 2019-07-30 15:58 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-pm, tiwai, gregkh, Rafael J. Wysocki,
	linux-kernel, vkoul, broonie, srinivas.kandagatla, jank,
	slawomir.blauciak, Sanyog Kale

On Tue, Jul 30, 2019 at 07:57:46AM -0500, Pierre-Louis Bossart wrote:
> On 7/30/19 6:21 AM, Andy Shevchenko wrote:
> > On Mon, Jul 29, 2019 at 05:07:39PM -0500, Pierre-Louis Bossart wrote:
> > > On 7/26/19 2:08 PM, Andy Shevchenko wrote:
> > > > On Fri, Jul 26, 2019 at 01:08:57PM -0500, Pierre-Louis Bossart wrote:
> > 
> > > > > -	if (ret < 0)
> > > > > +	if (ret < 0 && ret != -EACCES)
> > > > 
> > > > ...and here, the pm_runtime_put_noidle() call is missed.
> > > 
> > > yes but in the example you provided, they actually do more work than just
> > > decrement the device usage counter:
> > 
> > In their case they would like to do that. You decide what is appropriate call
> > in your case.
> > 
> > My point is, that reference counter in case of error handling should be
> > returned back to its value.
> 
> Agree on the reference count.
> I am however not clear on the next step and 'what is appropriate'.
> 
> If pm_runtime_get_sync() failed, then technically the device was not resumed

Not so straight. It depends on reference count. It might be true (most cases
I think), or not true, if device had been resumed previously by other call.

> so marking it as last_busy+autosuspend, or using a plain vanilla put() will
> not result in any action. I must be missing something here.

put_noidle(). Because if it failed on the first call and was resumed, put()
will try to shut it down (since reference count goes to no-user base).

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 17/40] soundwire: bus: use runtime_pm_get_sync/pm when enabled
  2019-07-30 15:58             ` Andy Shevchenko
@ 2019-07-30 15:59               ` Andy Shevchenko
  0 siblings, 0 replies; 183+ messages in thread
From: Andy Shevchenko @ 2019-07-30 15:59 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-pm, tiwai, gregkh, Rafael J. Wysocki,
	linux-kernel, vkoul, broonie, srinivas.kandagatla, jank,
	slawomir.blauciak, Sanyog Kale

On Tue, Jul 30, 2019 at 06:58:09PM +0300, Andy Shevchenko wrote:
> On Tue, Jul 30, 2019 at 07:57:46AM -0500, Pierre-Louis Bossart wrote:
> > On 7/30/19 6:21 AM, Andy Shevchenko wrote:
> > > On Mon, Jul 29, 2019 at 05:07:39PM -0500, Pierre-Louis Bossart wrote:
> > > > On 7/26/19 2:08 PM, Andy Shevchenko wrote:

> > so marking it as last_busy+autosuspend, or using a plain vanilla put() will
> > not result in any action. I must be missing something here.
> 
> put_noidle(). Because if it failed on the first call and was resumed, put()
> will try to shut it down (since reference count goes to no-user base).

Sorry, this has to be read as (was -> wasn't)

> put_noidle(). Because if it failed on the first call and wasn't resumed, put()
> will try to shut it down (since reference count goes to no-user base).

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 03/40] soundwire: cadence_master: align debugfs to 8 digits
  2019-07-25 23:39 ` [RFC PATCH 03/40] soundwire: cadence_master: align debugfs to 8 digits Pierre-Louis Bossart
  2019-07-26  9:38   ` Cezary Rojewski
@ 2019-08-02 11:50   ` Vinod Koul
  1 sibling, 0 replies; 183+ messages in thread
From: Vinod Koul @ 2019-08-02 11:50 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 25-07-19, 18:39, Pierre-Louis Bossart wrote:
> SQUASHME

Git trick!

commit this using:
git fixup <sha1>

where sha1 is commit where you want this to be squashed into!

then below will suuash them for you!
 
git rebase -i --autosquash 



> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/cadence_master.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
> index 91e8bacb83e3..9f611a1fff0a 100644
> --- a/drivers/soundwire/cadence_master.c
> +++ b/drivers/soundwire/cadence_master.c
> @@ -234,7 +234,7 @@ static ssize_t cdns_sprintf(struct sdw_cdns *cdns,
>  			    char *buf, size_t pos, unsigned int reg)
>  {
>  	return scnprintf(buf + pos, RD_BUF - pos,
> -			 "%4x\t%4x\n", reg, cdns_readl(cdns, reg));
> +			 "%4x\t%8x\n", reg, cdns_readl(cdns, reg));
>  }
>  
>  static ssize_t cdns_reg_read(struct file *file, char __user *user_buf,
> -- 
> 2.20.1

-- 
~Vinod

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 05/40] soundwire: intel: move interrupt enable after interrupt handler registration
  2019-07-25 23:39 ` [RFC PATCH 05/40] soundwire: intel: move interrupt enable after interrupt handler registration Pierre-Louis Bossart
@ 2019-08-02 11:53   ` Vinod Koul
  2019-08-02 15:08     ` Pierre-Louis Bossart
  0 siblings, 1 reply; 183+ messages in thread
From: Vinod Koul @ 2019-08-02 11:53 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 25-07-19, 18:39, Pierre-Louis Bossart wrote:
> Not sure why the existing code would enable interrupts without the
> ability to deal with them.
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/intel.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
> index aeadc341c0a3..68832e613b1e 100644
> --- a/drivers/soundwire/intel.c
> +++ b/drivers/soundwire/intel.c
> @@ -981,8 +981,6 @@ static int intel_probe(struct platform_device *pdev)
>  	if (ret)
>  		goto err_init;
>  
> -	ret = sdw_cdns_enable_interrupt(&sdw->cdns);
> -
>  	/* Read the PDI config and initialize cadence PDI */
>  	intel_pdi_init(sdw, &config);
>  	ret = sdw_cdns_pdi_init(&sdw->cdns, config);
> @@ -1000,6 +998,8 @@ static int intel_probe(struct platform_device *pdev)
>  		goto err_init;
>  	}
>  
> +	ret = sdw_cdns_enable_interrupt(&sdw->cdns);

we should also handle the return

-- 
~Vinod

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 06/40] soundwire: intel: prevent possible dereference in hw_params
  2019-07-25 23:39 ` [RFC PATCH 06/40] soundwire: intel: prevent possible dereference in hw_params Pierre-Louis Bossart
  2019-07-26  9:45   ` Cezary Rojewski
@ 2019-08-02 11:55   ` Vinod Koul
  2019-08-02 15:16     ` [alsa-devel] " Pierre-Louis Bossart
  1 sibling, 1 reply; 183+ messages in thread
From: Vinod Koul @ 2019-08-02 11:55 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 25-07-19, 18:39, Pierre-Louis Bossart wrote:
> This should not happen in production systems but we should test for
> all callback arguments before invoking the config_stream callback.

so you are saying callback arg is mandatory, if so please document that
assumption

> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/intel.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
> index 68832e613b1e..497879dd9c0d 100644
> --- a/drivers/soundwire/intel.c
> +++ b/drivers/soundwire/intel.c
> @@ -509,7 +509,7 @@ static int intel_config_stream(struct sdw_intel *sdw,
>  			       struct snd_soc_dai *dai,
>  			       struct snd_pcm_hw_params *hw_params, int link_id)
>  {
> -	if (sdw->res->ops && sdw->res->ops->config_stream)
> +	if (sdw->res->ops && sdw->res->ops->config_stream && sdw->res->arg)
>  		return sdw->res->ops->config_stream(sdw->res->arg,
>  				substream, dai, hw_params, link_id);
>  
> -- 
> 2.20.1

-- 
~Vinod

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 07/40] soundwire: intel: fix channel number reported by hardware
  2019-07-25 23:39 ` [RFC PATCH 07/40] soundwire: intel: fix channel number reported by hardware Pierre-Louis Bossart
@ 2019-08-02 11:57   ` Vinod Koul
  2019-08-02 15:18     ` Pierre-Louis Bossart
  0 siblings, 1 reply; 183+ messages in thread
From: Vinod Koul @ 2019-08-02 11:57 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 25-07-19, 18:39, Pierre-Louis Bossart wrote:
> PDI2 reports an invalid count, force the correct hardware-supported
> value
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/intel.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
> index 497879dd9c0d..51990b192dc0 100644
> --- a/drivers/soundwire/intel.c
> +++ b/drivers/soundwire/intel.c
> @@ -401,6 +401,15 @@ intel_pdi_get_ch_cap(struct sdw_intel *sdw, unsigned int pdi_num, bool pcm)
>  
>  	if (pcm) {
>  		count = intel_readw(shim, SDW_SHIM_PCMSYCHC(link_id, pdi_num));
> +
> +		/*
> +		 * TODO: pdi number 2 reports channel count as 1 even though
> +		 * it supports 8 channel. Performing hardcoding for pdi
> +		 * number 2.
> +		 */
> +		if (pdi_num == 2)
> +			count = 7;

Is that true for all Intel controllers or some generations. Would it not
be better to put this under some flag which is set on platform basis?

> +
>  	} else {
>  		count = intel_readw(shim, SDW_SHIM_PDMSCAP(link_id));
>  		count = ((count & SDW_SHIM_PDMSCAP_CPSS) >>
> -- 
> 2.20.1

-- 
~Vinod

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 08/40] soundwire: intel: remove BIOS work-arounds
  2019-07-25 23:40 ` [RFC PATCH 08/40] soundwire: intel: remove BIOS work-arounds Pierre-Louis Bossart
@ 2019-08-02 11:58   ` Vinod Koul
  0 siblings, 0 replies; 183+ messages in thread
From: Vinod Koul @ 2019-08-02 11:58 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 25-07-19, 18:40, Pierre-Louis Bossart wrote:
> the values passed by all existing BIOS are fine, let's use them as is.
> The existing code must have been needed only on early prototypes.

Thanks for this, I am applying this.

> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/intel.c | 11 -----------
>  1 file changed, 11 deletions(-)
> 
> diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
> index 51990b192dc0..c718c9c67a37 100644
> --- a/drivers/soundwire/intel.c
> +++ b/drivers/soundwire/intel.c
> @@ -922,17 +922,6 @@ static int intel_prop_read(struct sdw_bus *bus)
>  	/* Initialize with default handler to read all DisCo properties */
>  	sdw_master_read_prop(bus);
>  
> -	/* BIOS is not giving some values correctly. So, lets override them */
> -	bus->prop.num_clk_freq = 1;
> -	bus->prop.clk_freq = devm_kcalloc(bus->dev, bus->prop.num_clk_freq,
> -					  sizeof(*bus->prop.clk_freq),
> -					  GFP_KERNEL);
> -	if (!bus->prop.clk_freq)
> -		return -ENOMEM;
> -
> -	bus->prop.clk_freq[0] = bus->prop.max_clk_freq;
> -	bus->prop.err_threshold = 5;
> -
>  	return 0;
>  }
>  
> -- 
> 2.20.1

-- 
~Vinod

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 09/40] soundwire: cadence_master: fix usage of CONFIG_UPDATE
  2019-07-25 23:40 ` [RFC PATCH 09/40] soundwire: cadence_master: fix usage of CONFIG_UPDATE Pierre-Louis Bossart
                     ` (2 preceding siblings ...)
  2019-07-26  9:53   ` Cezary Rojewski
@ 2019-08-02 12:03   ` Vinod Koul
  2019-08-02 15:18     ` Pierre-Louis Bossart
  2019-08-05  8:51   ` Sanyog Kale
  4 siblings, 1 reply; 183+ messages in thread
From: Vinod Koul @ 2019-08-02 12:03 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 25-07-19, 18:40, Pierre-Louis Bossart wrote:

>  int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
>  {
> -	int ret;
> -
>  	_cdns_enable_interrupt(cdns);
> -	ret = cdns_clear_bit(cdns, CDNS_MCP_CONFIG_UPDATE,
> -			     CDNS_MCP_CONFIG_UPDATE_BIT);
> -	if (ret < 0)
> -		dev_err(cdns->dev, "Config update timedout\n");

I was expecting cdns_update_config() to be invoked here??

>  
> -	return ret;
> +	return 0;

It would be better if we return a value here a not success always

> @@ -943,7 +953,10 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
>  
>  	cdns_writel(cdns, CDNS_MCP_CONFIG, val);
>  
> -	return 0;
> +	/* commit changes */
> +	ret = cdns_update_config(cdns);
> +
> +	return ret;

return cdns_update_config()

-- 
~Vinod

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 11/40] soundwire: cadence_master: simplify bus clash interrupt clear
  2019-07-25 23:40 ` [RFC PATCH 11/40] soundwire: cadence_master: simplify bus clash interrupt clear Pierre-Louis Bossart
@ 2019-08-02 12:07   ` Vinod Koul
  0 siblings, 0 replies; 183+ messages in thread
From: Vinod Koul @ 2019-08-02 12:07 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 25-07-19, 18:40, Pierre-Louis Bossart wrote:
> The bus clash interrupts are generated when the status is one, and
> also cleared by writing a one. It's overkill/useless to use an OR when
> the bit is already set.

IIRC we were supposed to have different variable and that was the reason
for setting, yes should be removed.

I have applied this one as well

-- 
~Vinod

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 12/40] soundwire: cadence_master: revisit interrupt settings
  2019-07-25 23:40 ` [RFC PATCH 12/40] soundwire: cadence_master: revisit interrupt settings Pierre-Louis Bossart
@ 2019-08-02 12:10   ` Vinod Koul
  2019-08-02 15:23     ` Pierre-Louis Bossart
  0 siblings, 1 reply; 183+ messages in thread
From: Vinod Koul @ 2019-08-02 12:10 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Bard Liao, Sanyog Kale

On 25-07-19, 18:40, Pierre-Louis Bossart wrote:
> Adding missing interrupt masks (parity, etc) and missing checks.
> Clarify which masks are for which usage.
> 
> Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/cadence_master.c | 25 ++++++++++++++++++++++---
>  1 file changed, 22 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
> index bdc3ed844829..0f3b9c160b01 100644
> --- a/drivers/soundwire/cadence_master.c
> +++ b/drivers/soundwire/cadence_master.c
> @@ -76,9 +76,12 @@
>  #define CDNS_MCP_INT_DPINT			BIT(11)
>  #define CDNS_MCP_INT_CTRL_CLASH			BIT(10)
>  #define CDNS_MCP_INT_DATA_CLASH			BIT(9)
> +#define CDNS_MCP_INT_PARITY			BIT(8)
>  #define CDNS_MCP_INT_CMD_ERR			BIT(7)
> +#define CDNS_MCP_INT_RX_NE			BIT(3)
>  #define CDNS_MCP_INT_RX_WL			BIT(2)
>  #define CDNS_MCP_INT_TXE			BIT(1)
> +#define CDNS_MCP_INT_TXF			BIT(0)
>  
>  #define CDNS_MCP_INTSET				0x4C
>  
> @@ -689,6 +692,11 @@ irqreturn_t sdw_cdns_irq(int irq, void *dev_id)
>  		}
>  	}
>  
> +	if (int_status & CDNS_MCP_INT_PARITY) {
> +		/* Parity error detected by Master */
> +		dev_err_ratelimited(cdns->dev, "Parity error\n");
> +	}
> +
>  	if (int_status & CDNS_MCP_INT_CTRL_CLASH) {
>  		/* Slave is driving bit slot during control word */
>  		dev_err_ratelimited(cdns->dev, "Bus clash for control word\n");
> @@ -761,10 +769,21 @@ int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
>  	cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK1,
>  		    CDNS_MCP_SLAVE_INTMASK1_MASK);
>  
> +	/* enable detection of slave state changes */
>  	mask = CDNS_MCP_INT_SLAVE_RSVD | CDNS_MCP_INT_SLAVE_ALERT |
> -		CDNS_MCP_INT_SLAVE_ATTACH | CDNS_MCP_INT_SLAVE_NATTACH |
> -		CDNS_MCP_INT_CTRL_CLASH | CDNS_MCP_INT_DATA_CLASH |
> -		CDNS_MCP_INT_RX_WL | CDNS_MCP_INT_IRQ | CDNS_MCP_INT_DPINT;
> +		CDNS_MCP_INT_SLAVE_ATTACH | CDNS_MCP_INT_SLAVE_NATTACH;
> +
> +	/* enable detection of bus issues */
> +	mask |= CDNS_MCP_INT_CTRL_CLASH | CDNS_MCP_INT_DATA_CLASH |
> +		CDNS_MCP_INT_PARITY;
> +
> +	/* no detection of port interrupts for now */
> +
> +	/* enable detection of RX fifo level */
> +	mask |= CDNS_MCP_INT_RX_WL;
> +
> +	/* now enable all of the above */

I think this comment seems is at wrong line..?

> +	mask |= CDNS_MCP_INT_IRQ;
>  
>  	cdns_writel(cdns, CDNS_MCP_INTMASK, mask);
>  
> -- 
> 2.20.1

-- 
~Vinod

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 13/40] soundwire: cadence_master: fix register definition for SLAVE_STATE
  2019-07-25 23:40 ` [RFC PATCH 13/40] soundwire: cadence_master: fix register definition for SLAVE_STATE Pierre-Louis Bossart
@ 2019-08-02 12:12   ` Vinod Koul
  0 siblings, 0 replies; 183+ messages in thread
From: Vinod Koul @ 2019-08-02 12:12 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 25-07-19, 18:40, Pierre-Louis Bossart wrote:
> wrong prefix and wrong macro.

Applied, thanks

-- 
~Vinod

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 14/40] soundwire: cadence_master: fix definitions for INTSTAT0/1
  2019-07-25 23:40 ` [RFC PATCH 14/40] soundwire: cadence_master: fix definitions for INTSTAT0/1 Pierre-Louis Bossart
@ 2019-08-02 12:13   ` Vinod Koul
  0 siblings, 0 replies; 183+ messages in thread
From: Vinod Koul @ 2019-08-02 12:13 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 25-07-19, 18:40, Pierre-Louis Bossart wrote:
> Two off-by-one errors: INTSTAT0 missed BIT(31) and INTSTAT1 is only
> defined on first 16 bits.

Applied, thanks

-- 
~Vinod

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 15/40] soundwire: cadence_master: handle multiple status reports per Slave
  2019-07-25 23:40 ` [RFC PATCH 15/40] soundwire: cadence_master: handle multiple status reports per Slave Pierre-Louis Bossart
  2019-07-25 22:31   ` [alsa-devel] " Guennadi Liakhovetski
@ 2019-08-02 12:20   ` Vinod Koul
  2019-08-02 15:29     ` Pierre-Louis Bossart
  1 sibling, 1 reply; 183+ messages in thread
From: Vinod Koul @ 2019-08-02 12:20 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 25-07-19, 18:40, Pierre-Louis Bossart wrote:
> When a Slave reports multiple status in the sticky bits, find the
> latest configuration from the mirror of the PING frame status and
> update the status directly.
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/cadence_master.c | 34 ++++++++++++++++++++++++------
>  1 file changed, 28 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
> index 889fa2cd49ae..25d5c7267c15 100644
> --- a/drivers/soundwire/cadence_master.c
> +++ b/drivers/soundwire/cadence_master.c
> @@ -643,13 +643,35 @@ static int cdns_update_slave_status(struct sdw_cdns *cdns,
>  
>  		/* first check if Slave reported multiple status */
>  		if (set_status > 1) {
> +			u32 val;
> +
>  			dev_warn_ratelimited(cdns->dev,
> -					     "Slave reported multiple Status: %d\n",
> -					     mask);
> -			/*
> -			 * TODO: we need to reread the status here by
> -			 * issuing a PING cmd
> -			 */
> +					     "Slave %d reported multiple Status: %d\n",
> +					     i, mask);
> +
> +			/* re-check latest status extracted from PING commands */
> +			val = cdns_readl(cdns, CDNS_MCP_SLAVE_STAT);
> +			val >>= (i * 2);
> +
> +			switch (val & 0x3) {
> +			case 0:

why not case CDNS_MCP_SLAVE_INTSTAT_NPRESENT:

> +				status[i] = SDW_SLAVE_UNATTACHED;
> +				break;
> +			case 1:
> +				status[i] = SDW_SLAVE_ATTACHED;
> +				break;
> +			case 2:
> +				status[i] = SDW_SLAVE_ALERT;
> +				break;
> +			default:
> +				status[i] = SDW_SLAVE_RESERVED;
> +				break;
> +			}

we have same logic in the code block preceding this, maybe good idea to
write a helper and use for both

Also IIRC we can have multiple status set right?

-- 
~Vinod

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 05/40] soundwire: intel: move interrupt enable after interrupt handler registration
  2019-08-02 11:53   ` Vinod Koul
@ 2019-08-02 15:08     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-08-02 15:08 UTC (permalink / raw)
  To: Vinod Koul
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale



On 8/2/19 6:53 AM, Vinod Koul wrote:
> On 25-07-19, 18:39, Pierre-Louis Bossart wrote:
>> Not sure why the existing code would enable interrupts without the
>> ability to deal with them.
>>
>> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
>> ---
>>   drivers/soundwire/intel.c | 4 ++--
>>   1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
>> index aeadc341c0a3..68832e613b1e 100644
>> --- a/drivers/soundwire/intel.c
>> +++ b/drivers/soundwire/intel.c
>> @@ -981,8 +981,6 @@ static int intel_probe(struct platform_device *pdev)
>>   	if (ret)
>>   		goto err_init;
>>   
>> -	ret = sdw_cdns_enable_interrupt(&sdw->cdns);
>> -
>>   	/* Read the PDI config and initialize cadence PDI */
>>   	intel_pdi_init(sdw, &config);
>>   	ret = sdw_cdns_pdi_init(&sdw->cdns, config);
>> @@ -1000,6 +998,8 @@ static int intel_probe(struct platform_device *pdev)
>>   		goto err_init;
>>   	}
>>   
>> +	ret = sdw_cdns_enable_interrupt(&sdw->cdns);
> 
> we should also handle the return

yes, fixed already

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 06/40] soundwire: intel: prevent possible dereference in hw_params
  2019-08-02 11:55   ` Vinod Koul
@ 2019-08-02 15:16     ` Pierre-Louis Bossart
  2019-08-02 15:57       ` Vinod Koul
  0 siblings, 1 reply; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-08-02 15:16 UTC (permalink / raw)
  To: Vinod Koul
  Cc: alsa-devel, tiwai, gregkh, linux-kernel, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale



On 8/2/19 6:55 AM, Vinod Koul wrote:
> On 25-07-19, 18:39, Pierre-Louis Bossart wrote:
>> This should not happen in production systems but we should test for
>> all callback arguments before invoking the config_stream callback.
> 
> so you are saying callback arg is mandatory, if so please document that
> assumption

no, what this says is that if a config_stream is provided then it needs 
to have a valid argument.

I am not sure what you mean by "document that assumption", comment in 
the code (where?) or SoundWire documentation?

> 
>> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
>> ---
>>   drivers/soundwire/intel.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
>> index 68832e613b1e..497879dd9c0d 100644
>> --- a/drivers/soundwire/intel.c
>> +++ b/drivers/soundwire/intel.c
>> @@ -509,7 +509,7 @@ static int intel_config_stream(struct sdw_intel *sdw,
>>   			       struct snd_soc_dai *dai,
>>   			       struct snd_pcm_hw_params *hw_params, int link_id)
>>   {
>> -	if (sdw->res->ops && sdw->res->ops->config_stream)
>> +	if (sdw->res->ops && sdw->res->ops->config_stream && sdw->res->arg)
>>   		return sdw->res->ops->config_stream(sdw->res->arg,
>>   				substream, dai, hw_params, link_id);
>>   
>> -- 
>> 2.20.1
> 

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 07/40] soundwire: intel: fix channel number reported by hardware
  2019-08-02 11:57   ` Vinod Koul
@ 2019-08-02 15:18     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-08-02 15:18 UTC (permalink / raw)
  To: Vinod Koul
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale



On 8/2/19 6:57 AM, Vinod Koul wrote:
> On 25-07-19, 18:39, Pierre-Louis Bossart wrote:
>> PDI2 reports an invalid count, force the correct hardware-supported
>> value
>>
>> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
>> ---
>>   drivers/soundwire/intel.c | 9 +++++++++
>>   1 file changed, 9 insertions(+)
>>
>> diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
>> index 497879dd9c0d..51990b192dc0 100644
>> --- a/drivers/soundwire/intel.c
>> +++ b/drivers/soundwire/intel.c
>> @@ -401,6 +401,15 @@ intel_pdi_get_ch_cap(struct sdw_intel *sdw, unsigned int pdi_num, bool pcm)
>>   
>>   	if (pcm) {
>>   		count = intel_readw(shim, SDW_SHIM_PCMSYCHC(link_id, pdi_num));
>> +
>> +		/*
>> +		 * TODO: pdi number 2 reports channel count as 1 even though
>> +		 * it supports 8 channel. Performing hardcoding for pdi
>> +		 * number 2.
>> +		 */
>> +		if (pdi_num == 2)
>> +			count = 7;
> 
> Is that true for all Intel controllers or some generations. Would it not
> be better to put this under some flag which is set on platform basis?

This is true of all controllers released so far.
We will change this if the hardware changes.

> 
>> +
>>   	} else {
>>   		count = intel_readw(shim, SDW_SHIM_PDMSCAP(link_id));
>>   		count = ((count & SDW_SHIM_PDMSCAP_CPSS) >>
>> -- 
>> 2.20.1
> 

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 09/40] soundwire: cadence_master: fix usage of CONFIG_UPDATE
  2019-08-02 12:03   ` Vinod Koul
@ 2019-08-02 15:18     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-08-02 15:18 UTC (permalink / raw)
  To: Vinod Koul
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale



On 8/2/19 7:03 AM, Vinod Koul wrote:
> On 25-07-19, 18:40, Pierre-Louis Bossart wrote:
> 
>>   int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
>>   {
>> -	int ret;
>> -
>>   	_cdns_enable_interrupt(cdns);
>> -	ret = cdns_clear_bit(cdns, CDNS_MCP_CONFIG_UPDATE,
>> -			     CDNS_MCP_CONFIG_UPDATE_BIT);
>> -	if (ret < 0)
>> -		dev_err(cdns->dev, "Config update timedout\n");
> 
> I was expecting cdns_update_config() to be invoked here??
> 
>>   
>> -	return ret;
>> +	return 0;
> 
> It would be better if we return a value here a not success always
> 
>> @@ -943,7 +953,10 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
>>   
>>   	cdns_writel(cdns, CDNS_MCP_CONFIG, val);
>>   
>> -	return 0;
>> +	/* commit changes */
>> +	ret = cdns_update_config(cdns);
>> +
>> +	return ret;
> 
> return cdns_update_config()

yes, all of this is fixed already.


^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 12/40] soundwire: cadence_master: revisit interrupt settings
  2019-08-02 12:10   ` Vinod Koul
@ 2019-08-02 15:23     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-08-02 15:23 UTC (permalink / raw)
  To: Vinod Koul
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Bard Liao, Sanyog Kale


>> @@ -761,10 +769,21 @@ int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
>>   	cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK1,
>>   		    CDNS_MCP_SLAVE_INTMASK1_MASK);
>>   
>> +	/* enable detection of slave state changes */
>>   	mask = CDNS_MCP_INT_SLAVE_RSVD | CDNS_MCP_INT_SLAVE_ALERT |
>> -		CDNS_MCP_INT_SLAVE_ATTACH | CDNS_MCP_INT_SLAVE_NATTACH |
>> -		CDNS_MCP_INT_CTRL_CLASH | CDNS_MCP_INT_DATA_CLASH |
>> -		CDNS_MCP_INT_RX_WL | CDNS_MCP_INT_IRQ | CDNS_MCP_INT_DPINT;
>> +		CDNS_MCP_INT_SLAVE_ATTACH | CDNS_MCP_INT_SLAVE_NATTACH;
>> +
>> +	/* enable detection of bus issues */
>> +	mask |= CDNS_MCP_INT_CTRL_CLASH | CDNS_MCP_INT_DATA_CLASH |
>> +		CDNS_MCP_INT_PARITY;
>> +
>> +	/* no detection of port interrupts for now */
>> +
>> +	/* enable detection of RX fifo level */
>> +	mask |= CDNS_MCP_INT_RX_WL;
>> +
>> +	/* now enable all of the above */
> 
> I think this comment seems is at wrong line..?
> 
>> +	mask |= CDNS_MCP_INT_IRQ;
>>   
>>   	cdns_writel(cdns, CDNS_MCP_INTMASK, mask);

No it's at the right place.

This flag gates all others, if its value is zero then the value of all 
other bits is irrelevant.

that's what I meant by 'all of the above'.



^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 15/40] soundwire: cadence_master: handle multiple status reports per Slave
  2019-08-02 12:20   ` Vinod Koul
@ 2019-08-02 15:29     ` Pierre-Louis Bossart
  2019-08-02 16:01       ` Vinod Koul
  0 siblings, 1 reply; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-08-02 15:29 UTC (permalink / raw)
  To: Vinod Koul
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale



On 8/2/19 7:20 AM, Vinod Koul wrote:
> On 25-07-19, 18:40, Pierre-Louis Bossart wrote:
>> When a Slave reports multiple status in the sticky bits, find the
>> latest configuration from the mirror of the PING frame status and
>> update the status directly.
>>
>> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
>> ---
>>   drivers/soundwire/cadence_master.c | 34 ++++++++++++++++++++++++------
>>   1 file changed, 28 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
>> index 889fa2cd49ae..25d5c7267c15 100644
>> --- a/drivers/soundwire/cadence_master.c
>> +++ b/drivers/soundwire/cadence_master.c
>> @@ -643,13 +643,35 @@ static int cdns_update_slave_status(struct sdw_cdns *cdns,
>>   
>>   		/* first check if Slave reported multiple status */
>>   		if (set_status > 1) {
>> +			u32 val;
>> +
>>   			dev_warn_ratelimited(cdns->dev,
>> -					     "Slave reported multiple Status: %d\n",
>> -					     mask);
>> -			/*
>> -			 * TODO: we need to reread the status here by
>> -			 * issuing a PING cmd
>> -			 */
>> +					     "Slave %d reported multiple Status: %d\n",
>> +					     i, mask);
>> +
>> +			/* re-check latest status extracted from PING commands */
>> +			val = cdns_readl(cdns, CDNS_MCP_SLAVE_STAT);
>> +			val >>= (i * 2);
>> +
>> +			switch (val & 0x3) {
>> +			case 0:
> 
> why not case CDNS_MCP_SLAVE_INTSTAT_NPRESENT:

ok

> 
>> +				status[i] = SDW_SLAVE_UNATTACHED;
>> +				break;
>> +			case 1:
>> +				status[i] = SDW_SLAVE_ATTACHED;
>> +				break;
>> +			case 2:
>> +				status[i] = SDW_SLAVE_ALERT;
>> +				break;
>> +			default:
>> +				status[i] = SDW_SLAVE_RESERVED;
>> +				break;
>> +			}
> 
> we have same logic in the code block preceding this, maybe good idea to
> write a helper and use for both

Yes, I am thinking about this. There are multiple cases where we want to 
re-check the status and clear some bits, so helpers would be good.

> 
> Also IIRC we can have multiple status set right?

Yes, the status bits are sticky and mirror all values reported in PING 
frames. I am still working on how to clear those bits, there are cases 
where we clear bits and end-up never hearing from that device ever 
again. classic edge/level issue I suppose.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 06/40] soundwire: intel: prevent possible dereference in hw_params
  2019-08-02 15:16     ` [alsa-devel] " Pierre-Louis Bossart
@ 2019-08-02 15:57       ` Vinod Koul
  2019-08-02 16:52         ` Pierre-Louis Bossart
  0 siblings, 1 reply; 183+ messages in thread
From: Vinod Koul @ 2019-08-02 15:57 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, tiwai, gregkh, linux-kernel, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale

On 02-08-19, 10:16, Pierre-Louis Bossart wrote:
> 
> 
> On 8/2/19 6:55 AM, Vinod Koul wrote:
> > On 25-07-19, 18:39, Pierre-Louis Bossart wrote:
> > > This should not happen in production systems but we should test for
> > > all callback arguments before invoking the config_stream callback.
> > 
> > so you are saying callback arg is mandatory, if so please document that
> > assumption
> 
> no, what this says is that if a config_stream is provided then it needs to
> have a valid argument.

well typically args are not mandatory..

> I am not sure what you mean by "document that assumption", comment in the
> code (where?) or SoundWire documentation?

The callback documentation which in this is in include/linux/soundwire/sdw_intel.h

-- 
~Vinod

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 15/40] soundwire: cadence_master: handle multiple status reports per Slave
  2019-08-02 15:29     ` Pierre-Louis Bossart
@ 2019-08-02 16:01       ` Vinod Koul
  2019-08-02 16:41         ` Pierre-Louis Bossart
  0 siblings, 1 reply; 183+ messages in thread
From: Vinod Koul @ 2019-08-02 16:01 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 02-08-19, 10:29, Pierre-Louis Bossart wrote:
> On 8/2/19 7:20 AM, Vinod Koul wrote:
> > On 25-07-19, 18:40, Pierre-Louis Bossart wrote:

> > > +				status[i] = SDW_SLAVE_UNATTACHED;
> > > +				break;
> > > +			case 1:
> > > +				status[i] = SDW_SLAVE_ATTACHED;
> > > +				break;
> > > +			case 2:
> > > +				status[i] = SDW_SLAVE_ALERT;
> > > +				break;
> > > +			default:
> > > +				status[i] = SDW_SLAVE_RESERVED;
> > > +				break;
> > > +			}
> > 
> > we have same logic in the code block preceding this, maybe good idea to
> > write a helper and use for both
> 
> Yes, I am thinking about this. There are multiple cases where we want to
> re-check the status and clear some bits, so helpers would be good.
> 
> > 
> > Also IIRC we can have multiple status set right?
> 
> Yes, the status bits are sticky and mirror all values reported in PING
> frames. I am still working on how to clear those bits, there are cases where
> we clear bits and end-up never hearing from that device ever again. classic
> edge/level issue I suppose.

Then the case logic above doesn't work, it should be like the code block
preceding this..

Thanks
-- 
~Vinod

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 15/40] soundwire: cadence_master: handle multiple status reports per Slave
  2019-08-02 16:01       ` Vinod Koul
@ 2019-08-02 16:41         ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-08-02 16:41 UTC (permalink / raw)
  To: Vinod Koul
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale



On 8/2/19 11:01 AM, Vinod Koul wrote:
> On 02-08-19, 10:29, Pierre-Louis Bossart wrote:
>> On 8/2/19 7:20 AM, Vinod Koul wrote:
>>> On 25-07-19, 18:40, Pierre-Louis Bossart wrote:
> 
>>>> +				status[i] = SDW_SLAVE_UNATTACHED;
>>>> +				break;
>>>> +			case 1:
>>>> +				status[i] = SDW_SLAVE_ATTACHED;
>>>> +				break;
>>>> +			case 2:
>>>> +				status[i] = SDW_SLAVE_ALERT;
>>>> +				break;
>>>> +			default:
>>>> +				status[i] = SDW_SLAVE_RESERVED;
>>>> +				break;
>>>> +			}
>>>
>>> we have same logic in the code block preceding this, maybe good idea to
>>> write a helper and use for both
>>
>> Yes, I am thinking about this. There are multiple cases where we want to
>> re-check the status and clear some bits, so helpers would be good.
>>
>>>
>>> Also IIRC we can have multiple status set right?
>>
>> Yes, the status bits are sticky and mirror all values reported in PING
>> frames. I am still working on how to clear those bits, there are cases where
>> we clear bits and end-up never hearing from that device ever again. classic
>> edge/level issue I suppose.
> 
> Then the case logic above doesn't work, it should be like the code block
> preceding this..

what I was referring to already is a problem even in single status mode.

Let's say for example that a device shows up as Device0, then we try to 
enumerate it and program a non-zero device number. If that fails, we 
currently clear the Attached status for Device0, so will never have an 
interrupt ever again. The device is there, attached as Device0, but 
we've lost the single opportunity to make it usable. The link is in most 
cases going to be extremely reliable, but if we know of state machines 
that lead to a terminal state then we should proactively have a recovery 
mechanism to avoid complicated debug down the road for cases where the 
hardware has transient issues.

For the multiple status case, we will have to look at the details and 
figure out which of the flags get cleared and which ones don't.

One certainty is that we absolutely have to track IO errors in interrupt 
context. They are recoverable in regular context but not quite in 
interrupt context if we clear the status bits unconditionally.

Maybe a tangent here but to be transparent there are really multiple 
topics we are tracking at the moment:

1. error handling in interrupts. I found a leak where if a device goes 
in the weeds while we program its device number and resynchronizes then 
we allocate a new device number instead of reusing the initial one. The 
bit clearing is also to be checked as explained above.

2. module dependencies: there is a race condition leading to a kernel 
oops if the Slave probe is not complete before the .update_status is 
invoked.

3. jack detection. The jack detection routine is called as a result of 
an imp-def Slave interrupt. We never documented the assumption that if 
this jack detection takes time then it needs to be done offline, e.g. in 
a work queue. Or if we still want it to be done in a the interrupt 
thread then we need to re-enable interrupts earlier, otherwise one 
device can stop interrupt handling for a fairly long duration.

4. streaming stop on link errors. We've seen in tests that if you reset 
the link or a Slave device with debugfs while audio is playing then 
streaming continues. This condition could happen if a device loses sync, 
and the spec says the Slave needs to reset its channel enable bits. At 
the command level, we handle this situation and will recover, but there 
is no notification to the ALSA layers to try and recover on the PCM side 
of things (as if it were an underflow condition). We also try to disable 
a stream but get all kinds of errors since it's lost state.

All of those points are corner cases but they are important to solve for 
actual products.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 06/40] soundwire: intel: prevent possible dereference in hw_params
  2019-08-02 15:57       ` Vinod Koul
@ 2019-08-02 16:52         ` Pierre-Louis Bossart
  2019-08-02 17:37           ` Vinod Koul
  0 siblings, 1 reply; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-08-02 16:52 UTC (permalink / raw)
  To: Vinod Koul
  Cc: alsa-devel, tiwai, gregkh, linux-kernel, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale



On 8/2/19 10:57 AM, Vinod Koul wrote:
> On 02-08-19, 10:16, Pierre-Louis Bossart wrote:
>>
>>
>> On 8/2/19 6:55 AM, Vinod Koul wrote:
>>> On 25-07-19, 18:39, Pierre-Louis Bossart wrote:
>>>> This should not happen in production systems but we should test for
>>>> all callback arguments before invoking the config_stream callback.
>>>
>>> so you are saying callback arg is mandatory, if so please document that
>>> assumption
>>
>> no, what this says is that if a config_stream is provided then it needs to
>> have a valid argument.
> 
> well typically args are not mandatory..
> 
>> I am not sure what you mean by "document that assumption", comment in the
>> code (where?) or SoundWire documentation?
> 
> The callback documentation which in this is in include/linux/soundwire/sdw_intel.h
> 

/**
  * struct sdw_intel_ops: Intel audio driver callback ops
  *
  * @config_stream: configure the stream with the hw_params
  */
struct sdw_intel_ops {
	int (*config_stream)(void *arg, void *substream,
			     void *dai, void *hw_params, int stream_num);
};

all parameters are mandatory really, not sure what you are trying to get at.

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 17/40] soundwire: bus: use runtime_pm_get_sync/pm when enabled
  2019-07-25 23:40 ` [RFC PATCH 17/40] soundwire: bus: use runtime_pm_get_sync/pm when enabled Pierre-Louis Bossart
  2019-07-26  7:39   ` [alsa-devel] " Guennadi Liakhovetski
  2019-07-26 18:08   ` Pierre-Louis Bossart
@ 2019-08-02 16:58   ` Vinod Koul
  2019-08-02 17:20     ` Pierre-Louis Bossart
  2 siblings, 1 reply; 183+ messages in thread
From: Vinod Koul @ 2019-08-02 16:58 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 25-07-19, 18:40, Pierre-Louis Bossart wrote:
> Not all platforms support runtime_pm for now, let's use runtime_pm
> only when enabled.

We discussed this with Ulf sometime back and it was a consensus the core
should handle it, but that may take a while.

So that led me to explore what others do notably ASoC, based on this I
feel we should not check the error code. We handle the non streaming
case here but streaming is handled in ASoC which doesnt check the return

Pierre, can you verify the below patch and let me know if that is fine
for Intel platforms

--- >8 ---

From: Vinod Koul <vkoul@kernel.org>
Date: Fri, 2 Aug 2019 22:15:11 +0530
Subject: [PATCH] soundwire: dont check return of pm_runtime_get_sync()

Soundwire core checks pm_runtime_get_sync() return. But in case the
driver has not enabled runtime pm we get an error.

To fix this, dont check the return. We handle the non streaming case in
framework but streaming case has similar handling in ASoC so make it
same across use cases

Signed-off-by: Vinod Koul <vkoul@kernel.org>
---
 drivers/soundwire/bus.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
index fe745830a261..9cdf7e9e0852 100644
--- a/drivers/soundwire/bus.c
+++ b/drivers/soundwire/bus.c
@@ -326,9 +326,7 @@ int sdw_nread(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
 	if (ret < 0)
 		return ret;
 
-	ret = pm_runtime_get_sync(slave->bus->dev);
-	if (ret < 0)
-		return ret;
+	pm_runtime_get_sync(slave->bus->dev);
 
 	ret = sdw_transfer(slave->bus, &msg);
 	pm_runtime_put(slave->bus->dev);
@@ -354,9 +352,7 @@ int sdw_nwrite(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
 	if (ret < 0)
 		return ret;
 
-	ret = pm_runtime_get_sync(slave->bus->dev);
-	if (ret < 0)
-		return ret;
+	pm_runtime_get_sync(slave->bus->dev);
 
 	ret = sdw_transfer(slave->bus, &msg);
 	pm_runtime_put(slave->bus->dev);
-- 
2.20.1



> 
> Suggested-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/bus.c | 25 ++++++++++++++++---------
>  1 file changed, 16 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
> index 5ad4109dc72f..0a45dc5713df 100644
> --- a/drivers/soundwire/bus.c
> +++ b/drivers/soundwire/bus.c
> @@ -332,12 +332,16 @@ int sdw_nread(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
>  	if (ret < 0)
>  		return ret;
>  
> -	ret = pm_runtime_get_sync(slave->bus->dev);
> -	if (ret < 0)
> -		return ret;
> +	if (pm_runtime_enabled(slave->bus->dev)) {
> +		ret = pm_runtime_get_sync(slave->bus->dev);
> +		if (ret < 0)
> +			return ret;
> +	}
>  
>  	ret = sdw_transfer(slave->bus, &msg);
> -	pm_runtime_put(slave->bus->dev);
> +
> +	if (pm_runtime_enabled(slave->bus->dev))
> +		pm_runtime_put(slave->bus->dev);
>  
>  	return ret;
>  }
> @@ -359,13 +363,16 @@ int sdw_nwrite(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
>  			   slave->dev_num, SDW_MSG_FLAG_WRITE, val);
>  	if (ret < 0)
>  		return ret;
> -
> -	ret = pm_runtime_get_sync(slave->bus->dev);
> -	if (ret < 0)
> -		return ret;
> +	if (pm_runtime_enabled(slave->bus->dev)) {
> +		ret = pm_runtime_get_sync(slave->bus->dev);
> +		if (ret < 0)
> +			return ret;
> +	}
>  
>  	ret = sdw_transfer(slave->bus, &msg);
> -	pm_runtime_put(slave->bus->dev);
> +
> +	if (pm_runtime_enabled(slave->bus->dev))
> +		pm_runtime_put(slave->bus->dev);
>  
>  	return ret;
>  }
> -- 
> 2.20.1

-- 
~Vinod

^ permalink raw reply related	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 18/40] soundwire: bus: split handling of Device0 events
  2019-07-25 23:40 ` [RFC PATCH 18/40] soundwire: bus: split handling of Device0 events Pierre-Louis Bossart
@ 2019-08-02 16:59   ` Vinod Koul
  0 siblings, 0 replies; 183+ messages in thread
From: Vinod Koul @ 2019-08-02 16:59 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 25-07-19, 18:40, Pierre-Louis Bossart wrote:
> Assigning a device number to a Slave will result in additional events
> when it reports its status in a PING frame. There is no point in
> dealing with all the other devices in a loop, this can be done when a
> non-device0 event happens.

Applied, thanks

-- 
~Vinod

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 19/40] soundwire: bus: improve dynamic debug comments for enumeration
  2019-07-25 23:40 ` [RFC PATCH 19/40] soundwire: bus: improve dynamic debug comments for enumeration Pierre-Louis Bossart
@ 2019-08-02 17:00   ` Vinod Koul
  2019-08-02 17:20     ` Pierre-Louis Bossart
  0 siblings, 1 reply; 183+ messages in thread
From: Vinod Koul @ 2019-08-02 17:00 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 25-07-19, 18:40, Pierre-Louis Bossart wrote:
> update comments to provide better understanding of enumeration flows.
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/bus.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
> index bca378806d00..2354675ef104 100644
> --- a/drivers/soundwire/bus.c
> +++ b/drivers/soundwire/bus.c
> @@ -483,7 +483,8 @@ static int sdw_assign_device_num(struct sdw_slave *slave)
>  
>  	ret = sdw_write(slave, SDW_SCP_DEVNUMBER, dev_num);
>  	if (ret < 0) {
> -		dev_err(&slave->dev, "Program device_num failed: %d\n", ret);
> +		dev_err(&slave->dev, "Program device_num %d failed: %d\n",
> +			dev_num, ret);
>  		return ret;
>  	}
>  
> @@ -540,6 +541,7 @@ static int sdw_program_device_num(struct sdw_bus *bus)
>  	do {
>  		ret = sdw_transfer(bus, &msg);
>  		if (ret == -ENODATA) { /* end of device id reads */
> +			dev_dbg(bus->dev, "No more devices to enumerate\n");
>  			ret = 0;
>  			break;
>  		}
> @@ -982,6 +984,7 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
>  	int i, ret = 0;
>  
>  	if (status[0] == SDW_SLAVE_ATTACHED) {
> +		dev_err(bus->dev, "Slave attached, programming device number\n");

This should be debug level

-- 
~Vinod

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 20/40] soundwire: prototypes for suspend/resume
  2019-07-25 23:40 ` [RFC PATCH 20/40] soundwire: prototypes for suspend/resume Pierre-Louis Bossart
  2019-07-26 10:04   ` Cezary Rojewski
@ 2019-08-02 17:03   ` Vinod Koul
  2019-08-02 17:21     ` Pierre-Louis Bossart
  1 sibling, 1 reply; 183+ messages in thread
From: Vinod Koul @ 2019-08-02 17:03 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 25-07-19, 18:40, Pierre-Louis Bossart wrote:

Please do provide the changelog on why this change is needed.

> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/cadence_master.h | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/soundwire/cadence_master.h b/drivers/soundwire/cadence_master.h
> index c0bf6ff00a44..d375bbfead18 100644
> --- a/drivers/soundwire/cadence_master.h
> +++ b/drivers/soundwire/cadence_master.h
> @@ -165,6 +165,9 @@ int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns);
>  
>  void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root);
>  
> +int sdw_cdns_suspend(struct sdw_cdns *cdns);
> +bool sdw_cdns_check_resume_status(struct sdw_cdns *cdns);
> +
>  int sdw_cdns_get_stream(struct sdw_cdns *cdns,
>  			struct sdw_cdns_streams *stream,
>  			u32 ch, u32 dir);
> -- 
> 2.20.1

-- 
~Vinod

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 21/40] soundwire: export helpers to find row and column values
  2019-07-26 15:26     ` Pierre-Louis Bossart
@ 2019-08-02 17:04       ` Vinod Koul
  0 siblings, 0 replies; 183+ messages in thread
From: Vinod Koul @ 2019-08-02 17:04 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: Guennadi Liakhovetski, alsa-devel, tiwai, gregkh, linux-kernel,
	broonie, srinivas.kandagatla, jank, slawomir.blauciak,
	Sanyog Kale

On 26-07-19, 10:26, Pierre-Louis Bossart wrote:
> 
> 
> On 7/26/19 9:43 AM, Guennadi Liakhovetski wrote:
> > On Thu, Jul 25, 2019 at 06:40:13PM -0500, Pierre-Louis Bossart wrote:
> > > Add a prefix for common tables and export 2 helpers to set the frame
> > > shapes based on row/col values.
> > > 
> > > Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> > > ---
> > >   drivers/soundwire/bus.h    |  7 +++++--
> > >   drivers/soundwire/stream.c | 14 ++++++++------
> > >   2 files changed, 13 insertions(+), 8 deletions(-)
> > > 
> > > diff --git a/drivers/soundwire/bus.h b/drivers/soundwire/bus.h
> > > index 06ac4adb0074..c57c9c23f6ca 100644
> > > --- a/drivers/soundwire/bus.h
> > > +++ b/drivers/soundwire/bus.h
> > > @@ -73,8 +73,11 @@ struct sdw_msg {
> > >   #define SDW_DOUBLE_RATE_FACTOR		2
> > > -extern int rows[SDW_FRAME_ROWS];
> > > -extern int cols[SDW_FRAME_COLS];
> > > +extern int sdw_rows[SDW_FRAME_ROWS];
> > > +extern int sdw_cols[SDW_FRAME_COLS];
> > 
> > So these arrays actually have to be exported? In the current (5.2) sources they
> > seem to only be used in stream.c, maybe make them static there?
> > 
> > > +
> > > +int sdw_find_row_index(int row);
> > > +int sdw_find_col_index(int col);
> 
> yes, they need to be exported, they are used by the allocation algorithm (in
> Patch 27).
> Others will need this for non-Intel solutions, it's really a part of the
> standard definition and should be shared.
> I can improve the commit message to make this explicit.

Yes that would help! And also move it to before it's usage so it clear
that it is used in next one.

-- 
~Vinod

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 24/40] soundwire: cadence_master: use BIOS defaults for frame shape
  2019-07-25 23:40 ` [RFC PATCH 24/40] soundwire: cadence_master: use BIOS defaults for frame shape Pierre-Louis Bossart
  2019-07-26 10:20   ` Cezary Rojewski
@ 2019-08-02 17:10   ` Vinod Koul
  2019-08-02 17:24     ` Pierre-Louis Bossart
  2019-08-05 10:01   ` Sanyog Kale
  2 siblings, 1 reply; 183+ messages in thread
From: Vinod Koul @ 2019-08-02 17:10 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 25-07-19, 18:40, Pierre-Louis Bossart wrote:
> Remove hard-coding and use BIOS values. If they are wrong use default

BIOS :) this is cadence, am sure this can be used outside BIOS :D

It would be better to say firmware (ACPI/DT)

> 48x2 frame shape.
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/cadence_master.c | 19 +++++++++++++++++--
>  1 file changed, 17 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
> index 442f78c00f09..d84344e29f71 100644
> --- a/drivers/soundwire/cadence_master.c
> +++ b/drivers/soundwire/cadence_master.c
> @@ -175,7 +175,6 @@
>  /* Driver defaults */
>  
>  #define CDNS_DEFAULT_CLK_DIVIDER		0
> -#define CDNS_DEFAULT_FRAME_SHAPE		0x30
>  #define CDNS_DEFAULT_SSP_INTERVAL		0x18
>  #define CDNS_TX_TIMEOUT				2000
>  
> @@ -954,6 +953,20 @@ int sdw_cdns_pdi_init(struct sdw_cdns *cdns,
>  }
>  EXPORT_SYMBOL(sdw_cdns_pdi_init);
>  
> +static u32 cdns_set_default_frame_shape(int n_rows, int n_cols)
> +{
> +	u32 val;
> +	int c;
> +	int r;

This can be in single line!

> +
> +	r = sdw_find_row_index(n_rows);
> +	c = sdw_find_col_index(n_cols);
> +
> +	val = (r << 3) | c;

Magic 3?

-- 
~Vinod

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 25/40] soundwire: intel: use BIOS information to set clock dividers
  2019-07-25 23:40 ` [RFC PATCH 25/40] soundwire: intel: use BIOS information to set clock dividers Pierre-Louis Bossart
@ 2019-08-02 17:17   ` Vinod Koul
  2019-08-02 17:29     ` Pierre-Louis Bossart
  2019-08-05 10:28   ` Sanyog Kale
  1 sibling, 1 reply; 183+ messages in thread
From: Vinod Koul @ 2019-08-02 17:17 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 25-07-19, 18:40, Pierre-Louis Bossart wrote:
> The BIOS provides an Intel-specific property, let's use it to avoid
> hard-coded clock dividers.
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/cadence_master.c | 26 ++++++++++++++++++++++----
>  drivers/soundwire/intel.c          | 26 ++++++++++++++++++++++++++
>  include/linux/soundwire/sdw.h      |  2 ++

ah, intel patch touching bunch of things!

>  3 files changed, 50 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
> index d84344e29f71..10ebcef2e84e 100644
> --- a/drivers/soundwire/cadence_master.c
> +++ b/drivers/soundwire/cadence_master.c
> @@ -173,8 +173,6 @@
>  #define CDNS_PDI_CONFIG_PORT			GENMASK(4, 0)
>  
>  /* Driver defaults */
> -
> -#define CDNS_DEFAULT_CLK_DIVIDER		0
>  #define CDNS_DEFAULT_SSP_INTERVAL		0x18
>  #define CDNS_TX_TIMEOUT				2000
>  
> @@ -973,7 +971,10 @@ static u32 cdns_set_default_frame_shape(int n_rows, int n_cols)
>   */
>  int sdw_cdns_init(struct sdw_cdns *cdns)
>  {
> +	struct sdw_bus *bus = &cdns->bus;
> +	struct sdw_master_prop *prop = &bus->prop;
>  	u32 val;
> +	int divider;
>  	int ret;
>  
>  	/* Exit clock stop */
> @@ -985,9 +986,17 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
>  	}
>  
>  	/* Set clock divider */
> +	divider	= (prop->mclk_freq / prop->max_clk_freq) - 1;
>  	val = cdns_readl(cdns, CDNS_MCP_CLK_CTRL0);
> -	val |= CDNS_DEFAULT_CLK_DIVIDER;
> +	val |= divider;
>  	cdns_writel(cdns, CDNS_MCP_CLK_CTRL0, val);
> +	cdns_writel(cdns, CDNS_MCP_CLK_CTRL1, val);
> +
> +	pr_err("plb: mclk %d max_freq %d divider %d register %x\n",
> +	       prop->mclk_freq,
> +	       prop->max_clk_freq,
> +	       divider,
> +	       val);

I guess you forgot to remove this!

>  
>  	/* Set the default frame shape */
>  	val = cdns_set_default_frame_shape(prop->default_row,
> @@ -1035,6 +1044,7 @@ EXPORT_SYMBOL(sdw_cdns_init);
>  
>  int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params)
>  {
> +	struct sdw_master_prop *prop = &bus->prop;
>  	struct sdw_cdns *cdns = bus_to_cdns(bus);
>  	int mcp_clkctrl_off, mcp_clkctrl;
>  	int divider;
> @@ -1044,7 +1054,9 @@ int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params)
>  		return -EINVAL;
>  	}
>  
> -	divider	= (params->max_dr_freq / params->curr_dr_freq) - 1;
> +	divider	= prop->mclk_freq * SDW_DOUBLE_RATE_FACTOR /
> +		params->curr_dr_freq;
> +	divider--; /* divider is 1/(N+1) */
>  
>  	if (params->next_bank)
>  		mcp_clkctrl_off = CDNS_MCP_CLK_CTRL1;
> @@ -1055,6 +1067,12 @@ int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params)
>  	mcp_clkctrl |= divider;
>  	cdns_writel(cdns, mcp_clkctrl_off, mcp_clkctrl);
>  
> +	pr_err("plb: mclk * 2 %d curr_dr_freq %d divider %d register %x\n",
> +	       prop->mclk_freq * SDW_DOUBLE_RATE_FACTOR,
> +	       params->curr_dr_freq,
> +	       divider,
> +	       mcp_clkctrl);

here too!

> +
>  	return 0;
>  }
>  EXPORT_SYMBOL(cdns_bus_conf);
> diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
> index c718c9c67a37..796ac2bc8cea 100644
> --- a/drivers/soundwire/intel.c
> +++ b/drivers/soundwire/intel.c
> @@ -917,11 +917,37 @@ static int intel_register_dai(struct sdw_intel *sdw)
>  					  dais, num_dai);
>  }
>  
> +static int sdw_master_read_intel_prop(struct sdw_bus *bus)
> +{
> +	struct sdw_master_prop *prop = &bus->prop;
> +	struct fwnode_handle *link;
> +	char name[32];
> +	int nval, i;
> +
> +	/* Find master handle */
> +	snprintf(name, sizeof(name),
> +		 "mipi-sdw-link-%d-subproperties", bus->link_id);
> +
> +	link = device_get_named_child_node(bus->dev, name);
> +	if (!link) {
> +		dev_err(bus->dev, "Master node %s not found\n", name);
> +		return -EIO;
> +	}
> +
> +	fwnode_property_read_u32(link,
> +				 "intel-sdw-ip-clock",
> +				 &prop->mclk_freq);
> +	return 0;
> +}
> +
>  static int intel_prop_read(struct sdw_bus *bus)
>  {
>  	/* Initialize with default handler to read all DisCo properties */
>  	sdw_master_read_prop(bus);
>  
> +	/* read Intel-specific properties */
> +	sdw_master_read_intel_prop(bus);
> +
>  	return 0;
>  }
>  
> diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
> index 31d1e8acf25b..b6acc436ac80 100644
> --- a/include/linux/soundwire/sdw.h
> +++ b/include/linux/soundwire/sdw.h
> @@ -379,6 +379,7 @@ struct sdw_slave_prop {
>   * @dynamic_frame: Dynamic frame shape supported
>   * @err_threshold: Number of times that software may retry sending a single
>   * command
> + * @mclk_freq: clock reference passed to SoundWire Master, in Hz.
>   */
>  struct sdw_master_prop {
>  	u32 revision;
> @@ -393,6 +394,7 @@ struct sdw_master_prop {
>  	u32 default_col;
>  	bool dynamic_frame;
>  	u32 err_threshold;
> +	u32 mclk_freq;

Other than debug artifacts this looks sane, but can you split up the
cadence and intel parts into different patches please

-- 
~Vinod

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 26/40] soundwire: cadence_master: fix divider setting in clock register
  2019-07-25 23:40 ` [RFC PATCH 26/40] soundwire: cadence_master: fix divider setting in clock register Pierre-Louis Bossart
  2019-07-26  5:19   ` [alsa-devel] " Bard liao
@ 2019-08-02 17:19   ` Vinod Koul
  2019-08-02 17:30     ` Pierre-Louis Bossart
  2019-08-05 10:40   ` Sanyog Kale
  2 siblings, 1 reply; 183+ messages in thread
From: Vinod Koul @ 2019-08-02 17:19 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Rander Wang, Sanyog Kale

On 25-07-19, 18:40, Pierre-Louis Bossart wrote:
> From: Rander Wang <rander.wang@linux.intel.com>
> 
> The existing code uses an OR operation which would mix the original
> divider setting with the new one, resulting in an invalid
> configuration that can make codecs hang.

This looked fine but fails to apply, feel free to send as a fix

-- 
~Vinod

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 17/40] soundwire: bus: use runtime_pm_get_sync/pm when enabled
  2019-08-02 16:58   ` Vinod Koul
@ 2019-08-02 17:20     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-08-02 17:20 UTC (permalink / raw)
  To: Vinod Koul
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 8/2/19 11:58 AM, Vinod Koul wrote:
> On 25-07-19, 18:40, Pierre-Louis Bossart wrote:
>> Not all platforms support runtime_pm for now, let's use runtime_pm
>> only when enabled.
> 
> We discussed this with Ulf sometime back and it was a consensus the core
> should handle it, but that may take a while.
> 
> So that led me to explore what others do notably ASoC, based on this I
> feel we should not check the error code. We handle the non streaming
> case here but streaming is handled in ASoC which doesnt check the return
> 
> Pierre, can you verify the below patch and let me know if that is fine
> for Intel platforms

So if for some reason we cannot resume, then we'd still initiate a 
transaction and have even more issues to sort out.

Fail big and fail early would really be my preference.

Also the user of this function is largely the Slave driver, which 
typically doesn't do any streaming operation but controls the imp-def 
registers. The bus driver will only use this routine for standard 
registers and that's a very small part of the total traffic.

> 
> --- >8 ---
> 
> From: Vinod Koul <vkoul@kernel.org>
> Date: Fri, 2 Aug 2019 22:15:11 +0530
> Subject: [PATCH] soundwire: dont check return of pm_runtime_get_sync()
> 
> Soundwire core checks pm_runtime_get_sync() return. But in case the
> driver has not enabled runtime pm we get an error.
> 
> To fix this, dont check the return. We handle the non streaming case in
> framework but streaming case has similar handling in ASoC so make it
> same across use cases
> 
> Signed-off-by: Vinod Koul <vkoul@kernel.org>
> ---
>   drivers/soundwire/bus.c | 8 ++------
>   1 file changed, 2 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
> index fe745830a261..9cdf7e9e0852 100644
> --- a/drivers/soundwire/bus.c
> +++ b/drivers/soundwire/bus.c
> @@ -326,9 +326,7 @@ int sdw_nread(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
>   	if (ret < 0)
>   		return ret;
>   
> -	ret = pm_runtime_get_sync(slave->bus->dev);
> -	if (ret < 0)
> -		return ret;
> +	pm_runtime_get_sync(slave->bus->dev);
>   
>   	ret = sdw_transfer(slave->bus, &msg);
>   	pm_runtime_put(slave->bus->dev);
> @@ -354,9 +352,7 @@ int sdw_nwrite(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
>   	if (ret < 0)
>   		return ret;
>   
> -	ret = pm_runtime_get_sync(slave->bus->dev);
> -	if (ret < 0)
> -		return ret;
> +	pm_runtime_get_sync(slave->bus->dev);
>   
>   	ret = sdw_transfer(slave->bus, &msg);
>   	pm_runtime_put(slave->bus->dev);
> 


^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 19/40] soundwire: bus: improve dynamic debug comments for enumeration
  2019-08-02 17:00   ` Vinod Koul
@ 2019-08-02 17:20     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-08-02 17:20 UTC (permalink / raw)
  To: Vinod Koul
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 8/2/19 12:00 PM, Vinod Koul wrote:
> On 25-07-19, 18:40, Pierre-Louis Bossart wrote:
>> update comments to provide better understanding of enumeration flows.
>>
>> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
>> ---
>>   drivers/soundwire/bus.c | 5 ++++-
>>   1 file changed, 4 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
>> index bca378806d00..2354675ef104 100644
>> --- a/drivers/soundwire/bus.c
>> +++ b/drivers/soundwire/bus.c
>> @@ -483,7 +483,8 @@ static int sdw_assign_device_num(struct sdw_slave *slave)
>>   
>>   	ret = sdw_write(slave, SDW_SCP_DEVNUMBER, dev_num);
>>   	if (ret < 0) {
>> -		dev_err(&slave->dev, "Program device_num failed: %d\n", ret);
>> +		dev_err(&slave->dev, "Program device_num %d failed: %d\n",
>> +			dev_num, ret);
>>   		return ret;
>>   	}
>>   
>> @@ -540,6 +541,7 @@ static int sdw_program_device_num(struct sdw_bus *bus)
>>   	do {
>>   		ret = sdw_transfer(bus, &msg);
>>   		if (ret == -ENODATA) { /* end of device id reads */
>> +			dev_dbg(bus->dev, "No more devices to enumerate\n");
>>   			ret = 0;
>>   			break;
>>   		}
>> @@ -982,6 +984,7 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
>>   	int i, ret = 0;
>>   
>>   	if (status[0] == SDW_SLAVE_ATTACHED) {
>> +		dev_err(bus->dev, "Slave attached, programming device number\n");
> 
> This should be debug level

yes, good catch, will fix.


^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 20/40] soundwire: prototypes for suspend/resume
  2019-08-02 17:03   ` Vinod Koul
@ 2019-08-02 17:21     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-08-02 17:21 UTC (permalink / raw)
  To: Vinod Koul
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 8/2/19 12:03 PM, Vinod Koul wrote:
> On 25-07-19, 18:40, Pierre-Louis Bossart wrote:
> 
> Please do provide the changelog on why this change is needed.

not needed for now, will remove.

> 
>> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
>> ---
>>   drivers/soundwire/cadence_master.h | 3 +++
>>   1 file changed, 3 insertions(+)
>>
>> diff --git a/drivers/soundwire/cadence_master.h b/drivers/soundwire/cadence_master.h
>> index c0bf6ff00a44..d375bbfead18 100644
>> --- a/drivers/soundwire/cadence_master.h
>> +++ b/drivers/soundwire/cadence_master.h
>> @@ -165,6 +165,9 @@ int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns);
>>   
>>   void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root);
>>   
>> +int sdw_cdns_suspend(struct sdw_cdns *cdns);
>> +bool sdw_cdns_check_resume_status(struct sdw_cdns *cdns);
>> +
>>   int sdw_cdns_get_stream(struct sdw_cdns *cdns,
>>   			struct sdw_cdns_streams *stream,
>>   			u32 ch, u32 dir);
>> -- 
>> 2.20.1
> 


^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 24/40] soundwire: cadence_master: use BIOS defaults for frame shape
  2019-08-02 17:10   ` Vinod Koul
@ 2019-08-02 17:24     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-08-02 17:24 UTC (permalink / raw)
  To: Vinod Koul
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 8/2/19 12:10 PM, Vinod Koul wrote:
> On 25-07-19, 18:40, Pierre-Louis Bossart wrote:
>> Remove hard-coding and use BIOS values. If they are wrong use default
> 
> BIOS :) this is cadence, am sure this can be used outside BIOS :D
> 
> It would be better to say firmware (ACPI/DT)

yes

> 
>> 48x2 frame shape.
>>
>> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
>> ---
>>   drivers/soundwire/cadence_master.c | 19 +++++++++++++++++--
>>   1 file changed, 17 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
>> index 442f78c00f09..d84344e29f71 100644
>> --- a/drivers/soundwire/cadence_master.c
>> +++ b/drivers/soundwire/cadence_master.c
>> @@ -175,7 +175,6 @@
>>   /* Driver defaults */
>>   
>>   #define CDNS_DEFAULT_CLK_DIVIDER		0
>> -#define CDNS_DEFAULT_FRAME_SHAPE		0x30
>>   #define CDNS_DEFAULT_SSP_INTERVAL		0x18
>>   #define CDNS_TX_TIMEOUT				2000
>>   
>> @@ -954,6 +953,20 @@ int sdw_cdns_pdi_init(struct sdw_cdns *cdns,
>>   }
>>   EXPORT_SYMBOL(sdw_cdns_pdi_init);
>>   
>> +static u32 cdns_set_default_frame_shape(int n_rows, int n_cols)
>> +{
>> +	u32 val;
>> +	int c;
>> +	int r;
> 
> This can be in single line!

one line per variable is what I prefer.

> 
>> +
>> +	r = sdw_find_row_index(n_rows);
>> +	c = sdw_find_col_index(n_cols);
>> +
>> +	val = (r << 3) | c;
> 
> Magic 3?

yes fixed already.


^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 31/40] soundwire: intel: move shutdown() callback and don't export symbol
  2019-07-26 14:46     ` [alsa-devel] " Pierre-Louis Bossart
@ 2019-08-02 17:28       ` Vinod Koul
  2019-08-02 17:42         ` Pierre-Louis Bossart
  2019-08-14 19:31         ` Pierre-Louis Bossart
  0 siblings, 2 replies; 183+ messages in thread
From: Vinod Koul @ 2019-08-02 17:28 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: Cezary Rojewski, alsa-devel, linux-kernel, tiwai, broonie,
	gregkh, jank, srinivas.kandagatla, slawomir.blauciak,
	Sanyog Kale

On 26-07-19, 09:46, Pierre-Louis Bossart wrote:
> 
> 
> On 7/26/19 5:38 AM, Cezary Rojewski wrote:
> > On 2019-07-26 01:40, Pierre-Louis Bossart wrote:
> > > +void intel_shutdown(struct snd_pcm_substream *substream,
> > > +            struct snd_soc_dai *dai)
> > > +{
> > > +    struct sdw_cdns_dma_data *dma;
> > > +
> > > +    dma = snd_soc_dai_get_dma_data(dai, substream);
> > > +    if (!dma)
> > > +        return;
> > > +
> > > +    snd_soc_dai_set_dma_data(dai, substream, NULL);
> > > +    kfree(dma);
> > > +}
> > 
> > Correct me if I'm wrong, but do we really need to _get_dma_ here?
> > _set_dma_ seems bulletproof, same for kfree.
> 
> I must admit I have no idea why we have a reference to DMAs here, this looks
> like an abuse to store a dai-specific context, and the initial test looks
> like copy-paste to detect invalid configs, as done in other callbacks. Vinod
> and Sanyog might have more history than me here.

I dont see snd_soc_dai_set_dma_data() call for
sdw_cdns_dma_data so somthing is missing (at least in upstream code)

IIRC we should have a snd_soc_dai_set_dma_data() in alloc or some
initialization routine and we free it here.. Sanyog?

-- 
~Vinod

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 25/40] soundwire: intel: use BIOS information to set clock dividers
  2019-08-02 17:17   ` Vinod Koul
@ 2019-08-02 17:29     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-08-02 17:29 UTC (permalink / raw)
  To: Vinod Koul
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 8/2/19 12:17 PM, Vinod Koul wrote:
> On 25-07-19, 18:40, Pierre-Louis Bossart wrote:
>> The BIOS provides an Intel-specific property, let's use it to avoid
>> hard-coded clock dividers.
>>
>> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
>> ---
>>   drivers/soundwire/cadence_master.c | 26 ++++++++++++++++++++++----
>>   drivers/soundwire/intel.c          | 26 ++++++++++++++++++++++++++
>>   include/linux/soundwire/sdw.h      |  2 ++
> 
> ah, intel patch touching bunch of things!

not really, it's more removing Intel-specific configs in the Cadence parts.

> 
>>   3 files changed, 50 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
>> index d84344e29f71..10ebcef2e84e 100644
>> --- a/drivers/soundwire/cadence_master.c
>> +++ b/drivers/soundwire/cadence_master.c
>> @@ -173,8 +173,6 @@
>>   #define CDNS_PDI_CONFIG_PORT			GENMASK(4, 0)
>>   
>>   /* Driver defaults */
>> -
>> -#define CDNS_DEFAULT_CLK_DIVIDER		0
>>   #define CDNS_DEFAULT_SSP_INTERVAL		0x18
>>   #define CDNS_TX_TIMEOUT				2000
>>   
>> @@ -973,7 +971,10 @@ static u32 cdns_set_default_frame_shape(int n_rows, int n_cols)
>>    */
>>   int sdw_cdns_init(struct sdw_cdns *cdns)
>>   {
>> +	struct sdw_bus *bus = &cdns->bus;
>> +	struct sdw_master_prop *prop = &bus->prop;
>>   	u32 val;
>> +	int divider;
>>   	int ret;
>>   
>>   	/* Exit clock stop */
>> @@ -985,9 +986,17 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
>>   	}
>>   
>>   	/* Set clock divider */
>> +	divider	= (prop->mclk_freq / prop->max_clk_freq) - 1;
>>   	val = cdns_readl(cdns, CDNS_MCP_CLK_CTRL0);
>> -	val |= CDNS_DEFAULT_CLK_DIVIDER;
>> +	val |= divider;
>>   	cdns_writel(cdns, CDNS_MCP_CLK_CTRL0, val);
>> +	cdns_writel(cdns, CDNS_MCP_CLK_CTRL1, val);
>> +
>> +	pr_err("plb: mclk %d max_freq %d divider %d register %x\n",
>> +	       prop->mclk_freq,
>> +	       prop->max_clk_freq,
>> +	       divider,
>> +	       val);
> 
> I guess you forgot to remove this!

yes, fixed already

> 
>>   
>>   	/* Set the default frame shape */
>>   	val = cdns_set_default_frame_shape(prop->default_row,
>> @@ -1035,6 +1044,7 @@ EXPORT_SYMBOL(sdw_cdns_init);
>>   
>>   int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params)
>>   {
>> +	struct sdw_master_prop *prop = &bus->prop;
>>   	struct sdw_cdns *cdns = bus_to_cdns(bus);
>>   	int mcp_clkctrl_off, mcp_clkctrl;
>>   	int divider;
>> @@ -1044,7 +1054,9 @@ int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params)
>>   		return -EINVAL;
>>   	}
>>   
>> -	divider	= (params->max_dr_freq / params->curr_dr_freq) - 1;
>> +	divider	= prop->mclk_freq * SDW_DOUBLE_RATE_FACTOR /
>> +		params->curr_dr_freq;
>> +	divider--; /* divider is 1/(N+1) */
>>   
>>   	if (params->next_bank)
>>   		mcp_clkctrl_off = CDNS_MCP_CLK_CTRL1;
>> @@ -1055,6 +1067,12 @@ int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params)
>>   	mcp_clkctrl |= divider;
>>   	cdns_writel(cdns, mcp_clkctrl_off, mcp_clkctrl);
>>   
>> +	pr_err("plb: mclk * 2 %d curr_dr_freq %d divider %d register %x\n",
>> +	       prop->mclk_freq * SDW_DOUBLE_RATE_FACTOR,
>> +	       params->curr_dr_freq,
>> +	       divider,
>> +	       mcp_clkctrl);
> 
> here too!

yep

> 
>> +
>>   	return 0;
>>   }
>>   EXPORT_SYMBOL(cdns_bus_conf);
>> diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
>> index c718c9c67a37..796ac2bc8cea 100644
>> --- a/drivers/soundwire/intel.c
>> +++ b/drivers/soundwire/intel.c
>> @@ -917,11 +917,37 @@ static int intel_register_dai(struct sdw_intel *sdw)
>>   					  dais, num_dai);
>>   }
>>   
>> +static int sdw_master_read_intel_prop(struct sdw_bus *bus)
>> +{
>> +	struct sdw_master_prop *prop = &bus->prop;
>> +	struct fwnode_handle *link;
>> +	char name[32];
>> +	int nval, i;
>> +
>> +	/* Find master handle */
>> +	snprintf(name, sizeof(name),
>> +		 "mipi-sdw-link-%d-subproperties", bus->link_id);
>> +
>> +	link = device_get_named_child_node(bus->dev, name);
>> +	if (!link) {
>> +		dev_err(bus->dev, "Master node %s not found\n", name);
>> +		return -EIO;
>> +	}
>> +
>> +	fwnode_property_read_u32(link,
>> +				 "intel-sdw-ip-clock",
>> +				 &prop->mclk_freq);
>> +	return 0;
>> +}
>> +
>>   static int intel_prop_read(struct sdw_bus *bus)
>>   {
>>   	/* Initialize with default handler to read all DisCo properties */
>>   	sdw_master_read_prop(bus);
>>   
>> +	/* read Intel-specific properties */
>> +	sdw_master_read_intel_prop(bus);
>> +
>>   	return 0;
>>   }
>>   
>> diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
>> index 31d1e8acf25b..b6acc436ac80 100644
>> --- a/include/linux/soundwire/sdw.h
>> +++ b/include/linux/soundwire/sdw.h
>> @@ -379,6 +379,7 @@ struct sdw_slave_prop {
>>    * @dynamic_frame: Dynamic frame shape supported
>>    * @err_threshold: Number of times that software may retry sending a single
>>    * command
>> + * @mclk_freq: clock reference passed to SoundWire Master, in Hz.
>>    */
>>   struct sdw_master_prop {
>>   	u32 revision;
>> @@ -393,6 +394,7 @@ struct sdw_master_prop {
>>   	u32 default_col;
>>   	bool dynamic_frame;
>>   	u32 err_threshold;
>> +	u32 mclk_freq;
> 
> Other than debug artifacts this looks sane, but can you split up the
> cadence and intel parts into different patches please

ok, i'll split in 3. prototype, intel, cadence.


^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 26/40] soundwire: cadence_master: fix divider setting in clock register
  2019-08-02 17:19   ` Vinod Koul
@ 2019-08-02 17:30     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-08-02 17:30 UTC (permalink / raw)
  To: Vinod Koul
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Rander Wang, Sanyog Kale

On 8/2/19 12:19 PM, Vinod Koul wrote:
> On 25-07-19, 18:40, Pierre-Louis Bossart wrote:
>> From: Rander Wang <rander.wang@linux.intel.com>
>>
>> The existing code uses an OR operation which would mix the original
>> divider setting with the new one, resulting in an invalid
>> configuration that can make codecs hang.
> 
> This looked fine but fails to apply, feel free to send as a fix

likely because it's on top of patch 25




^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 34/40] soundwire: intel: ignore disabled links for suspend/resume
  2019-07-25 23:40 ` [RFC PATCH 34/40] soundwire: intel: ignore disabled links for suspend/resume Pierre-Louis Bossart
@ 2019-08-02 17:30   ` Vinod Koul
  2019-08-02 17:44     ` Pierre-Louis Bossart
  0 siblings, 1 reply; 183+ messages in thread
From: Vinod Koul @ 2019-08-02 17:30 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 25-07-19, 18:40, Pierre-Louis Bossart wrote:

Please add explanation why..

> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/intel.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
> index 1477c35f616f..a976480d6f36 100644
> --- a/drivers/soundwire/intel.c
> +++ b/drivers/soundwire/intel.c
> @@ -1161,6 +1161,12 @@ static int intel_suspend(struct device *dev)
>  
>  	sdw = dev_get_drvdata(dev);
>  
> +	if (sdw->cdns.bus.prop.hw_disabled) {
> +		dev_dbg(dev, "SoundWire master %d is disabled, ignoring\n",
> +			sdw->cdns.bus.link_id);
> +		return 0;
> +	}
> +
>  	ret = intel_link_power_down(sdw);
>  	if (ret) {
>  		dev_err(dev, "Link power down failed: %d", ret);
> @@ -1179,6 +1185,12 @@ static int intel_resume(struct device *dev)
>  
>  	sdw = dev_get_drvdata(dev);
>  
> +	if (sdw->cdns.bus.prop.hw_disabled) {
> +		dev_dbg(dev, "SoundWire master %d is disabled, ignoring\n",
> +			sdw->cdns.bus.link_id);
> +		return 0;
> +	}
> +
>  	ret = intel_init(sdw);
>  	if (ret) {
>  		dev_err(dev, "%s failed: %d", __func__, ret);
> -- 
> 2.20.1

-- 
~Vinod

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 35/40] soundwire: intel: export helper to exit reset
  2019-07-25 23:40 ` [RFC PATCH 35/40] soundwire: intel: export helper to exit reset Pierre-Louis Bossart
  2019-07-26 15:52   ` [alsa-devel] " Guennadi Liakhovetski
@ 2019-08-02 17:31   ` Vinod Koul
  2019-08-02 17:44     ` Pierre-Louis Bossart
  1 sibling, 1 reply; 183+ messages in thread
From: Vinod Koul @ 2019-08-02 17:31 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 25-07-19, 18:40, Pierre-Louis Bossart wrote:

Here as well

> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/cadence_master.c | 9 +++++++--
>  drivers/soundwire/cadence_master.h | 1 +
>  drivers/soundwire/intel.c          | 4 ++++
>  3 files changed, 12 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
> index 4a189e487830..f486fe15fb46 100644
> --- a/drivers/soundwire/cadence_master.c
> +++ b/drivers/soundwire/cadence_master.c
> @@ -780,7 +780,11 @@ EXPORT_SYMBOL(sdw_cdns_thread);
>   * init routines
>   */
>  
> -static int do_reset(struct sdw_cdns *cdns)
> +/**
> + * sdw_cdns_exit_reset() - Program reset parameters and start bus operations
> + * @cdns: Cadence instance
> + */
> +int sdw_cdns_exit_reset(struct sdw_cdns *cdns)
>  {
>  	int ret;
>  
> @@ -804,6 +808,7 @@ static int do_reset(struct sdw_cdns *cdns)
>  
>  	return ret;
>  }
> +EXPORT_SYMBOL(sdw_cdns_exit_reset);
>  
>  /**
>   * sdw_cdns_enable_interrupt() - Enable SDW interrupts and update config
> @@ -839,7 +844,7 @@ int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
>  
>  	cdns_writel(cdns, CDNS_MCP_INTMASK, mask);
>  
> -	return do_reset(cdns);
> +	return 0;
>  }
>  EXPORT_SYMBOL(sdw_cdns_enable_interrupt);
>  
> diff --git a/drivers/soundwire/cadence_master.h b/drivers/soundwire/cadence_master.h
> index de97bc22acb7..2b551f9226f3 100644
> --- a/drivers/soundwire/cadence_master.h
> +++ b/drivers/soundwire/cadence_master.h
> @@ -161,6 +161,7 @@ irqreturn_t sdw_cdns_thread(int irq, void *dev_id);
>  int sdw_cdns_init(struct sdw_cdns *cdns);
>  int sdw_cdns_pdi_init(struct sdw_cdns *cdns,
>  		      struct sdw_cdns_stream_config config);
> +int sdw_cdns_exit_reset(struct sdw_cdns *cdns);
>  int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns);
>  
>  void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root);
> diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
> index a976480d6f36..9ebe38e4d979 100644
> --- a/drivers/soundwire/intel.c
> +++ b/drivers/soundwire/intel.c
> @@ -1112,6 +1112,8 @@ static int intel_probe(struct platform_device *pdev)
>  
>  	ret = sdw_cdns_enable_interrupt(&sdw->cdns);
>  
> +	ret = sdw_cdns_exit_reset(&sdw->cdns);
> +
>  	/* Register DAIs */
>  	ret = intel_register_dai(sdw);
>  	if (ret) {
> @@ -1199,6 +1201,8 @@ static int intel_resume(struct device *dev)
>  
>  	sdw_cdns_enable_interrupt(&sdw->cdns);
>  
> +	ret = sdw_cdns_exit_reset(&sdw->cdns);
> +
>  	return ret;
>  }
>  
> -- 
> 2.20.1

-- 
~Vinod

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 06/40] soundwire: intel: prevent possible dereference in hw_params
  2019-08-02 16:52         ` Pierre-Louis Bossart
@ 2019-08-02 17:37           ` Vinod Koul
  0 siblings, 0 replies; 183+ messages in thread
From: Vinod Koul @ 2019-08-02 17:37 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, tiwai, gregkh, linux-kernel, broonie,
	srinivas.kandagatla, jank, slawomir.blauciak, Sanyog Kale

On 02-08-19, 11:52, Pierre-Louis Bossart wrote:
> 
> 
> On 8/2/19 10:57 AM, Vinod Koul wrote:
> > On 02-08-19, 10:16, Pierre-Louis Bossart wrote:
> > > 
> > > 
> > > On 8/2/19 6:55 AM, Vinod Koul wrote:
> > > > On 25-07-19, 18:39, Pierre-Louis Bossart wrote:
> > > > > This should not happen in production systems but we should test for
> > > > > all callback arguments before invoking the config_stream callback.
> > > > 
> > > > so you are saying callback arg is mandatory, if so please document that
> > > > assumption
> > > 
> > > no, what this says is that if a config_stream is provided then it needs to
> > > have a valid argument.
> > 
> > well typically args are not mandatory..
> > 
> > > I am not sure what you mean by "document that assumption", comment in the
> > > code (where?) or SoundWire documentation?
> > 
> > The callback documentation which in this is in include/linux/soundwire/sdw_intel.h
> > 
> 
> /**
>  * struct sdw_intel_ops: Intel audio driver callback ops
>  *
>  * @config_stream: configure the stream with the hw_params
>  */
> struct sdw_intel_ops {
> 	int (*config_stream)(void *arg, void *substream,
> 			     void *dai, void *hw_params, int stream_num);
> };
> 
> all parameters are mandatory really, not sure what you are trying to get at.

It would be good to make a note that argument is mandatory!

Thanks
-- 
~Vinod

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 31/40] soundwire: intel: move shutdown() callback and don't export symbol
  2019-08-02 17:28       ` Vinod Koul
@ 2019-08-02 17:42         ` Pierre-Louis Bossart
  2019-08-14 19:31         ` Pierre-Louis Bossart
  1 sibling, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-08-02 17:42 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Cezary Rojewski, alsa-devel, linux-kernel, tiwai, broonie,
	gregkh, jank, srinivas.kandagatla, slawomir.blauciak,
	Sanyog Kale

On 8/2/19 12:28 PM, Vinod Koul wrote:
> On 26-07-19, 09:46, Pierre-Louis Bossart wrote:
>>
>>
>> On 7/26/19 5:38 AM, Cezary Rojewski wrote:
>>> On 2019-07-26 01:40, Pierre-Louis Bossart wrote:
>>>> +void intel_shutdown(struct snd_pcm_substream *substream,
>>>> +            struct snd_soc_dai *dai)
>>>> +{
>>>> +    struct sdw_cdns_dma_data *dma;
>>>> +
>>>> +    dma = snd_soc_dai_get_dma_data(dai, substream);
>>>> +    if (!dma)
>>>> +        return;
>>>> +
>>>> +    snd_soc_dai_set_dma_data(dai, substream, NULL);
>>>> +    kfree(dma);
>>>> +}
>>>
>>> Correct me if I'm wrong, but do we really need to _get_dma_ here?
>>> _set_dma_ seems bulletproof, same for kfree.
>>
>> I must admit I have no idea why we have a reference to DMAs here, this looks
>> like an abuse to store a dai-specific context, and the initial test looks
>> like copy-paste to detect invalid configs, as done in other callbacks. Vinod
>> and Sanyog might have more history than me here.
> 
> I dont see snd_soc_dai_set_dma_data() call for
> sdw_cdns_dma_data so somthing is missing (at least in upstream code)
> 
> IIRC we should have a snd_soc_dai_set_dma_data() in alloc or some
> initialization routine and we free it here.. Sanyog?

the code does a bunch of get_dma_data() and this seems to work, but 
indeed I don't see where the _set_dma_data() is done. magic.


^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 34/40] soundwire: intel: ignore disabled links for suspend/resume
  2019-08-02 17:30   ` Vinod Koul
@ 2019-08-02 17:44     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-08-02 17:44 UTC (permalink / raw)
  To: Vinod Koul
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 8/2/19 12:30 PM, Vinod Koul wrote:
> On 25-07-19, 18:40, Pierre-Louis Bossart wrote:
> 
> Please add explanation why..

yes missed this

> 
>> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
>> ---
>>   drivers/soundwire/intel.c | 12 ++++++++++++
>>   1 file changed, 12 insertions(+)
>>
>> diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
>> index 1477c35f616f..a976480d6f36 100644
>> --- a/drivers/soundwire/intel.c
>> +++ b/drivers/soundwire/intel.c
>> @@ -1161,6 +1161,12 @@ static int intel_suspend(struct device *dev)
>>   
>>   	sdw = dev_get_drvdata(dev);
>>   
>> +	if (sdw->cdns.bus.prop.hw_disabled) {
>> +		dev_dbg(dev, "SoundWire master %d is disabled, ignoring\n",
>> +			sdw->cdns.bus.link_id);
>> +		return 0;
>> +	}
>> +
>>   	ret = intel_link_power_down(sdw);
>>   	if (ret) {
>>   		dev_err(dev, "Link power down failed: %d", ret);
>> @@ -1179,6 +1185,12 @@ static int intel_resume(struct device *dev)
>>   
>>   	sdw = dev_get_drvdata(dev);
>>   
>> +	if (sdw->cdns.bus.prop.hw_disabled) {
>> +		dev_dbg(dev, "SoundWire master %d is disabled, ignoring\n",
>> +			sdw->cdns.bus.link_id);
>> +		return 0;
>> +	}
>> +
>>   	ret = intel_init(sdw);
>>   	if (ret) {
>>   		dev_err(dev, "%s failed: %d", __func__, ret);
>> -- 
>> 2.20.1
> 


^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 35/40] soundwire: intel: export helper to exit reset
  2019-08-02 17:31   ` Vinod Koul
@ 2019-08-02 17:44     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-08-02 17:44 UTC (permalink / raw)
  To: Vinod Koul
  Cc: alsa-devel, linux-kernel, tiwai, broonie, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Sanyog Kale

On 8/2/19 12:31 PM, Vinod Koul wrote:
> On 25-07-19, 18:40, Pierre-Louis Bossart wrote:
> 
> Here as well

I squashed this with earlier patches to fix the init sequence in one shot

> 
>> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
>> ---
>>   drivers/soundwire/cadence_master.c | 9 +++++++--
>>   drivers/soundwire/cadence_master.h | 1 +
>>   drivers/soundwire/intel.c          | 4 ++++
>>   3 files changed, 12 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
>> index 4a189e487830..f486fe15fb46 100644
>> --- a/drivers/soundwire/cadence_master.c
>> +++ b/drivers/soundwire/cadence_master.c
>> @@ -780,7 +780,11 @@ EXPORT_SYMBOL(sdw_cdns_thread);
>>    * init routines
>>    */
>>   
>> -static int do_reset(struct sdw_cdns *cdns)
>> +/**
>> + * sdw_cdns_exit_reset() - Program reset parameters and start bus operations
>> + * @cdns: Cadence instance
>> + */
>> +int sdw_cdns_exit_reset(struct sdw_cdns *cdns)
>>   {
>>   	int ret;
>>   
>> @@ -804,6 +808,7 @@ static int do_reset(struct sdw_cdns *cdns)
>>   
>>   	return ret;
>>   }
>> +EXPORT_SYMBOL(sdw_cdns_exit_reset);
>>   
>>   /**
>>    * sdw_cdns_enable_interrupt() - Enable SDW interrupts and update config
>> @@ -839,7 +844,7 @@ int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
>>   
>>   	cdns_writel(cdns, CDNS_MCP_INTMASK, mask);
>>   
>> -	return do_reset(cdns);
>> +	return 0;
>>   }
>>   EXPORT_SYMBOL(sdw_cdns_enable_interrupt);
>>   
>> diff --git a/drivers/soundwire/cadence_master.h b/drivers/soundwire/cadence_master.h
>> index de97bc22acb7..2b551f9226f3 100644
>> --- a/drivers/soundwire/cadence_master.h
>> +++ b/drivers/soundwire/cadence_master.h
>> @@ -161,6 +161,7 @@ irqreturn_t sdw_cdns_thread(int irq, void *dev_id);
>>   int sdw_cdns_init(struct sdw_cdns *cdns);
>>   int sdw_cdns_pdi_init(struct sdw_cdns *cdns,
>>   		      struct sdw_cdns_stream_config config);
>> +int sdw_cdns_exit_reset(struct sdw_cdns *cdns);
>>   int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns);
>>   
>>   void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root);
>> diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
>> index a976480d6f36..9ebe38e4d979 100644
>> --- a/drivers/soundwire/intel.c
>> +++ b/drivers/soundwire/intel.c
>> @@ -1112,6 +1112,8 @@ static int intel_probe(struct platform_device *pdev)
>>   
>>   	ret = sdw_cdns_enable_interrupt(&sdw->cdns);
>>   
>> +	ret = sdw_cdns_exit_reset(&sdw->cdns);
>> +
>>   	/* Register DAIs */
>>   	ret = intel_register_dai(sdw);
>>   	if (ret) {
>> @@ -1199,6 +1201,8 @@ static int intel_resume(struct device *dev)
>>   
>>   	sdw_cdns_enable_interrupt(&sdw->cdns);
>>   
>> +	ret = sdw_cdns_exit_reset(&sdw->cdns);
>> +
>>   	return ret;
>>   }
>>   
>> -- 
>> 2.20.1
> 


^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 02/40] soundwire: cadence_master: add debugfs register dump
  2019-07-25 23:39 ` [RFC PATCH 02/40] soundwire: cadence_master: add debugfs register dump Pierre-Louis Bossart
  2019-07-26 14:09   ` Greg KH
@ 2019-08-05  7:55   ` Sanyog Kale
  2019-08-05 15:20     ` [alsa-devel] " Pierre-Louis Bossart
  1 sibling, 1 reply; 183+ messages in thread
From: Sanyog Kale @ 2019-08-05  7:55 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak

On Thu, Jul 25, 2019 at 06:39:54PM -0500, Pierre-Louis Bossart wrote:
> Add debugfs file to dump the Cadence master registers
> 
> Credits: this patch is based on an earlier internal contribution by
> Vinod Koul, Sanyog Kale, Shreyas Nc and Hardik Shah. The main change
> is the use of scnprintf to avoid known issues with snprintf.
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/cadence_master.c | 98 ++++++++++++++++++++++++++++++
>  drivers/soundwire/cadence_master.h |  2 +
>  2 files changed, 100 insertions(+)
> 
> diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
> index ff4badc9b3de..91e8bacb83e3 100644
> --- a/drivers/soundwire/cadence_master.c
> +++ b/drivers/soundwire/cadence_master.c
> @@ -8,6 +8,7 @@
>  
>  #include <linux/delay.h>
>  #include <linux/device.h>
> +#include <linux/debugfs.h>
>  #include <linux/interrupt.h>
>  #include <linux/io.h>
>  #include <linux/module.h>
> @@ -223,6 +224,103 @@ static int cdns_clear_bit(struct sdw_cdns *cdns, int offset, u32 value)
>  	return -EAGAIN;
>  }
>  
> +/*
> + * debugfs
> + */
> +
> +#define RD_BUF (2 * PAGE_SIZE)
> +
> +static ssize_t cdns_sprintf(struct sdw_cdns *cdns,
> +			    char *buf, size_t pos, unsigned int reg)
> +{
> +	return scnprintf(buf + pos, RD_BUF - pos,
> +			 "%4x\t%4x\n", reg, cdns_readl(cdns, reg));
> +}
> +
> +static ssize_t cdns_reg_read(struct file *file, char __user *user_buf,
> +			     size_t count, loff_t *ppos)
> +{
> +	struct sdw_cdns *cdns = file->private_data;
> +	char *buf;
> +	ssize_t ret;
> +	int i, j;
> +
> +	buf = kzalloc(RD_BUF, GFP_KERNEL);
> +	if (!buf)
> +		return -ENOMEM;
> +
> +	ret = scnprintf(buf, RD_BUF, "Register  Value\n");
> +	ret += scnprintf(buf + ret, RD_BUF - ret, "\nMCP Registers\n");
> +	for (i = 0; i < 8; i++) /* 8 MCP registers */
> +		ret += cdns_sprintf(cdns, buf, ret, i * 4);
> +
> +	ret += scnprintf(buf + ret, RD_BUF - ret,
> +			 "\nStatus & Intr Registers\n");
> +	for (i = 0; i < 13; i++) /* 13 Status & Intr registers */
> +		ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_STAT + i * 4);
> +
> +	ret += scnprintf(buf + ret, RD_BUF - ret,
> +			 "\nSSP & Clk ctrl Registers\n");
> +	ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_SSP_CTRL0);
> +	ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_SSP_CTRL1);
> +	ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_CLK_CTRL0);
> +	ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_CLK_CTRL1);
> +
> +	ret += scnprintf(buf + ret, RD_BUF - ret,
> +			 "\nDPn B0 Registers\n");
> +	for (i = 0; i < 7; i++) {
> +		ret += scnprintf(buf + ret, RD_BUF - ret,
> +				 "\nDP-%d\n", i);
> +		for (j = 0; j < 6; j++)
> +			ret += cdns_sprintf(cdns, buf, ret,
> +					CDNS_DPN_B0_CONFIG(i) + j * 4);
> +	}
> +
> +	ret += scnprintf(buf + ret, RD_BUF - ret,
> +			 "\nDPn B1 Registers\n");
> +	for (i = 0; i < 7; i++) {
> +		ret += scnprintf(buf + ret, RD_BUF - ret,
> +				 "\nDP-%d\n", i);
> +
> +		for (j = 0; j < 6; j++)
> +			ret += cdns_sprintf(cdns, buf, ret,
> +					CDNS_DPN_B1_CONFIG(i) + j * 4);
> +	}
> +
> +	ret += scnprintf(buf + ret, RD_BUF - ret,
> +			 "\nDPn Control Registers\n");
> +	for (i = 0; i < 7; i++)
> +		ret += cdns_sprintf(cdns, buf, ret,
> +				CDNS_PORTCTRL + i * CDNS_PORT_OFFSET);
> +
> +	ret += scnprintf(buf + ret, RD_BUF - ret,
> +			 "\nPDIn Config Registers\n");
> +	for (i = 0; i < 7; i++)

please use macros for all the hardcodings.

> +		ret += cdns_sprintf(cdns, buf, ret, CDNS_PDI_CONFIG(i));
> +
> +	ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
> +	kfree(buf);
> +
> +	return ret;
> +}
> +
> +static const struct file_operations cdns_reg_fops = {
> +	.open = simple_open,
> +	.read = cdns_reg_read,
> +	.llseek = default_llseek,
> +};
> +
> +/**
> + * sdw_cdns_debugfs_init() - Cadence debugfs init
> + * @cdns: Cadence instance
> + * @root: debugfs root
> + */
> +void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root)
> +{
> +	debugfs_create_file("cdns-registers", 0400, root, cdns, &cdns_reg_fops);
> +}
> +EXPORT_SYMBOL_GPL(sdw_cdns_debugfs_init);
> +
>  /*
>   * IO Calls
>   */
> diff --git a/drivers/soundwire/cadence_master.h b/drivers/soundwire/cadence_master.h
> index fe2af62958b1..c0bf6ff00a44 100644
> --- a/drivers/soundwire/cadence_master.h
> +++ b/drivers/soundwire/cadence_master.h
> @@ -163,6 +163,8 @@ int sdw_cdns_pdi_init(struct sdw_cdns *cdns,
>  		      struct sdw_cdns_stream_config config);
>  int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns);
>  
> +void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root);
> +
>  int sdw_cdns_get_stream(struct sdw_cdns *cdns,
>  			struct sdw_cdns_streams *stream,
>  			u32 ch, u32 dir);
> -- 
> 2.20.1
> 

-- 

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 09/40] soundwire: cadence_master: fix usage of CONFIG_UPDATE
  2019-07-25 23:40 ` [RFC PATCH 09/40] soundwire: cadence_master: fix usage of CONFIG_UPDATE Pierre-Louis Bossart
                     ` (3 preceding siblings ...)
  2019-08-02 12:03   ` Vinod Koul
@ 2019-08-05  8:51   ` Sanyog Kale
  4 siblings, 0 replies; 183+ messages in thread
From: Sanyog Kale @ 2019-08-05  8:51 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak

On Thu, Jul 25, 2019 at 06:40:01PM -0500, Pierre-Louis Bossart wrote:
> Per the hardware documentation, all changes to MCP_CONFIG,
> MCP_CONTROL, MCP_CMDCTRL and MCP_PHYCTRL need to be validated with a
> self-clearing write to MCP_CONFIG_UPDATE.
> 
> For some reason, the existing code only does this write to
> CONFIG_UPDATE when enabling interrupts. Add a helper and do the update
> when the CONFIG is changed.
>

the sequence of intel_probe is as follows:
1. intel_link_power_up
2. intel_shim_init
3. sdw_cdns_init
4. sdw_cdns_enable_interrupt

Since we do self-clearing write to MCP_CONFIG_UPDATE in
sdw_cdns_enable_interrupt once for all the config changes,
we dont perform it as part of sdw_cdns_init.

It does make sense to seperate it out from sdw_cdns_enable_interrupt so
that we can use when clockstop is enabled where we dont need to enable
interrupts.

> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/cadence_master.c | 29 +++++++++++++++++++++--------
>  1 file changed, 21 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
> index 9f611a1fff0a..eb46cf651d62 100644
> --- a/drivers/soundwire/cadence_master.c
> +++ b/drivers/soundwire/cadence_master.c
> @@ -224,6 +224,22 @@ static int cdns_clear_bit(struct sdw_cdns *cdns, int offset, u32 value)
>  	return -EAGAIN;
>  }
>  
> +/*
> + * all changes to the MCP_CONFIG, MCP_CONTROL, MCP_CMDCTRL and MCP_PHYCTRL
> + * need to be confirmed with a write to MCP_CONFIG_UPDATE
> + */
> +static int cdns_update_config(struct sdw_cdns *cdns)
> +{
> +	int ret;
> +
> +	ret = cdns_clear_bit(cdns, CDNS_MCP_CONFIG_UPDATE,
> +			     CDNS_MCP_CONFIG_UPDATE_BIT);
> +	if (ret < 0)
> +		dev_err(cdns->dev, "Config update timedout\n");
> +
> +	return ret;
> +}
> +
>  /*
>   * debugfs
>   */
> @@ -758,15 +774,9 @@ static int _cdns_enable_interrupt(struct sdw_cdns *cdns)
>   */
>  int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
>  {
> -	int ret;
> -
>  	_cdns_enable_interrupt(cdns);
> -	ret = cdns_clear_bit(cdns, CDNS_MCP_CONFIG_UPDATE,
> -			     CDNS_MCP_CONFIG_UPDATE_BIT);
> -	if (ret < 0)
> -		dev_err(cdns->dev, "Config update timedout\n");
>  
> -	return ret;
> +	return 0;
>  }
>  EXPORT_SYMBOL(sdw_cdns_enable_interrupt);
>  
> @@ -943,7 +953,10 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
>  
>  	cdns_writel(cdns, CDNS_MCP_CONFIG, val);
>  
> -	return 0;
> +	/* commit changes */
> +	ret = cdns_update_config(cdns);
> +
> +	return ret;
>  }
>  EXPORT_SYMBOL(sdw_cdns_init);
>  
> -- 
> 2.20.1
> 

-- 

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 21/40] soundwire: export helpers to find row and column values
  2019-07-25 23:40 ` [RFC PATCH 21/40] soundwire: export helpers to find row and column values Pierre-Louis Bossart
  2019-07-26 14:43   ` [alsa-devel] " Guennadi Liakhovetski
@ 2019-08-05  9:39   ` Sanyog Kale
  2019-08-05 15:27     ` [alsa-devel] " Pierre-Louis Bossart
  1 sibling, 1 reply; 183+ messages in thread
From: Sanyog Kale @ 2019-08-05  9:39 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak

On Thu, Jul 25, 2019 at 06:40:13PM -0500, Pierre-Louis Bossart wrote:
> Add a prefix for common tables and export 2 helpers to set the frame
> shapes based on row/col values.
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/bus.h    |  7 +++++--
>  drivers/soundwire/stream.c | 14 ++++++++------
>  2 files changed, 13 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/soundwire/bus.h b/drivers/soundwire/bus.h
> index 06ac4adb0074..c57c9c23f6ca 100644
> --- a/drivers/soundwire/bus.h
> +++ b/drivers/soundwire/bus.h
> @@ -73,8 +73,11 @@ struct sdw_msg {
>  
>  #define SDW_DOUBLE_RATE_FACTOR		2
>  
> -extern int rows[SDW_FRAME_ROWS];
> -extern int cols[SDW_FRAME_COLS];
> +extern int sdw_rows[SDW_FRAME_ROWS];
> +extern int sdw_cols[SDW_FRAME_COLS];
> +
> +int sdw_find_row_index(int row);
> +int sdw_find_col_index(int col);

We use index values only in bank switch operations to program registers. Do we
really need to export sdw_find_row_index & sdw_find_col_index?? If i understand
correctly the allocation algorithm only needs to know about cols and rows values
and not index.

>  
>  /**
>   * sdw_port_runtime: Runtime port parameters for Master or Slave
> diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c
> index a0476755a459..53f5e790fcd7 100644
> --- a/drivers/soundwire/stream.c
> +++ b/drivers/soundwire/stream.c
> @@ -21,37 +21,39 @@
>   * The rows are arranged as per the array index value programmed
>   * in register. The index 15 has dummy value 0 in order to fill hole.
>   */
> -int rows[SDW_FRAME_ROWS] = {48, 50, 60, 64, 75, 80, 125, 147,
> +int sdw_rows[SDW_FRAME_ROWS] = {48, 50, 60, 64, 75, 80, 125, 147,
>  			96, 100, 120, 128, 150, 160, 250, 0,
>  			192, 200, 240, 256, 72, 144, 90, 180};
>  
> -int cols[SDW_FRAME_COLS] = {2, 4, 6, 8, 10, 12, 14, 16};
> +int sdw_cols[SDW_FRAME_COLS] = {2, 4, 6, 8, 10, 12, 14, 16};
>  
> -static int sdw_find_col_index(int col)
> +int sdw_find_col_index(int col)
>  {
>  	int i;
>  
>  	for (i = 0; i < SDW_FRAME_COLS; i++) {
> -		if (cols[i] == col)
> +		if (sdw_cols[i] == col)
>  			return i;
>  	}
>  
>  	pr_warn("Requested column not found, selecting lowest column no: 2\n");
>  	return 0;
>  }
> +EXPORT_SYMBOL(sdw_find_col_index);
>  
> -static int sdw_find_row_index(int row)
> +int sdw_find_row_index(int row)
>  {
>  	int i;
>  
>  	for (i = 0; i < SDW_FRAME_ROWS; i++) {
> -		if (rows[i] == row)
> +		if (sdw_rows[i] == row)
>  			return i;
>  	}
>  
>  	pr_warn("Requested row not found, selecting lowest row no: 48\n");
>  	return 0;
>  }
> +EXPORT_SYMBOL(sdw_find_row_index);
>  
>  static int _sdw_program_slave_port_params(struct sdw_bus *bus,
>  					  struct sdw_slave *slave,
> -- 
> 2.20.1
> 

-- 

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 23/40] soundwire: stream: fix disable sequence
  2019-07-25 23:40 ` [RFC PATCH 23/40] soundwire: stream: fix disable sequence Pierre-Louis Bossart
  2019-07-26 10:14   ` Cezary Rojewski
  2019-07-26 14:51   ` Guennadi Liakhovetski
@ 2019-08-05  9:56   ` Sanyog Kale
  2019-08-05 15:33     ` [alsa-devel] " Pierre-Louis Bossart
  2 siblings, 1 reply; 183+ messages in thread
From: Sanyog Kale @ 2019-08-05  9:56 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak

On Thu, Jul 25, 2019 at 06:40:15PM -0500, Pierre-Louis Bossart wrote:
> When we disable the stream and then call hw_free, two bank switches
> will be handled and as a result we re-enable the stream on hw_free.
>

I didnt quite get why there will be two bank switches as part of disable flow
which leads to enabling of stream?

> Make sure the stream is disabled on both banks.
> 
> TODO: we need to completely revisit all this and make sure we have a
> mirroring mechanism between current and alternate banks.
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/stream.c | 19 ++++++++++++++++++-
>  1 file changed, 18 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c
> index 53f5e790fcd7..75b9ad1fb1a6 100644
> --- a/drivers/soundwire/stream.c
> +++ b/drivers/soundwire/stream.c
> @@ -1637,7 +1637,24 @@ static int _sdw_disable_stream(struct sdw_stream_runtime *stream)
>  		}
>  	}
>  
> -	return do_bank_switch(stream);
> +	ret = do_bank_switch(stream);
> +	if (ret < 0) {
> +		dev_err(bus->dev, "Bank switch failed: %d\n", ret);
> +		return ret;
> +	}
> +
> +	/* make sure alternate bank (previous current) is also disabled */
> +	list_for_each_entry(m_rt, &stream->master_list, stream_node) {
> +		bus = m_rt->bus;
> +		/* Disable port(s) */
> +		ret = sdw_enable_disable_ports(m_rt, false);
> +		if (ret < 0) {
> +			dev_err(bus->dev, "Disable port(s) failed: %d\n", ret);
> +			return ret;
> +		}
> +	}
> +
> +	return 0;
>  }
>  
>  /**
> -- 
> 2.20.1
> 

-- 

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 24/40] soundwire: cadence_master: use BIOS defaults for frame shape
  2019-07-25 23:40 ` [RFC PATCH 24/40] soundwire: cadence_master: use BIOS defaults for frame shape Pierre-Louis Bossart
  2019-07-26 10:20   ` Cezary Rojewski
  2019-08-02 17:10   ` Vinod Koul
@ 2019-08-05 10:01   ` Sanyog Kale
  2 siblings, 0 replies; 183+ messages in thread
From: Sanyog Kale @ 2019-08-05 10:01 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak

On Thu, Jul 25, 2019 at 06:40:16PM -0500, Pierre-Louis Bossart wrote:
> Remove hard-coding and use BIOS values. If they are wrong use default
> 48x2 frame shape.
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/cadence_master.c | 19 +++++++++++++++++--
>  1 file changed, 17 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
> index 442f78c00f09..d84344e29f71 100644
> --- a/drivers/soundwire/cadence_master.c
> +++ b/drivers/soundwire/cadence_master.c
> @@ -175,7 +175,6 @@
>  /* Driver defaults */
>  
>  #define CDNS_DEFAULT_CLK_DIVIDER		0
> -#define CDNS_DEFAULT_FRAME_SHAPE		0x30
>  #define CDNS_DEFAULT_SSP_INTERVAL		0x18
>  #define CDNS_TX_TIMEOUT				2000
>  
> @@ -954,6 +953,20 @@ int sdw_cdns_pdi_init(struct sdw_cdns *cdns,
>  }
>  EXPORT_SYMBOL(sdw_cdns_pdi_init);
>  
> +static u32 cdns_set_default_frame_shape(int n_rows, int n_cols)
> +{
> +	u32 val;
> +	int c;
> +	int r;
> +
> +	r = sdw_find_row_index(n_rows);
> +	c = sdw_find_col_index(n_cols);
> +

Now i get why you need above functions to be exported, please ignore my
previous comment.

> +	val = (r << 3) | c;
> +
> +	return val;
> +}
> +
>  /**
>   * sdw_cdns_init() - Cadence initialization
>   * @cdns: Cadence instance
> @@ -977,7 +990,9 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
>  	cdns_writel(cdns, CDNS_MCP_CLK_CTRL0, val);
>  
>  	/* Set the default frame shape */
> -	cdns_writel(cdns, CDNS_MCP_FRAME_SHAPE_INIT, CDNS_DEFAULT_FRAME_SHAPE);
> +	val = cdns_set_default_frame_shape(prop->default_row,
> +					   prop->default_col);
> +	cdns_writel(cdns, CDNS_MCP_FRAME_SHAPE_INIT, val);
>  
>  	/* Set SSP interval to default value */
>  	cdns_writel(cdns, CDNS_MCP_SSP_CTRL0, CDNS_DEFAULT_SSP_INTERVAL);
> -- 
> 2.20.1
> 

-- 

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 25/40] soundwire: intel: use BIOS information to set clock dividers
  2019-07-25 23:40 ` [RFC PATCH 25/40] soundwire: intel: use BIOS information to set clock dividers Pierre-Louis Bossart
  2019-08-02 17:17   ` Vinod Koul
@ 2019-08-05 10:28   ` Sanyog Kale
  2019-08-05 15:40     ` [alsa-devel] " Pierre-Louis Bossart
  1 sibling, 1 reply; 183+ messages in thread
From: Sanyog Kale @ 2019-08-05 10:28 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak

On Thu, Jul 25, 2019 at 06:40:17PM -0500, Pierre-Louis Bossart wrote:
> The BIOS provides an Intel-specific property, let's use it to avoid
> hard-coded clock dividers.
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/cadence_master.c | 26 ++++++++++++++++++++++----
>  drivers/soundwire/intel.c          | 26 ++++++++++++++++++++++++++
>  include/linux/soundwire/sdw.h      |  2 ++
>  3 files changed, 50 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
> index d84344e29f71..10ebcef2e84e 100644
> --- a/drivers/soundwire/cadence_master.c
> +++ b/drivers/soundwire/cadence_master.c
> @@ -173,8 +173,6 @@
>  #define CDNS_PDI_CONFIG_PORT			GENMASK(4, 0)
>  
>  /* Driver defaults */
> -
> -#define CDNS_DEFAULT_CLK_DIVIDER		0
>  #define CDNS_DEFAULT_SSP_INTERVAL		0x18
>  #define CDNS_TX_TIMEOUT				2000
>  
> @@ -973,7 +971,10 @@ static u32 cdns_set_default_frame_shape(int n_rows, int n_cols)
>   */
>  int sdw_cdns_init(struct sdw_cdns *cdns)
>  {
> +	struct sdw_bus *bus = &cdns->bus;
> +	struct sdw_master_prop *prop = &bus->prop;
>  	u32 val;
> +	int divider;
>  	int ret;
>  
>  	/* Exit clock stop */
> @@ -985,9 +986,17 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
>  	}
>  
>  	/* Set clock divider */
> +	divider	= (prop->mclk_freq / prop->max_clk_freq) - 1;

Do you expect mclk_freq and max_clk_freq to be same?

>  	val = cdns_readl(cdns, CDNS_MCP_CLK_CTRL0);
> -	val |= CDNS_DEFAULT_CLK_DIVIDER;
> +	val |= divider;
>  	cdns_writel(cdns, CDNS_MCP_CLK_CTRL0, val);
> +	cdns_writel(cdns, CDNS_MCP_CLK_CTRL1, val);
> +
> +	pr_err("plb: mclk %d max_freq %d divider %d register %x\n",
> +	       prop->mclk_freq,
> +	       prop->max_clk_freq,
> +	       divider,
> +	       val);

This can be removed.

>  
>  	/* Set the default frame shape */
>  	val = cdns_set_default_frame_shape(prop->default_row,
> @@ -1035,6 +1044,7 @@ EXPORT_SYMBOL(sdw_cdns_init);
>  
>  int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params)
>  {
> +	struct sdw_master_prop *prop = &bus->prop;
>  	struct sdw_cdns *cdns = bus_to_cdns(bus);
>  	int mcp_clkctrl_off, mcp_clkctrl;
>  	int divider;
> @@ -1044,7 +1054,9 @@ int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params)
>  		return -EINVAL;
>  	}
>  
> -	divider	= (params->max_dr_freq / params->curr_dr_freq) - 1;
> +	divider	= prop->mclk_freq * SDW_DOUBLE_RATE_FACTOR /

What is the reason for not using max_dr_freq? Its precomputed as
prop->max_clk_freq * SDW_DOUBLE_RATE_FACTOR;

> +		params->curr_dr_freq;
> +	divider--; /* divider is 1/(N+1) */
>  
>  	if (params->next_bank)
>  		mcp_clkctrl_off = CDNS_MCP_CLK_CTRL1;
> @@ -1055,6 +1067,12 @@ int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params)
>  	mcp_clkctrl |= divider;
>  	cdns_writel(cdns, mcp_clkctrl_off, mcp_clkctrl);
>  
> +	pr_err("plb: mclk * 2 %d curr_dr_freq %d divider %d register %x\n",
> +	       prop->mclk_freq * SDW_DOUBLE_RATE_FACTOR,
> +	       params->curr_dr_freq,
> +	       divider,
> +	       mcp_clkctrl);
> +
>  	return 0;
>  }
>  EXPORT_SYMBOL(cdns_bus_conf);
> diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
> index c718c9c67a37..796ac2bc8cea 100644
> --- a/drivers/soundwire/intel.c
> +++ b/drivers/soundwire/intel.c
> @@ -917,11 +917,37 @@ static int intel_register_dai(struct sdw_intel *sdw)
>  					  dais, num_dai);
>  }
>  
> +static int sdw_master_read_intel_prop(struct sdw_bus *bus)
> +{
> +	struct sdw_master_prop *prop = &bus->prop;
> +	struct fwnode_handle *link;
> +	char name[32];
> +	int nval, i;
> +
> +	/* Find master handle */
> +	snprintf(name, sizeof(name),
> +		 "mipi-sdw-link-%d-subproperties", bus->link_id);
> +
> +	link = device_get_named_child_node(bus->dev, name);
> +	if (!link) {
> +		dev_err(bus->dev, "Master node %s not found\n", name);
> +		return -EIO;
> +	}
> +
> +	fwnode_property_read_u32(link,
> +				 "intel-sdw-ip-clock",
> +				 &prop->mclk_freq);
> +	return 0;
> +}
> +
>  static int intel_prop_read(struct sdw_bus *bus)
>  {
>  	/* Initialize with default handler to read all DisCo properties */
>  	sdw_master_read_prop(bus);
>  
> +	/* read Intel-specific properties */
> +	sdw_master_read_intel_prop(bus);
> +
>  	return 0;
>  }
>  
> diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
> index 31d1e8acf25b..b6acc436ac80 100644
> --- a/include/linux/soundwire/sdw.h
> +++ b/include/linux/soundwire/sdw.h
> @@ -379,6 +379,7 @@ struct sdw_slave_prop {
>   * @dynamic_frame: Dynamic frame shape supported
>   * @err_threshold: Number of times that software may retry sending a single
>   * command
> + * @mclk_freq: clock reference passed to SoundWire Master, in Hz.
>   */
>  struct sdw_master_prop {
>  	u32 revision;
> @@ -393,6 +394,7 @@ struct sdw_master_prop {
>  	u32 default_col;
>  	bool dynamic_frame;
>  	u32 err_threshold;
> +	u32 mclk_freq;
>  };
>  
>  int sdw_master_read_prop(struct sdw_bus *bus);
> -- 
> 2.20.1
> 

-- 

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 26/40] soundwire: cadence_master: fix divider setting in clock register
  2019-07-25 23:40 ` [RFC PATCH 26/40] soundwire: cadence_master: fix divider setting in clock register Pierre-Louis Bossart
  2019-07-26  5:19   ` [alsa-devel] " Bard liao
  2019-08-02 17:19   ` Vinod Koul
@ 2019-08-05 10:40   ` Sanyog Kale
  2019-08-05 15:41     ` [alsa-devel] " Pierre-Louis Bossart
  2 siblings, 1 reply; 183+ messages in thread
From: Sanyog Kale @ 2019-08-05 10:40 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Rander Wang

On Thu, Jul 25, 2019 at 06:40:18PM -0500, Pierre-Louis Bossart wrote:
> From: Rander Wang <rander.wang@linux.intel.com>
> 
> The existing code uses an OR operation which would mix the original
> divider setting with the new one, resulting in an invalid
> configuration that can make codecs hang.
> 
> Add the mask definition and use cdns_updatel to update divider
> 
> Signed-off-by: Rander Wang <rander.wang@linux.intel.com>
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/cadence_master.c | 12 +++++++-----
>  1 file changed, 7 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
> index 10ebcef2e84e..18c6ac026e85 100644
> --- a/drivers/soundwire/cadence_master.c
> +++ b/drivers/soundwire/cadence_master.c
> @@ -57,6 +57,7 @@
>  #define CDNS_MCP_SSP_CTRL1			0x28
>  #define CDNS_MCP_CLK_CTRL0			0x30
>  #define CDNS_MCP_CLK_CTRL1			0x38
> +#define CDNS_MCP_CLK_MCLKD_MASK		GENMASK(7, 0)
>  
>  #define CDNS_MCP_STAT				0x40
>  
> @@ -988,9 +989,11 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
>  	/* Set clock divider */
>  	divider	= (prop->mclk_freq / prop->max_clk_freq) - 1;
>  	val = cdns_readl(cdns, CDNS_MCP_CLK_CTRL0);

reg read of CLK_CTRL0 can be removed.

> -	val |= divider;
> -	cdns_writel(cdns, CDNS_MCP_CLK_CTRL0, val);
> -	cdns_writel(cdns, CDNS_MCP_CLK_CTRL1, val);
> +
> +	cdns_updatel(cdns, CDNS_MCP_CLK_CTRL0,
> +		     CDNS_MCP_CLK_MCLKD_MASK, divider);
> +	cdns_updatel(cdns, CDNS_MCP_CLK_CTRL1,
> +		     CDNS_MCP_CLK_MCLKD_MASK, divider);
>  
>  	pr_err("plb: mclk %d max_freq %d divider %d register %x\n",
>  	       prop->mclk_freq,
> @@ -1064,8 +1067,7 @@ int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params)
>  		mcp_clkctrl_off = CDNS_MCP_CLK_CTRL0;
>  
>  	mcp_clkctrl = cdns_readl(cdns, mcp_clkctrl_off);

same as above.

> -	mcp_clkctrl |= divider;
> -	cdns_writel(cdns, mcp_clkctrl_off, mcp_clkctrl);
> +	cdns_updatel(cdns, mcp_clkctrl_off, CDNS_MCP_CLK_MCLKD_MASK, divider);
>  
>  	pr_err("plb: mclk * 2 %d curr_dr_freq %d divider %d register %x\n",
>  	       prop->mclk_freq * SDW_DOUBLE_RATE_FACTOR,
> -- 
> 2.20.1
> 

-- 

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 02/40] soundwire: cadence_master: add debugfs register dump
  2019-08-05  7:55   ` Sanyog Kale
@ 2019-08-05 15:20     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-08-05 15:20 UTC (permalink / raw)
  To: Sanyog Kale
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak


>> +static ssize_t cdns_reg_read(struct file *file, char __user *user_buf,
>> +			     size_t count, loff_t *ppos)
>> +{
>> +	struct sdw_cdns *cdns = file->private_data;
>> +	char *buf;
>> +	ssize_t ret;
>> +	int i, j;
>> +
>> +	buf = kzalloc(RD_BUF, GFP_KERNEL);
>> +	if (!buf)
>> +		return -ENOMEM;
>> +
>> +	ret = scnprintf(buf, RD_BUF, "Register  Value\n");
>> +	ret += scnprintf(buf + ret, RD_BUF - ret, "\nMCP Registers\n");
>> +	for (i = 0; i < 8; i++) /* 8 MCP registers */
>> +		ret += cdns_sprintf(cdns, buf, ret, i * 4);
>> +
>> +	ret += scnprintf(buf + ret, RD_BUF - ret,
>> +			 "\nStatus & Intr Registers\n");
>> +	for (i = 0; i < 13; i++) /* 13 Status & Intr registers */
>> +		ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_STAT + i * 4);
>> +
>> +	ret += scnprintf(buf + ret, RD_BUF - ret,
>> +			 "\nSSP & Clk ctrl Registers\n");
>> +	ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_SSP_CTRL0);
>> +	ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_SSP_CTRL1);
>> +	ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_CLK_CTRL0);
>> +	ret += cdns_sprintf(cdns, buf, ret, CDNS_MCP_CLK_CTRL1);
>> +
>> +	ret += scnprintf(buf + ret, RD_BUF - ret,
>> +			 "\nDPn B0 Registers\n");
>> +	for (i = 0; i < 7; i++) {
>> +		ret += scnprintf(buf + ret, RD_BUF - ret,
>> +				 "\nDP-%d\n", i);
>> +		for (j = 0; j < 6; j++)
>> +			ret += cdns_sprintf(cdns, buf, ret,
>> +					CDNS_DPN_B0_CONFIG(i) + j * 4);
>> +	}
>> +
>> +	ret += scnprintf(buf + ret, RD_BUF - ret,
>> +			 "\nDPn B1 Registers\n");
>> +	for (i = 0; i < 7; i++) {
>> +		ret += scnprintf(buf + ret, RD_BUF - ret,
>> +				 "\nDP-%d\n", i);
>> +
>> +		for (j = 0; j < 6; j++)
>> +			ret += cdns_sprintf(cdns, buf, ret,
>> +					CDNS_DPN_B1_CONFIG(i) + j * 4);
>> +	}
>> +
>> +	ret += scnprintf(buf + ret, RD_BUF - ret,
>> +			 "\nDPn Control Registers\n");
>> +	for (i = 0; i < 7; i++)
>> +		ret += cdns_sprintf(cdns, buf, ret,
>> +				CDNS_PORTCTRL + i * CDNS_PORT_OFFSET);
>> +
>> +	ret += scnprintf(buf + ret, RD_BUF - ret,
>> +			 "\nPDIn Config Registers\n");
>> +	for (i = 0; i < 7; i++)
> 
> please use macros for all the hardcodings.

yes, I completely changed that part in the upcoming update by using 
register start/stop for all loops, it makes the code more consistent and 
easier to change (SoundWire 1.2 registers will need to be added)


^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 21/40] soundwire: export helpers to find row and column values
  2019-08-05  9:39   ` Sanyog Kale
@ 2019-08-05 15:27     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-08-05 15:27 UTC (permalink / raw)
  To: Sanyog Kale
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak



On 8/5/19 4:39 AM, Sanyog Kale wrote:
> On Thu, Jul 25, 2019 at 06:40:13PM -0500, Pierre-Louis Bossart wrote:
>> Add a prefix for common tables and export 2 helpers to set the frame
>> shapes based on row/col values.
>>
>> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
>> ---
>>   drivers/soundwire/bus.h    |  7 +++++--
>>   drivers/soundwire/stream.c | 14 ++++++++------
>>   2 files changed, 13 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/soundwire/bus.h b/drivers/soundwire/bus.h
>> index 06ac4adb0074..c57c9c23f6ca 100644
>> --- a/drivers/soundwire/bus.h
>> +++ b/drivers/soundwire/bus.h
>> @@ -73,8 +73,11 @@ struct sdw_msg {
>>   
>>   #define SDW_DOUBLE_RATE_FACTOR		2
>>   
>> -extern int rows[SDW_FRAME_ROWS];
>> -extern int cols[SDW_FRAME_COLS];
>> +extern int sdw_rows[SDW_FRAME_ROWS];
>> +extern int sdw_cols[SDW_FRAME_COLS];
>> +
>> +int sdw_find_row_index(int row);
>> +int sdw_find_col_index(int col);
> 
> We use index values only in bank switch operations to program registers. Do we
> really need to export sdw_find_row_index & sdw_find_col_index?? If i understand
> correctly the allocation algorithm only needs to know about cols and rows values
> and not index.

The allocation does work with cols and rows indeed, but will first run 
the code below where the information f is required:

static int sdw_select_row_col(struct sdw_bus *bus, int clk_freq)
{
	struct sdw_master_prop *prop = &bus->prop;
	int frame_int, frame_freq;
	int r, c;

	for (c = 0; c < SDW_FRAME_COLS; c++) {
		for (r = 0; r < SDW_FRAME_ROWS; r++) {
			if (sdw_rows[r] != prop->default_row ||
			    sdw_cols[c] != prop->default_col)
				continue;

			frame_int = sdw_rows[r] * sdw_cols[c];
			frame_freq = clk_freq / frame_int;

			if ((clk_freq - (frame_freq * SDW_FRAME_CTRL_BITS)) <
			    bus->params.bandwidth)
				continue;

			bus->params.row = sdw_rows[r];
			bus->params.col = sdw_cols[c];
			return 0;
		}
	}

	return -EINVAL;
}

as for the two helpers, they are used in both the allocation and the 
cadence code (to determine the initial frame shape from properties).

And other solutions for non-Intel platforms will also need this to 
convert from indices to frame shape.

So yes all of this is needed.


> 
>>   
>>   /**
>>    * sdw_port_runtime: Runtime port parameters for Master or Slave
>> diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c
>> index a0476755a459..53f5e790fcd7 100644
>> --- a/drivers/soundwire/stream.c
>> +++ b/drivers/soundwire/stream.c
>> @@ -21,37 +21,39 @@
>>    * The rows are arranged as per the array index value programmed
>>    * in register. The index 15 has dummy value 0 in order to fill hole.
>>    */
>> -int rows[SDW_FRAME_ROWS] = {48, 50, 60, 64, 75, 80, 125, 147,
>> +int sdw_rows[SDW_FRAME_ROWS] = {48, 50, 60, 64, 75, 80, 125, 147,
>>   			96, 100, 120, 128, 150, 160, 250, 0,
>>   			192, 200, 240, 256, 72, 144, 90, 180};
>>   
>> -int cols[SDW_FRAME_COLS] = {2, 4, 6, 8, 10, 12, 14, 16};
>> +int sdw_cols[SDW_FRAME_COLS] = {2, 4, 6, 8, 10, 12, 14, 16};
>>   
>> -static int sdw_find_col_index(int col)
>> +int sdw_find_col_index(int col)
>>   {
>>   	int i;
>>   
>>   	for (i = 0; i < SDW_FRAME_COLS; i++) {
>> -		if (cols[i] == col)
>> +		if (sdw_cols[i] == col)
>>   			return i;
>>   	}
>>   
>>   	pr_warn("Requested column not found, selecting lowest column no: 2\n");
>>   	return 0;
>>   }
>> +EXPORT_SYMBOL(sdw_find_col_index);
>>   
>> -static int sdw_find_row_index(int row)
>> +int sdw_find_row_index(int row)
>>   {
>>   	int i;
>>   
>>   	for (i = 0; i < SDW_FRAME_ROWS; i++) {
>> -		if (rows[i] == row)
>> +		if (sdw_rows[i] == row)
>>   			return i;
>>   	}
>>   
>>   	pr_warn("Requested row not found, selecting lowest row no: 48\n");
>>   	return 0;
>>   }
>> +EXPORT_SYMBOL(sdw_find_row_index);
>>   
>>   static int _sdw_program_slave_port_params(struct sdw_bus *bus,
>>   					  struct sdw_slave *slave,
>> -- 
>> 2.20.1
>>
> 

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 23/40] soundwire: stream: fix disable sequence
  2019-08-05  9:56   ` Sanyog Kale
@ 2019-08-05 15:33     ` Pierre-Louis Bossart
  2019-08-05 16:32       ` Sanyog Kale
  0 siblings, 1 reply; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-08-05 15:33 UTC (permalink / raw)
  To: Sanyog Kale
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak



On 8/5/19 4:56 AM, Sanyog Kale wrote:
> On Thu, Jul 25, 2019 at 06:40:15PM -0500, Pierre-Louis Bossart wrote:
>> When we disable the stream and then call hw_free, two bank switches
>> will be handled and as a result we re-enable the stream on hw_free.
>>
> 
> I didnt quite get why there will be two bank switches as part of disable flow
> which leads to enabling of stream?

You have two bank switches, one to stop streaming and on in de-prepare. 
It's symmetrical with the start sequence, where we do a bank switch to 
prepare and another to enable.

Let's assume we are using bank0 when streaming.

Before the first bank switch, the channel_enable is set to false in the 
alternate bank1. When the bank switch happens, bank1 become active and 
the streaming stops. But bank0 registers have not been modified so when 
we do the second bank switch in de-prepare we make bank0 active, and the 
ch_enable bits are still set so streaming will restart... When we stop 
streaming, we need to make sure the ch_enable bits are cleared in the 
two banks.


> 
>> Make sure the stream is disabled on both banks.
>>
>> TODO: we need to completely revisit all this and make sure we have a
>> mirroring mechanism between current and alternate banks.
>>
>> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
>> ---
>>   drivers/soundwire/stream.c | 19 ++++++++++++++++++-
>>   1 file changed, 18 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c
>> index 53f5e790fcd7..75b9ad1fb1a6 100644
>> --- a/drivers/soundwire/stream.c
>> +++ b/drivers/soundwire/stream.c
>> @@ -1637,7 +1637,24 @@ static int _sdw_disable_stream(struct sdw_stream_runtime *stream)
>>   		}
>>   	}
>>   
>> -	return do_bank_switch(stream);
>> +	ret = do_bank_switch(stream);
>> +	if (ret < 0) {
>> +		dev_err(bus->dev, "Bank switch failed: %d\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	/* make sure alternate bank (previous current) is also disabled */
>> +	list_for_each_entry(m_rt, &stream->master_list, stream_node) {
>> +		bus = m_rt->bus;
>> +		/* Disable port(s) */
>> +		ret = sdw_enable_disable_ports(m_rt, false);
>> +		if (ret < 0) {
>> +			dev_err(bus->dev, "Disable port(s) failed: %d\n", ret);
>> +			return ret;
>> +		}
>> +	}
>> +
>> +	return 0;
>>   }
>>   
>>   /**
>> -- 
>> 2.20.1
>>
> 

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 25/40] soundwire: intel: use BIOS information to set clock dividers
  2019-08-05 10:28   ` Sanyog Kale
@ 2019-08-05 15:40     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-08-05 15:40 UTC (permalink / raw)
  To: Sanyog Kale
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak



On 8/5/19 5:28 AM, Sanyog Kale wrote:
> On Thu, Jul 25, 2019 at 06:40:17PM -0500, Pierre-Louis Bossart wrote:
>> The BIOS provides an Intel-specific property, let's use it to avoid
>> hard-coded clock dividers.
>>
>> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
>> ---
>>   drivers/soundwire/cadence_master.c | 26 ++++++++++++++++++++++----
>>   drivers/soundwire/intel.c          | 26 ++++++++++++++++++++++++++
>>   include/linux/soundwire/sdw.h      |  2 ++
>>   3 files changed, 50 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
>> index d84344e29f71..10ebcef2e84e 100644
>> --- a/drivers/soundwire/cadence_master.c
>> +++ b/drivers/soundwire/cadence_master.c
>> @@ -173,8 +173,6 @@
>>   #define CDNS_PDI_CONFIG_PORT			GENMASK(4, 0)
>>   
>>   /* Driver defaults */
>> -
>> -#define CDNS_DEFAULT_CLK_DIVIDER		0
>>   #define CDNS_DEFAULT_SSP_INTERVAL		0x18
>>   #define CDNS_TX_TIMEOUT				2000
>>   
>> @@ -973,7 +971,10 @@ static u32 cdns_set_default_frame_shape(int n_rows, int n_cols)
>>    */
>>   int sdw_cdns_init(struct sdw_cdns *cdns)
>>   {
>> +	struct sdw_bus *bus = &cdns->bus;
>> +	struct sdw_master_prop *prop = &bus->prop;
>>   	u32 val;
>> +	int divider;
>>   	int ret;
>>   
>>   	/* Exit clock stop */
>> @@ -985,9 +986,17 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
>>   	}
>>   
>>   	/* Set clock divider */
>> +	divider	= (prop->mclk_freq / prop->max_clk_freq) - 1;
> 
> Do you expect mclk_freq and max_clk_freq to be same?

Nope. For Icelake the MCLK is 38.4 MHz and is, but the max_clk needs to 
be 9.6 max (can't be higher per the SoundWire spec).

The max_clk_freq may even be lower thank 9.6 MHz due to specific 
topologies where the higher frequencies are problematic if the trace 
lengths are too long.

For CNL/CML the MCLK is 24 MHz but ironically we run the bus at 12 MHz, 
so the divider is smaller.

> 
>>   	val = cdns_readl(cdns, CDNS_MCP_CLK_CTRL0);
>> -	val |= CDNS_DEFAULT_CLK_DIVIDER;
>> +	val |= divider;
>>   	cdns_writel(cdns, CDNS_MCP_CLK_CTRL0, val);
>> +	cdns_writel(cdns, CDNS_MCP_CLK_CTRL1, val);
>> +
>> +	pr_err("plb: mclk %d max_freq %d divider %d register %x\n",
>> +	       prop->mclk_freq,
>> +	       prop->max_clk_freq,
>> +	       divider,
>> +	       val);
> 
> This can be removed.

yes, done already.

> 
>>   
>>   	/* Set the default frame shape */
>>   	val = cdns_set_default_frame_shape(prop->default_row,
>> @@ -1035,6 +1044,7 @@ EXPORT_SYMBOL(sdw_cdns_init);
>>   
>>   int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params)
>>   {
>> +	struct sdw_master_prop *prop = &bus->prop;
>>   	struct sdw_cdns *cdns = bus_to_cdns(bus);
>>   	int mcp_clkctrl_off, mcp_clkctrl;
>>   	int divider;
>> @@ -1044,7 +1054,9 @@ int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params)
>>   		return -EINVAL;
>>   	}
>>   
>> -	divider	= (params->max_dr_freq / params->curr_dr_freq) - 1;
>> +	divider	= prop->mclk_freq * SDW_DOUBLE_RATE_FACTOR /
> 
> What is the reason for not using max_dr_freq? Its precomputed as
> prop->max_clk_freq * SDW_DOUBLE_RATE_FACTOR;

no, as explained above the divider needs to start from the clock 
provided to the IP, which is different from the max frequency clock the 
bus operates at. the MCLK is a fixed value for all platforms using the 
same SOC/PCH, the max_clk is platform-dependent and its value is 
provided by the firmware (BIOS/DT).

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 26/40] soundwire: cadence_master: fix divider setting in clock register
  2019-08-05 10:40   ` Sanyog Kale
@ 2019-08-05 15:41     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-08-05 15:41 UTC (permalink / raw)
  To: Sanyog Kale
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak, Rander Wang


>> @@ -988,9 +989,11 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
>>   	/* Set clock divider */
>>   	divider	= (prop->mclk_freq / prop->max_clk_freq) - 1;
>>   	val = cdns_readl(cdns, CDNS_MCP_CLK_CTRL0);
> 
> reg read of CLK_CTRL0 can be removed.

yes for both comments. Thanks for the review Sanyog, appreciate it.

> 
>> -	val |= divider;
>> -	cdns_writel(cdns, CDNS_MCP_CLK_CTRL0, val);
>> -	cdns_writel(cdns, CDNS_MCP_CLK_CTRL1, val);
>> +
>> +	cdns_updatel(cdns, CDNS_MCP_CLK_CTRL0,
>> +		     CDNS_MCP_CLK_MCLKD_MASK, divider);
>> +	cdns_updatel(cdns, CDNS_MCP_CLK_CTRL1,
>> +		     CDNS_MCP_CLK_MCLKD_MASK, divider);
>>   
>>   	pr_err("plb: mclk %d max_freq %d divider %d register %x\n",
>>   	       prop->mclk_freq,
>> @@ -1064,8 +1067,7 @@ int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params)
>>   		mcp_clkctrl_off = CDNS_MCP_CLK_CTRL0;
>>   
>>   	mcp_clkctrl = cdns_readl(cdns, mcp_clkctrl_off);
> 
> same as above.
> 
>> -	mcp_clkctrl |= divider;
>> -	cdns_writel(cdns, mcp_clkctrl_off, mcp_clkctrl);
>> +	cdns_updatel(cdns, mcp_clkctrl_off, CDNS_MCP_CLK_MCLKD_MASK, divider);
>>   
>>   	pr_err("plb: mclk * 2 %d curr_dr_freq %d divider %d register %x\n",
>>   	       prop->mclk_freq * SDW_DOUBLE_RATE_FACTOR,
>> -- 
>> 2.20.1
>>
> 

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 23/40] soundwire: stream: fix disable sequence
  2019-08-05 15:33     ` [alsa-devel] " Pierre-Louis Bossart
@ 2019-08-05 16:32       ` Sanyog Kale
  2019-08-05 19:12         ` Pierre-Louis Bossart
  0 siblings, 1 reply; 183+ messages in thread
From: Sanyog Kale @ 2019-08-05 16:32 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak

On Mon, Aug 05, 2019 at 10:33:25AM -0500, Pierre-Louis Bossart wrote:
> 
> 
> On 8/5/19 4:56 AM, Sanyog Kale wrote:
> > On Thu, Jul 25, 2019 at 06:40:15PM -0500, Pierre-Louis Bossart wrote:
> > > When we disable the stream and then call hw_free, two bank switches
> > > will be handled and as a result we re-enable the stream on hw_free.
> > > 
> > 
> > I didnt quite get why there will be two bank switches as part of disable flow
> > which leads to enabling of stream?
> 
> You have two bank switches, one to stop streaming and on in de-prepare. It's
> symmetrical with the start sequence, where we do a bank switch to prepare
> and another to enable.

Got it. I misunderstood it that two bank switches are performed as part of
disable_stream.

> 
> Let's assume we are using bank0 when streaming.
> 
> Before the first bank switch, the channel_enable is set to false in the
> alternate bank1. When the bank switch happens, bank1 become active and the
> streaming stops. But bank0 registers have not been modified so when we do
> the second bank switch in de-prepare we make bank0 active, and the ch_enable
> bits are still set so streaming will restart... When we stop streaming, we
> need to make sure the ch_enable bits are cleared in the two banks.

This is clear. Even though the channels remains enabled, i believe there
won't be any data pushed on lines as stream will be closed.

Regarding mirroring approach, I assume after bank switch we will take
snapshot of active bank and program same in inactive bank.

> 
> 
> > 
> > > Make sure the stream is disabled on both banks.
> > > 
> > > TODO: we need to completely revisit all this and make sure we have a
> > > mirroring mechanism between current and alternate banks.
> > > 
> > > Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> > > ---
> > >   drivers/soundwire/stream.c | 19 ++++++++++++++++++-
> > >   1 file changed, 18 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c
> > > index 53f5e790fcd7..75b9ad1fb1a6 100644
> > > --- a/drivers/soundwire/stream.c
> > > +++ b/drivers/soundwire/stream.c
> > > @@ -1637,7 +1637,24 @@ static int _sdw_disable_stream(struct sdw_stream_runtime *stream)
> > >   		}
> > >   	}
> > > -	return do_bank_switch(stream);
> > > +	ret = do_bank_switch(stream);
> > > +	if (ret < 0) {
> > > +		dev_err(bus->dev, "Bank switch failed: %d\n", ret);
> > > +		return ret;
> > > +	}
> > > +
> > > +	/* make sure alternate bank (previous current) is also disabled */
> > > +	list_for_each_entry(m_rt, &stream->master_list, stream_node) {
> > > +		bus = m_rt->bus;
> > > +		/* Disable port(s) */
> > > +		ret = sdw_enable_disable_ports(m_rt, false);
> > > +		if (ret < 0) {
> > > +			dev_err(bus->dev, "Disable port(s) failed: %d\n", ret);
> > > +			return ret;
> > > +		}
> > > +	}
> > > +
> > > +	return 0;
> > >   }
> > >   /**
> > > -- 
> > > 2.20.1
> > > 
> > 

-- 

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 27/40] soundwire: Add Intel resource management algorithm
  2019-07-25 23:40 ` [RFC PATCH 27/40] soundwire: Add Intel resource management algorithm Pierre-Louis Bossart
  2019-07-26 11:07   ` Cezary Rojewski
  2019-07-26 15:43   ` Guennadi Liakhovetski
@ 2019-08-05 16:54   ` Sanyog Kale
  2019-08-05 19:08     ` [alsa-devel] " Pierre-Louis Bossart
  2 siblings, 1 reply; 183+ messages in thread
From: Sanyog Kale @ 2019-08-05 16:54 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak

On Thu, Jul 25, 2019 at 06:40:19PM -0500, Pierre-Louis Bossart wrote:
> This algorithm computes bus parameters like clock frequency, frame
> shape and port transport parameters based on active stream(s) running
> on the bus.
> 
> This implementation is optimal for Intel platforms. Developers can
> also implement their own .compute_params() callback for specific
> resource management algorithm.
> 
> Credits: this patch is based on an earlier internal contribution by
> Vinod Koul, Sanyog Kale, Shreyas Nc and Hardik Shah. All hard-coded
> values were removed from the initial contribution to use BIOS
> information instead.
> 
> FIXME: remove checkpatch report
> WARNING: Reusing the krealloc arg is almost always a bug
> +			group->rates = krealloc(group->rates,
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/Makefile                  |   2 +-
>  drivers/soundwire/algo_dynamic_allocation.c | 403 ++++++++++++++++++++
>  drivers/soundwire/bus.c                     |   3 +
>  drivers/soundwire/bus.h                     |  46 ++-
>  drivers/soundwire/stream.c                  |  20 +
>  include/linux/soundwire/sdw.h               |   5 +
>  6 files changed, 476 insertions(+), 3 deletions(-)
>  create mode 100644 drivers/soundwire/algo_dynamic_allocation.c
> 
> diff --git a/drivers/soundwire/Makefile b/drivers/soundwire/Makefile
> index 88990cac48a7..f59a9d4a28fd 100644
> --- a/drivers/soundwire/Makefile
> +++ b/drivers/soundwire/Makefile
> @@ -5,7 +5,7 @@
>  
>  #Bus Objs
>  soundwire-bus-objs := bus_type.o bus.o slave.o mipi_disco.o stream.o \
> -			debugfs.o
> +			debugfs.o algo_dynamic_allocation.o
>  
>  obj-$(CONFIG_SOUNDWIRE_BUS) += soundwire-bus.o
>  
> diff --git a/drivers/soundwire/algo_dynamic_allocation.c b/drivers/soundwire/algo_dynamic_allocation.c
> new file mode 100644
> index 000000000000..89edb39162b8
> --- /dev/null
> +++ b/drivers/soundwire/algo_dynamic_allocation.c
> @@ -0,0 +1,403 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
> +// Copyright(c) 2015-18 Intel Corporation.
> +
> +/*
> + * Bandwidth management algorithm based on 2^n gears
> + *
> + */
> +
> +#include <linux/device.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/slab.h>
> +#include <linux/soundwire/sdw.h>
> +#include "bus.h"
> +
> +#define SDW_STRM_RATE_GROUPING		1
> +
> +struct sdw_group_params {
> +	unsigned int rate;
> +	int full_bw;
> +	int payload_bw;
> +	int hwidth;
> +};
> +
> +struct sdw_group {
> +	unsigned int count;
> +	unsigned int max_size;
> +	unsigned int *rates;
> +};
> +
> +struct sdw_transport_data {
> +	int hstart;
> +	int hstop;
> +	int block_offset;
> +	int sub_block_offset;
> +};
> +
> +
> +/**
> + * sdw_compute_port_params: Compute transport and port parameters
> + *
> + * @bus: SDW Bus instance
> + */
> +static int sdw_compute_port_params(struct sdw_bus *bus)
> +{
> +	struct sdw_group_params *params = NULL;
> +	struct sdw_group group;
> +	int ret;
> +
> +	ret = sdw_get_group_count(bus, &group);
> +	if (ret < 0)
> +		goto out;
> +
> +	if (group.count == 0)
> +		goto out;
> +
> +	params = kcalloc(group.count, sizeof(*params), GFP_KERNEL);
> +	if (!params) {
> +		ret = -ENOMEM;
> +		goto out;
> +	}
> +
> +	/* Compute transport parameters for grouped streams */
> +	ret = sdw_compute_group_params(bus, params,
> +				       &group.rates[0], group.count);
> +	if (ret < 0)
> +		goto out;
> +
> +	_sdw_compute_port_params(bus, params, group.count);
> +
> +out:
> +	kfree(params);
> +	kfree(group.rates);
> +
> +	return ret;
> +}
> +
> +static int sdw_select_row_col(struct sdw_bus *bus, int clk_freq)
> +{
> +	struct sdw_master_prop *prop = &bus->prop;
> +	int frame_int, frame_freq;
> +	int r, c;
> +
> +	for (c = 0; c < SDW_FRAME_COLS; c++) {
> +		for (r = 0; r < SDW_FRAME_ROWS; r++) {
> +			if (sdw_rows[r] != prop->default_row ||
> +			    sdw_cols[c] != prop->default_col)
> +				continue;

Are we only supporting default rows and cols?

> +
> +			frame_int = sdw_rows[r] * sdw_cols[c];
> +			frame_freq = clk_freq / frame_int;
> +
> +			if ((clk_freq - (frame_freq * SDW_FRAME_CTRL_BITS)) <
> +			    bus->params.bandwidth)
> +				continue;
> +
> +			bus->params.row = sdw_rows[r];
> +			bus->params.col = sdw_cols[c];
> +			return 0;
> +		}
> +	}
> +
> +	return -EINVAL;
> +}
> +
> -- 
> 2.20.1
> 

-- 

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [RFC PATCH 28/40] soundwire: intel: handle disabled links
  2019-07-25 23:40 ` [RFC PATCH 28/40] soundwire: intel: handle disabled links Pierre-Louis Bossart
@ 2019-08-05 16:57   ` Sanyog Kale
  2019-08-05 19:18     ` [alsa-devel] " Pierre-Louis Bossart
  0 siblings, 1 reply; 183+ messages in thread
From: Sanyog Kale @ 2019-08-05 16:57 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak

On Thu, Jul 25, 2019 at 06:40:20PM -0500, Pierre-Louis Bossart wrote:
> On most hardware platforms, SoundWire interfaces are pin-muxed with
> other interfaces (typically DMIC or I2S) and the status of each link
> needs to be checked at boot time.
> 
> For Intel platforms, the BIOS provides a menu to enable/disable the
> links separately, and the information is provided to the OS with an
> Intel-specific _DSD property. The same capability will be added to
> revisions of the MIPI DisCo specification.
> 
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> ---
>  drivers/soundwire/intel.c     | 26 ++++++++++++++++++++++----
>  include/linux/soundwire/sdw.h |  2 ++
>  2 files changed, 24 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
> index 796ac2bc8cea..5947fa8e840b 100644
> --- a/drivers/soundwire/intel.c
> +++ b/drivers/soundwire/intel.c
> @@ -90,6 +90,8 @@
>  #define SDW_ALH_STRMZCFG_DMAT		GENMASK(7, 0)
>  #define SDW_ALH_STRMZCFG_CHN		GENMASK(19, 16)
>  
> +#define SDW_INTEL_QUIRK_MASK_BUS_DISABLE	BIT(1)
> +
>  enum intel_pdi_type {
>  	INTEL_PDI_IN = 0,
>  	INTEL_PDI_OUT = 1,
> @@ -922,7 +924,7 @@ static int sdw_master_read_intel_prop(struct sdw_bus *bus)
>  	struct sdw_master_prop *prop = &bus->prop;
>  	struct fwnode_handle *link;
>  	char name[32];
> -	int nval, i;
> +	u32 quirk_mask;
>  
>  	/* Find master handle */
>  	snprintf(name, sizeof(name),
> @@ -937,6 +939,14 @@ static int sdw_master_read_intel_prop(struct sdw_bus *bus)
>  	fwnode_property_read_u32(link,
>  				 "intel-sdw-ip-clock",
>  				 &prop->mclk_freq);
> +
> +	fwnode_property_read_u32(link,
> +				 "intel-quirk-mask",
> +				 &quirk_mask);
> +
> +	if (quirk_mask & SDW_INTEL_QUIRK_MASK_BUS_DISABLE)
> +		prop->hw_disabled = true;
> +
>  	return 0;
>  }
>  
> @@ -997,6 +1007,12 @@ static int intel_probe(struct platform_device *pdev)
>  		goto err_master_reg;
>  	}
>  
> +	if (sdw->cdns.bus.prop.hw_disabled) {
> +		dev_info(&pdev->dev, "SoundWire master %d is disabled, ignoring\n",
> +			 sdw->cdns.bus.link_id);
> +		return 0;
> +	}
> +
>  	/* Initialize shim and controller */
>  	intel_link_power_up(sdw);
>  	intel_shim_init(sdw);
> @@ -1050,9 +1066,11 @@ static int intel_remove(struct platform_device *pdev)
>  
>  	sdw = platform_get_drvdata(pdev);
>  
> -	intel_debugfs_exit(sdw);
> -	free_irq(sdw->res->irq, sdw);
> -	snd_soc_unregister_component(sdw->cdns.dev);
> +	if (!sdw->cdns.bus.prop.hw_disabled) {
> +		intel_debugfs_exit(sdw);
> +		free_irq(sdw->res->irq, sdw);
> +		snd_soc_unregister_component(sdw->cdns.dev);
> +	}
>  	sdw_delete_bus_master(&sdw->cdns.bus);
>  
>  	return 0;
> diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
> index c7dfc824be80..f78b076a8782 100644
> --- a/include/linux/soundwire/sdw.h
> +++ b/include/linux/soundwire/sdw.h
> @@ -380,6 +380,7 @@ struct sdw_slave_prop {
>   * @err_threshold: Number of times that software may retry sending a single
>   * command
>   * @mclk_freq: clock reference passed to SoundWire Master, in Hz.
> + * @hw_disabled: if true, the Master is not functional, typically due to pin-mux
>   */
>  struct sdw_master_prop {
>  	u32 revision;
> @@ -395,6 +396,7 @@ struct sdw_master_prop {
>  	bool dynamic_frame;
>  	u32 err_threshold;
>  	u32 mclk_freq;
> +	bool hw_disabled;

Do we have such cases where some of SoundWire links are disabled and
some enabled?

>  };
>  
>  int sdw_master_read_prop(struct sdw_bus *bus);
> -- 
> 2.20.1
> 

-- 

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 27/40] soundwire: Add Intel resource management algorithm
  2019-08-05 16:54   ` Sanyog Kale
@ 2019-08-05 19:08     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-08-05 19:08 UTC (permalink / raw)
  To: Sanyog Kale
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak


>> +static int sdw_select_row_col(struct sdw_bus *bus, int clk_freq)
>> +{
>> +	struct sdw_master_prop *prop = &bus->prop;
>> +	int frame_int, frame_freq;
>> +	int r, c;
>> +
>> +	for (c = 0; c < SDW_FRAME_COLS; c++) {
>> +		for (r = 0; r < SDW_FRAME_ROWS; r++) {
>> +			if (sdw_rows[r] != prop->default_row ||
>> +			    sdw_cols[c] != prop->default_col)
>> +				continue;
> 
> Are we only supporting default rows and cols?

for now yes. Note that the default is defined by firmware and e.g. 
different for ICL (50x4) and CML (125x2). The firmware itself also 
provides a single clock value so we'd need to override the DSDT or force 
the properties to be different to use multiple gears.

This will probably change at some point when we have multiple device per 
link. SoundWire 1.2 devices also provide a standard means to control the 
clock, otherwise with SoundWire 1.1 the clock management requires quite 
a bit of imp-def changes that we have not tested.

> 
>> +
>> +			frame_int = sdw_rows[r] * sdw_cols[c];
>> +			frame_freq = clk_freq / frame_int;
>> +
>> +			if ((clk_freq - (frame_freq * SDW_FRAME_CTRL_BITS)) <
>> +			    bus->params.bandwidth)
>> +				continue;
>> +
>> +			bus->params.row = sdw_rows[r];
>> +			bus->params.col = sdw_cols[c];
>> +			return 0;
>> +		}
>> +	}
>> +
>> +	return -EINVAL;
>> +}
>> +
>> -- 
>> 2.20.1
>>
> 

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 23/40] soundwire: stream: fix disable sequence
  2019-08-05 16:32       ` Sanyog Kale
@ 2019-08-05 19:12         ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-08-05 19:12 UTC (permalink / raw)
  To: Sanyog Kale
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak



On 8/5/19 11:32 AM, Sanyog Kale wrote:
> On Mon, Aug 05, 2019 at 10:33:25AM -0500, Pierre-Louis Bossart wrote:
>>
>>
>> On 8/5/19 4:56 AM, Sanyog Kale wrote:
>>> On Thu, Jul 25, 2019 at 06:40:15PM -0500, Pierre-Louis Bossart wrote:
>>>> When we disable the stream and then call hw_free, two bank switches
>>>> will be handled and as a result we re-enable the stream on hw_free.
>>>>
>>>
>>> I didnt quite get why there will be two bank switches as part of disable flow
>>> which leads to enabling of stream?
>>
>> You have two bank switches, one to stop streaming and on in de-prepare. It's
>> symmetrical with the start sequence, where we do a bank switch to prepare
>> and another to enable.
> 
> Got it. I misunderstood it that two bank switches are performed as part of
> disable_stream.
> 
>>
>> Let's assume we are using bank0 when streaming.
>>
>> Before the first bank switch, the channel_enable is set to false in the
>> alternate bank1. When the bank switch happens, bank1 become active and the
>> streaming stops. But bank0 registers have not been modified so when we do
>> the second bank switch in de-prepare we make bank0 active, and the ch_enable
>> bits are still set so streaming will restart... When we stop streaming, we
>> need to make sure the ch_enable bits are cleared in the two banks.
> 
> This is clear. Even though the channels remains enabled, i believe there
> won't be any data pushed on lines as stream will be closed.

Actually the link remains active. We tested this by setting the PRBS 
data mode and the Slave device detects when we artificially inject errors.

There is however no data consumption on the DMA side of the Master IP 
since the DMA is indeed stopped.

> 
> Regarding mirroring approach, I assume after bank switch we will take
> snapshot of active bank and program same in inactive bank.

That should be the approach yes.

> 
>>
>>
>>>
>>>> Make sure the stream is disabled on both banks.
>>>>
>>>> TODO: we need to completely revisit all this and make sure we have a
>>>> mirroring mechanism between current and alternate banks.
>>>>
>>>> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
>>>> ---
>>>>    drivers/soundwire/stream.c | 19 ++++++++++++++++++-
>>>>    1 file changed, 18 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c
>>>> index 53f5e790fcd7..75b9ad1fb1a6 100644
>>>> --- a/drivers/soundwire/stream.c
>>>> +++ b/drivers/soundwire/stream.c
>>>> @@ -1637,7 +1637,24 @@ static int _sdw_disable_stream(struct sdw_stream_runtime *stream)
>>>>    		}
>>>>    	}
>>>> -	return do_bank_switch(stream);
>>>> +	ret = do_bank_switch(stream);
>>>> +	if (ret < 0) {
>>>> +		dev_err(bus->dev, "Bank switch failed: %d\n", ret);
>>>> +		return ret;
>>>> +	}
>>>> +
>>>> +	/* make sure alternate bank (previous current) is also disabled */
>>>> +	list_for_each_entry(m_rt, &stream->master_list, stream_node) {
>>>> +		bus = m_rt->bus;
>>>> +		/* Disable port(s) */
>>>> +		ret = sdw_enable_disable_ports(m_rt, false);
>>>> +		if (ret < 0) {
>>>> +			dev_err(bus->dev, "Disable port(s) failed: %d\n", ret);
>>>> +			return ret;
>>>> +		}
>>>> +	}
>>>> +
>>>> +	return 0;
>>>>    }
>>>>    /**
>>>> -- 
>>>> 2.20.1
>>>>
>>>
> 

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 28/40] soundwire: intel: handle disabled links
  2019-08-05 16:57   ` Sanyog Kale
@ 2019-08-05 19:18     ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-08-05 19:18 UTC (permalink / raw)
  To: Sanyog Kale
  Cc: alsa-devel, linux-kernel, tiwai, broonie, vkoul, gregkh, jank,
	srinivas.kandagatla, slawomir.blauciak



On 8/5/19 11:57 AM, Sanyog Kale wrote:
> On Thu, Jul 25, 2019 at 06:40:20PM -0500, Pierre-Louis Bossart wrote:
>> On most hardware platforms, SoundWire interfaces are pin-muxed with
>> other interfaces (typically DMIC or I2S) and the status of each link
>> needs to be checked at boot time.
>>
>> For Intel platforms, the BIOS provides a menu to enable/disable the
>> links separately, and the information is provided to the OS with an
>> Intel-specific _DSD property. The same capability will be added to
>> revisions of the MIPI DisCo specification.

[snip]

>> diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
>> index c7dfc824be80..f78b076a8782 100644
>> --- a/include/linux/soundwire/sdw.h
>> +++ b/include/linux/soundwire/sdw.h
>> @@ -380,6 +380,7 @@ struct sdw_slave_prop {
>>    * @err_threshold: Number of times that software may retry sending a single
>>    * command
>>    * @mclk_freq: clock reference passed to SoundWire Master, in Hz.
>> + * @hw_disabled: if true, the Master is not functional, typically due to pin-mux
>>    */
>>   struct sdw_master_prop {
>>   	u32 revision;
>> @@ -395,6 +396,7 @@ struct sdw_master_prop {
>>   	bool dynamic_frame;
>>   	u32 err_threshold;
>>   	u32 mclk_freq;
>> +	bool hw_disabled;
> 
> Do we have such cases where some of SoundWire links are disabled and
> some enabled?

Yes, by default my ICL test board uses HDaudio for the codec so the 
SoundWire link0 is disabled. If I rework the board and change the BIOS 
advanced menu then SoundWire link0 is enabled. This information is 
dynamically provided to the OS after the _INI step.
SoundWire-2/3 are used typically for attached DMICs or for a combination 
of SoundWire amplifier and mic capture. It's really platform-specific.

> 
>>   };
>>   
>>   int sdw_master_read_prop(struct sdw_bus *bus);
>> -- 
>> 2.20.1
>>
> 

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 31/40] soundwire: intel: move shutdown() callback and don't export symbol
  2019-08-02 17:28       ` Vinod Koul
  2019-08-02 17:42         ` Pierre-Louis Bossart
@ 2019-08-14 19:31         ` Pierre-Louis Bossart
  2019-08-23  7:34           ` Vinod Koul
  1 sibling, 1 reply; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-08-14 19:31 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Cezary Rojewski, tiwai, gregkh, alsa-devel, linux-kernel,
	broonie, srinivas.kandagatla, jank, slawomir.blauciak,
	Sanyog Kale



>>>> +void intel_shutdown(struct snd_pcm_substream *substream,
>>>> +            struct snd_soc_dai *dai)
>>>> +{
>>>> +    struct sdw_cdns_dma_data *dma;
>>>> +
>>>> +    dma = snd_soc_dai_get_dma_data(dai, substream);
>>>> +    if (!dma)
>>>> +        return;
>>>> +
>>>> +    snd_soc_dai_set_dma_data(dai, substream, NULL);
>>>> +    kfree(dma);
>>>> +}
>>>
>>> Correct me if I'm wrong, but do we really need to _get_dma_ here?
>>> _set_dma_ seems bulletproof, same for kfree.
>>
>> I must admit I have no idea why we have a reference to DMAs here, this looks
>> like an abuse to store a dai-specific context, and the initial test looks
>> like copy-paste to detect invalid configs, as done in other callbacks. Vinod
>> and Sanyog might have more history than me here.
> 
> I dont see snd_soc_dai_set_dma_data() call for
> sdw_cdns_dma_data so somthing is missing (at least in upstream code)
> 
> IIRC we should have a snd_soc_dai_set_dma_data() in alloc or some
> initialization routine and we free it here.. Sanyog?

Vinod, I double-checked that we do not indeed have a call to 
snd_soc_dai_dma_data(), but there is code in cdns_set_stream() that sets 
the relevant dai->playback/capture_dma_data, see below

I am not a big fan of this code, touching the ASoC core internal fields 
isn't a good idea in general.

Also not sure why for a DAI we need both _drvdata and _dma_data 
(especially for this case where the information stored has absolutely 
nothing to do with DMAs).

If the idea was to keep a context that is direction-dependent, that's 
likely unnecessary. For the Intel/Cadence case the interfaces can be 
configured as playback OR capture, not both concurrently, so the "dma" 
information could have been stored in the generic DAI _drvdata.

I have other things to look into for now but this code will likely need 
to be cleaned-up at some point to remove unnecessary parts.

int cdns_set_sdw_stream(struct snd_soc_dai *dai,
			void *stream, bool pcm, int direction)
{
	struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
	struct sdw_cdns_dma_data *dma;

	dma = kzalloc(sizeof(*dma), GFP_KERNEL);
	if (!dma)
		return -ENOMEM;

	if (pcm)
		dma->stream_type = SDW_STREAM_PCM;
	else
		dma->stream_type = SDW_STREAM_PDM;

	dma->bus = &cdns->bus;
	dma->link_id = cdns->instance;

	dma->stream = stream;

 >>> this is equivalent to snd_soc_dai_dma_data()

	if (direction == SNDRV_PCM_STREAM_PLAYBACK)
		dai->playback_dma_data = dma;
	else
		dai->capture_dma_data = dma;
<<<<
	return 0;
}
EXPORT_SYMBOL(cdns_set_sdw_stream);

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 31/40] soundwire: intel: move shutdown() callback and don't export symbol
  2019-08-14 19:31         ` Pierre-Louis Bossart
@ 2019-08-23  7:34           ` Vinod Koul
  2019-08-23 15:57             ` Pierre-Louis Bossart
  0 siblings, 1 reply; 183+ messages in thread
From: Vinod Koul @ 2019-08-23  7:34 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: Cezary Rojewski, tiwai, gregkh, alsa-devel, linux-kernel,
	broonie, srinivas.kandagatla, jank, slawomir.blauciak,
	Sanyog Kale

On 14-08-19, 14:31, Pierre-Louis Bossart wrote:
> 
> 
> > > > > +void intel_shutdown(struct snd_pcm_substream *substream,
> > > > > +            struct snd_soc_dai *dai)
> > > > > +{
> > > > > +    struct sdw_cdns_dma_data *dma;
> > > > > +
> > > > > +    dma = snd_soc_dai_get_dma_data(dai, substream);
> > > > > +    if (!dma)
> > > > > +        return;
> > > > > +
> > > > > +    snd_soc_dai_set_dma_data(dai, substream, NULL);
> > > > > +    kfree(dma);
> > > > > +}
> > > > 
> > > > Correct me if I'm wrong, but do we really need to _get_dma_ here?
> > > > _set_dma_ seems bulletproof, same for kfree.
> > > 
> > > I must admit I have no idea why we have a reference to DMAs here, this looks
> > > like an abuse to store a dai-specific context, and the initial test looks
> > > like copy-paste to detect invalid configs, as done in other callbacks. Vinod
> > > and Sanyog might have more history than me here.
> > 
> > I dont see snd_soc_dai_set_dma_data() call for
> > sdw_cdns_dma_data so somthing is missing (at least in upstream code)
> > 
> > IIRC we should have a snd_soc_dai_set_dma_data() in alloc or some
> > initialization routine and we free it here.. Sanyog?
> 
> Vinod, I double-checked that we do not indeed have a call to
> snd_soc_dai_dma_data(), but there is code in cdns_set_stream() that sets the
> relevant dai->playback/capture_dma_data, see below
> 
> I am not a big fan of this code, touching the ASoC core internal fields
> isn't a good idea in general.

IIRC as long as you stick to single link I do not see this required. The
question comes into picture when we have multi links as you would need
to allocate a soundwire stream and set that for all the sdw DAIs

So, what is the current model of soundwire stream, which entity allocates
that and do you still care about multi-link? is there any machine driver
with soundwire upstream yet?

> Also not sure why for a DAI we need both _drvdata and _dma_data (especially

_drvdata is global for driver whereas _dma_data is typically used per
DAI

> for this case where the information stored has absolutely nothing to do with
> DMAs).
> 
> If the idea was to keep a context that is direction-dependent, that's likely
> unnecessary. For the Intel/Cadence case the interfaces can be configured as
> playback OR capture, not both concurrently, so the "dma" information could
> have been stored in the generic DAI _drvdata.
> 
> I have other things to look into for now but this code will likely need to
> be cleaned-up at some point to remove unnecessary parts.

Sure please go ahead and do the cleanup.
> 
> int cdns_set_sdw_stream(struct snd_soc_dai *dai,
> 			void *stream, bool pcm, int direction)
> {
> 	struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
> 	struct sdw_cdns_dma_data *dma;
> 
> 	dma = kzalloc(sizeof(*dma), GFP_KERNEL);
> 	if (!dma)
> 		return -ENOMEM;
> 
> 	if (pcm)
> 		dma->stream_type = SDW_STREAM_PCM;
> 	else
> 		dma->stream_type = SDW_STREAM_PDM;
> 
> 	dma->bus = &cdns->bus;
> 	dma->link_id = cdns->instance;
> 
> 	dma->stream = stream;
> 
> >>> this is equivalent to snd_soc_dai_dma_data()
> 
> 	if (direction == SNDRV_PCM_STREAM_PLAYBACK)
> 		dai->playback_dma_data = dma;
> 	else
> 		dai->capture_dma_data = dma;
> <<<<
> 	return 0;
> }
> EXPORT_SYMBOL(cdns_set_sdw_stream);

-- 
~Vinod

^ permalink raw reply	[flat|nested] 183+ messages in thread

* Re: [alsa-devel] [RFC PATCH 31/40] soundwire: intel: move shutdown() callback and don't export symbol
  2019-08-23  7:34           ` Vinod Koul
@ 2019-08-23 15:57             ` Pierre-Louis Bossart
  0 siblings, 0 replies; 183+ messages in thread
From: Pierre-Louis Bossart @ 2019-08-23 15:57 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Cezary Rojewski, tiwai, gregkh, alsa-devel, linux-kernel,
	broonie, srinivas.kandagatla, jank, slawomir.blauciak,
	Sanyog Kale



>>>>>> +void intel_shutdown(struct snd_pcm_substream *substream,
>>>>>> +            struct snd_soc_dai *dai)
>>>>>> +{
>>>>>> +    struct sdw_cdns_dma_data *dma;
>>>>>> +
>>>>>> +    dma = snd_soc_dai_get_dma_data(dai, substream);
>>>>>> +    if (!dma)
>>>>>> +        return;
>>>>>> +
>>>>>> +    snd_soc_dai_set_dma_data(dai, substream, NULL);
>>>>>> +    kfree(dma);
>>>>>> +}
>>>>>
>>>>> Correct me if I'm wrong, but do we really need to _get_dma_ here?
>>>>> _set_dma_ seems bulletproof, same for kfree.
>>>>
>>>> I must admit I have no idea why we have a reference to DMAs here, this looks
>>>> like an abuse to store a dai-specific context, and the initial test looks
>>>> like copy-paste to detect invalid configs, as done in other callbacks. Vinod
>>>> and Sanyog might have more history than me here.
>>>
>>> I dont see snd_soc_dai_set_dma_data() call for
>>> sdw_cdns_dma_data so somthing is missing (at least in upstream code)
>>>
>>> IIRC we should have a snd_soc_dai_set_dma_data() in alloc or some
>>> initialization routine and we free it here.. Sanyog?
>>
>> Vinod, I double-checked that we do not indeed have a call to
>> snd_soc_dai_dma_data(), but there is code in cdns_set_stream() that sets the
>> relevant dai->playback/capture_dma_data, see below
>>
>> I am not a big fan of this code, touching the ASoC core internal fields
>> isn't a good idea in general.
> 
> IIRC as long as you stick to single link I do not see this required. The
> question comes into picture when we have multi links as you would need
> to allocate a soundwire stream and set that for all the sdw DAIs
> 
> So, what is the current model of soundwire stream, which entity allocates
> that and do you still care about multi-link? is there any machine driver
> with soundwire upstream yet?

yes, multi-link is definitively required and one of the main appeals of 
SoundWire. We have a platform with 2 amplifiers on separate links and 
they need to be synchronized and handled with the stream concept.

The tentative plan would be to move the stream allocation to the dailink 
.init (or equivalent), and make sure each DAI in that link used the same 
stream information. There are dependencies on the multi-cpu concept that 
Morimoto-san wanted to push, so we'll likely be the first users.

For the DAI trigger, we will need to change the existing API so that a 
sdw_stream_enable() can be called multiple times, but only takes effect 
when the .trigger of the first DAI in the stream is invoked. This is a 
similar behavior than with HDaudio .trigger operations when the SYNC 
bits are used.

We will do this when we have a first pass working with all codec drivers 
upstream and a basic machine driver upstream with all 4 links working 
independently.

Everything is done in public btw, you can track our WIP solutions here:

https://github.com/thesofproject/linux/pull/1140
https://github.com/thesofproject/linux/pull/1141
https://github.com/thesofproject/linux/pull/1142


^ permalink raw reply	[flat|nested] 183+ messages in thread

end of thread, other threads:[~2019-08-23 15:57 UTC | newest]

Thread overview: 183+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-25 23:39 [RFC PATCH 00/40] soundwire: updates for 5.4 Pierre-Louis Bossart
2019-07-25 23:39 ` [RFC PATCH 01/40] soundwire: add debugfs support Pierre-Louis Bossart
2019-07-25 22:15   ` [alsa-devel] " Guennadi Liakhovetski
2019-07-26 13:43     ` Pierre-Louis Bossart
2019-07-26  9:22   ` Cezary Rojewski
2019-07-26 13:57     ` [alsa-devel] " Pierre-Louis Bossart
2019-07-26 14:04   ` Greg KH
2019-07-26 15:29     ` Pierre-Louis Bossart
2019-07-25 23:39 ` [RFC PATCH 02/40] soundwire: cadence_master: add debugfs register dump Pierre-Louis Bossart
2019-07-26 14:09   ` Greg KH
2019-07-26 15:32     ` Pierre-Louis Bossart
2019-08-05  7:55   ` Sanyog Kale
2019-08-05 15:20     ` [alsa-devel] " Pierre-Louis Bossart
2019-07-25 23:39 ` [RFC PATCH 03/40] soundwire: cadence_master: align debugfs to 8 digits Pierre-Louis Bossart
2019-07-26  9:38   ` Cezary Rojewski
2019-07-26 13:58     ` [alsa-devel] " Pierre-Louis Bossart
2019-08-02 11:50   ` Vinod Koul
2019-07-25 23:39 ` [RFC PATCH 04/40] soundwire: intel: add debugfs register dump Pierre-Louis Bossart
2019-07-26  9:35   ` Cezary Rojewski
2019-07-26 14:00     ` [alsa-devel] " Pierre-Louis Bossart
2019-07-26 14:11       ` Greg KH
2019-07-26 14:06   ` Greg KH
2019-07-26 14:09     ` Greg KH
2019-07-26 15:34     ` Pierre-Louis Bossart
2019-07-25 23:39 ` [RFC PATCH 05/40] soundwire: intel: move interrupt enable after interrupt handler registration Pierre-Louis Bossart
2019-08-02 11:53   ` Vinod Koul
2019-08-02 15:08     ` Pierre-Louis Bossart
2019-07-25 23:39 ` [RFC PATCH 06/40] soundwire: intel: prevent possible dereference in hw_params Pierre-Louis Bossart
2019-07-26  9:45   ` Cezary Rojewski
2019-07-26 14:02     ` [alsa-devel] " Pierre-Louis Bossart
2019-08-02 11:55   ` Vinod Koul
2019-08-02 15:16     ` [alsa-devel] " Pierre-Louis Bossart
2019-08-02 15:57       ` Vinod Koul
2019-08-02 16:52         ` Pierre-Louis Bossart
2019-08-02 17:37           ` Vinod Koul
2019-07-25 23:39 ` [RFC PATCH 07/40] soundwire: intel: fix channel number reported by hardware Pierre-Louis Bossart
2019-08-02 11:57   ` Vinod Koul
2019-08-02 15:18     ` Pierre-Louis Bossart
2019-07-25 23:40 ` [RFC PATCH 08/40] soundwire: intel: remove BIOS work-arounds Pierre-Louis Bossart
2019-08-02 11:58   ` Vinod Koul
2019-07-25 23:40 ` [RFC PATCH 09/40] soundwire: cadence_master: fix usage of CONFIG_UPDATE Pierre-Louis Bossart
2019-07-25 22:23   ` [alsa-devel] " Guennadi Liakhovetski
2019-07-26 14:05     ` Pierre-Louis Bossart
2019-07-26  2:11   ` Bard liao
2019-07-26 13:33     ` Pierre-Louis Bossart
2019-07-26  9:53   ` Cezary Rojewski
2019-07-26  9:54     ` Cezary Rojewski
2019-08-02 12:03   ` Vinod Koul
2019-08-02 15:18     ` Pierre-Louis Bossart
2019-08-05  8:51   ` Sanyog Kale
2019-07-25 23:40 ` [RFC PATCH 10/40] soundwire: cadence_master: remove useless wrapper Pierre-Louis Bossart
2019-07-25 23:40 ` [RFC PATCH 11/40] soundwire: cadence_master: simplify bus clash interrupt clear Pierre-Louis Bossart
2019-08-02 12:07   ` Vinod Koul
2019-07-25 23:40 ` [RFC PATCH 12/40] soundwire: cadence_master: revisit interrupt settings Pierre-Louis Bossart
2019-08-02 12:10   ` Vinod Koul
2019-08-02 15:23     ` Pierre-Louis Bossart
2019-07-25 23:40 ` [RFC PATCH 13/40] soundwire: cadence_master: fix register definition for SLAVE_STATE Pierre-Louis Bossart
2019-08-02 12:12   ` Vinod Koul
2019-07-25 23:40 ` [RFC PATCH 14/40] soundwire: cadence_master: fix definitions for INTSTAT0/1 Pierre-Louis Bossart
2019-08-02 12:13   ` Vinod Koul
2019-07-25 23:40 ` [RFC PATCH 15/40] soundwire: cadence_master: handle multiple status reports per Slave Pierre-Louis Bossart
2019-07-25 22:31   ` [alsa-devel] " Guennadi Liakhovetski
2019-07-26 14:09     ` Pierre-Louis Bossart
2019-08-02 12:20   ` Vinod Koul
2019-08-02 15:29     ` Pierre-Louis Bossart
2019-08-02 16:01       ` Vinod Koul
2019-08-02 16:41         ` Pierre-Louis Bossart
2019-07-25 23:40 ` [RFC PATCH 16/40] soundwire: cadence_master: improve startup sequence with link hw_reset Pierre-Louis Bossart
2019-07-26  7:22   ` [alsa-devel] " Guennadi Liakhovetski
2019-07-26 14:11     ` Pierre-Louis Bossart
2019-07-25 23:40 ` [RFC PATCH 17/40] soundwire: bus: use runtime_pm_get_sync/pm when enabled Pierre-Louis Bossart
2019-07-26  7:39   ` [alsa-devel] " Guennadi Liakhovetski
2019-07-26  7:47     ` Jan Kotas
2019-07-26  8:22       ` Guennadi Liakhovetski
2019-07-26  8:33         ` Jan Kotas
2019-07-26  8:42           ` Guennadi Liakhovetski
2019-07-26 18:08   ` Pierre-Louis Bossart
2019-07-26 18:25     ` [alsa-devel] " Guennadi Liakhovetski
2019-07-26 19:11       ` Andy Shevchenko
2019-07-26 19:08     ` Andy Shevchenko
2019-07-29 22:07       ` [alsa-devel] " Pierre-Louis Bossart
2019-07-30 11:21         ` Andy Shevchenko
2019-07-30 12:57           ` Pierre-Louis Bossart
2019-07-30 15:58             ` Andy Shevchenko
2019-07-30 15:59               ` Andy Shevchenko
2019-08-02 16:58   ` Vinod Koul
2019-08-02 17:20     ` Pierre-Louis Bossart
2019-07-25 23:40 ` [RFC PATCH 18/40] soundwire: bus: split handling of Device0 events Pierre-Louis Bossart
2019-08-02 16:59   ` Vinod Koul
2019-07-25 23:40 ` [RFC PATCH 19/40] soundwire: bus: improve dynamic debug comments for enumeration Pierre-Louis Bossart
2019-08-02 17:00   ` Vinod Koul
2019-08-02 17:20     ` Pierre-Louis Bossart
2019-07-25 23:40 ` [RFC PATCH 20/40] soundwire: prototypes for suspend/resume Pierre-Louis Bossart
2019-07-26 10:04   ` Cezary Rojewski
2019-07-26 14:15     ` [alsa-devel] " Pierre-Louis Bossart
2019-08-02 17:03   ` Vinod Koul
2019-08-02 17:21     ` Pierre-Louis Bossart
2019-07-25 23:40 ` [RFC PATCH 21/40] soundwire: export helpers to find row and column values Pierre-Louis Bossart
2019-07-26 14:43   ` [alsa-devel] " Guennadi Liakhovetski
2019-07-26 15:26     ` Pierre-Louis Bossart
2019-08-02 17:04       ` Vinod Koul
2019-08-05  9:39   ` Sanyog Kale
2019-08-05 15:27     ` [alsa-devel] " Pierre-Louis Bossart
2019-07-25 23:40 ` [RFC PATCH 22/40] soundwire: include mod_devicetable.h to avoid compiling warnings Pierre-Louis Bossart
2019-07-25 23:40 ` [RFC PATCH 23/40] soundwire: stream: fix disable sequence Pierre-Louis Bossart
2019-07-26 10:14   ` Cezary Rojewski
2019-07-26 14:17     ` [alsa-devel] " Pierre-Louis Bossart
2019-07-26 14:51   ` Guennadi Liakhovetski
2019-07-26 15:05     ` Pierre-Louis Bossart
2019-08-05  9:56   ` Sanyog Kale
2019-08-05 15:33     ` [alsa-devel] " Pierre-Louis Bossart
2019-08-05 16:32       ` Sanyog Kale
2019-08-05 19:12         ` Pierre-Louis Bossart
2019-07-25 23:40 ` [RFC PATCH 24/40] soundwire: cadence_master: use BIOS defaults for frame shape Pierre-Louis Bossart
2019-07-26 10:20   ` Cezary Rojewski
2019-07-26 14:22     ` [alsa-devel] " Pierre-Louis Bossart
2019-08-02 17:10   ` Vinod Koul
2019-08-02 17:24     ` Pierre-Louis Bossart
2019-08-05 10:01   ` Sanyog Kale
2019-07-25 23:40 ` [RFC PATCH 25/40] soundwire: intel: use BIOS information to set clock dividers Pierre-Louis Bossart
2019-08-02 17:17   ` Vinod Koul
2019-08-02 17:29     ` Pierre-Louis Bossart
2019-08-05 10:28   ` Sanyog Kale
2019-08-05 15:40     ` [alsa-devel] " Pierre-Louis Bossart
2019-07-25 23:40 ` [RFC PATCH 26/40] soundwire: cadence_master: fix divider setting in clock register Pierre-Louis Bossart
2019-07-26  5:19   ` [alsa-devel] " Bard liao
2019-07-26  5:56     ` rander.wang
2019-07-26 14:24     ` Pierre-Louis Bossart
2019-08-02 17:19   ` Vinod Koul
2019-08-02 17:30     ` Pierre-Louis Bossart
2019-08-05 10:40   ` Sanyog Kale
2019-08-05 15:41     ` [alsa-devel] " Pierre-Louis Bossart
2019-07-25 23:40 ` [RFC PATCH 27/40] soundwire: Add Intel resource management algorithm Pierre-Louis Bossart
2019-07-26 11:07   ` Cezary Rojewski
2019-07-26 14:41     ` [alsa-devel] " Pierre-Louis Bossart
2019-07-26 15:43   ` Guennadi Liakhovetski
2019-07-26 17:55     ` Pierre-Louis Bossart
2019-08-05 16:54   ` Sanyog Kale
2019-08-05 19:08     ` [alsa-devel] " Pierre-Louis Bossart
2019-07-25 23:40 ` [RFC PATCH 28/40] soundwire: intel: handle disabled links Pierre-Louis Bossart
2019-08-05 16:57   ` Sanyog Kale
2019-08-05 19:18     ` [alsa-devel] " Pierre-Louis Bossart
2019-07-25 23:40 ` [RFC PATCH 29/40] soundwire: intel_init: add kernel module parameter to filter out links Pierre-Louis Bossart
2019-07-26 10:30   ` Cezary Rojewski
2019-07-26 14:43     ` [alsa-devel] " Pierre-Louis Bossart
2019-07-25 23:40 ` [RFC PATCH 30/40] soundwire: cadence_master: add kernel parameter to override interrupt mask Pierre-Louis Bossart
2019-07-25 23:40 ` [RFC PATCH 31/40] soundwire: intel: move shutdown() callback and don't export symbol Pierre-Louis Bossart
2019-07-26 10:38   ` Cezary Rojewski
2019-07-26 14:46     ` [alsa-devel] " Pierre-Louis Bossart
2019-08-02 17:28       ` Vinod Koul
2019-08-02 17:42         ` Pierre-Louis Bossart
2019-08-14 19:31         ` Pierre-Louis Bossart
2019-08-23  7:34           ` Vinod Koul
2019-08-23 15:57             ` Pierre-Louis Bossart
2019-07-25 23:40 ` [RFC PATCH 32/40] soundwire: intel: add helper for initialization Pierre-Louis Bossart
2019-07-26 10:42   ` Cezary Rojewski
2019-07-26 14:55     ` [alsa-devel] " Pierre-Louis Bossart
2019-07-25 23:40 ` [RFC PATCH 33/40] soundwire: intel: Add basic power management support Pierre-Louis Bossart
2019-07-26 10:50   ` Cezary Rojewski
2019-07-26 14:57     ` [alsa-devel] " Pierre-Louis Bossart
2019-07-25 23:40 ` [RFC PATCH 34/40] soundwire: intel: ignore disabled links for suspend/resume Pierre-Louis Bossart
2019-08-02 17:30   ` Vinod Koul
2019-08-02 17:44     ` Pierre-Louis Bossart
2019-07-25 23:40 ` [RFC PATCH 35/40] soundwire: intel: export helper to exit reset Pierre-Louis Bossart
2019-07-26 15:52   ` [alsa-devel] " Guennadi Liakhovetski
2019-07-26 17:22     ` Pierre-Louis Bossart
2019-08-02 17:31   ` Vinod Koul
2019-08-02 17:44     ` Pierre-Louis Bossart
2019-07-25 23:40 ` [RFC PATCH 36/40] soundwire: intel: disable interrupts on suspend Pierre-Louis Bossart
2019-07-26 15:55   ` [alsa-devel] " Guennadi Liakhovetski
2019-07-26 17:26     ` Pierre-Louis Bossart
2019-07-25 23:40 ` [RFC PATCH 37/40] soundwire: cadence_master: add hw_reset capability in debugfs Pierre-Louis Bossart
2019-07-26 14:07   ` Greg KH
2019-07-26 15:01     ` [alsa-devel] " Pierre-Louis Bossart
2019-07-26 15:57   ` Guennadi Liakhovetski
2019-07-26 17:31     ` Pierre-Louis Bossart
2019-07-25 23:40 ` [RFC PATCH 38/40] soundwire: cadence_master: make clock stop exit configurable on init Pierre-Louis Bossart
2019-07-26 16:02   ` [alsa-devel] " Guennadi Liakhovetski
2019-07-26 17:35     ` Pierre-Louis Bossart
2019-07-25 23:40 ` [RFC PATCH 39/40] soundwire: intel: add pm_runtime support Pierre-Louis Bossart
2019-07-25 23:40 ` [RFC PATCH 40/40] soundwire: intel: add delay on restart for enumeration Pierre-Louis Bossart
2019-07-26 11:14 ` [RFC PATCH 00/40] soundwire: updates for 5.4 Cezary Rojewski
2019-07-26 15:23   ` [alsa-devel] " Pierre-Louis Bossart

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).