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

Commit 41644243 authored by Amir Levy's avatar Amir Levy
Browse files

msm: gsi: driver upgrade for gsi version 1.2 and 1.3



Add support to handle different HW versions on the driver.
Update register/sequences per HPG.

Change-Id: Ibb6b1ce3a035260edbba61c2a443bbda09b17cee
CRs-Fixed: 1019773
Acked-by: default avatarAdy Abraham <adya@qti.qualcomm.com>
Signed-off-by: default avatarSkylar Chang <chiaweic@codeaurora.org>
Signed-off-by: default avatarGidon Studinski <gidons@codeaurora.org>
Signed-off-by: default avatarAmir Levy <alevy@codeaurora.org>
parent cdccd636
Loading
Loading
Loading
Loading
+174 −41
Original line number Diff line number Diff line
@@ -170,7 +170,12 @@ static void gsi_handle_glob_err(uint32_t err)
		gsi_ctx->per.notify_cb(&per_notify);
		break;
	case GSI_ERR_TYPE_CHAN:
		BUG_ON(log->virt_idx >= GSI_MAX_CHAN);
		if (log->virt_idx >= gsi_ctx->max_ch) {
			GSIERR("Unexpected ch %d\n", log->virt_idx);
			WARN_ON(1);
			return;
		}

		ch = &gsi_ctx->chan[log->virt_idx];
		chan_notify.chan_user_data = ch->props.chan_user_data;
		chan_notify.err_desc = err & 0xFFFF;
@@ -213,7 +218,12 @@ static void gsi_handle_glob_err(uint32_t err)
			WARN_ON(1);
		break;
	case GSI_ERR_TYPE_EVT:
		BUG_ON(log->virt_idx >= GSI_MAX_EVT_RING);
		if (log->virt_idx >= gsi_ctx->max_ev) {
			GSIERR("Unexpected ev %d\n", log->virt_idx);
			WARN_ON(1);
			return;
		}

		ev = &gsi_ctx->evtr[log->virt_idx];
		evt_notify.user_data = ev->props.user_data;
		evt_notify.err_desc = err & 0xFFFF;
