From 8a8b12b2456b97e8bbdd6dc060964f8fc0c4da7a Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Fri, 15 Nov 2019 23:06:41 +0530 Subject: [PATCH] soc: soundwire: Update ssp period for fractional sample rates Frame sync for fractional sample rates is different. Update ssp period based on frame sync of fractional sample rate for synchronization of the data channels. Change-Id: I25eaa5195abcdfad54cfed09beb0abe5aff2499a Signed-off-by: Sudheer Papothi --- soc/swr-mstr-ctrl.c | 46 +++++++++++++++++++++++++++++++++++++++++++-- soc/swr-mstr-ctrl.h | 2 +- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 2682c454dfee..0f8e68793816 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -26,6 +26,7 @@ #include "swr-mstr-ctrl.h" #define SWRM_FRAME_SYNC_SEL 4000 /* 4KHz */ +#define SWRM_FRAME_SYNC_SEL_NATIVE 3675 /* 3.675KHz */ #define SWRM_SYSTEM_RESUME_TIMEOUT_MS 700 #define SWRM_SYS_SUSPEND_WAIT 1 @@ -882,6 +883,39 @@ static void enable_bank_switch(struct swr_mstr_ctrl *swrm, u8 bank, SWRS_SCP_FRAME_CTRL_BANK(bank)); } +static void swrm_switch_frame_shape(struct swr_mstr_ctrl *swrm, int mclk_freq) +{ + u8 bank; + u32 n_row, n_col; + u32 value = 0; + u32 row = 0, col = 0; + u8 ssp_period = 0; + int frame_sync = SWRM_FRAME_SYNC_SEL; + + if (mclk_freq == MCLK_FREQ_NATIVE) { + n_col = SWR_MAX_COL; + col = SWRM_COL_16; + n_row = SWR_ROW_64; + row = SWRM_ROW_64; + frame_sync = SWRM_FRAME_SYNC_SEL_NATIVE; + } else { + n_col = SWR_MIN_COL; + col = SWRM_COL_02; + n_row = SWR_ROW_50; + row = SWRM_ROW_50; + frame_sync = SWRM_FRAME_SYNC_SEL; + } + + bank = get_inactive_bank_num(swrm); + ssp_period = swrm_get_ssp_period(swrm, row, col, frame_sync); + dev_dbg(swrm->dev, "%s: ssp_period: %d\n", __func__, ssp_period); + value = ((n_row << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) | + (n_col << SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT) | + ((ssp_period - 1) << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT)); + swr_master_write(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank), value); + enable_bank_switch(swrm, bank, n_row, n_col); +} + static struct swr_port_info *swrm_get_port_req(struct swrm_mports *mport, u8 slv_port, u8 dev_num) { @@ -1196,6 +1230,7 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_BMSK | SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_BMSK); u8 inactive_bank; + int frame_sync = SWRM_FRAME_SYNC_SEL; if (!swrm) { pr_err("%s: swrm is null\n", __func__); @@ -1278,13 +1313,15 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) n_col ? 16 : 2); 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", n_col ? 16 : 2); n_row = SWR_ROW_50; row = SWRM_ROW_50; + frame_sync = SWRM_FRAME_SYNC_SEL; } - ssp_period = swrm_get_ssp_period(swrm, row, col, 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); value = swr_master_read(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank)); @@ -2991,8 +3028,13 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) if (swrm->state == SWR_MSTR_DOWN) dev_dbg(swrm->dev, "%s:SWR master is already Down:%d\n", __func__, swrm->state); - else + else { + swrm->mclk_freq = *(int *)data; + swrm->bus_clk = swrm->mclk_freq; + swrm_switch_frame_shape(swrm, + swrm->bus_clk); swrm_device_suspend(&pdev->dev); + } /* * add delay to ensure clk release happen * if interrupt triggered for clk stop, diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index b07a80db6102..ab277721097b 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -25,7 +25,7 @@ #define SWR_ROW_48 0 #define SWR_ROW_50 1 -#define SWR_ROW_64 2 +#define SWR_ROW_64 3 #define SWR_MAX_COL 7 /* Cols = 16 */ #define SWR_MIN_COL 0 /* Cols = 2 */