2626#define SWRM_COMP_STATUS 0x014
2727#define SWRM_LINK_MANAGER_EE 0x018
2828#define SWRM_EE_CPU 1
29+ #define SWRM_MAX_EE 1
2930#define SWRM_FRM_GEN_ENABLED BIT(0)
3031#define SWRM_VERSION_1_3_0 0x01030000
3132#define SWRM_VERSION_1_5_1 0x01050001
118119#define SWRM_V2_0_CLK_CTRL 0x5060
119120#define SWRM_V2_0_CLK_CTRL_CLK_START BIT(0)
120121#define SWRM_V2_0_LINK_STATUS 0x5064
122+ #define SWRM_V2_REG_EE_STRIDE 0x1000
121123
122124#define SWRM_DP_PORT_CTRL_EN_CHAN_SHFT 0x18
123125#define SWRM_DP_PORT_CTRL_OFFSET2_SHFT 0x10
@@ -202,6 +204,7 @@ struct qcom_swrm_ctrl {
202204 struct mutex port_lock ;
203205 struct clk * hclk ;
204206 int irq ;
207+ u32 ee ;
205208 unsigned int version ;
206209 int wake_irq ;
207210 int num_din_ports ;
@@ -222,6 +225,7 @@ struct qcom_swrm_ctrl {
222225 u32 slave_status ;
223226 u32 wr_fifo_depth ;
224227 bool clock_stop_not_supported ;
228+ unsigned int reg_layout_local [SWRM_OFFSET_DP_SAMPLECTRL2_BANK + 1 ];
225229};
226230
227231struct qcom_swrm_data {
@@ -328,6 +332,36 @@ static const struct qcom_swrm_data swrm_v3_0_data = {
328332};
329333#define to_qcom_sdw (b ) container_of(b, struct qcom_swrm_ctrl, bus)
330334
335+ static void qcom_swrm_set_ee_register_layout (struct qcom_swrm_ctrl * ctrl ,
336+ const struct qcom_swrm_data * data )
337+ {
338+ int ee_offset ;
339+
340+ memcpy (ctrl -> reg_layout_local , data -> reg_layout ,
341+ sizeof (ctrl -> reg_layout_local ));
342+ ctrl -> reg_layout = ctrl -> reg_layout_local ;
343+
344+ if (ctrl -> version < SWRM_VERSION_2_0_0 )
345+ return ;
346+
347+ /*
348+ * Current register constants map EE1. For EE0, use the EE register
349+ * window stride to access status/IRQ/FIFO registers.
350+ */
351+ ee_offset = ((int )ctrl -> ee - SWRM_EE_CPU ) * SWRM_V2_REG_EE_STRIDE ;
352+ if (!ee_offset )
353+ return ;
354+
355+ ctrl -> reg_layout_local [SWRM_REG_FRAME_GEN_ENABLED ] += ee_offset ;
356+ ctrl -> reg_layout_local [SWRM_REG_INTERRUPT_STATUS ] += ee_offset ;
357+ ctrl -> reg_layout_local [SWRM_REG_INTERRUPT_CLEAR ] += ee_offset ;
358+ ctrl -> reg_layout_local [SWRM_REG_INTERRUPT_CPU_EN ] += ee_offset ;
359+ ctrl -> reg_layout_local [SWRM_REG_CMD_FIFO_WR_CMD ] += ee_offset ;
360+ ctrl -> reg_layout_local [SWRM_REG_CMD_FIFO_RD_CMD ] += ee_offset ;
361+ ctrl -> reg_layout_local [SWRM_REG_CMD_FIFO_STATUS ] += ee_offset ;
362+ ctrl -> reg_layout_local [SWRM_REG_CMD_FIFO_RD_FIFO_ADDR ] += ee_offset ;
363+ }
364+
331365static int qcom_swrm_ahb_reg_read (struct qcom_swrm_ctrl * ctrl , int reg ,
332366 u32 * val )
333367{
@@ -904,12 +938,13 @@ static int qcom_swrm_init(struct qcom_swrm_ctrl *ctrl)
904938 ctrl -> reg_write (ctrl , SWRM_MCP_CFG_ADDR , val );
905939
906940 if (ctrl -> version == SWRM_VERSION_1_7_0 ) {
907- ctrl -> reg_write (ctrl , SWRM_LINK_MANAGER_EE , SWRM_EE_CPU );
941+ ctrl -> reg_write (ctrl , SWRM_LINK_MANAGER_EE , ctrl -> ee );
908942 ctrl -> reg_write (ctrl , SWRM_MCP_BUS_CTRL ,
909- SWRM_MCP_BUS_CLK_START << SWRM_EE_CPU );
943+ SWRM_MCP_BUS_CLK_START << ctrl -> ee );
910944 } else if (ctrl -> version >= SWRM_VERSION_2_0_0 ) {
911- ctrl -> reg_write (ctrl , SWRM_LINK_MANAGER_EE , SWRM_EE_CPU );
912- ctrl -> reg_write (ctrl , SWRM_V2_0_CLK_CTRL ,
945+ ctrl -> reg_write (ctrl , SWRM_LINK_MANAGER_EE , ctrl -> ee );
946+ ctrl -> reg_write (ctrl , SWRM_V2_0_CLK_CTRL +
947+ ((int )ctrl -> ee - SWRM_EE_CPU ) * SWRM_V2_REG_EE_STRIDE ,
913948 SWRM_V2_0_CLK_CTRL_CLK_START );
914949 } else {
915950 ctrl -> reg_write (ctrl , SWRM_MCP_BUS_CTRL , SWRM_MCP_BUS_CLK_START );
@@ -935,11 +970,9 @@ static int qcom_swrm_init(struct qcom_swrm_ctrl *ctrl)
935970 ctrl -> reg_write (ctrl , ctrl -> reg_layout [SWRM_REG_INTERRUPT_CLEAR ],
936971 0xFFFFFFFF );
937972
938- /* enable CPU IRQs */
939- if (ctrl -> mmio ) {
940- ctrl -> reg_write (ctrl , ctrl -> reg_layout [SWRM_REG_INTERRUPT_CPU_EN ],
941- SWRM_INTERRUPT_STATUS_RMSK );
942- }
973+ /* enable CPU IRQs for the selected EE window */
974+ ctrl -> reg_write (ctrl , ctrl -> reg_layout [SWRM_REG_INTERRUPT_CPU_EN ],
975+ SWRM_INTERRUPT_STATUS_RMSK );
943976
944977 /* Set IRQ to PULSE */
945978 ctrl -> reg_write (ctrl , SWRM_COMP_CFG_ADDR ,
@@ -1545,7 +1578,22 @@ static int qcom_swrm_probe(struct platform_device *pdev)
15451578 return - ENOMEM ;
15461579
15471580 data = of_device_get_match_data (dev );
1581+ ctrl -> ee = SWRM_EE_CPU ;
1582+ ret = of_property_read_u32 (dev -> of_node , "qcom,swr-master-ee-val" , & ctrl -> ee );
1583+ if (ret )
1584+ ret = of_property_read_u32 (dev -> of_node , "qcom,ee" , & ctrl -> ee );
1585+ if (ret )
1586+ ctrl -> ee = SWRM_EE_CPU ;
1587+ if (ctrl -> ee > SWRM_MAX_EE ) {
1588+ dev_warn (dev , "invalid SoundWire EE %u, using EE%u\n" ,
1589+ ctrl -> ee , SWRM_EE_CPU );
1590+ ctrl -> ee = SWRM_EE_CPU ;
1591+ }
15481592 ctrl -> max_reg = data -> max_reg ;
1593+ /*
1594+ * Defer EE register window selection until HW version is known.
1595+ * For v2.0+ the IRQ/FIFO window is EE-banked.
1596+ */
15491597 ctrl -> reg_layout = data -> reg_layout ;
15501598 ctrl -> rows_index = sdw_find_row_index (data -> default_rows );
15511599 ctrl -> cols_index = sdw_find_col_index (data -> default_cols );
@@ -1623,6 +1671,7 @@ static int qcom_swrm_probe(struct platform_device *pdev)
16231671 prop -> default_row = data -> default_rows ;
16241672
16251673 ctrl -> reg_read (ctrl , SWRM_COMP_HW_VERSION , & ctrl -> version );
1674+ qcom_swrm_set_ee_register_layout (ctrl , data );
16261675
16271676 ret = devm_request_threaded_irq (dev , ctrl -> irq , NULL ,
16281677 qcom_swrm_irq_handler ,
@@ -1724,24 +1773,26 @@ static int __maybe_unused swrm_runtime_resume(struct device *dev)
17241773 if (!swrm_wait_for_frame_gen_enabled (ctrl ))
17251774 dev_err (ctrl -> dev , "link failed to connect\n" );
17261775
1727- /* wait for hw enumeration to complete */
1728- wait_for_completion_timeout (& ctrl -> enumeration ,
1729- msecs_to_jiffies (TIMEOUT_MS ));
1730- qcom_swrm_get_device_status (ctrl );
1731- sdw_handle_slave_status (& ctrl -> bus , ctrl -> status );
1732- } else {
1733- reset_control_reset (ctrl -> audio_cgcr );
1734-
1735- if (ctrl -> version == SWRM_VERSION_1_7_0 ) {
1736- ctrl -> reg_write (ctrl , SWRM_LINK_MANAGER_EE , SWRM_EE_CPU );
1737- ctrl -> reg_write (ctrl , SWRM_MCP_BUS_CTRL ,
1738- SWRM_MCP_BUS_CLK_START << SWRM_EE_CPU );
1739- } else if (ctrl -> version >= SWRM_VERSION_2_0_0 ) {
1740- ctrl -> reg_write (ctrl , SWRM_LINK_MANAGER_EE , SWRM_EE_CPU );
1741- ctrl -> reg_write (ctrl , SWRM_V2_0_CLK_CTRL ,
1742- SWRM_V2_0_CLK_CTRL_CLK_START );
1776+ /* wait for hw enumeration to complete */
1777+ wait_for_completion_timeout (& ctrl -> enumeration ,
1778+ msecs_to_jiffies (TIMEOUT_MS ));
1779+ qcom_swrm_get_device_status (ctrl );
1780+ sdw_handle_slave_status (& ctrl -> bus , ctrl -> status );
17431781 } else {
1744- ctrl -> reg_write (ctrl , SWRM_MCP_BUS_CTRL , SWRM_MCP_BUS_CLK_START );
1782+ reset_control_reset (ctrl -> audio_cgcr );
1783+
1784+ if (ctrl -> version == SWRM_VERSION_1_7_0 ) {
1785+ ctrl -> reg_write (ctrl , SWRM_LINK_MANAGER_EE , ctrl -> ee );
1786+ ctrl -> reg_write (ctrl , SWRM_MCP_BUS_CTRL ,
1787+ SWRM_MCP_BUS_CLK_START << ctrl -> ee );
1788+ } else if (ctrl -> version >= SWRM_VERSION_2_0_0 ) {
1789+ ctrl -> reg_write (ctrl , SWRM_LINK_MANAGER_EE , ctrl -> ee );
1790+ ctrl -> reg_write (ctrl , SWRM_V2_0_CLK_CTRL +
1791+ ((int )ctrl -> ee - SWRM_EE_CPU ) *
1792+ SWRM_V2_REG_EE_STRIDE ,
1793+ SWRM_V2_0_CLK_CTRL_CLK_START );
1794+ } else {
1795+ ctrl -> reg_write (ctrl , SWRM_MCP_BUS_CTRL , SWRM_MCP_BUS_CLK_START );
17451796 }
17461797 ctrl -> reg_write (ctrl , ctrl -> reg_layout [SWRM_REG_INTERRUPT_CLEAR ],
17471798 SWRM_INTERRUPT_STATUS_MASTER_CLASH_DET );
0 commit comments