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

Commit 6331a9e9 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: ipa4: MBIM workaround"

parents 3914cd5b 441322cd
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -3484,7 +3484,7 @@ static unsigned int ipa3_get_bus_vote(void)
	} else {
		WARN(1, "unexpected clock rate");
	}
	IPADBG("curr %d idx %d\n", ipa3_ctx->curr_ipa_clk_rate, idx);
	IPADBG_LOW("curr %d idx %d\n", ipa3_ctx->curr_ipa_clk_rate, idx);

	return idx;
}
+33 −0
Original line number Diff line number Diff line
@@ -391,6 +391,8 @@ int ipa3_reset_gsi_channel(u32 clnt_hdl)
	int result = -EFAULT;
	enum gsi_status gsi_res;
	int aggr_active_bitmap = 0;
	bool undo_aggr_value = false;
	struct ipahal_reg_clkon_cfg fields;

	IPADBG("entry\n");
	if (clnt_hdl >= ipa3_ctx->ipa_num_pipes ||
@@ -403,6 +405,25 @@ int ipa3_reset_gsi_channel(u32 clnt_hdl)

	if (!ep->keep_ipa_awake)
		IPA_ACTIVE_CLIENTS_INC_EP(ipa3_get_client_mapping(clnt_hdl));

	/*
	 * IPAv4.0 HW has a limitation where WSEQ in MBIM NTH header is not
	 * reset to 0 when MBIM pipe is reset. Workaround is to disable
	 * HW clock gating for AGGR block using IPA_CLKON_CFG reg. undo flag to
	 * disable the bit after reset is finished
	 */
	if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) {
		if (ep->cfg.aggr.aggr == IPA_MBIM_16 &&
			ep->cfg.aggr.aggr_en != IPA_BYPASS_AGGR) {
			ipahal_read_reg_fields(IPA_CLKON_CFG, &fields);
			if (fields.open_aggr_wrapper == true) {
				undo_aggr_value = true;
				fields.open_aggr_wrapper = false;
				ipahal_write_reg_fields(IPA_CLKON_CFG, &fields);
			}
		}
	}

	/*
	 * Check for open aggregation frame on Consumer EP -
	 * reset with open aggregation frame WA
@@ -434,10 +455,22 @@ int ipa3_reset_gsi_channel(u32 clnt_hdl)
	if (!ep->keep_ipa_awake)
		IPA_ACTIVE_CLIENTS_DEC_EP(ipa3_get_client_mapping(clnt_hdl));

	/* undo the aggr value if flag was set above*/
	if (undo_aggr_value) {
		fields.open_aggr_wrapper = false;
		ipahal_write_reg_fields(IPA_CLKON_CFG, &fields);
	}

	IPADBG("exit\n");
	return 0;

reset_chan_fail:
	/* undo the aggr value if flag was set above*/
	if (undo_aggr_value) {
		fields.open_aggr_wrapper = false;
		ipahal_write_reg_fields(IPA_CLKON_CFG, &fields);
	}

	if (!ep->keep_ipa_awake)
		IPA_ACTIVE_CLIENTS_DEC_EP(ipa3_get_client_mapping(clnt_hdl));
	return result;
