audio-kernel:swr: Add dynamic SWRM clk support

- Add support to load dynamic soundwire master clk
  from devicetree file.

Change-Id: I59527f42aa7d3a7b00a0b161c3867c16aaecb263
Signed-off-by: Harendra Gautam <quic_hgautam@quicinc.com>
This commit is contained in:
Harendra Gautam 2023-09-13 10:59:58 +05:30
commit 5206840c7d
3 changed files with 76 additions and 23 deletions

View file

@ -18,6 +18,12 @@
#define SWR_CLK_RATE_4P8MHZ 4800000
#define SWR_CLK_RATE_9P6MHZ 9600000
#define SWR_CLK_RATE_11P2896MHZ 11289600
#define SWR_CLK_RATE_0P384MHZ 384000
#define SWR_CLK_RATE_0P768MHZ 768000
#define SWR_CLK_RATE_1P536MHZ 1536000
#define SWR_CLK_RATE_3P072MHZ 3072000
#define SWR_CLK_RATE_6P144MHZ 6144000
#define SWR_CLK_RATE_12P288MHZ 12288000
extern struct bus_type soundwire_type;
struct swr_device;

View file

@ -34,6 +34,7 @@ struct swr_mstr_port {
#define MCLK_FREQ 9600000
#define MCLK_FREQ_LP 600000
#define MCLK_FREQ_NATIVE 11289600
#define MCLK_FREQ_12P288MHZ 12288000
#if (IS_ENABLED(CONFIG_SOUNDWIRE_WCD_CTRL) || \
IS_ENABLED(CONFIG_SOUNDWIRE_MSTR_CTRL))

View file

