Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 14f47cc8 authored by Ramprasad Katkam's avatar Ramprasad Katkam Committed by Gerrit - the friendly Code Review server
Browse files

asoc: swr-mstr: add rx and tx master frame configuration



Add Rx and TX master frame configuration.

Change-Id: I067931565270e7390d9c5311e0869dfdb6685999
Signed-off-by: default avatarRamprasad Katkam <katkam@codeaurora.org>
parent 997da401
Loading
Loading
Loading
Loading
+149 −45
Original line number Original line Diff line number Diff line
@@ -38,6 +38,8 @@
#define SWR_REG_VAL_PACK(data, dev, id, reg)	\
#define SWR_REG_VAL_PACK(data, dev, id, reg)	\
			((reg) | ((id) << 16) | ((dev) << 20) | ((data) << 24))
			((reg) | ((id) << 16) | ((dev) << 20) | ((data) << 24))


#define SWR_INVALID_PARAM 0xFF

/* pm runtime auto suspend timer in msecs */
/* pm runtime auto suspend timer in msecs */
static int auto_suspend_timer = SWR_AUTO_SUSPEND_DELAY * 1000;
static int auto_suspend_timer = SWR_AUTO_SUSPEND_DELAY * 1000;
module_param(auto_suspend_timer, int, 0664);
module_param(auto_suspend_timer, int, 0664);
@@ -55,7 +57,6 @@ enum {
	MASTER_ID_RX,
	MASTER_ID_RX,
	MASTER_ID_TX
	MASTER_ID_TX
};
};
#define MASTER_ID_MASK 0xF
#define TRUE 1
#define TRUE 1
#define FALSE 0
#define FALSE 0


@@ -320,36 +321,51 @@ static bool swrm_is_port_en(struct swr_master *mstr)
	return !!(mstr->num_port);
	return !!(mstr->num_port);
}
}


static int swrm_get_port_config(struct swr_mstr_ctrl *swrm)
static void copy_port_tables(struct swr_mstr_ctrl *swrm,
				struct port_params *params)
{
{
	u8 master_device_id;
	u8 i;
	int i;
	struct port_params *config = params;

	/* update device_id for tx/rx */
	master_device_id = MASTER_ID_WSA;


	switch (master_device_id & MASTER_ID_MASK) {
	case MASTER_ID_WSA:
		/* get port params for wsa */
	for (i = 0; i < SWR_MSTR_PORT_LEN; i++) {
	for (i = 0; i < SWR_MSTR_PORT_LEN; i++) {
		/* wsa uses single frame structure for all configurations */
		/* wsa uses single frame structure for all configurations */
		if (!swrm->mport_cfg[i].port_en)
		if (!swrm->mport_cfg[i].port_en)
			continue;
			continue;
			swrm->mport_cfg[i].sinterval = wsa_frame_superset[i].si;
		swrm->mport_cfg[i].sinterval = config[i].si;
			swrm->mport_cfg[i].offset1 = wsa_frame_superset[i].off1;
		swrm->mport_cfg[i].offset1 = config[i].off1;
			swrm->mport_cfg[i].offset2 = wsa_frame_superset[i].off2;
		swrm->mport_cfg[i].offset2 = config[i].off2;
		swrm->mport_cfg[i].hstart = config[i].hstart;
		swrm->mport_cfg[i].hstop = config[i].hstop;
		swrm->mport_cfg[i].blk_pack_mode = config[i].bp_mode;
		swrm->mport_cfg[i].blk_grp_count = config[i].bgp_ctrl;
		swrm->mport_cfg[i].word_length = config[i].wd_len;
		swrm->mport_cfg[i].lane_ctrl = config[i].lane_ctrl;
	}
}
}
static int swrm_get_port_config(struct swr_mstr_ctrl *swrm)
{
	struct port_params *params;

	switch (swrm->master_id) {
	case MASTER_ID_WSA:
		params = wsa_frame_superset;
		break;
		break;
	case MASTER_ID_RX:
	case MASTER_ID_RX:
		/* get port params for rx */
		/* Two RX tables for dsd and without dsd enabled */
		if (swrm->mport_cfg[4].port_en)
			params = rx_frame_params_dsd;
		else
			params = rx_frame_params;
		break;
		break;
	case MASTER_ID_TX:
	case MASTER_ID_TX:
		/* get port params for tx */
		params = tx_frame_params_superset;
		break;
		break;
	default: /* MASTER_GENERIC*/
	default: /* MASTER_GENERIC*/
		/* computer generic frame parameters */
		/* computer generic frame parameters */
		return -EINVAL;
		return -EINVAL;
	}
	}

	copy_port_tables(swrm, params);
	return 0;
	return 0;
}
}