+12 −6
Original line number Diff line number Diff line
@@ -57,7 +57,6 @@
#define IPA_BCR_REG_VAL_v3_0 (0x00000001)
#define IPA_BCR_REG_VAL_v3_5 (0x0000003B)
#define IPA_BCR_REG_VAL_v4_0 (0x00000039)
#define IPA_CLKON_CFG_v4_0 (0x30000000)
#define IPA_AGGR_GRAN_MIN (1)
#define IPA_AGGR_GRAN_MAX (32)
#define IPA_EOT_COAL_GRAN_MIN (1)
@@ -2284,13 +2283,20 @@ int ipa3_init_hw(void)
	ipahal_write_reg(IPA_BCR, val);

	if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) {
		struct ipahal_reg_tx_cfg cfg;
		struct ipahal_reg_clkon_cfg clkon_cfg;
		struct ipahal_reg_tx_cfg tx_cfg;

		ipahal_write_reg(IPA_CLKON_CFG, IPA_CLKON_CFG_v4_0);
		ipahal_read_reg_fields(IPA_TX_CFG, &cfg);
		memset(&clkon_cfg, 0, sizeof(clkon_cfg));

		/*enable open global clocks*/
		clkon_cfg.open_global_2x_clk = true;
		clkon_cfg.open_global = true;
		ipahal_write_reg_fields(IPA_CLKON_CFG, &clkon_cfg);

		ipahal_read_reg_fields(IPA_TX_CFG, &tx_cfg);
		/* disable PA_MASK_EN to allow holb drop */
		cfg.pa_mask_en = 0;
		ipahal_write_reg_fields(IPA_TX_CFG, &cfg);
		tx_cfg.pa_mask_en = 0;
		ipahal_write_reg_fields(IPA_TX_CFG, &tx_cfg);
	}

	ipa3_cfg_qsb();
+256 −1
Original line number Diff line number Diff line
@@ -399,6 +399,261 @@ static void ipareg_construct_endp_status_n_v4_0(
			IPA_ENDP_STATUS_n_STATUS_PKT_SUPPRESS_BMSK);
}

static void ipareg_construct_clkon_cfg(
	enum ipahal_reg_name reg, const void *fields, u32 *val)
{
	struct ipahal_reg_clkon_cfg *clkon_cfg =
		(struct ipahal_reg_clkon_cfg *)fields;

	IPA_SETFIELD_IN_REG(*val, clkon_cfg->open_global_2x_clk,
			IPA_CLKON_CFG_OPEN_GLOBAL_2X_CLK_SHFT,
			IPA_CLKON_CFG_OPEN_GLOBAL_2X_CLK_BMSK);

	IPA_SETFIELD_IN_REG(*val, clkon_cfg->open_global,
			IPA_CLKON_CFG_OPEN_GLOBAL_SHFT,
			IPA_CLKON_CFG_OPEN_GLOBAL_BMSK);

	IPA_SETFIELD_IN_REG(*val, clkon_cfg->open_gsi_if,
			IPA_CLKON_CFG_OPEN_GSI_IF_SHFT,
			IPA_CLKON_CFG_OPEN_GSI_IF_BMSK);

	IPA_SETFIELD_IN_REG(*val, clkon_cfg->open_weight_arb,
			IPA_CLKON_CFG_OPEN_WEIGHT_ARB_SHFT,
			IPA_CLKON_CFG_OPEN_WEIGHT_ARB_BMSK);

	IPA_SETFIELD_IN_REG(*val, clkon_cfg->open_qmb,
			IPA_CLKON_CFG_OPEN_QMB_SHFT,
			IPA_CLKON_CFG_OPEN_QMB_BMSK);

	IPA_SETFIELD_IN_REG(*val, clkon_cfg->open_ram_slaveway,
			IPA_CLKON_CFG_OPEN_RAM_SLAVEWAY_SHFT,
			IPA_CLKON_CFG_OPEN_RAM_SLAVEWAY_BMSK);

	IPA_SETFIELD_IN_REG(*val, clkon_cfg->open_aggr_wrapper,
			IPA_CLKON_CFG_OPEN_AGGR_WRAPPER_SHFT,
			IPA_CLKON_CFG_OPEN_AGGR_WRAPPER_BMSK);

	IPA_SETFIELD_IN_REG(*val, clkon_cfg->open_qsb2axi_cmdq_l,
			IPA_CLKON_CFG_OPEN_QSB2AXI_CMDQ_L_SHFT,
			IPA_CLKON_CFG_OPEN_QSB2AXI_CMDQ_L_BMSK);

	IPA_SETFIELD_IN_REG(*val, clkon_cfg->open_fnr,
			IPA_CLKON_CFG_OPEN_FNR_SHFT,
			IPA_CLKON_CFG_OPEN_FNR_BMSK);

	IPA_SETFIELD_IN_REG(*val, clkon_cfg->open_tx_1,
			IPA_CLKON_CFG_OPEN_TX_1_SHFT,
			IPA_CLKON_CFG_OPEN_TX_1_BMSK);

