Browse Source

Merge "soc: soundwire: change ssp period based on frame shape"

qctecmdr 5 years ago
parent
commit
137583f46f
2 changed files with 45 additions and 4 deletions
  1. 44 4
      soc/swr-mstr-ctrl.c
  2. 1 0
      soc/swr-mstr-ctrl.h

+ 44 - 4
soc/swr-mstr-ctrl.c

@@ -25,6 +25,7 @@
 #include "swrm_registers.h"
 #include "swr-mstr-ctrl.h"
 
+#define SWRM_FRAME_SYNC_SEL    4000 /* 4KHz */
 #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
+
 /* pm runtime auto suspend timer in msecs */
 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) {
 			/* wait 500 us before retry on fifo read failure */
 			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) {
 		/* set col = 16 */
 		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;
+		}
 	}
 	/* 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",
 			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);
+
 	/* Clear Rows and Cols */
 	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;

+ 1 - 0
soc/swr-mstr-ctrl.h

@@ -142,6 +142,7 @@ struct swr_mstr_ctrl {
 	int wake_irq;
 	int version;
 	int mclk_freq;
+	int bus_clk;
 	u32 num_dev;
 	int slave_status;
 	struct swrm_mports mport_cfg[SWR_MAX_MSTR_PORT_NUM];