@@ -257,6 +267,9 @@ static void gsi_handle_glob_ee(int ee)
	if (val & GSI_EE_n_CNTXT_GLOB_IRQ_STTS_ERROR_INT_BMSK) {
		err = gsi_readl(gsi_ctx->base +
			GSI_EE_n_ERROR_LOG_OFFS(ee));
		if (gsi_ctx->per.ver >= GSI_VER_1_2)
			gsi_writel(0, gsi_ctx->base +
				GSI_EE_n_ERROR_LOG_OFFS(ee));
		gsi_writel(clr, gsi_ctx->base +
			GSI_EE_n_ERROR_LOG_CLR_OFFS(ee));
		gsi_handle_glob_err(err);
@@ -311,7 +324,12 @@ static void gsi_process_chan(struct gsi_xfer_compl_evt *evt,
	uint64_t rp;

	ch_id = evt->chid;
	BUG_ON(ch_id >= GSI_MAX_CHAN);
	if (ch_id >= gsi_ctx->max_ch) {
		GSIERR("Unexpected ch %d\n", ch_id);
		WARN_ON(1);
		return;
	}

	ch_ctx = &gsi_ctx->chan[ch_id];
	BUG_ON(ch_ctx->props.prot != GSI_CHAN_PROT_GPI);
	rp = evt->xfer_ptr;
@@ -567,6 +585,75 @@ static irqreturn_t gsi_isr(int irq, void *ctxt)
	return IRQ_HANDLED;
}

static uint32_t gsi_get_max_channels(enum gsi_ver ver)
{
	uint32_t reg;

	switch (ver) {
	case GSI_VER_1_0:
		reg = gsi_readl(gsi_ctx->base +
			GSI_V1_0_EE_n_GSI_HW_PARAM_OFFS(gsi_ctx->per.ee));
		reg = (reg & GSI_V1_0_EE_n_GSI_HW_PARAM_GSI_CH_NUM_BMSK) >>
			GSI_V1_0_EE_n_GSI_HW_PARAM_GSI_CH_NUM_SHFT;
		break;
	case GSI_VER_1_2:
		reg = gsi_readl(gsi_ctx->base +
			GSI_V1_2_EE_n_GSI_HW_PARAM_0_OFFS(gsi_ctx->per.ee));
		reg = (reg & GSI_V1_2_EE_n_GSI_HW_PARAM_0_GSI_CH_NUM_BMSK) >>
			GSI_V1_2_EE_n_GSI_HW_PARAM_0_GSI_CH_NUM_SHFT;
		break;
	case GSI_VER_1_3:
		reg = gsi_readl(gsi_ctx->base +
			GSI_V1_3_EE_n_GSI_HW_PARAM_2_OFFS(gsi_ctx->per.ee));
		reg = (reg &
			GSI_V1_3_EE_n_GSI_HW_PARAM_2_GSI_NUM_CH_PER_EE_BMSK) >>
			GSI_V1_3_EE_n_GSI_HW_PARAM_2_GSI_NUM_CH_PER_EE_SHFT;
		break;
	default:
		GSIERR("bad gsi version %d\n", ver);
		WARN_ON(1);
		reg = 0;
	}

	GSIDBG("max channels %d\n", reg);

	return reg;
}

static uint32_t gsi_get_max_event_rings(enum gsi_ver ver)
{
	uint32_t reg;

	switch (ver) {
	case GSI_VER_1_0:
		reg = gsi_readl(gsi_ctx->base +
			GSI_V1_0_EE_n_GSI_HW_PARAM_OFFS(gsi_ctx->per.ee));
		reg = (reg & GSI_V1_0_EE_n_GSI_HW_PARAM_GSI_EV_CH_NUM_BMSK) >>
			GSI_V1_0_EE_n_GSI_HW_PARAM_GSI_EV_CH_NUM_SHFT;
		break;
	case GSI_VER_1_2:
		reg = gsi_readl(gsi_ctx->base +
			GSI_V1_2_EE_n_GSI_HW_PARAM_0_OFFS(gsi_ctx->per.ee));
		reg = (reg & GSI_V1_2_EE_n_GSI_HW_PARAM_0_GSI_EV_CH_NUM_BMSK) >>
			GSI_V1_2_EE_n_GSI_HW_PARAM_0_GSI_EV_CH_NUM_SHFT;
		break;
	case GSI_VER_1_3:
		reg = gsi_readl(gsi_ctx->base +
			GSI_V1_3_EE_n_GSI_HW_PARAM_2_OFFS(gsi_ctx->per.ee));
		reg = (reg &
			GSI_V1_3_EE_n_GSI_HW_PARAM_2_GSI_NUM_EV_PER_EE_BMSK) >>
			GSI_V1_3_EE_n_GSI_HW_PARAM_2_GSI_NUM_EV_PER_EE_SHFT;
		break;
	default:
		GSIERR("bad gsi version %d\n", ver);
		WARN_ON(1);
		reg = 0;
	}

	GSIDBG("max event rings %d\n", reg);

	return reg;
}
int gsi_complete_clk_grant(unsigned long dev_hdl)
{
	unsigned long flags;
@@ -611,6 +698,11 @@ int gsi_register_device(struct gsi_per_props *props, unsigned long *dev_hdl)
		return -GSI_STATUS_INVALID_PARAMS;
	}

	if (props->ver <= GSI_VER_ERR || props->ver >= GSI_VER_MAX) {
		GSIERR("bad params gsi_ver=%d\n", props->ver);
		return -GSI_STATUS_INVALID_PARAMS;
	}

	if (!props->notify_cb) {
		GSIERR("notify callback must be provided\n");
		return -GSI_STATUS_INVALID_PARAMS;
@@ -668,8 +760,25 @@ int gsi_register_device(struct gsi_per_props *props, unsigned long *dev_hdl)
	mutex_init(&gsi_ctx->mlock);
	atomic_set(&gsi_ctx->num_chan, 0);
	atomic_set(&gsi_ctx->num_evt_ring, 0);
	/* only support 16 un-reserved + 7 reserved event virtual IDs */
	gsi_ctx->evt_bmap = ~0x7E03FF;
	gsi_ctx->max_ch = gsi_get_max_channels(gsi_ctx->per.ver);
	if (gsi_ctx->max_ch == 0) {
		devm_iounmap(gsi_ctx->dev, gsi_ctx->base);
		devm_free_irq(gsi_ctx->dev, props->irq, gsi_ctx);
		GSIERR("failed to get max channels\n");
		return -GSI_STATUS_ERROR;
	}
	gsi_ctx->max_ev = gsi_get_max_event_rings(gsi_ctx->per.ver);
	if (gsi_ctx->max_ev == 0) {
		devm_iounmap(gsi_ctx->dev, gsi_ctx->base);
		devm_free_irq(gsi_ctx->dev, props->irq, gsi_ctx);
		GSIERR("failed to get max event rings\n");
		return -GSI_STATUS_ERROR;
	}

	/* bitmap is max events excludes reserved events */
	gsi_ctx->evt_bmap = ~((1 << gsi_ctx->max_ev) - 1);
	gsi_ctx->evt_bmap |= ((1 << (GSI_MHI_ER_END + 1)) - 1) ^
		((1 << GSI_MHI_ER_START) - 1);

	/*
	 * enable all interrupts but GSI_BREAK_POINT.
@@ -693,6 +802,10 @@ int gsi_register_device(struct gsi_per_props *props, unsigned long *dev_hdl)
	else
		GSIERR("Manager EE has not enabled GSI, GSI un-usable\n");

	if (gsi_ctx->per.ver >= GSI_VER_1_2)
		gsi_writel(0, gsi_ctx->base +
			GSI_EE_n_ERROR_LOG_OFFS(gsi_ctx->per.ee));

	*dev_hdl = (uintptr_t)gsi_ctx;

	return GSI_STATUS_SUCCESS;
@@ -1059,7 +1172,7 @@ int gsi_write_evt_ring_scratch(unsigned long evt_ring_hdl,
		return -GSI_STATUS_NODEV;
	}

	if (evt_ring_hdl >= GSI_MAX_EVT_RING) {
	if (evt_ring_hdl >= gsi_ctx->max_ev) {
		GSIERR("bad params evt_ring_hdl=%lu\n", evt_ring_hdl);
		return -GSI_STATUS_INVALID_PARAMS;
	}
@@ -1093,7 +1206,7 @@ int gsi_dealloc_evt_ring(unsigned long evt_ring_hdl)
		return -GSI_STATUS_NODEV;
	}

	if (evt_ring_hdl >= GSI_MAX_EVT_RING) {
	if (evt_ring_hdl >= gsi_ctx->max_ev) {
		GSIERR("bad params evt_ring_hdl=%lu\n", evt_ring_hdl);
		return -GSI_STATUS_INVALID_PARAMS;
	}
@@ -1160,7 +1273,7 @@ int gsi_query_evt_ring_db_addr(unsigned long evt_ring_hdl,
		return -GSI_STATUS_INVALID_PARAMS;
	}

	if (evt_ring_hdl >= GSI_MAX_EVT_RING) {
	if (evt_ring_hdl >= gsi_ctx->max_ev) {
		GSIERR("bad params evt_ring_hdl=%lu\n", evt_ring_hdl);
		return -GSI_STATUS_INVALID_PARAMS;
	}
@@ -1194,7 +1307,7 @@ int gsi_reset_evt_ring(unsigned long evt_ring_hdl)
		return -GSI_STATUS_NODEV;
	}

	if (evt_ring_hdl >= GSI_MAX_EVT_RING) {
	if (evt_ring_hdl >= gsi_ctx->max_ev) {
		GSIERR("bad params evt_ring_hdl=%lu\n", evt_ring_hdl);
		return -GSI_STATUS_INVALID_PARAMS;
	}
@@ -1255,7 +1368,7 @@ int gsi_get_evt_ring_cfg(unsigned long evt_ring_hdl,
		return -GSI_STATUS_INVALID_PARAMS;
	}

	if (evt_ring_hdl >= GSI_MAX_EVT_RING) {
	if (evt_ring_hdl >= gsi_ctx->max_ev) {
		GSIERR("bad params evt_ring_hdl=%lu\n", evt_ring_hdl);
		return -GSI_STATUS_INVALID_PARAMS;
	}
@@ -1291,7 +1404,7 @@ int gsi_set_evt_ring_cfg(unsigned long evt_ring_hdl,
		return -GSI_STATUS_INVALID_PARAMS;
	}

	if (evt_ring_hdl >= GSI_MAX_EVT_RING) {
	if (evt_ring_hdl >= gsi_ctx->max_ev) {
		GSIERR("bad params evt_ring_hdl=%lu\n", evt_ring_hdl);
		return -GSI_STATUS_INVALID_PARAMS;
	}
@@ -1382,7 +1495,7 @@ static int gsi_validate_channel_props(struct gsi_chan_props *props)
{
	uint64_t ra;

	if (props->ch_id >= GSI_MAX_CHAN) {
	if (props->ch_id >= gsi_ctx->max_ch) {
		GSIERR("ch_id %u invalid\n", props->ch_id);
		return -GSI_STATUS_INVALID_PARAMS;
	}
@@ -1573,7 +1686,7 @@ int gsi_write_channel_scratch(unsigned long chan_hdl,
		return -GSI_STATUS_NODEV;
	}

	if (chan_hdl >= GSI_MAX_CHAN) {
	if (chan_hdl >= gsi_ctx->max_ch) {
		GSIERR("bad params chan_hdl=%lu\n", chan_hdl);
		return -GSI_STATUS_INVALID_PARAMS;
	}
@@ -1610,7 +1723,7 @@ int gsi_query_channel_db_addr(unsigned long chan_hdl,
		return -GSI_STATUS_INVALID_PARAMS;
	}

	if (chan_hdl >= GSI_MAX_CHAN) {
	if (chan_hdl >= gsi_ctx->max_ch) {
		GSIERR("bad params chan_hdl=%lu\n", chan_hdl);
		return -GSI_STATUS_INVALID_PARAMS;
	}
@@ -1642,7 +1755,7 @@ int gsi_start_channel(unsigned long chan_hdl)
		return -GSI_STATUS_NODEV;
	}

	if (chan_hdl >= GSI_MAX_CHAN) {
	if (chan_hdl >= gsi_ctx->max_ch) {
		GSIERR("bad params chan_hdl=%lu\n", chan_hdl);
		return -GSI_STATUS_INVALID_PARAMS;
	}
@@ -1694,7 +1807,7 @@ int gsi_stop_channel(unsigned long chan_hdl)
		return -GSI_STATUS_NODEV;
	}

	if (chan_hdl >= GSI_MAX_CHAN) {
	if (chan_hdl >= gsi_ctx->max_ch) {
		GSIERR("bad params chan_hdl=%lu\n", chan_hdl);
		return -GSI_STATUS_INVALID_PARAMS;
	}
@@ -1763,7 +1876,7 @@ int gsi_stop_db_channel(unsigned long chan_hdl)
		return -GSI_STATUS_NODEV;
	}

	if (chan_hdl >= GSI_MAX_CHAN) {
	if (chan_hdl >= gsi_ctx->max_ch) {
		GSIERR("bad params chan_hdl=%lu\n", chan_hdl);
		return -GSI_STATUS_INVALID_PARAMS;
	}
@@ -1832,7 +1945,7 @@ int gsi_reset_channel(unsigned long chan_hdl)
		return -GSI_STATUS_NODEV;
	}

	if (chan_hdl >= GSI_MAX_CHAN) {
	if (chan_hdl >= gsi_ctx->max_ch) {
		GSIERR("bad params chan_hdl=%lu\n", chan_hdl);
		return -GSI_STATUS_INVALID_PARAMS;
	}
@@ -1898,7 +2011,7 @@ int gsi_dealloc_channel(unsigned long chan_hdl)
		return -GSI_STATUS_NODEV;
	}

	if (chan_hdl >= GSI_MAX_CHAN) {
	if (chan_hdl >= gsi_ctx->max_ch) {
		GSIERR("bad params chan_hdl=%lu\n", chan_hdl);
		return -GSI_STATUS_INVALID_PARAMS;
	}
@@ -2021,7 +2134,7 @@ int gsi_query_channel_info(unsigned long chan_hdl,
		return -GSI_STATUS_NODEV;
	}

	if (chan_hdl >= GSI_MAX_CHAN || !info) {
	if (chan_hdl >= gsi_ctx->max_ch || !info) {
		GSIERR("bad params chan_hdl=%lu info=%p\n", chan_hdl, info);
		return -GSI_STATUS_INVALID_PARAMS;
	}
@@ -2091,7 +2204,7 @@ int gsi_is_channel_empty(unsigned long chan_hdl, bool *is_empty)
		return -GSI_STATUS_NODEV;
	}

	if (chan_hdl >= GSI_MAX_CHAN || !is_empty) {
	if (chan_hdl >= gsi_ctx->max_ch || !is_empty) {
		GSIERR("bad params chan_hdl=%lu is_empty=%p\n",
				chan_hdl, is_empty);
		return -GSI_STATUS_INVALID_PARAMS;
@@ -2155,7 +2268,7 @@ int gsi_queue_xfer(unsigned long chan_hdl, uint16_t num_xfers,
		return -GSI_STATUS_NODEV;
	}

	if (chan_hdl >= GSI_MAX_CHAN || !num_xfers || !xfer) {
	if (chan_hdl >= gsi_ctx->max_ch || !num_xfers || !xfer) {
		GSIERR("bad params chan_hdl=%lu num_xfers=%u xfer=%p\n",
				chan_hdl, num_xfers, xfer);
		return -GSI_STATUS_INVALID_PARAMS;
@@ -2242,7 +2355,7 @@ int gsi_start_xfer(unsigned long chan_hdl)
		return -GSI_STATUS_NODEV;
	}

	if (chan_hdl >= GSI_MAX_CHAN) {
	if (chan_hdl >= gsi_ctx->max_ch) {
		GSIERR("bad params chan_hdl=%lu\n", chan_hdl);
		return -GSI_STATUS_INVALID_PARAMS;
	}
@@ -2278,7 +2391,7 @@ int gsi_poll_channel(unsigned long chan_hdl,
		return -GSI_STATUS_NODEV;
	}

	if (chan_hdl >= GSI_MAX_CHAN || !notify) {
	if (chan_hdl >= gsi_ctx->max_ch || !notify) {
		GSIERR("bad params chan_hdl=%lu notify=%p\n", chan_hdl, notify);
		return -GSI_STATUS_INVALID_PARAMS;
	}
@@ -2327,7 +2440,7 @@ int gsi_config_channel_mode(unsigned long chan_hdl, enum gsi_chan_mode mode)
		return -GSI_STATUS_NODEV;
	}

	if (chan_hdl >= GSI_MAX_CHAN) {
	if (chan_hdl >= gsi_ctx->max_ch) {
		GSIERR("bad params chan_hdl=%lu mode=%u\n", chan_hdl, mode);
		return -GSI_STATUS_INVALID_PARAMS;
	}
@@ -2390,7 +2503,7 @@ int gsi_get_channel_cfg(unsigned long chan_hdl, struct gsi_chan_props *props,
		return -GSI_STATUS_INVALID_PARAMS;
	}

	if (chan_hdl >= GSI_MAX_CHAN) {
	if (chan_hdl >= gsi_ctx->max_ch) {
		GSIERR("bad params chan_hdl=%lu\n", chan_hdl);
		return -GSI_STATUS_INVALID_PARAMS;
	}
@@ -2426,7 +2539,7 @@ int gsi_set_channel_cfg(unsigned long chan_hdl, struct gsi_chan_props *props,
		return -GSI_STATUS_INVALID_PARAMS;
	}

	if (chan_hdl >= GSI_MAX_CHAN) {
	if (chan_hdl >= gsi_ctx->max_ch) {
		GSIERR("bad params chan_hdl=%lu\n", chan_hdl);
		return -GSI_STATUS_INVALID_PARAMS;
	}
@@ -2471,9 +2584,9 @@ static void gsi_configure_ieps(void *base)
	gsi_writel(5, gsi_base + GSI_GSI_IRAM_PTR_EE_GENERIC_CMD_OFFS);
	gsi_writel(6, gsi_base + GSI_GSI_IRAM_PTR_EVENT_GEN_COMP_OFFS);
	gsi_writel(7, gsi_base + GSI_GSI_IRAM_PTR_INT_MOD_STOPED_OFFS);
	gsi_writel(8, gsi_base + GSI_GSI_IRAM_PTR_IPA_IF_DESC_PROC_COMP_OFFS);
	gsi_writel(9, gsi_base + GSI_GSI_IRAM_PTR_IPA_IF_RESET_COMP_OFFS);
	gsi_writel(10, gsi_base + GSI_GSI_IRAM_PTR_IPA_IF_STOP_COMP_OFFS);
	gsi_writel(8, gsi_base + GSI_GSI_IRAM_PTR_PERIPH_IF_TLV_IN_0_OFFS);
	gsi_writel(9, gsi_base + GSI_GSI_IRAM_PTR_PERIPH_IF_TLV_IN_2_OFFS);
	gsi_writel(10, gsi_base + GSI_GSI_IRAM_PTR_PERIPH_IF_TLV_IN_1_OFFS);
	gsi_writel(11, gsi_base + GSI_GSI_IRAM_PTR_NEW_RE_OFFS);
	gsi_writel(12, gsi_base + GSI_GSI_IRAM_PTR_READ_ENG_COMP_OFFS);
	gsi_writel(13, gsi_base + GSI_GSI_IRAM_PTR_TIMER_EXPIRED_OFFS);
@@ -2502,9 +2615,9 @@ static void gsi_configure_bck_prs_matrix(void *base)
		gsi_base + GSI_IC_PROCESS_DESC_BCK_PRS_LSB_OFFS);
	gsi_writel(0x00000000,
		gsi_base + GSI_IC_PROCESS_DESC_BCK_PRS_MSB_OFFS);
	gsi_writel(0x00ffffff, gsi_base + GSI_IC_TLV_STOP_BCK_PRS_LSB_OFFS);
	gsi_writel(0xf9ffffff, gsi_base + GSI_IC_TLV_STOP_BCK_PRS_LSB_OFFS);
	gsi_writel(0xffffffff, gsi_base + GSI_IC_TLV_STOP_BCK_PRS_MSB_OFFS);
	gsi_writel(0xfdffffff, gsi_base + GSI_IC_TLV_RESET_BCK_PRS_LSB_OFFS);
	gsi_writel(0xf9ffffff, gsi_base + GSI_IC_TLV_RESET_BCK_PRS_LSB_OFFS);
	gsi_writel(0xffffffff, gsi_base + GSI_IC_TLV_RESET_BCK_PRS_MSB_OFFS);
	gsi_writel(0xffffffff, gsi_base + GSI_IC_RGSTR_TIMER_BCK_PRS_LSB_OFFS);
	gsi_writel(0xfffffffe, gsi_base + GSI_IC_RGSTR_TIMER_BCK_PRS_MSB_OFFS);
@@ -2551,6 +2664,25 @@ int gsi_enable_fw(phys_addr_t gsi_base_addr, u32 gsi_size)
	}

	/* Enable the MCS and set to x2 clocks */
	if (gsi_ctx->per.ver >= GSI_VER_1_2) {
		value = ((1 << GSI_GSI_MCS_CFG_MCS_ENABLE_SHFT) &
				GSI_GSI_MCS_CFG_MCS_ENABLE_BMSK);
		gsi_writel(value, gsi_base + GSI_GSI_MCS_CFG_OFFS);

		value = (((1 << GSI_GSI_CFG_GSI_ENABLE_SHFT) &
				GSI_GSI_CFG_GSI_ENABLE_BMSK) |
			((0 << GSI_GSI_CFG_MCS_ENABLE_SHFT) &
				GSI_GSI_CFG_MCS_ENABLE_BMSK) |
			((1 << GSI_GSI_CFG_DOUBLE_MCS_CLK_FREQ_SHFT) &
				GSI_GSI_CFG_DOUBLE_MCS_CLK_FREQ_BMSK) |
			((0 << GSI_GSI_CFG_UC_IS_MCS_SHFT) &
				GSI_GSI_CFG_UC_IS_MCS_BMSK) |
			((0 << GSI_GSI_CFG_GSI_PWR_CLPS_SHFT) &
				GSI_GSI_CFG_GSI_PWR_CLPS_BMSK) |
			((0 << GSI_GSI_CFG_BP_MTRIX_DISABLE_SHFT) &
				GSI_GSI_CFG_BP_MTRIX_DISABLE_BMSK));
		gsi_writel(value, gsi_base + GSI_GSI_CFG_OFFS);
	} else {
		value = (((1 << GSI_GSI_CFG_GSI_ENABLE_SHFT) &
				GSI_GSI_CFG_GSI_ENABLE_BMSK) |
			((1 << GSI_GSI_CFG_MCS_ENABLE_SHFT) &
@@ -2560,6 +2692,7 @@ int gsi_enable_fw(phys_addr_t gsi_base_addr, u32 gsi_size)
			((0 << GSI_GSI_CFG_UC_IS_MCS_SHFT) &
				GSI_GSI_CFG_UC_IS_MCS_BMSK));
		gsi_writel(value, gsi_base + GSI_GSI_CFG_OFFS);
	}

	iounmap(gsi_base);

+6 −4
Original line number Diff line number Diff line
@@ -19,8 +19,8 @@
#include <linux/spinlock.h>
#include <linux/msm_gsi.h>

#define GSI_MAX_CHAN      31
#define GSI_MAX_EVT_RING  23
#define GSI_CHAN_MAX      31
#define GSI_EVT_RING_MAX  23
#define GSI_NO_EVT_ERINDEX 31

#define gsi_readl(c)	({ u32 __v = readl_relaxed(c); __iormb(); __v; })
@@ -130,8 +130,8 @@ struct gsi_ctx {
	struct device *dev;
	struct gsi_per_props per;
	bool per_registered;
	struct gsi_chan_ctx chan[GSI_MAX_CHAN];
	struct gsi_evt_ctx evtr[GSI_MAX_EVT_RING];
	struct gsi_chan_ctx chan[GSI_CHAN_MAX];
	struct gsi_evt_ctx evtr[GSI_EVT_RING_MAX];
	struct mutex mlock;
	spinlock_t slock;
	unsigned long evt_bmap;
@@ -141,6 +141,8 @@ struct gsi_ctx {
	struct gsi_ee_scratch scratch;
	int num_ch_dp_stats;
	struct workqueue_struct *dp_stat_wq;
	u32 max_ch;
	u32 max_ev;
};

enum gsi_re_type {
+37 −16
Original line number Diff line number Diff line
@@ -71,7 +71,7 @@ static ssize_t gsi_dump_evt(struct file *file,

	TDBG("arg1=%u arg2=%u\n", arg1, arg2);

	if (arg1 >= GSI_MAX_EVT_RING) {
	if (arg1 >= gsi_ctx->max_ev) {
		TERR("invalid evt ring id %u\n", arg1);
		return -EFAULT;
	}
@@ -184,7 +184,7 @@ static ssize_t gsi_dump_ch(struct file *file,

	TDBG("arg1=%u arg2=%u\n", arg1, arg2);

	if (arg1 >= GSI_MAX_CHAN) {
	if (arg1 >= gsi_ctx->max_ch) {
		TERR("invalid chan id %u\n", arg1);
		return -EFAULT;
	}
@@ -271,9 +271,30 @@ static ssize_t gsi_dump_ee(struct file *file,
	val = gsi_readl(gsi_ctx->base +
		GSI_EE_n_GSI_STATUS_OFFS(gsi_ctx->per.ee));
	TERR("EE%2d STATUS 0x%x\n", gsi_ctx->per.ee, val);
	if (gsi_ctx->per.ver == GSI_VER_1_0) {
		val = gsi_readl(gsi_ctx->base +
		GSI_EE_n_GSI_HW_PARAM_OFFS(gsi_ctx->per.ee));
			GSI_V1_0_EE_n_GSI_HW_PARAM_OFFS(gsi_ctx->per.ee));
		TERR("EE%2d HW_PARAM 0x%x\n", gsi_ctx->per.ee, val);
	} else if (gsi_ctx->per.ver == GSI_VER_1_2) {
		val = gsi_readl(gsi_ctx->base +
			GSI_V1_2_EE_n_GSI_HW_PARAM_0_OFFS(gsi_ctx->per.ee));
		TERR("EE%2d HW_PARAM_0 0x%x\n", gsi_ctx->per.ee, val);
		val = gsi_readl(gsi_ctx->base +
			GSI_V1_2_EE_n_GSI_HW_PARAM_1_OFFS(gsi_ctx->per.ee));
		TERR("EE%2d HW_PARAM_1 0x%x\n", gsi_ctx->per.ee, val);
	} else if (gsi_ctx->per.ver == GSI_VER_1_3) {
		val = gsi_readl(gsi_ctx->base +
			GSI_V1_3_EE_n_GSI_HW_PARAM_0_OFFS(gsi_ctx->per.ee));
		TERR("EE%2d HW_PARAM_0 0x%x\n", gsi_ctx->per.ee, val);
		val = gsi_readl(gsi_ctx->base +
			GSI_V1_3_EE_n_GSI_HW_PARAM_1_OFFS(gsi_ctx->per.ee));
		TERR("EE%2d HW_PARAM_1 0x%x\n", gsi_ctx->per.ee, val);
		val = gsi_readl(gsi_ctx->base +
			GSI_V1_3_EE_n_GSI_HW_PARAM_2_OFFS(gsi_ctx->per.ee));
		TERR("EE%2d HW_PARAM_2 0x%x\n", gsi_ctx->per.ee, val);
	} else {
		WARN_ON(1);
	}
	val = gsi_readl(gsi_ctx->base +
		GSI_EE_n_GSI_SW_VERSION_OFFS(gsi_ctx->per.ee));
	TERR("EE%2d SW_VERSION 0x%x\n", gsi_ctx->per.ee, val);
@@ -329,7 +350,7 @@ static ssize_t gsi_dump_map(struct file *file,
	int i;

	TERR("EVT bitmap 0x%lx\n", gsi_ctx->evt_bmap);
	for (i = 0; i < GSI_MAX_CHAN; i++) {
	for (i = 0; i < gsi_ctx->max_ch; i++) {
		ctx = &gsi_ctx->chan[i];

		if (ctx->allocated) {
@@ -402,8 +423,8 @@ static ssize_t gsi_dump_stats(struct file *file,

	if (ch_id == -1) {
		min = 0;
		max = GSI_MAX_CHAN;
	} else if (ch_id < 0 || ch_id >= GSI_MAX_CHAN ||
		max = gsi_ctx->max_ch;
	} else if (ch_id < 0 || ch_id >= gsi_ctx->max_ch ||
		   !gsi_ctx->chan[ch_id].allocated) {
		goto error;
	} else {
@@ -464,7 +485,7 @@ static ssize_t gsi_enable_dp_stats(struct file *file,
	if (kstrtos32(dbg_buff + 1, 0, &ch_id))
		goto error;

	if (ch_id < 0 || ch_id >= GSI_MAX_CHAN ||
	if (ch_id < 0 || ch_id >= gsi_ctx->max_ch ||
	    !gsi_ctx->chan[ch_id].allocated) {
		goto error;
	}
@@ -540,7 +561,7 @@ static ssize_t gsi_set_max_elem_dp_stats(struct file *file,
		/* get */
		if (kstrtou32(dbg_buff, 0, &ch_id))
			goto error;
		if (ch_id >= GSI_MAX_CHAN)
		if (ch_id >= gsi_ctx->max_ch)
			goto error;
		PRT_STAT("ch %d: max_re_expected=%d\n", ch_id,
			gsi_ctx->chan[ch_id].props.max_re_expected);
@@ -553,7 +574,7 @@ static ssize_t gsi_set_max_elem_dp_stats(struct file *file,

	TDBG("ch_id=%u max_elem=%u\n", ch_id, max_elem);

	if (ch_id >= GSI_MAX_CHAN) {
	if (ch_id >= gsi_ctx->max_ch) {
		TERR("invalid chan id %u\n", ch_id);
		goto error;
	}
@@ -572,7 +593,7 @@ static void gsi_wq_print_dp_stats(struct work_struct *work)
{
	int ch_id;

	for (ch_id = 0; ch_id < GSI_MAX_CHAN; ch_id++) {
	for (ch_id = 0; ch_id < gsi_ctx->max_ch; ch_id++) {
		if (gsi_ctx->chan[ch_id].print_dp_stats)
			gsi_dump_ch_stats(&gsi_ctx->chan[ch_id]);
	}
@@ -618,7 +639,7 @@ static void gsi_wq_update_dp_stats(struct work_struct *work)
{
	int ch_id;

	for (ch_id = 0; ch_id < GSI_MAX_CHAN; ch_id++) {
	for (ch_id = 0; ch_id < gsi_ctx->max_ch; ch_id++) {
		if (gsi_ctx->chan[ch_id].allocated &&
		    gsi_ctx->chan[ch_id].props.prot != GSI_CHAN_PROT_GPI &&
		    gsi_ctx->chan[ch_id].enable_dp_stats)
@@ -649,8 +670,8 @@ static ssize_t gsi_rst_stats(struct file *file,

	if (ch_id == -1) {
		min = 0;
		max = GSI_MAX_CHAN;
	} else if (ch_id < 0 || ch_id >= GSI_MAX_CHAN ||
		max = gsi_ctx->max_ch;
	} else if (ch_id < 0 || ch_id >= gsi_ctx->max_ch ||
		   !gsi_ctx->chan[ch_id].allocated) {
		goto error;
	} else {
@@ -691,7 +712,7 @@ static ssize_t gsi_print_dp_stats(struct file *file,
	if (kstrtos32(dbg_buff + 1, 0, &ch_id))
		goto error;

	if (ch_id < 0 || ch_id >= GSI_MAX_CHAN ||
	if (ch_id < 0 || ch_id >= gsi_ctx->max_ch ||
	    !gsi_ctx->chan[ch_id].allocated) {
		goto error;
	}
+184 −33

File changed.

Preview size limit exceeded, changes collapsed.

+27 −0
Original line number Diff line number Diff line
@@ -3585,6 +3585,32 @@ static int ipa3_gsi_pre_fw_load_init(void)
	return 0;
}

static enum gsi_ver ipa3_get_gsi_ver(enum ipa_hw_type ipa_hw_type)
{
	enum gsi_ver gsi_ver;

	switch (ipa_hw_type) {
	case IPA_HW_v3_0:
	case IPA_HW_v3_1:
		gsi_ver = GSI_VER_1_0;
		break;
	case IPA_HW_v3_5:
		gsi_ver = GSI_VER_1_2;
		break;
	case IPA_HW_v3_5_1:
		gsi_ver = GSI_VER_1_3;
		break;
	default:
		IPAERR("No GSI version for ipa type %d\n", ipa_hw_type);
		WARN_ON(1);
		gsi_ver = GSI_VER_ERR;
	}

	IPADBG("GSI version %d\n", gsi_ver);

	return gsi_ver;
}

/**
 * ipa3_post_init() - Initialize the IPA Driver (Part II).
 * This part contains all initialization which requires interaction with
@@ -3614,6 +3640,7 @@ static int ipa3_post_init(const struct ipa3_plat_drv_res *resource_p,

	if (ipa3_ctx->transport_prototype == IPA_TRANSPORT_TYPE_GSI) {
		memset(&gsi_props, 0, sizeof(gsi_props));
		gsi_props.ver = ipa3_get_gsi_ver(resource_p->ipa_hw_type);
		gsi_props.ee = resource_p->ee;
		gsi_props.intr = GSI_INTR_IRQ;
		gsi_props.irq = resource_p->transport_irq;
Loading