@ -1160,8 +1160,8 @@ static void swrm_switch_frame_shape(struct swr_mstr_ctrl *swrm, int mclk_freq)
} else {
n_col = SWR_MIN_COL;
col = SWRM_COL_02;
n_row = SWR_ROW_50;
row = SWRM_ROW_50;
n_row = (mclk_freq == MCLK_FREQ_12P288MHZ) ? SWR_ROW_64 : SWR_ROW_50;
row = (mclk_freq == MCLK_FREQ_12P288MHZ) ? SWRM_ROW_64 : SWRM_ROW_50;
frame_sync = SWRM_FRAME_SYNC_SEL;
}
@ -1222,16 +1222,25 @@ int swrm_get_clk_div_rate(int mclk_freq, int bus_clk_freq)
if (mclk_freq == SWR_CLK_RATE_9P6MHZ) {
if (bus_clk_freq <= SWR_CLK_RATE_0P6MHZ)
bus_clk_freq = SWR_CLK_RATE_0P6MHZ;
else if (bus_clk_freq <= SWR_CLK_RATE_1P2MHZ)
bus_clk_freq = SWR_CLK_RATE_4P8MHZ;
else if (bus_clk_freq <= SWR_CLK_RATE_2P4MHZ)
bus_clk_freq = SWR_CLK_RATE_4P8MHZ;
else if(bus_clk_freq <= SWR_CLK_RATE_4P8MHZ)
else if ((bus_clk_freq <= SWR_CLK_RATE_1P2MHZ) ||
(bus_clk_freq <= SWR_CLK_RATE_2P4MHZ) ||
(bus_clk_freq <= SWR_CLK_RATE_4P8MHZ))
bus_clk_freq = SWR_CLK_RATE_4P8MHZ;
else if(bus_clk_freq <= SWR_CLK_RATE_9P6MHZ)
bus_clk_freq = SWR_CLK_RATE_9P6MHZ;
else
bus_clk_freq = SWR_CLK_RATE_9P6MHZ;
} else if (mclk_freq == SWR_CLK_RATE_12P288MHZ) {
if (bus_clk_freq <= SWR_CLK_RATE_0P768MHZ)
bus_clk_freq = SWR_CLK_RATE_0P768MHZ;
else if ((bus_clk_freq <= SWR_CLK_RATE_1P536MHZ) ||
(bus_clk_freq <= SWR_CLK_RATE_3P072MHZ) ||
(bus_clk_freq <= SWR_CLK_RATE_6P144MHZ))
bus_clk_freq = SWR_CLK_RATE_6P144MHZ;
else if(bus_clk_freq <= SWR_CLK_RATE_12P288MHZ)
bus_clk_freq = SWR_CLK_RATE_12P288MHZ;
else
bus_clk_freq = SWR_CLK_RATE_12P288MHZ;
} else if (mclk_freq == SWR_CLK_RATE_11P2896MHZ)
bus_clk_freq = SWR_CLK_RATE_11P2896MHZ;
@ -1368,12 +1377,14 @@ static void swrm_get_device_frame_shape(struct swr_mstr_ctrl *swrm,
if ((swrm->master_id == MASTER_ID_TX) &&
(swrm->use_custom_phy_addr) &&
((swrm->bus_clk == SWR_CLK_RATE_9P6MHZ) ||
((swrm->bus_clk == SWR_CLK_RATE_12P288MHZ) ||
(swrm->bus_clk == SWR_CLK_RATE_9P6MHZ) ||
(swrm->bus_clk == SWR_CLK_RATE_0P6MHZ) ||
(swrm->bus_clk == SWR_CLK_RATE_4P8MHZ))) {
dev_num = swrm_get_device_id(swrm, port_req->dev_num);
port_id = port_req->slave_port_id;
if (swrm->bus_clk == SWR_CLK_RATE_9P6MHZ)
if ((swrm->bus_clk == SWR_CLK_RATE_12P288MHZ) ||
(swrm->bus_clk == SWR_CLK_RATE_9P6MHZ))
pp_dev = swrdev_frame_params_9p6MHz[dev_num].pp;
else if (swrm->bus_clk == SWR_CLK_RATE_0P6MHZ)
pp_dev = swrdev_frame_params_0p6MHz[dev_num].pp;
@ -1681,7 +1692,8 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable)
/* set col = 16 */
n_col = SWR_MAX_COL;
col = SWRM_COL_16;
if (swrm->bus_clk == MCLK_FREQ_LP) {
if ((swrm->bus_clk == MCLK_FREQ_LP) ||
(swrm->bus_clk == SWR_CLK_RATE_0P768MHZ)) {
n_col = SWR_MIN_COL;
col = SWRM_COL_02;
}
@ -1699,16 +1711,15 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable)
}
/* Use default 50 * x, frame shape. Change based on mclk */
if (swrm->mclk_freq == MCLK_FREQ_NATIVE) {
dev_dbg(swrm->dev, "setting 64 x %d frameshape\n", col);
n_row = SWR_ROW_64;
row = SWRM_ROW_64;
frame_sync = SWRM_FRAME_SYNC_SEL_NATIVE;
} else {
dev_dbg(swrm->dev, "setting 50 x %d frameshape\n", col);
n_row = SWR_ROW_50;
row = SWRM_ROW_50;
n_row = (swrm->mclk_freq == MCLK_FREQ_12P288MHZ) ? SWR_ROW_64 : SWR_ROW_50;
row = (swrm->mclk_freq == MCLK_FREQ_12P288MHZ) ? SWRM_ROW_64 : SWRM_ROW_50;
frame_sync = SWRM_FRAME_SYNC_SEL;
}
dev_dbg(swrm->dev, "setting %d x %d frameshape\n", row, col);
ssp_period = swrm_get_ssp_period(swrm, row, col, frame_sync);
bus_clk_div_factor = swrm_get_clk_div(swrm->mclk_freq, swrm->bus_clk);
dev_dbg(swrm->dev, "%s: ssp_period: %d, bus_clk_div:%d \n", __func__,
@ -2450,14 +2461,28 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm)
{
int ret = 0, i = 0;
u32 val;
u8 row_ctrl = SWR_ROW_50;
u8 col_ctrl = SWR_MIN_COL;
u8 row_ctrl = 0, row = 0;
u8 col_ctrl = SWR_MIN_COL, col = SWRM_COL_02;
u8 ssp_period = 1;
u8 retry_cmd_num = 3;
u32 reg[SWRM_MAX_INIT_REG];
u32 value[SWRM_MAX_INIT_REG];
u32 temp = 0;
int len = 0;
int frame_sync = SWRM_FRAME_SYNC_SEL;
if (swrm->mclk_freq == MCLK_FREQ_NATIVE) {
row_ctrl = SWR_ROW_64;
row = SWRM_ROW_64;
frame_sync = SWRM_FRAME_SYNC_SEL_NATIVE;
} else {
row_ctrl = (swrm->mclk_freq == MCLK_FREQ_12P288MHZ) ?
SWR_ROW_64 : SWR_ROW_50;
row = (swrm->mclk_freq == MCLK_FREQ_12P288MHZ) ?
SWRM_ROW_64 : SWRM_ROW_50;
frame_sync = SWRM_FRAME_SYNC_SEL;
}
/* Change no of retry counts to 1 for wsa to avoid underflow */
if (swrm->master_id == MASTER_ID_WSA)
@ -2475,8 +2500,7 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm)
__func__, temp);
}
}
ssp_period = swrm_get_ssp_period(swrm, SWRM_ROW_50,
SWRM_COL_02, SWRM_FRAME_SYNC_SEL);
ssp_period = swrm_get_ssp_period(swrm, row, col, frame_sync);
dev_dbg(swrm->dev, "%s: ssp_period: %d\n", __func__, ssp_period);
/* Clear Rows and Cols */
@ -2595,7 +2619,7 @@ static int swrm_probe(struct platform_device *pdev)
{
struct swr_mstr_ctrl *swrm;
struct swr_ctrl_platform_data *pdata;
u32 i, num_ports, port_num, port_type, ch_mask, swrm_hctl_reg = 0;
u32 i, num_ports, port_num, port_type, ch_mask, swrm_hctl_reg = 0, mclk_freq = 0;
u32 *temp, map_size, map_length, ch_iter = 0, old_port_num = 0;
int ret = 0;
struct clk *lpass_core_hw_vote = NULL;
@ -2830,8 +2854,6 @@ static int swrm_probe(struct platform_device *pdev)
swrm->num_rx_chs = 0;
swrm->clk_ref_count = 0;
swrm->swr_irq_wakeup_capable = 0;
swrm->mclk_freq = MCLK_FREQ;
swrm->bus_clk = MCLK_FREQ;
swrm->dev_up = true;
swrm->state = SWR_MSTR_UP;
swrm->ipc_wakeup = false;
@ -2861,6 +2883,17 @@ static int swrm_probe(struct platform_device *pdev)
for (i = 0 ; i < SWR_MSTR_PORT_LEN; i++)
INIT_LIST_HEAD(&swrm->mport_cfg[i].port_req_list);
ret = of_property_read_u32(pdev->dev.of_node, "qcom,swrm-mclk-clk-rate",
&mclk_freq);
if (ret) {
swrm->mclk_freq = MCLK_FREQ;
dev_dbg(&pdev->dev, "%s SWRM MCLK not specified, using default: %d,\n",
__func__, swrm->mclk_freq);
} else {
swrm->mclk_freq = mclk_freq;
}
swrm->bus_clk = swrm->mclk_freq;
if (of_property_read_u32(pdev->dev.of_node,
"qcom,disable-div2-clk-switch",
&swrm->disable_div2_clk_switch)) {
@ -3092,6 +3125,12 @@ static int swrm_runtime_resume(struct device *dev)
struct swr_master *mstr = &swrm->master;
struct swr_device *swr_dev;
u32 temp = 0;
u8 row_ctrl = SWR_ROW_50;
u8 col_ctrl = SWR_MIN_COL;
if ((swrm->mclk_freq == MCLK_FREQ_NATIVE) ||
(swrm->mclk_freq == MCLK_FREQ_12P288MHZ))
row_ctrl = SWR_ROW_64;
dev_dbg(dev, "%s: pm_runtime: resume, state:%d\n",
__func__, swrm->state);
@ -3178,7 +3217,7 @@ static int swrm_runtime_resume(struct device *dev)
SWRS_SCP_INT_STATUS_MASK_1);
if (swrm->state == SWR_MSTR_SSR) {
mutex_unlock(&swrm->reslock);
enable_bank_switch(swrm, 0, SWR_ROW_50, SWR_MIN_COL);
enable_bank_switch(swrm, 0, row_ctrl, col_ctrl);
mutex_lock(&swrm->reslock);
}
} else {
@ -3235,6 +3274,13 @@ static int swrm_runtime_suspend(struct device *dev)
int current_state = 0;
struct irq_data *irq_data = NULL;
u8 row_ctrl = SWR_ROW_50;
u8 col_ctrl = SWR_MIN_COL;
if ((swrm->mclk_freq == MCLK_FREQ_NATIVE) ||
(swrm->mclk_freq == MCLK_FREQ_12P288MHZ))
row_ctrl = SWR_ROW_64;
dev_dbg(dev, "%s: pm_runtime: suspend state: %d\n",
__func__, swrm->state);
if (swrm->state == SWR_MSTR_SSR_RESET) {
@ -3268,7 +3314,7 @@ static int swrm_runtime_suspend(struct device *dev)
dev_err(dev, "%s: clk stop mode not supported or SSR entry\n",
__func__);
mutex_unlock(&swrm->reslock);
enable_bank_switch(swrm, 0, SWR_ROW_50, SWR_MIN_COL);
enable_bank_switch(swrm, 0, row_ctrl, col_ctrl);
mutex_lock(&swrm->reslock);
swrm_clk_pause(swrm);
swr_master_write(swrm, SWRM_COMP_CFG, 0x00);