Loading drivers/platform/msm/gsi/gsi.c +174 −41 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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. Loading @@ -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; Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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) & Loading @@ -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); Loading drivers/platform/msm/gsi/gsi.h +6 −4 Original line number Diff line number Diff line Loading @@ -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; }) Loading Loading @@ -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; Loading @@ -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 { Loading drivers/platform/msm/gsi/gsi_dbg.c +37 −16 Original line number Diff line number Diff line Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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); Loading Loading @@ -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) { Loading Loading @@ -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 { Loading Loading @@ -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; } Loading Loading @@ -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); Loading @@ -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; } Loading @@ -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]); } Loading Loading @@ -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) Loading Loading @@ -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 { Loading Loading @@ -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; } Loading drivers/platform/msm/gsi/gsi_reg.h +184 −33 File changed.Preview size limit exceeded, changes collapsed. Show changes drivers/platform/msm/ipa/ipa_v3/ipa.c +27 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading
drivers/platform/msm/gsi/gsi.c +174 −41 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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. Loading @@ -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; Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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) & Loading @@ -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); Loading
drivers/platform/msm/gsi/gsi.h +6 −4 Original line number Diff line number Diff line Loading @@ -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; }) Loading Loading @@ -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; Loading @@ -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 { Loading
drivers/platform/msm/gsi/gsi_dbg.c +37 −16 Original line number Diff line number Diff line Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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); Loading Loading @@ -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) { Loading Loading @@ -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 { Loading Loading @@ -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; } Loading Loading @@ -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); Loading @@ -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; } Loading @@ -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]); } Loading Loading @@ -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) Loading Loading @@ -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 { Loading Loading @@ -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; } Loading
drivers/platform/msm/gsi/gsi_reg.h +184 −33 File changed.Preview size limit exceeded, changes collapsed. Show changes
drivers/platform/msm/ipa/ipa_v3/ipa.c +27 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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