	IPA_SETFIELD_IN_REG(*val, clkon_cfg->open_tx_0,
			IPA_CLKON_CFG_OPEN_TX_0_SHFT,
			IPA_CLKON_CFG_OPEN_TX_0_BMSK);

	IPA_SETFIELD_IN_REG(*val, clkon_cfg->open_ntf_tx_cmdqs,
			IPA_CLKON_CFG_OPEN_NTF_TX_CMDQS_SHFT,
			IPA_CLKON_CFG_OPEN_NTF_TX_CMDQS_BMSK);

	IPA_SETFIELD_IN_REG(*val, clkon_cfg->open_dcmp,
			IPA_CLKON_CFG_OPEN_DCMP_SHFT,
			IPA_CLKON_CFG_OPEN_DCMP_BMSK);

	IPA_SETFIELD_IN_REG(*val, clkon_cfg->open_h_dcph,
			IPA_CLKON_CFG_OPEN_H_DCPH_SHFT,
			IPA_CLKON_CFG_OPEN_H_DCPH_BMSK);

	IPA_SETFIELD_IN_REG(*val, clkon_cfg->open_d_dcph,
			IPA_CLKON_CFG_OPEN_D_DCPH_SHFT,
			IPA_CLKON_CFG_OPEN_D_DCPH_BMSK);

	IPA_SETFIELD_IN_REG(*val, clkon_cfg->open_ack_mngr,
			IPA_CLKON_CFG_OPEN_ACK_MNGR_SHFT,
			IPA_CLKON_CFG_OPEN_ACK_MNGR_BMSK);

	IPA_SETFIELD_IN_REG(*val, clkon_cfg->open_ctx_handler,
			IPA_CLKON_CFG_OPEN_CTX_HANDLER_SHFT,
			IPA_CLKON_CFG_OPEN_CTX_HANDLER_BMSK);

	IPA_SETFIELD_IN_REG(*val, clkon_cfg->open_rsrc_mngr,
			IPA_CLKON_CFG_OPEN_RSRC_MNGR_SHFT,
			IPA_CLKON_CFG_OPEN_RSRC_MNGR_BMSK);

	IPA_SETFIELD_IN_REG(*val, clkon_cfg->open_dps_tx_cmdqs,
			IPA_CLKON_CFG_OPEN_DPS_TX_CMDQS_SHFT,
			IPA_CLKON_CFG_OPEN_DPS_TX_CMDQS_BMSK);

	IPA_SETFIELD_IN_REG(*val, clkon_cfg->open_hps_dps_cmdqs,
			IPA_CLKON_CFG_OPEN_HPS_DPS_CMDQS_SHFT,
			IPA_CLKON_CFG_OPEN_HPS_DPS_CMDQS_BMSK);

	IPA_SETFIELD_IN_REG(*val, clkon_cfg->open_rx_hps_cmdqs,
			IPA_CLKON_CFG_OPEN_RX_HPS_CMDQS_SHFT,
			IPA_CLKON_CFG_OPEN_RX_HPS_CMDQS_BMSK);

	IPA_SETFIELD_IN_REG(*val, clkon_cfg->open_dps,
			IPA_CLKON_CFG_OPEN_DPS_SHFT,
			IPA_CLKON_CFG_OPEN_DPS_BMSK);

	IPA_SETFIELD_IN_REG(*val, clkon_cfg->open_hps,
			IPA_CLKON_CFG_OPEN_HPS_SHFT,
			IPA_CLKON_CFG_OPEN_HPS_BMSK);

	IPA_SETFIELD_IN_REG(*val, clkon_cfg->open_ftch_dps,
			IPA_CLKON_CFG_OPEN_FTCH_DPS_SHFT,
			IPA_CLKON_CFG_OPEN_FTCH_DPS_BMSK);

	IPA_SETFIELD_IN_REG(*val, clkon_cfg->open_ftch_hps,
			IPA_CLKON_CFG_OPEN_FTCH_HPS_SHFT,
			IPA_CLKON_CFG_OPEN_FTCH_HPS_BMSK);