@@ -735,6 +751,7 @@ static void swrm_copy_data_port_config(struct swr_master *master, u8 bank)
	u32 reg[SWRM_MAX_PORT_REG];
	u32 reg[SWRM_MAX_PORT_REG];
	u32 val[SWRM_MAX_PORT_REG];
	u32 val[SWRM_MAX_PORT_REG];
	int len = 0;
	int len = 0;
	u8 hparams;
	struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master);
	struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master);


	if (!swrm) {
	if (!swrm) {
@@ -770,13 +787,54 @@ static void swrm_copy_data_port_config(struct swr_master *master, u8 bank)
					SWRS_DP_OFFSET_CONTROL_1_BANK(slv_id,
					SWRS_DP_OFFSET_CONTROL_1_BANK(slv_id,
								bank));
								bank));


			if (port_req->slave_port_id) {
			if (mport->offset2 != SWR_INVALID_PARAM) {
				reg[len] = SWRM_CMD_FIFO_WR_CMD;
				reg[len] = SWRM_CMD_FIFO_WR_CMD;
				val[len++] = SWR_REG_VAL_PACK(mport->offset2,
				val[len++] = SWR_REG_VAL_PACK(mport->offset2,
						port_req->dev_num, 0x00,
						port_req->dev_num, 0x00,
						SWRS_DP_OFFSET_CONTROL_2_BANK(
						SWRS_DP_OFFSET_CONTROL_2_BANK(
							slv_id, bank));
							slv_id, bank));
			}
			}
			if (mport->hstart != SWR_INVALID_PARAM
				&& mport->hstop != SWR_INVALID_PARAM) {
				hparams = (mport->hstart << 4) | mport->hstop;

				reg[len] = SWRM_CMD_FIFO_WR_CMD;
				val[len++] = SWR_REG_VAL_PACK(hparams,
						port_req->dev_num, 0x00,
						SWRS_DP_HCONTROL_BANK(slv_id,
									bank));
			}
			if (mport->word_length != SWR_INVALID_PARAM) {
				reg[len] = SWRM_CMD_FIFO_WR_CMD;
				val[len++] =
					SWR_REG_VAL_PACK(mport->word_length,
						port_req->dev_num, 0x00,
						SWRS_DP_BLOCK_CONTROL_1(slv_id));
			}
			if (mport->blk_pack_mode != SWR_INVALID_PARAM) {
				reg[len] = SWRM_CMD_FIFO_WR_CMD;
				val[len++] =
					SWR_REG_VAL_PACK(mport->blk_pack_mode,
					port_req->dev_num, 0x00,
					SWRS_DP_BLOCK_CONTROL_3_BANK(slv_id,
									bank));
			}
			if (mport->blk_grp_count != SWR_INVALID_PARAM) {
				reg[len] = SWRM_CMD_FIFO_WR_CMD;
				val[len++] =
					 SWR_REG_VAL_PACK(mport->blk_grp_count,
						port_req->dev_num, 0x00,
						SWRS_DP_BLOCK_CONTROL_2_BANK(slv_id,
									bank));
			}
			if (mport->lane_ctrl != SWR_INVALID_PARAM) {
				reg[len] = SWRM_CMD_FIFO_WR_CMD;
				val[len++] =
					SWR_REG_VAL_PACK(mport->lane_ctrl,
						port_req->dev_num, 0x00,
						SWRS_DP_LANE_CONTROL_BANK(slv_id,
									bank));
			}
			port_req->ch_en = port_req->req_ch;
			port_req->ch_en = port_req->req_ch;
		}
		}
		value = ((mport->req_ch)
		value = ((mport->req_ch)
@@ -790,11 +848,33 @@ static void swrm_copy_data_port_config(struct swr_master *master, u8 bank)


		reg[len] = SWRM_DP_PORT_CTRL_BANK(i + 1, bank);
		reg[len] = SWRM_DP_PORT_CTRL_BANK(i + 1, bank);
		val[len++] = value;
		val[len++] = value;

		dev_dbg(swrm->dev, "%s: mport :%d, reg: 0x%x, val: 0x%x\n",
		dev_dbg(swrm->dev, "%s: mport :%d, reg: 0x%x, val: 0x%x\n",
			__func__, i,
			__func__, i,
			(SWRM_DP_PORT_CTRL_BANK(i + 1, bank)), value);
			(SWRM_DP_PORT_CTRL_BANK(i + 1, bank)), value);


		if (mport->lane_ctrl != SWR_INVALID_PARAM) {
			reg[len] = SWRM_DP_PORT_CTRL_2_BANK(i + 1, bank);
			val[len++] = mport->lane_ctrl;
		}
		if (mport->word_length != SWR_INVALID_PARAM) {
			reg[len] = SWRM_DP_BLOCK_CTRL_1(i + 1);
			val[len++] = mport->word_length;
		}

		if (mport->blk_grp_count != SWR_INVALID_PARAM) {
			reg[len] = SWRM_DP_BLOCK_CTRL2_BANK(i + 1, bank);
			val[len++] = mport->blk_grp_count;
		}
		if (mport->hstart != SWR_INVALID_PARAM
				&& mport->hstop != SWR_INVALID_PARAM) {
			reg[len] = SWRM_DP_PORT_HCTRL_BANK(i + 1, bank);
			hparams = (mport->hstart << 4) | mport->hstop;
			val[len++] = hparams;
		}
		if (mport->blk_pack_mode != SWR_INVALID_PARAM) {
			reg[len] = SWRM_DP_BLOCK_CTRL3_BANK(i + 1, bank);
			val[len++] = mport->blk_pack_mode;
		}
		mport->ch_en = mport->req_ch;
		mport->ch_en = mport->req_ch;


	}
	}
