Commit 65bec0c4 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull soundwire updates from Vinod Koul:

 - Core: DP prepare polling for avoiding interrupt deadlock

 - AMD clock init and bandwidth refactoring

 - Intel more codecs to wake list, clear message on before signaling
   waiting thread

* tag 'soundwire-7.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire:
  soundwire: intel_auxdevice: Add cs42l49 to wake_capable_list
  soundwire: cadence: Clear message complete before signaling waiting thread
  soundwire: Intel: test bus.bpt_stream before assigning it
  soundwire: bus: demote UNATTACHED state warnings to dev_dbg()
  soundwire: stream: Poll for DP prepare to avoid interrupt deadlock
  soundwire: amd: refactor bandwidth calculation logic
  soundwire: amd: add clock init control function
  soundwire: intel_auxdevice: Add CS47L47 to wake_capable_list
  soundwire: slave: Don't register devices that are disabled in ACPI
  soundwire: sdw.h: repair names and format of kernel-doc comments
parents 0b6bc3db b8f2d65f
Loading
Loading
Loading
Loading
+89 −11
Original line number Diff line number Diff line
@@ -27,6 +27,36 @@

#define to_amd_sdw(b)	container_of(b, struct amd_sdw_manager, bus)

static int amd_sdw_clk_init_ctrl(struct amd_sdw_manager *amd_manager)
{
	struct sdw_bus *bus = &amd_manager->bus;
	struct sdw_master_prop *prop = &bus->prop;
	u32 divider;

	dev_dbg(amd_manager->dev, "mclk %d max %d row %d col %d frame_rate:%d\n",
		prop->mclk_freq, prop->max_clk_freq, prop->default_row,
		prop->default_col, prop->default_frame_rate);

	if (!prop->default_frame_rate || !prop->default_row) {
		dev_err(amd_manager->dev, "Default frame_rate %d or row %d is invalid\n",
			prop->default_frame_rate, prop->default_row);
		return -EINVAL;
	}

	/* Set clock divider */
	divider = (prop->mclk_freq / bus->params.curr_dr_freq);
	writel(divider, amd_manager->mmio + ACP_SW_CLK_FREQUENCY_CTRL);

	/* Set frame shape base on the actual bus frequency. */
	prop->default_col = bus->params.curr_dr_freq /
			    prop->default_frame_rate / prop->default_row;
	amd_manager->cols_index = sdw_find_col_index(prop->default_col);
	amd_manager->rows_index = sdw_find_row_index(prop->default_row);
	bus->params.col = prop->default_col;
	bus->params.row = prop->default_row;
	return 0;
}