	IPA_SETFIELD_IN_REG(*val, clkon_cfg->open_ram_arb,
			IPA_CLKON_CFG_OPEN_RAM_ARB_SHFT,
			IPA_CLKON_CFG_OPEN_RAM_ARB_BMSK);

	IPA_SETFIELD_IN_REG(*val, clkon_cfg->open_misc,
			IPA_CLKON_CFG_OPEN_MISC_SHFT,
			IPA_CLKON_CFG_OPEN_MISC_BMSK);

	IPA_SETFIELD_IN_REG(*val, clkon_cfg->open_tx_wrapper,
			IPA_CLKON_CFG_OPEN_TX_WRAPPER_SHFT,
			IPA_CLKON_CFG_OPEN_TX_WRAPPER_BMSK);

	IPA_SETFIELD_IN_REG(*val, clkon_cfg->open_proc,
			IPA_CLKON_CFG_OPEN_PROC_SHFT,
			IPA_CLKON_CFG_OPEN_PROC_BMSK);

	IPA_SETFIELD_IN_REG(*val, clkon_cfg->open_rx,
			IPA_CLKON_CFG_OPEN_RX_SHFT,
			IPA_CLKON_CFG_OPEN_RX_BMSK);
}

static void ipareg_parse_clkon_cfg(
	enum ipahal_reg_name reg, void *fields, u32 val)
{
	struct ipahal_reg_clkon_cfg *clkon_cfg =
		(struct ipahal_reg_clkon_cfg *)fields;

	memset(clkon_cfg, 0, sizeof(struct ipahal_reg_clkon_cfg));
	clkon_cfg->open_global_2x_clk = IPA_GETFIELD_FROM_REG(val,
			IPA_CLKON_CFG_OPEN_GLOBAL_2X_CLK_SHFT,
			IPA_CLKON_CFG_OPEN_GLOBAL_2X_CLK_BMSK);

	clkon_cfg->open_global = IPA_GETFIELD_FROM_REG(val,
			IPA_CLKON_CFG_OPEN_GLOBAL_SHFT,
			IPA_CLKON_CFG_OPEN_GLOBAL_BMSK);

	clkon_cfg->open_gsi_if = IPA_GETFIELD_FROM_REG(val,
			IPA_CLKON_CFG_OPEN_GSI_IF_SHFT,
			IPA_CLKON_CFG_OPEN_GSI_IF_BMSK);

	clkon_cfg->open_weight_arb = IPA_GETFIELD_FROM_REG(val,
			IPA_CLKON_CFG_OPEN_WEIGHT_ARB_SHFT,
			IPA_CLKON_CFG_OPEN_WEIGHT_ARB_BMSK);

	clkon_cfg->open_qmb = IPA_GETFIELD_FROM_REG(val,
			IPA_CLKON_CFG_OPEN_QMB_SHFT,
			IPA_CLKON_CFG_OPEN_QMB_BMSK);

	clkon_cfg->open_ram_slaveway = IPA_GETFIELD_FROM_REG(val,
			IPA_CLKON_CFG_OPEN_RAM_SLAVEWAY_SHFT,
			IPA_CLKON_CFG_OPEN_RAM_SLAVEWAY_BMSK);

	clkon_cfg->open_aggr_wrapper = IPA_GETFIELD_FROM_REG(val,
			IPA_CLKON_CFG_OPEN_AGGR_WRAPPER_SHFT,
			IPA_CLKON_CFG_OPEN_AGGR_WRAPPER_BMSK);

	clkon_cfg->open_qsb2axi_cmdq_l = IPA_GETFIELD_FROM_REG(val,
			IPA_CLKON_CFG_OPEN_QSB2AXI_CMDQ_L_SHFT,
			IPA_CLKON_CFG_OPEN_QSB2AXI_CMDQ_L_BMSK);

	clkon_cfg->open_fnr = IPA_GETFIELD_FROM_REG(val,
			IPA_CLKON_CFG_OPEN_FNR_SHFT,
			IPA_CLKON_CFG_OPEN_FNR_BMSK);