@@ -826,7 +906,7 @@ static void swrm_apply_port_config(struct swr_master *master)
static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable)
static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable)
{
{
	u8 bank;
	u8 bank;
	u32 value, n_col;
	u32 value, n_row, n_col;
	int ret;
	int ret;
	struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master);
	struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master);
	int mask = (SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_BMSK |
	int mask = (SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_BMSK |
@@ -863,21 +943,22 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable)
		__func__, enable, swrm->num_cfg_devs);
		__func__, enable, swrm->num_cfg_devs);


	if (enable) {
	if (enable) {
		/* set Row = 48 and col = 16 */
		/* set col = 16 */
		n_col = SWR_MAX_COL;
		n_col = SWR_MAX_COL;
	} else {
	} else {
		/*
		/*
		 * Do not change to 48x2 if there are still active ports
		 * 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;
			n_col = SWR_MIN_COL;
		else
		else
			n_col = SWR_MAX_COL;
			n_col = SWR_MAX_COL;
	}
	}

	/* Use default 50 * x, frame shape. Change based on mclk */
	n_row = SWR_ROW_50;
	value = swr_master_read(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank));
	value = swr_master_read(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank));
	value &= (~mask);
	value &= (~mask);
	value |= ((0 << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) |
	value |= ((n_row << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) |
		  (n_col << SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT) |
		  (n_col << SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT) |
		  (0 << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT));
		  (0 << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT));
	swr_master_write(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank), value);
	swr_master_write(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank), value);
@@ -885,7 +966,7 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable)
	dev_dbg(swrm->dev, "%s: regaddr: 0x%x, value: 0x%x\n", __func__,
	dev_dbg(swrm->dev, "%s: regaddr: 0x%x, value: 0x%x\n", __func__,
		SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank), value);
		SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank), value);


	enable_bank_switch(swrm, bank, SWR_MAX_ROW, n_col);
	enable_bank_switch(swrm, bank, n_row, n_col);
	inactive_bank = bank ? 0 : 1;
	inactive_bank = bank ? 0 : 1;


	if (enable)
	if (enable)
