|
@@ -25,6 +25,7 @@
|
|
|
#include "swrm_registers.h"
|
|
|
#include "swr-mstr-ctrl.h"
|
|
|
|
|
|
+#define SWRM_FRAME_SYNC_SEL 4000
|
|
|
#define SWRM_SYSTEM_RESUME_TIMEOUT_MS 700
|
|
|
#define SWRM_SYS_SUSPEND_WAIT 1
|
|
|
|
|
@@ -43,6 +44,13 @@
|
|
|
#define ERR_AUTO_SUSPEND_TIMER_VAL 0x1
|
|
|
|
|
|
#define SWRM_INTERRUPT_STATUS_MASK 0x1FDFD
|
|
|
+
|
|
|
+#define SWRM_ROW_48 48
|
|
|
+#define SWRM_ROW_50 50
|
|
|
+#define SWRM_ROW_64 64
|
|
|
+#define SWRM_COL_02 02
|
|
|
+#define SWRM_COL_16 16
|
|
|
+
|
|
|
|
|
|
static int auto_suspend_timer = SWR_AUTO_SUSPEND_DELAY * 1000;
|
|
|
module_param(auto_suspend_timer, int, 0664);
|
|
@@ -341,6 +349,16 @@ static int swrm_request_hw_vote(struct swr_mstr_ctrl *swrm,
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+static int swrm_get_ssp_period(struct swr_mstr_ctrl *swrm,
|
|
|
+ int row, int col,
|
|
|
+ int frame_sync)
|
|
|
+{
|
|
|
+ if (!swrm || !row || !col || !frame_sync)
|
|
|
+ return 1;
|
|
|
+
|
|
|
+ return ((swrm->bus_clk * 2) / ((row * col) * frame_sync));
|
|
|
+}
|
|
|
+
|
|
|
static int swrm_clk_request(struct swr_mstr_ctrl *swrm, bool enable)
|
|
|
{
|
|
|
int ret = 0;
|
|
@@ -591,6 +609,10 @@ retry_read:
|
|
|
if (retry_attempt < MAX_FIFO_RD_FAIL_RETRY) {
|
|
|
|
|
|
usleep_range(500, 505);
|
|
|
+ if (retry_attempt == (MAX_FIFO_RD_FAIL_RETRY - 1)) {
|
|
|
+ swr_master_write(swrm, SWRM_CMD_FIFO_CMD, 0x1);
|
|
|
+ swr_master_write(swrm, SWRM_CMD_FIFO_RD_CMD, val);
|
|
|
+ }
|
|
|
retry_attempt++;
|
|
|
goto retry_read;
|
|
|
} else {
|
|
@@ -1093,7 +1115,9 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable)
|
|
|
{
|
|
|
u8 bank;
|
|
|
u32 value, n_row, n_col;
|
|
|
+ u32 row = 0, col = 0;
|
|
|
int ret;
|
|
|
+ u8 ssp_period = 0;
|
|
|
struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master);
|
|
|
int mask = (SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_BMSK |
|
|
|
SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_BMSK |
|
|
@@ -1162,30 +1186,39 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable)
|
|
|
if (enable) {
|
|
|
|
|
|
n_col = SWR_MAX_COL;
|
|
|
+ col = SWRM_COL_16;
|
|
|
} else {
|
|
|
|
|
|
* Do not change to col = 2 if there are still active ports
|
|
|
*/
|
|
|
- if (!master->num_port)
|
|
|
+ if (!master->num_port) {
|
|
|
n_col = SWR_MIN_COL;
|
|
|
- else
|
|
|
+ col = SWRM_COL_02;
|
|
|
+ } else {
|
|
|
n_col = SWR_MAX_COL;
|
|
|
+ col = SWRM_COL_16;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
if (swrm->mclk_freq == MCLK_FREQ_NATIVE) {
|
|
|
dev_dbg(swrm->dev, "setting 64 x %d frameshape\n",
|
|
|
n_col ? 16 : 2);
|
|
|
n_row = SWR_ROW_64;
|
|
|
+ row = SWRM_ROW_64;
|
|
|
} else {
|
|
|
dev_dbg(swrm->dev, "setting 50 x %d frameshape\n",
|
|
|
n_col ? 16 : 2);
|
|
|
n_row = SWR_ROW_50;
|
|
|
+ row = SWRM_ROW_50;
|
|
|
}
|
|
|
+ ssp_period = swrm_get_ssp_period(swrm, row, col, SWRM_FRAME_SYNC_SEL);
|
|
|
+ dev_dbg(swrm->dev, "%s: ssp_period: %d\n", __func__, ssp_period);
|
|
|
+
|
|
|
value = swr_master_read(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank));
|
|
|
value &= (~mask);
|
|
|
value |= ((n_row << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) |
|
|
|
(n_col << SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT) |
|
|
|
- (0 << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT));
|
|
|
+ ((ssp_period - 1) << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT));
|
|
|
swr_master_write(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank), value);
|
|
|
|
|
|
dev_dbg(swrm->dev, "%s: regaddr: 0x%x, value: 0x%x\n", __func__,
|
|
@@ -1726,6 +1759,7 @@ handle_irq:
|
|
|
case SWRM_INTERRUPT_STATUS_WR_CMD_FIFO_OVERFLOW:
|
|
|
dev_dbg(swrm->dev, "%s: SWR write FIFO overflow\n",
|
|
|
__func__);
|
|
|
+ swr_master_write(swrm, SWRM_CMD_FIFO_CMD, 0x1);
|
|
|
break;
|
|
|
case SWRM_INTERRUPT_STATUS_CMD_ERROR:
|
|
|
value = swr_master_read(swrm, SWRM_CMD_FIFO_STATUS);
|
|
@@ -2019,10 +2053,14 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm)
|
|
|
u32 temp = 0;
|
|
|
int len = 0;
|
|
|
|
|
|
+ ssp_period = swrm_get_ssp_period(swrm, SWRM_ROW_50,
|
|
|
+ SWRM_COL_02, SWRM_FRAME_SYNC_SEL);
|
|
|
+ dev_dbg(swrm->dev, "%s: ssp_period: %d\n", __func__, ssp_period);
|
|
|
+
|
|
|
|
|
|
val = ((row_ctrl << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) |
|
|
|
(col_ctrl << SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT) |
|
|
|
- (ssp_period << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT));
|
|
|
+ ((ssp_period - 1) << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT));
|
|
|
|
|
|
reg[len] = SWRM_MCP_FRAME_CTRL_BANK_ADDR(0);
|
|
|
value[len++] = val;
|
|
@@ -2303,6 +2341,7 @@ static int swrm_probe(struct platform_device *pdev)
|
|
|
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;
|
|
@@ -2882,6 +2921,7 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data)
|
|
|
usleep_range(10000, 10500);
|
|
|
}
|
|
|
swrm->mclk_freq = *(int *)data;
|
|
|
+ swrm->bus_clk = swrm->mclk_freq;
|
|
|
mutex_unlock(&swrm->mlock);
|
|
|
}
|
|
|
break;
|