	clkon_cfg->open_tx_1 = IPA_GETFIELD_FROM_REG(val,
			IPA_CLKON_CFG_OPEN_TX_1_SHFT,
			IPA_CLKON_CFG_OPEN_TX_1_BMSK);

	clkon_cfg->open_tx_0 = IPA_GETFIELD_FROM_REG(val,
			IPA_CLKON_CFG_OPEN_TX_0_SHFT,
			IPA_CLKON_CFG_OPEN_TX_0_BMSK);

	clkon_cfg->open_ntf_tx_cmdqs = IPA_GETFIELD_FROM_REG(val,
			IPA_CLKON_CFG_OPEN_NTF_TX_CMDQS_SHFT,
			IPA_CLKON_CFG_OPEN_NTF_TX_CMDQS_BMSK);

	clkon_cfg->open_dcmp = IPA_GETFIELD_FROM_REG(val,
			IPA_CLKON_CFG_OPEN_DCMP_SHFT,
			IPA_CLKON_CFG_OPEN_DCMP_BMSK);

	clkon_cfg->open_h_dcph = IPA_GETFIELD_FROM_REG(val,
			IPA_CLKON_CFG_OPEN_H_DCPH_SHFT,
			IPA_CLKON_CFG_OPEN_H_DCPH_BMSK);

	clkon_cfg->open_d_dcph = IPA_GETFIELD_FROM_REG(val,
			IPA_CLKON_CFG_OPEN_D_DCPH_SHFT,
			IPA_CLKON_CFG_OPEN_D_DCPH_BMSK);

	clkon_cfg->open_ack_mngr = IPA_GETFIELD_FROM_REG(val,
			IPA_CLKON_CFG_OPEN_ACK_MNGR_SHFT,
			IPA_CLKON_CFG_OPEN_ACK_MNGR_BMSK);

	clkon_cfg->open_ctx_handler = IPA_GETFIELD_FROM_REG(val,
			IPA_CLKON_CFG_OPEN_CTX_HANDLER_SHFT,
			IPA_CLKON_CFG_OPEN_CTX_HANDLER_BMSK);

	clkon_cfg->open_rsrc_mngr = IPA_GETFIELD_FROM_REG(val,
			IPA_CLKON_CFG_OPEN_RSRC_MNGR_SHFT,
			IPA_CLKON_CFG_OPEN_RSRC_MNGR_BMSK);

	clkon_cfg->open_dps_tx_cmdqs = IPA_GETFIELD_FROM_REG(val,
			IPA_CLKON_CFG_OPEN_DPS_TX_CMDQS_SHFT,
			IPA_CLKON_CFG_OPEN_DPS_TX_CMDQS_BMSK);

	clkon_cfg->open_hps_dps_cmdqs = IPA_GETFIELD_FROM_REG(val,
			IPA_CLKON_CFG_OPEN_HPS_DPS_CMDQS_SHFT,
			IPA_CLKON_CFG_OPEN_HPS_DPS_CMDQS_BMSK);

	clkon_cfg->open_rx_hps_cmdqs = IPA_GETFIELD_FROM_REG(val,
			IPA_CLKON_CFG_OPEN_RX_HPS_CMDQS_SHFT,
			IPA_CLKON_CFG_OPEN_RX_HPS_CMDQS_BMSK);

	clkon_cfg->open_dps = IPA_GETFIELD_FROM_REG(val,
			IPA_CLKON_CFG_OPEN_DPS_SHFT,
			IPA_CLKON_CFG_OPEN_DPS_BMSK);

	clkon_cfg->open_hps = IPA_GETFIELD_FROM_REG(val,
			IPA_CLKON_CFG_OPEN_HPS_SHFT,
			IPA_CLKON_CFG_OPEN_HPS_BMSK);

	clkon_cfg->open_ftch_dps = IPA_GETFIELD_FROM_REG(val,
			IPA_CLKON_CFG_OPEN_FTCH_DPS_SHFT,
			IPA_CLKON_CFG_OPEN_FTCH_DPS_BMSK);

