From b58f10f76f8194f8f4f531e7f6e8812d28e915b1 Mon Sep 17 00:00:00 2001 From: Sarath Varma Ganapathiraju Date: Tue, 5 Mar 2024 23:55:20 +0530 Subject: [PATCH] soc: add support for swr version 1p7 -add support for swr version 1p7. -Return 0 instead of EBUSY during swrm_suspend to allow system to enter suspend without rx swrm preventing it. - Update proper reg value during pcm port config. Change-Id: Id42d3625a0609507fffc92b650cfae92b0e1dc4f Signed-off-by: Sarath Varma Ganapathiraju --- asoc/pineapple-port-config.h | 57 ++++++++++++++++++++++++++- soc/Kbuild | 2 +- soc/swr-mstr-ctrl.c | 75 +++++++++++++++++++++++++++++------- soc/swr-mstr-ctrl.h | 3 +- soc/swr-mstr-registers.h | 4 +- 5 files changed, 123 insertions(+), 18 deletions(-) diff --git a/asoc/pineapple-port-config.h b/asoc/pineapple-port-config.h index 16894bea3d..ade7b29274 100644 --- a/asoc/pineapple-port-config.h +++ b/asoc/pineapple-port-config.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _PINEAPPLE_PORT_CONFIG @@ -16,6 +16,7 @@ * stream_type} */ +#ifdef CONFIG_SWRM_VER_2P0 static struct port_params wsa_frame_params_default[SWR_MSTR_PORT_LEN] = { {7, 1, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0xFF, 0xFF, 0x00, 0x00}, /* SPKR1 */ {31, 3, 7, 0xFF, 0xFF, 0xFF, 1, 0xFF, 0xFF, 0x00, 0x00}, /* CMP1 */ @@ -94,7 +95,61 @@ static struct port_params rx_frame_params_44p1KHz[SWR_MSTR_PORT_LEN] = { {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, /* CMPT */ {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, /* IPCM */ }; +#endif +#ifdef CONFIG_SWRM_VER_1P7 +static struct port_params wsa_frame_params_default[SWR_MSTR_PORT_LEN] = { + {7, 1, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0xFF, 0xFF, 0x00, 0x00}, /* SPKR1 */ + {31, 3, 7, 0xFF, 0xFF, 0xFF, 1, 0xFF, 0xFF, 0x00, 0x00}, /* CMP1 */ + {63, 5, 31, 0xFF, 0xFF, 0xFF, 1, 0xFF, 0xFF, 0x00, 0x00}, /* SB1 */ + {7, 2, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0xFF, 0xFF, 0x00, 0x00}, /* SPKR2 */ + {31, 4, 7, 0xFF, 0xFF, 0xFF, 1, 0xFF, 0xFF, 0x00, 0x00}, /* CMP2 */ + {63, 21, 31, 0xFF, 0xFF, 0xFF, 1, 0xFF, 0xFF, 0x00, 0x00}, /* SB2 */ + {15, 6, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0xFF, 0xFF, 0x01, 0x00}, /* IVS1 */ + {15, 13, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0xFF, 0xFF, 0x01, 0x00}, /* IVS2 */ +}; + +static struct port_params wsa_frame_params_receiver[SWR_MSTR_PORT_LEN] = { + {3, 1, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0xFF, 0xFF, 0x00, 0x00}, /* SPKR1 */ + {31, 3, 7, 0xFF, 0xFF, 0xFF, 1, 0xFF, 0xFF, 0x00, 0x00}, /* CMP1 */ + {63, 5, 31, 0xFF, 0xFF, 0xFF, 1, 0xFF, 0xFF, 0x00, 0x00}, /* SB1 */ + {3, 2, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0xFF, 0xFF, 0x00, 0x00}, /* SPKR2 */ + {31, 4, 7, 0xFF, 0xFF, 0xFF, 1, 0xFF, 0xFF, 0x00, 0x00}, /* CMP2 */ + {63, 21, 31, 0xFF, 0xFF, 0xFF, 1, 0xFF, 0xFF, 0x00, 0x00}, /* SB2 */ + {15, 6, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0xFF, 0xFF, 0x01, 0x00}, /* IVS1 */ + {15, 13, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0xFF, 0xFF, 0x01, 0x00}, /* IVS2 */ +}; + +static struct port_params rx_frame_params_dsd[SWR_MSTR_PORT_LEN] = { + {3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1, 0x00, 0x00}, /* HPH/EAR */ + {63, 0, 0, 3, 6, 7, 0, 0xFF, 0, 0x00, 0x02}, /* HPH_CLH */ + {31, 11, 11, 0xFF, 0xFF, 4, 1, 0xFF, 0, 0x00, 0x02}, /* HPH_CMP */ + {7, 9, 0, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0, 0x00, 0x00}, /* LO/AUX */ + {3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 3, 0, 0x00, 0x00}, /* DSD */ +}; + +/* Headset + PCM Haptics */ +static struct port_params rx_frame_params_default[SWR_MSTR_PORT_LEN] = { + {3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1, 0x00, 0x00}, /* HPH/EAR */ + {63, 0, 0, 3, 6, 7, 0, 0xFF, 0, 0x00, 0x02}, /* HPH_CLH */ + {31, 11, 11, 0xFF, 0xFF, 4, 1, 0xFF, 0, 0x00, 0x02}, /* HPH_CMP */ + {7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* LO/AUX */ + {0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0x00, 0x00}, /* DSD */ + {0x18F, 0, 0, 0x8, 0x8, 0x0F, 0x00, 0, 0, 0x00, 0x01}, /* PCM_OUT */ +}; + +/* Headset(44.1K) + PCM Haptics */ +static struct port_params rx_frame_params_44p1KHz[SWR_MSTR_PORT_LEN] = { + {3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1, 0x00, 0x00}, /* HPH/EAR */ + {63, 0, 0, 3, 6, 7, 0, 0xFF, 0, 0x00, 0x02}, /* HPH_CLH */ + {31, 11, 11, 0xFF, 0xFF, 4, 1, 0xFF, 0, 0x00, 0x02}, /* HPH_CMP */ + {3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0, 0x00, 0x00}, /* LO/AUX */ + {0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0x00, 0x00}, /* DSD */ + {0x1FF, 0, 0, 0x8, 0x8, 0x0F, 0, 0, 0, 0x00, 0x01}, /* PCM_OUT */ +}; +#endif + +/* Port configurations to support wcd937x wcd939x */ static struct swr_mstr_port_map sm_port_map[] = { {RX_MACRO, SWR_UC0, rx_frame_params_default}, {RX_MACRO, SWR_UC1, rx_frame_params_dsd}, diff --git a/soc/Kbuild b/soc/Kbuild index f3827e2f75..93f74be3cd 100644 --- a/soc/Kbuild +++ b/soc/Kbuild @@ -59,7 +59,7 @@ ifeq ($(KERNEL_BUILD), 0) include $(AUDIO_ROOT)/config/kalamaauto.conf INCS += -include $(AUDIO_ROOT)/config/kalamaautoconf.h endif - ifeq ($(CONFIG_ARCH_PINEAPPLE), y) + ifeq ($(BOARD_PLATFORM), pineapple cliffs cliffs7) include $(AUDIO_ROOT)/config/pineappleauto.conf INCS += -include $(AUDIO_ROOT)/config/pineappleautoconf.h endif diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 41284f9642..a230b0bdcd 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -786,15 +786,44 @@ static int swrm_pcm_port_config(struct swr_mstr_ctrl *swrm, u8 port_num, return -EINVAL; } - if (stream_type == SWR_PDM) + switch (stream_type) { + case SWR_PCM: + case SWR_PDM_32: + if (swrm->version != SWRM_VERSION_1_7) { + if (dir) + reg_addr = SWRM_DIN_DP_PCM_PORT_CTRL(port_num); + else + reg_addr = SWRM_DOUT_DP_PCM_PORT_CTRL(port_num); + reg_val = enable ? 0x3 : 0x0; + swr_master_write(swrm, reg_addr, reg_val); + } else if (stream_type == SWR_PCM) { + if (dir) + reg_addr = SWRM_DIN_DP_PCM_PORT_CTRL(port_num); + else + reg_addr = SWRM_DOUT_DP_PCM_PORT_CTRL(port_num); + swr_master_write(swrm, reg_addr, enable); + } + break; + case SWR_PDM: + default: return 0; + } + if (swrm->version == SWRM_VERSION_1_7) { + reg_val = SWRM_COMP_FEATURE_CFG_DEFAULT_VAL_V1P7; - reg_addr = ((dir) ? SWRM_DIN_DP_PCM_PORT_CTRL(port_num) : \ - SWRM_DOUT_DP_PCM_PORT_CTRL(port_num)); - reg_val = enable ? 0x3 : 0x0; - swr_master_write(swrm, reg_addr, reg_val); - dev_dbg(swrm->dev, "%s : pcm port %s, reg_val = %d, for addr %x\n", - __func__, enable ? "Enabled" : "disabled", reg_val, reg_addr); + if (enable) { + if (swrm->pcm_enable_count == 0) { + reg_val |= SWRM_COMP_FEATURE_CFG_PCM_EN_MASK; + swr_master_write(swrm, SWRM_COMP_FEATURE_CFG, reg_val); + } + swrm->pcm_enable_count++; + } else { + if (swrm->pcm_enable_count > 0) + swrm->pcm_enable_count--; + if (swrm->pcm_enable_count == 0) + swr_master_write(swrm, SWRM_COMP_FEATURE_CFG, reg_val); + } + } return 0; } @@ -1692,6 +1721,8 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) } clear_bit(DISABLE_PENDING, &swrm->port_req_pending); swrm_cleanup_disabled_port_reqs(master); + /* reset enable_count to 0 in SSR if master is already down */ + swrm->pcm_enable_count = 0; if (!swrm_is_port_en(master)) { dev_dbg(&master->dev, "%s: pm_runtime auto suspend triggered\n", __func__); @@ -2273,6 +2304,7 @@ handle_irq: swrm->clk_stop_wakeup = false; } break; +#ifdef CONFIG_SWRM_VER_2P0 case SWRM_INTERRUPT_STATUS_CMD_IGNORED_AND_EXEC_CONTINUED: value = swr_master_read(swrm, SWRM_CMD_FIFO_STATUS(swrm->ee_val)); dev_err_ratelimited(swrm->dev, @@ -2281,6 +2313,7 @@ handle_irq: /* Wait 3.5ms to clear */ usleep_range(3500, 3505); break; +#endif case SWRM_INTERRUPT_STATUS_DOUT_RATE_MISMATCH: dev_err(swrm->dev, "%s: SWR Port Channel rate mismatch\n", __func__); @@ -2616,6 +2649,14 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm) value[len++] = 0x01; #endif +#ifdef CONFIG_SWRM_VER_1P7 + reg[len] = SWRM_MCP_BUS_CTRL; + if (swrm->version < SWRM_VERSION_1_7) + value[len++] = 0x2; + else + value[len++] = 0x2 << swrm->ee_val; +#endif + /* Set IRQ to PULSE */ reg[len] = SWRM_COMP_CFG; value[len++] = 0x02; @@ -2830,7 +2871,7 @@ static int swrm_probe(struct platform_device *pdev) dev_err(swrm->dev, "missing port mapping\n"); goto err_pdata_fail; } - + swrm->pcm_enable_count = 0; map_length = map_size / (3 * sizeof(u32)); if (num_ports > SWR_MSTR_PORT_LEN) { dev_err(&pdev->dev, "%s:invalid number of swr ports\n", @@ -3034,10 +3075,12 @@ static int swrm_probe(struct platform_device *pdev) & SWRM_COMP_PARAMS_WR_FIFO_DEPTH) >> 10); swrm_hw_ver = swr_master_read(swrm, SWRM_COMP_HW_VERSION); - if (swrm->version != swrm_hw_ver) + if (swrm->version != swrm_hw_ver) { dev_info(&pdev->dev, "%s: version specified in dtsi: 0x%x not match with HW read version 0x%x\n", __func__, swrm->version, swrm_hw_ver); + swrm->version = swrm_hw_ver; + } swrm->num_auto_enum = ((swr_master_read(swrm, SWRM_COMP_PARAMS) & SWRM_COMP_PARAMS_AUTO_ENUM_SLAVES) >> 20); @@ -3197,7 +3240,7 @@ static int swrm_runtime_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); - int ret = 0; + int ret = 0, val = 0; bool swrm_clk_req_err = false; bool hw_core_err = false, aud_core_err = false; struct swr_master *mstr = &swrm->master; @@ -3301,10 +3344,16 @@ static int swrm_runtime_resume(struct device *dev) } /*wake up from clock stop*/ #ifdef CONFIG_SWRM_VER_2P0 + val = 0x01; swr_master_write(swrm, - SWRM_CLK_CTRL(swrm->ee_val), 0x01); + SWRM_CLK_CTRL(swrm->ee_val), val); #else - swr_master_write(swrm, SWRM_MCP_BUS_CTRL, 0x2); + if (swrm->version < SWRM_VERSION_1_7) + val = 0x2; + else + val = 0x2 << swrm->ee_val; + + swr_master_write(swrm, SWRM_MCP_BUS_CTRL, val); #endif /* clear and enable bus clash interrupt */ swr_master_write(swrm, @@ -3983,7 +4032,7 @@ static int swrm_suspend(struct device *dev) dev_dbg(swrm->dev, "%s: suspend failed state %d, wlock %d\n", __func__, swrm->pm_state, swrm->wlock_holders); - return -EBUSY; + return 0; } else { dev_dbg(swrm->dev, "%s: done, state %d, wlock %d\n", diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index 2d133e451e..83835b6de9 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _SWR_WCD_CTRL_H @@ -190,6 +190,7 @@ struct swr_mstr_ctrl { int hw_core_clk_en; int aud_core_clk_en; int clk_src; + u32 pcm_enable_count; u32 disable_div2_clk_switch; u32 rd_fifo_depth; u32 wr_fifo_depth; diff --git a/soc/swr-mstr-registers.h b/soc/swr-mstr-registers.h index 5b6294e844..d9c0a9ad46 100644 --- a/soc/swr-mstr-registers.h +++ b/soc/swr-mstr-registers.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015, 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _SWRM_REGISTERS_H @@ -49,7 +49,7 @@ #define SWRM_INTERRUPT_CLEAR_1(n) (SWRM_BASE+0x0228*n) #define SWRM_CPU1_INTERRUPT_EN(n) (SWRM_BASE+0x0210*n) #define SWRM_CPU1_INTERRUPT_EN_1(n) (SWRM_BASE+0x0230*n) -#define SWRM_CPU0_CMD_RESPONSE(n) (SWRM_BASE+0x0250*n) +#define SWRM_CPU0_CMD_RESPONSE(n) (SWRM_BASE+0x0250+0x4*n) #define SWRM_CPU1_CMD_FIFO_WR_CMD(n) (SWRM_BASE+0x031C*n) #define SWRM_CPU1_CMD_FIFO_RD_CMD(n) (SWRM_BASE+0x0320*n)