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

Configure Feed

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

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

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

+138 -36
+89 -11
drivers/soundwire/amd_manager.c
··· 27 27 28 28 #define to_amd_sdw(b) container_of(b, struct amd_sdw_manager, bus) 29 29 30 + static int amd_sdw_clk_init_ctrl(struct amd_sdw_manager *amd_manager) 31 + { 32 + struct sdw_bus *bus = &amd_manager->bus; 33 + struct sdw_master_prop *prop = &bus->prop; 34 + u32 divider; 35 + 36 + dev_dbg(amd_manager->dev, "mclk %d max %d row %d col %d frame_rate:%d\n", 37 + prop->mclk_freq, prop->max_clk_freq, prop->default_row, 38 + prop->default_col, prop->default_frame_rate); 39 + 40 + if (!prop->default_frame_rate || !prop->default_row) { 41 + dev_err(amd_manager->dev, "Default frame_rate %d or row %d is invalid\n", 42 + prop->default_frame_rate, prop->default_row); 43 + return -EINVAL; 44 + } 45 + 46 + /* Set clock divider */ 47 + divider = (prop->mclk_freq / bus->params.curr_dr_freq); 48 + writel(divider, amd_manager->mmio + ACP_SW_CLK_FREQUENCY_CTRL); 49 + 50 + /* Set frame shape base on the actual bus frequency. */ 51 + prop->default_col = bus->params.curr_dr_freq / 52 + prop->default_frame_rate / prop->default_row; 53 + amd_manager->cols_index = sdw_find_col_index(prop->default_col); 54 + amd_manager->rows_index = sdw_find_row_index(prop->default_row); 55 + bus->params.col = prop->default_col; 56 + bus->params.row = prop->default_row; 57 + return 0; 58 + } 59 + 30 60 static int amd_init_sdw_manager(struct amd_sdw_manager *amd_manager) 31 61 { 32 62 u32 val; ··· 467 437 468 438 static int amd_sdw_compute_params(struct sdw_bus *bus, struct sdw_stream_runtime *stream) 469 439 { 440 + struct amd_sdw_manager *amd_manager = to_amd_sdw(bus); 470 441 struct sdw_transport_data t_data = {0}; 471 442 struct sdw_master_runtime *m_rt; 472 443 struct sdw_port_runtime *p_rt; 473 444 struct sdw_bus_params *b_params = &bus->params; 474 445 int port_bo, hstart, hstop, sample_int; 475 - unsigned int rate, bps; 446 + unsigned int rate, bps, channels; 447 + unsigned int stream_slot_size, max_slots; 448 + static unsigned int next_offset[AMD_SDW_MAX_MANAGER_COUNT] = {1}; 449 + unsigned int inst_id = amd_manager->instance; 476 450 477 451 port_bo = 0; 478 452 hstart = 1; ··· 487 453 list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) { 488 454 rate = m_rt->stream->params.rate; 489 455 bps = m_rt->stream->params.bps; 456 + channels = m_rt->stream->params.ch_count; 490 457 sample_int = (bus->params.curr_dr_freq / rate); 458 + 459 + /* Compute slots required for this stream dynamically */ 460 + stream_slot_size = bps * channels; 461 + 491 462 list_for_each_entry(p_rt, &m_rt->port_list, port_node) { 492 - port_bo = (p_rt->num * 64) + 1; 493 - dev_dbg(bus->dev, "p_rt->num=%d hstart=%d hstop=%d port_bo=%d\n", 494 - p_rt->num, hstart, hstop, port_bo); 463 + if (p_rt->num >= amd_manager->max_ports) { 464 + dev_err(bus->dev, "Port %d exceeds max ports %d\n", 465 + p_rt->num, amd_manager->max_ports); 466 + return -EINVAL; 467 + } 468 + 469 + if (!amd_manager->port_offset_map[p_rt->num]) { 470 + /* 471 + * port block offset calculation for 6MHz bus clock frequency with 472 + * different frame sizes 50 x 10 and 125 x 2 473 + */ 474 + if (bus->params.curr_dr_freq == 12000000) { 475 + max_slots = bus->params.row * (bus->params.col - 1); 476 + if (next_offset[inst_id] + stream_slot_size <= 477 + (max_slots - 1)) { 478 + amd_manager->port_offset_map[p_rt->num] = 479 + next_offset[inst_id]; 480 + next_offset[inst_id] += stream_slot_size; 481 + } else { 482 + dev_err(bus->dev, 483 + "No space for port %d\n", p_rt->num); 484 + return -ENOMEM; 485 + } 486 + } else { 487 + /* 488 + * port block offset calculation for 12MHz bus clock 489 + * frequency 490 + */ 491 + amd_manager->port_offset_map[p_rt->num] = 492 + (p_rt->num * 64) + 1; 493 + } 494 + } 495 + port_bo = amd_manager->port_offset_map[p_rt->num]; 496 + dev_dbg(bus->dev, 497 + "Port=%d hstart=%d hstop=%d port_bo=%d slots=%d max_ports=%d\n", 498 + p_rt->num, hstart, hstop, port_bo, stream_slot_size, 499 + amd_manager->max_ports); 500 + 495 501 sdw_fill_xport_params(&p_rt->transport_params, p_rt->num, 496 502 false, SDW_BLK_GRP_CNT_1, sample_int, 497 503 port_bo, port_bo >> 8, hstart, hstop, ··· 1034 960 1035 961 prop = &amd_manager->bus.prop; 1036 962 if (!prop->hw_disabled) { 963 + ret = amd_sdw_clk_init_ctrl(amd_manager); 964 + if (ret) 965 + return ret; 1037 966 ret = amd_init_sdw_manager(amd_manager); 1038 967 if (ret) 1039 968 return ret; ··· 1061 984 struct resource *res; 1062 985 struct device *dev = &pdev->dev; 1063 986 struct sdw_master_prop *prop; 1064 - struct sdw_bus_params *params; 1065 987 struct amd_sdw_manager *amd_manager; 1066 988 int ret; 1067 989 ··· 1123 1047 default: 1124 1048 return -EINVAL; 1125 1049 } 1050 + amd_manager->max_ports = amd_manager->num_dout_ports + amd_manager->num_din_ports; 1051 + amd_manager->port_offset_map = devm_kcalloc(dev, amd_manager->max_ports, 1052 + sizeof(int), GFP_KERNEL); 1053 + if (!amd_manager->port_offset_map) 1054 + return -ENOMEM; 1126 1055 1127 - params = &amd_manager->bus.params; 1128 - 1129 - params->col = AMD_SDW_DEFAULT_COLUMNS; 1130 - params->row = AMD_SDW_DEFAULT_ROWS; 1131 1056 prop = &amd_manager->bus.prop; 1132 - prop->clk_freq = &amd_sdw_freq_tbl[0]; 1133 1057 prop->mclk_freq = AMD_SDW_BUS_BASE_FREQ; 1134 - prop->max_clk_freq = AMD_SDW_DEFAULT_CLK_FREQ; 1135 1058 1136 1059 ret = sdw_bus_master_add(&amd_manager->bus, dev, dev->fwnode); 1137 1060 if (ret) { ··· 1422 1347 } 1423 1348 } 1424 1349 sdw_clear_slave_status(bus, SDW_UNATTACH_REQUEST_MASTER_RESET); 1350 + ret = amd_sdw_clk_init_ctrl(amd_manager); 1351 + if (ret) 1352 + return ret; 1425 1353 amd_init_sdw_manager(amd_manager); 1426 1354 amd_enable_sdw_interrupts(amd_manager); 1427 1355 ret = amd_enable_sdw_manager(amd_manager);
-4
drivers/soundwire/amd_manager.h
··· 203 203 #define AMD_SDW_DEVICE_STATE_D3 3 204 204 #define ACP_PME_EN 0x0001400 205 205 206 - static u32 amd_sdw_freq_tbl[AMD_SDW_MAX_FREQ_NUM] = { 207 - AMD_SDW_DEFAULT_CLK_FREQ, 208 - }; 209 - 210 206 struct sdw_manager_dp_reg { 211 207 u32 frame_fmt_reg; 212 208 u32 sample_int_reg;
+4 -4
drivers/soundwire/bus.c
··· 1899 1899 1900 1900 if (status[i] == SDW_SLAVE_UNATTACHED && 1901 1901 slave->status != SDW_SLAVE_UNATTACHED) { 1902 - dev_warn(&slave->dev, "Slave %d state check1: UNATTACHED, status was %d\n", 1903 - i, slave->status); 1902 + dev_dbg(&slave->dev, "Slave %d state check1: UNATTACHED, status was %d\n", 1903 + i, slave->status); 1904 1904 sdw_modify_slave_status(slave, SDW_SLAVE_UNATTACHED); 1905 1905 1906 1906 /* Ensure driver knows that peripheral unattached */ ··· 1951 1951 if (slave->status == SDW_SLAVE_UNATTACHED) 1952 1952 break; 1953 1953 1954 - dev_warn(&slave->dev, "Slave %d state check2: UNATTACHED, status was %d\n", 1955 - i, slave->status); 1954 + dev_dbg(&slave->dev, "Slave %d state check2: UNATTACHED, status was %d\n", 1955 + i, slave->status); 1956 1956 1957 1957 sdw_modify_slave_status(slave, SDW_SLAVE_UNATTACHED); 1958 1958 break;
+8
drivers/soundwire/cadence_master.c
··· 933 933 934 934 cdns_read_response(cdns); 935 935 936 + /* 937 + * Clear interrupt before signalling the completion to avoid 938 + * a race between this thread and the main thread starting 939 + * another TX. 940 + */ 941 + cdns_writel(cdns, CDNS_MCP_INTSTAT, CDNS_MCP_INT_RX_WL); 942 + int_status &= ~CDNS_MCP_INT_RX_WL; 943 + 936 944 if (defer && defer->msg) { 937 945 cdns_fill_msg_resp(cdns, defer->msg, 938 946 defer->length, 0);
+5
drivers/soundwire/intel_ace2x.c
··· 82 82 int len; 83 83 int i; 84 84 85 + if (cdns->bus.bpt_stream) { 86 + dev_err(cdns->dev, "%s: BPT stream already exists\n", __func__); 87 + return -EAGAIN; 88 + } 89 + 85 90 stream = sdw_alloc_stream("BPT", SDW_STREAM_BPT); 86 91 if (!stream) 87 92 return -ENOMEM;
+2
drivers/soundwire/intel_auxdevice.c
··· 53 53 static struct wake_capable_part wake_capable_list[] = { 54 54 {0x01fa, 0x4243}, 55 55 {0x01fa, 0x4245}, 56 + {0x01fa, 0x4249}, 57 + {0x01fa, 0x4747}, 56 58 {0x025d, 0x5682}, 57 59 {0x025d, 0x700}, 58 60 {0x025d, 0x711},
+3
drivers/soundwire/slave.c
··· 115 115 u64 addr; 116 116 int ret; 117 117 118 + if (acpi_bus_get_status(adev) || !acpi_dev_ready_for_enumeration(adev)) 119 + return false; 120 + 118 121 ret = acpi_get_local_u64_address(adev->handle, &addr); 119 122 if (ret < 0) 120 123 return false;
+14 -8
drivers/soundwire/stream.c
··· 8 8 #include <linux/delay.h> 9 9 #include <linux/device.h> 10 10 #include <linux/init.h> 11 + #include <linux/iopoll.h> 11 12 #include <linux/module.h> 12 13 #include <linux/mod_devicetable.h> 13 14 #include <linux/slab.h> ··· 18 17 #include <linux/string_choices.h> 19 18 #include <sound/soc.h> 20 19 #include "bus.h" 20 + 21 + #define SDW_PORT_PREP_POLL_USEC 1000 21 22 22 23 /* 23 24 * Array of supported rows and columns as per MIPI SoundWire Specification 1.1 ··· 446 443 struct sdw_port_runtime *p_rt, 447 444 bool prep) 448 445 { 449 - struct completion *port_ready; 450 446 struct sdw_dpn_prop *dpn_prop; 451 447 struct sdw_prepare_ch prep_ch; 452 448 u32 imp_def_interrupts; ··· 520 518 return ret; 521 519 } 522 520 523 - /* Wait for completion on port ready */ 524 - port_ready = &s_rt->slave->port_ready[prep_ch.num]; 525 - wait_for_completion_timeout(port_ready, 526 - msecs_to_jiffies(ch_prep_timeout)); 521 + /* 522 + * Poll for NOT_PREPARED==0. Cannot use the interrupt because 523 + * this code holds bus_lock which blocks interrupt handling. 524 + */ 525 + ret = read_poll_timeout(sdw_read_no_pm, val, 526 + (val < 0) || ((val & p_rt->ch_mask) == 0), 527 + SDW_PORT_PREP_POLL_USEC, ch_prep_timeout * USEC_PER_MSEC, 528 + false, s_rt->slave, SDW_DPN_PREPARESTATUS(p_rt->num)); 529 + if (ret || (val < 0)) { 530 + if (val < 0) 531 + ret = val; 527 532 528 - val = sdw_read_no_pm(s_rt->slave, SDW_DPN_PREPARESTATUS(p_rt->num)); 529 - if ((val < 0) || (val & p_rt->ch_mask)) { 530 - ret = (val < 0) ? val : -ETIMEDOUT; 531 533 dev_err(&s_rt->slave->dev, 532 534 "Chn prep failed for port %d: %d\n", prep_ch.num, ret); 533 535 return ret;
+9 -9
include/linux/soundwire/sdw.h
··· 532 532 }; 533 533 534 534 /** 535 - * sdw_reg_bank - SoundWire register banks 535 + * enum sdw_reg_bank - SoundWire register banks 536 536 * @SDW_BANK0: Soundwire register bank 0 537 537 * @SDW_BANK1: Soundwire register bank 1 538 538 */ ··· 751 751 * struct sdw_transport_params: Data Port Transport Parameters 752 752 * 753 753 * @blk_grp_ctrl_valid: Port implements block group control 754 - * @num: Port number 754 + * @port_num: Port number 755 755 * @blk_grp_ctrl: Block group control value 756 756 * @sample_interval: Sample interval 757 757 * @offset1: Blockoffset of the payload data ··· 782 782 /** 783 783 * struct sdw_enable_ch: Enable/disable Data Port channel 784 784 * 785 - * @num: Port number 785 + * @port_num: Port number 786 786 * @ch_mask: Active channel mask 787 787 * @enable: Enable (true) /disable (false) channel 788 788 */ ··· 885 885 void sdw_show_ping_status(struct sdw_bus *bus, bool sync_delay); 886 886 887 887 /** 888 - * sdw_port_config: Master or Slave Port configuration 888 + * struct sdw_port_config: Master or Slave Port configuration 889 889 * 890 890 * @num: Port number 891 891 * @ch_mask: channels mask for port ··· 896 896 }; 897 897 898 898 /** 899 - * sdw_stream_config: Master or Slave stream configuration 899 + * struct sdw_stream_config: Master or Slave stream configuration 900 900 * 901 901 * @frame_rate: Audio frame rate of the stream, in Hz 902 902 * @ch_count: Channel count of the stream ··· 913 913 }; 914 914 915 915 /** 916 - * sdw_stream_state: Stream states 916 + * enum sdw_stream_state: Stream states 917 917 * 918 918 * @SDW_STREAM_ALLOCATED: New stream allocated. 919 919 * @SDW_STREAM_CONFIGURED: Stream configured ··· 934 934 }; 935 935 936 936 /** 937 - * sdw_stream_params: Stream parameters 937 + * struct sdw_stream_params: Stream parameters 938 938 * 939 939 * @rate: Sampling frequency, in Hz 940 940 * @ch_count: Number of channels ··· 947 947 }; 948 948 949 949 /** 950 - * sdw_stream_runtime: Runtime stream parameters 950 + * struct sdw_stream_runtime: Runtime stream parameters 951 951 * 952 952 * @name: SoundWire stream name 953 953 * @params: Stream parameters ··· 983 983 * @defer_msg: Defer message 984 984 * @params: Current bus parameters 985 985 * @stream_refcount: number of streams currently using this bus 986 - * @btp_stream_refcount: number of BTP streams currently using this bus (should 986 + * @bpt_stream_refcount: number of BTP streams currently using this bus (should 987 987 * be zero or one, multiple streams per link is not supported). 988 988 * @bpt_stream: pointer stored to handle BTP streams. 989 989 * @ops: Master callback ops
+4
include/linux/soundwire/sdw_amd.h
··· 66 66 * @status: peripheral devices status array 67 67 * @num_din_ports: number of input ports 68 68 * @num_dout_ports: number of output ports 69 + * @max_ports: total number of input ports and output ports 69 70 * @cols_index: Column index in frame shape 70 71 * @rows_index: Rows index in frame shape 72 + * @port_offset_map: dynamic array to map port block offset 71 73 * @instance: SoundWire manager instance 72 74 * @quirks: SoundWire manager quirks 73 75 * @wake_en_mask: wake enable mask per SoundWire manager ··· 94 92 95 93 int num_din_ports; 96 94 int num_dout_ports; 95 + int max_ports; 97 96 98 97 int cols_index; 99 98 int rows_index; 100 99 100 + int *port_offset_map; 101 101 u32 instance; 102 102 u32 quirks; 103 103 u32 wake_en_mask;