	clkon_cfg->open_ftch_hps = IPA_GETFIELD_FROM_REG(val,
			IPA_CLKON_CFG_OPEN_FTCH_HPS_SHFT,
			IPA_CLKON_CFG_OPEN_FTCH_HPS_BMSK);

	clkon_cfg->open_ram_arb = IPA_GETFIELD_FROM_REG(val,
			IPA_CLKON_CFG_OPEN_RAM_ARB_SHFT,
			IPA_CLKON_CFG_OPEN_RAM_ARB_BMSK);

	clkon_cfg->open_misc = IPA_GETFIELD_FROM_REG(val,
			IPA_CLKON_CFG_OPEN_MISC_SHFT,
			IPA_CLKON_CFG_OPEN_MISC_BMSK);

	clkon_cfg->open_tx_wrapper = IPA_GETFIELD_FROM_REG(val,
			IPA_CLKON_CFG_OPEN_TX_WRAPPER_SHFT,
			IPA_CLKON_CFG_OPEN_TX_WRAPPER_BMSK);

	clkon_cfg->open_proc = IPA_GETFIELD_FROM_REG(val,
			IPA_CLKON_CFG_OPEN_PROC_SHFT,
			IPA_CLKON_CFG_OPEN_PROC_BMSK);

	clkon_cfg->open_rx = IPA_GETFIELD_FROM_REG(val,
			IPA_CLKON_CFG_OPEN_RX_SHFT,
			IPA_CLKON_CFG_OPEN_RX_BMSK);
}

static void ipareg_construct_qcncm(
	enum ipahal_reg_name reg, const void *fields, u32 *val)
{
@@ -1522,7 +1777,7 @@ static struct ipahal_reg_obj ipahal_reg_objs[IPA_HW_MAX][IPA_REG_MAX] = {
		ipareg_construct_endp_status_n_v4_0, ipareg_parse_dummy,
		0x00000840, 0x70},
	[IPA_HW_v4_0][IPA_CLKON_CFG] = {
		ipareg_construct_dummy, ipareg_parse_dummy,
		ipareg_construct_clkon_cfg, ipareg_parse_clkon_cfg,
		0x00000044, 0},
	[IPA_HW_v4_0][IPA_ENDP_INIT_CONN_TRACK_n] = {
		ipareg_construct_endp_init_conn_track_n,
+41 −0
Original line number Diff line number Diff line
@@ -198,6 +198,47 @@ struct ipahal_reg_ep_cfg_status {
	u8 status_pkt_suppress;
};

/*
 * struct ipahal_reg_clkon_cfg-  Enables SW bypass clock-gating for the IPA core
 *
 * @all: Enables SW bypass clock-gating controls for this sub-module;
 *	0: CGC is enabled by internal logic, 1: No CGC (clk is always 'ON').
 *	sub-module affected is based on var name -> ex: open_rx refers
 *	to IPA_RX sub-module and open_global refers to global IPA 1x clock
 */
struct ipahal_reg_clkon_cfg {
	bool open_global_2x_clk;
	bool open_global;
	bool open_gsi_if;
	bool open_weight_arb;
	bool open_qmb;
	bool open_ram_slaveway;
	bool open_aggr_wrapper;
	bool open_qsb2axi_cmdq_l;
	bool open_fnr;
	bool open_tx_1;
	bool open_tx_0;
	bool open_ntf_tx_cmdqs;
	bool open_dcmp;
	bool open_h_dcph;
	bool open_d_dcph;
	bool open_ack_mngr;
	bool open_ctx_handler;
	bool open_rsrc_mngr;
	bool open_dps_tx_cmdqs;
	bool open_hps_dps_cmdqs;
	bool open_rx_hps_cmdqs;
	bool open_dps;
	bool open_hps;
	bool open_ftch_dps;
	bool open_ftch_hps;
	bool open_ram_arb;
	bool open_misc;
	bool open_tx_wrapper;
	bool open_proc;
	bool open_rx;
};

/*
 * struct ipa_hash_tuple - Hash tuple members for flt and rt
 *  the fields tells if to be masked or not
Loading