@@ -1288,7 +1369,7 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm)
{
{
	int ret = 0;
	int ret = 0;
	u32 val;
	u32 val;
	u8 row_ctrl = SWR_MAX_ROW;
	u8 row_ctrl = SWR_ROW_50;
	u8 col_ctrl = SWR_MIN_COL;
	u8 col_ctrl = SWR_MIN_COL;
	u8 ssp_period = 1;
	u8 ssp_period = 1;
	u8 retry_cmd_num = 3;
	u8 retry_cmd_num = 3;
@@ -1374,6 +1455,12 @@ static int swrm_probe(struct platform_device *pdev)
		ret = -EINVAL;
		ret = -EINVAL;
		goto err_pdata_fail;
		goto err_pdata_fail;
	}
	}
	ret = of_property_read_u32(pdev->dev.of_node, "qcom,swr_master_id",
				&swrm->master_id);
	if (ret) {
		dev_err(&pdev->dev, "%s: failed to get master id\n", __func__);
		goto err_pdata_fail;
	}
	if (!(of_property_read_u32(pdev->dev.of_node,
	if (!(of_property_read_u32(pdev->dev.of_node,
			"swrm-io-base", &swrm->swrm_base_reg)))
			"swrm-io-base", &swrm->swrm_base_reg)))
		ret = of_property_read_u32(pdev->dev.of_node,
		ret = of_property_read_u32(pdev->dev.of_node,
@@ -1412,7 +1499,11 @@ static int swrm_probe(struct platform_device *pdev)
		ret = -EINVAL;
		ret = -EINVAL;
		goto err_pdata_fail;
		goto err_pdata_fail;
	}
	}

	if (of_property_read_u32(pdev->dev.of_node,
			"qcom,swr-clock-stop-mode0",
			&swrm->clk_stop_mode0_supp)) {
		swrm->clk_stop_mode0_supp = FALSE;
	}
	/* Parse soundwire port mapping */
	/* Parse soundwire port mapping */
	ret = of_property_read_u32(pdev->dev.of_node, "qcom,swr-num-ports",
	ret = of_property_read_u32(pdev->dev.of_node, "qcom,swr-num-ports",
				&num_ports);
				&num_ports);
@@ -1648,6 +1739,7 @@ static int swrm_runtime_resume(struct device *dev)
			if (swrm_clk_request(swrm, true))
			if (swrm_clk_request(swrm, true))
				goto exit;
				goto exit;
		}
		}
		if (!swrm->clk_stop_mode0_supp) {
			list_for_each_entry(swr_dev, &mstr->devices, dev_list) {
			list_for_each_entry(swr_dev, &mstr->devices, dev_list) {
				ret = swr_device_up(swr_dev);
				ret = swr_device_up(swr_dev);
				if (ret) {
				if (ret) {
@@ -1658,6 +1750,11 @@ static int swrm_runtime_resume(struct device *dev)
					goto exit;
					goto exit;
				}
				}
			}
			}
		} else {
			/*wake up from clock stop*/
			swr_master_write(swrm, SWRM_MCP_BUS_CTRL_ADDR, 0x2);
			usleep_range(100, 105);
		}
		swr_master_write(swrm, SWRM_COMP_SW_RESET, 0x01);
		swr_master_write(swrm, SWRM_COMP_SW_RESET, 0x01);
		swr_master_write(swrm, SWRM_COMP_SW_RESET, 0x01);
		swr_master_write(swrm, SWRM_COMP_SW_RESET, 0x01);
		swrm_master_init(swrm);
		swrm_master_init(swrm);
@@ -1693,6 +1790,7 @@ static int swrm_runtime_suspend(struct device *dev)
			ret = -EBUSY;
			ret = -EBUSY;
			goto exit;
			goto exit;
		}
		}
		if (!swrm->clk_stop_mode0_supp) {
			swrm_clk_pause(swrm);
			swrm_clk_pause(swrm);
			swr_master_write(swrm, SWRM_COMP_CFG_ADDR, 0x00);
			swr_master_write(swrm, SWRM_COMP_CFG_ADDR, 0x00);
			list_for_each_entry(swr_dev, &mstr->devices, dev_list) {
			list_for_each_entry(swr_dev, &mstr->devices, dev_list) {
@@ -1704,6 +1802,12 @@ static int swrm_runtime_suspend(struct device *dev)
					goto exit;
					goto exit;
				}
				}
			}
			}
		} else {
			/* clock stop sequence */
			swrm_cmd_fifo_wr_cmd(swrm, 0x2, 0xF, 0xF,
					SWRS_SCP_CONTROL);
			usleep_range(100, 105);
		}
		swrm_clk_request(swrm, false);
		swrm_clk_request(swrm, false);
	}
	}
exit:
exit:
+13 −1
Original line number Original line Diff line number Diff line
@@ -15,7 +15,9 @@
#include <linux/module.h>
#include <linux/module.h>
#include <soc/swr-wcd.h>
#include <soc/swr-wcd.h>


#define SWR_MAX_ROW		0 /* Rows = 48 */
#define SWR_ROW_48		0
#define SWR_ROW_50		1
#define SWR_ROW_64		2
#define SWR_MAX_COL		7 /* Cols = 16 */
#define SWR_MAX_COL		7 /* Cols = 16 */
#define SWR_MIN_COL		0 /* Cols = 2 */
#define SWR_MIN_COL		0 /* Cols = 2 */