static int amd_init_sdw_manager(struct amd_sdw_manager *amd_manager)
{
	u32 val;
@@ -437,12 +467,16 @@ static u32 amd_sdw_read_ping_status(struct sdw_bus *bus)

static int amd_sdw_compute_params(struct sdw_bus *bus, struct sdw_stream_runtime *stream)
{
	struct amd_sdw_manager *amd_manager = to_amd_sdw(bus);
	struct sdw_transport_data t_data = {0};
	struct sdw_master_runtime *m_rt;
	struct sdw_port_runtime *p_rt;
	struct sdw_bus_params *b_params = &bus->params;
	int port_bo, hstart, hstop, sample_int;
	unsigned int rate, bps;
	unsigned int rate, bps, channels;
	unsigned int stream_slot_size, max_slots;
	static unsigned int next_offset[AMD_SDW_MAX_MANAGER_COUNT] = {1};
	unsigned int inst_id = amd_manager->instance;

	port_bo = 0;
	hstart = 1;
@@ -453,11 +487,51 @@ static int amd_sdw_compute_params(struct sdw_bus *bus, struct sdw_stream_runtime
	list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
		rate = m_rt->stream->params.rate;
		bps = m_rt->stream->params.bps;
		channels = m_rt->stream->params.ch_count;
		sample_int = (bus->params.curr_dr_freq / rate);

		/* Compute slots required for this stream dynamically */
		stream_slot_size = bps * channels;

		list_for_each_entry(p_rt, &m_rt->port_list, port_node) {
			port_bo = (p_rt->num * 64) + 1;
			dev_dbg(bus->dev, "p_rt->num=%d hstart=%d hstop=%d port_bo=%d\n",
				p_rt->num, hstart, hstop, port_bo);
			if (p_rt->num >= amd_manager->max_ports) {
				dev_err(bus->dev, "Port %d exceeds max ports %d\n",
					p_rt->num, amd_manager->max_ports);
				return -EINVAL;
			}

			if (!amd_manager->port_offset_map[p_rt->num]) {
				/*
				 * port block offset calculation for 6MHz bus clock frequency with
				 * different frame sizes 50 x 10 and 125 x 2
				 */
				if (bus->params.curr_dr_freq == 12000000) {
					max_slots = bus->params.row * (bus->params.col - 1);
					if (next_offset[inst_id] + stream_slot_size <=
					    (max_slots - 1)) {
						amd_manager->port_offset_map[p_rt->num] =
									next_offset[inst_id];
						next_offset[inst_id] += stream_slot_size;
					} else {
						dev_err(bus->dev,
							"No space for port %d\n", p_rt->num);
						return -ENOMEM;
					}
				} else {
					 /*
					  * port block offset calculation for 12MHz bus clock
					  * frequency
					  */
					amd_manager->port_offset_map[p_rt->num] =
									(p_rt->num * 64) + 1;
				}
			}
			port_bo = amd_manager->port_offset_map[p_rt->num];
			dev_dbg(bus->dev,
				"Port=%d hstart=%d hstop=%d port_bo=%d slots=%d max_ports=%d\n",
				p_rt->num, hstart, hstop, port_bo, stream_slot_size,
				amd_manager->max_ports);

			sdw_fill_xport_params(&p_rt->transport_params, p_rt->num,
					      false, SDW_BLK_GRP_CNT_1, sample_int,
					      port_bo, port_bo >> 8, hstart, hstop,
@@ -960,6 +1034,9 @@ int amd_sdw_manager_start(struct amd_sdw_manager *amd_manager)

	prop = &amd_manager->bus.prop;
	if (!prop->hw_disabled) {
		ret = amd_sdw_clk_init_ctrl(amd_manager);
		if (ret)
			return ret;
		ret = amd_init_sdw_manager(amd_manager);
		if (ret)
			return ret;
@@ -984,7 +1061,6 @@ static int amd_sdw_manager_probe(struct platform_device *pdev)
	struct resource *res;
	struct device *dev = &pdev->dev;
	struct sdw_master_prop *prop;
	struct sdw_bus_params *params;
	struct amd_sdw_manager *amd_manager;
	int ret;

@@ -1047,15 +1123,14 @@ static int amd_sdw_manager_probe(struct platform_device *pdev)
	default:
		return -EINVAL;
	}
	amd_manager->max_ports = amd_manager->num_dout_ports + amd_manager->num_din_ports;
	amd_manager->port_offset_map = devm_kcalloc(dev, amd_manager->max_ports,
						    sizeof(int), GFP_KERNEL);
	if (!amd_manager->port_offset_map)
		return -ENOMEM;

	params = &amd_manager->bus.params;

	params->col = AMD_SDW_DEFAULT_COLUMNS;
	params->row = AMD_SDW_DEFAULT_ROWS;
	prop = &amd_manager->bus.prop;
	prop->clk_freq = &amd_sdw_freq_tbl[0];
	prop->mclk_freq = AMD_SDW_BUS_BASE_FREQ;
	prop->max_clk_freq = AMD_SDW_DEFAULT_CLK_FREQ;

	ret = sdw_bus_master_add(&amd_manager->bus, dev, dev->fwnode);
	if (ret) {
@@ -1347,6 +1422,9 @@ static int __maybe_unused amd_resume_runtime(struct device *dev)
			}
		}
		sdw_clear_slave_status(bus, SDW_UNATTACH_REQUEST_MASTER_RESET);
		ret = amd_sdw_clk_init_ctrl(amd_manager);
		if (ret)
			return ret;
		amd_init_sdw_manager(amd_manager);
		amd_enable_sdw_interrupts(amd_manager);
		ret = amd_enable_sdw_manager(amd_manager);
+0 −4
Original line number Diff line number Diff line
@@ -203,10 +203,6 @@
#define AMD_SDW_DEVICE_STATE_D3				3
#define ACP_PME_EN					0x0001400

static u32 amd_sdw_freq_tbl[AMD_SDW_MAX_FREQ_NUM] = {
	AMD_SDW_DEFAULT_CLK_FREQ,
};

struct sdw_manager_dp_reg {
	u32 frame_fmt_reg;
	u32 sample_int_reg;
+4 −4
Original line number Diff line number Diff line
@@ -1899,7 +1899,7 @@ int sdw_handle_slave_status(struct sdw_bus *bus,

		if (status[i] == SDW_SLAVE_UNATTACHED &&
		    slave->status != SDW_SLAVE_UNATTACHED) {
			dev_warn(&slave->dev, "Slave %d state check1: UNATTACHED, status was %d\n",
			dev_dbg(&slave->dev, "Slave %d state check1: UNATTACHED, status was %d\n",
			i, slave->status);
			sdw_modify_slave_status(slave, SDW_SLAVE_UNATTACHED);

@@ -1951,7 +1951,7 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
			if (slave->status == SDW_SLAVE_UNATTACHED)
				break;

			dev_warn(&slave->dev, "Slave %d state check2: UNATTACHED, status was %d\n",
			dev_dbg(&slave->dev, "Slave %d state check2: UNATTACHED, status was %d\n",
			i, slave->status);

			sdw_modify_slave_status(slave, SDW_SLAVE_UNATTACHED);
+8 −0
Original line number Diff line number Diff line
@@ -933,6 +933,14 @@ irqreturn_t sdw_cdns_irq(int irq, void *dev_id)

		cdns_read_response(cdns);

		/*
		 * Clear interrupt before signalling the completion to avoid
		 * a race between this thread and the main thread starting
		 * another TX.
		 */
		cdns_writel(cdns, CDNS_MCP_INTSTAT, CDNS_MCP_INT_RX_WL);
		int_status &= ~CDNS_MCP_INT_RX_WL;

		if (defer && defer->msg) {
			cdns_fill_msg_resp(cdns, defer->msg,
					   defer->length, 0);
+5 −0
Original line number Diff line number Diff line
@@ -82,6 +82,11 @@ static int intel_ace2x_bpt_open_stream(struct sdw_intel *sdw, struct sdw_slave *
	int len;
	int i;

	if (cdns->bus.bpt_stream) {
		dev_err(cdns->dev, "%s: BPT stream already exists\n", __func__);
		return -EAGAIN;
	}

	stream = sdw_alloc_stream("BPT", SDW_STREAM_BPT);
	if (!stream)
		return -ENOMEM;
Loading