@@ -62,6 +64,12 @@ struct port_params {
	u8 si;
	u8 si;
	u8 off1;
	u8 off1;
	u8 off2;
	u8 off2;
	u8 hstart;/* head start */
	u8 hstop; /* head stop */
	u8 wd_len;/* word length */
	u8 bp_mode; /* block pack mode */
	u8 bgp_ctrl;/* block group control */
	u8 lane_ctrl;/* lane to be used */
};
};


struct swrm_mports {
struct swrm_mports {
@@ -77,6 +85,8 @@ struct swrm_mports {
	u8 hstop;
	u8 hstop;
	u8 blk_grp_count;
	u8 blk_grp_count;
	u8 blk_pack_mode;
	u8 blk_pack_mode;
	u8 word_length;
	u8 lane_ctrl;
};
};


struct swrm_port_type {
struct swrm_port_type {
@@ -109,6 +119,7 @@ struct swr_mstr_ctrl {
	char __iomem *swrm_dig_base;
	char __iomem *swrm_dig_base;
	u8 rcmd_id;
	u8 rcmd_id;
	u8 wcmd_id;
	u8 wcmd_id;
	u32 master_id;
	void *handle; /* SWR Master handle from client for read and writes */
	void *handle; /* SWR Master handle from client for read and writes */
	int (*read)(void *handle, int reg);
	int (*read)(void *handle, int reg);
	int (*write)(void *handle, int reg, int val);
	int (*write)(void *handle, int reg, int val);
@@ -132,6 +143,7 @@ struct swr_mstr_ctrl {
	struct swrm_port_type
	struct swrm_port_type
			port_mapping[SWR_MSTR_PORT_LEN][SWR_MAX_CH_PER_PORT];
			port_mapping[SWR_MSTR_PORT_LEN][SWR_MAX_CH_PER_PORT];
	int swr_irq;
	int swr_irq;
	u32 clk_stop_mode0_supp;
};
};


#endif /* _SWR_WCD_CTRL_H */
#endif /* _SWR_WCD_CTRL_H */
+37 −8
Original line number Original line Diff line number Diff line
@@ -15,15 +15,44 @@


#define WSA_MSTR_PORT_MASK 0xFF
#define WSA_MSTR_PORT_MASK 0xFF



/*
 * Add port configuration in the format
 *{ si, off1, off2, hstart, hstop, wd_len, bp_mode, bgp_ctrl, lane_ctrl}
 */

struct port_params wsa_frame_superset[SWR_MSTR_PORT_LEN] = {
struct port_params wsa_frame_superset[SWR_MSTR_PORT_LEN] = {
		{7, 1, 0},
	{7,  1,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
		{31, 2, 0},
	{31, 2,  0,    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
		{63, 12, 31},
	{63, 12, 31,   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
		{7, 6, 0},
	{7,  6,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
		{31, 18, 0},
	{31, 18, 0,    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
		{63, 13, 31},
	{63, 13, 31,   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
		{15, 7, 0},
	{15, 7,  0,    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
		{15, 10, 0},
	{15, 10, 0,    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
};

struct port_params rx_frame_params[SWR_MSTR_PORT_LEN] = {
	{3,  0,  0,  0xFF, 0xFF, 1,    0xFF, 0xFF, 1},
	{31, 0,  0,  3,    6,    7,    0,    0xFF, 0},
	{31, 11, 11, 0xFF, 0xFF, 4,    1,    0xFF, 0},
	{3,  1,  0,  0xFF, 0xFF, 0xFF, 0xFF, 1,    0},
	{0,  0,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0,    0},
};

struct port_params rx_frame_params_dsd[SWR_MSTR_PORT_LEN] = {
	{3,  0,  0,  0xFF, 0xFF, 1,    0xFF, 0xFF, 1},
	{31, 0,  0,  3,    6,    7,    0,    0xFF, 0},
	{31, 11, 11, 0xFF, 0xFF, 4,    1,    0xFF, 0},
	{7,  9,  0,  0xFF, 0xFF, 0xFF, 0xFF, 1,    0},
	{3,  1,  0,  0xFF, 0xFF, 0xFF, 0xFF, 3,    0},
};

struct port_params tx_frame_params_superset[SWR_MSTR_PORT_LEN] = {
	{1,  1,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0},
	{1,  0,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1},
	{3,  1,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0},
	{3,  0,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1},
};
};


#endif /* _SWRM_REGISTERS_H */
#endif /* _SWRM_REGISTERS_H */