Loading drivers/platform/msm/gsi/gsi.c +43 −30 Original line number Diff line number Diff line Loading @@ -415,6 +415,16 @@ static void gsi_ring_chan_doorbell(struct gsi_chan_ctx *ctx) { uint32_t val; /* * allocate new events for this channel first * before submitting the new TREs. * for TO_GSI channels the event ring doorbell is rang as part of * interrupt handling. */ if (ctx->evtr && ctx->props.dir == GSI_CHAN_DIR_FROM_GSI) gsi_ring_evt_doorbell(ctx->evtr); ctx->ring.wp = ctx->ring.wp_local; /* write order MUST be MSB followed by LSB */ val = ((ctx->ring.wp_local >> 32) & GSI_EE_n_GSI_CH_k_DOORBELL_1_WRITE_PTR_MSB_BMSK) << Loading Loading @@ -470,8 +480,8 @@ static void gsi_handle_ieob(int ee) cntr = 0; rp = gsi_readl(gsi_ctx->base + GSI_EE_n_EV_CH_k_CNTXT_4_OFFS(i, ee)); rp |= ((uint64_t)gsi_readl(gsi_ctx->base + GSI_EE_n_EV_CH_k_CNTXT_5_OFFS(i, ee))) << 32; rp |= ctx->ring.rp & 0xFFFFFFFF00000000; ctx->ring.rp = rp; while (ctx->ring.rp_local != rp) { ++cntr; Loading Loading @@ -1529,6 +1539,7 @@ static void gsi_init_chan_ring(struct gsi_chan_props *props, static int gsi_validate_channel_props(struct gsi_chan_props *props) { uint64_t ra; uint64_t last; if (props->ch_id >= gsi_ctx->max_ch) { GSIERR("ch_id %u invalid\n", props->ch_id); Loading Loading @@ -1556,6 +1567,17 @@ static int gsi_validate_channel_props(struct gsi_chan_props *props) return -GSI_STATUS_INVALID_PARAMS; } last = props->ring_base_addr + props->ring_len - props->re_size; /* MSB should stay same within the ring */ if ((props->ring_base_addr & 0xFFFFFFFF00000000ULL) != (last & 0xFFFFFFFF00000000ULL)) { GSIERR("MSB is not fixed on ring base 0x%llx size 0x%x\n", props->ring_base_addr, props->ring_len); return -GSI_STATUS_INVALID_PARAMS; } if (props->prot == GSI_CHAN_PROT_GPI && !props->ring_base_vaddr) { GSIERR("protocol %u requires ring base VA\n", props->prot); Loading Loading @@ -2128,29 +2150,22 @@ static void __gsi_query_channel_free_re(struct gsi_chan_ctx *ctx, uint16_t *num_free_re) { uint16_t start; uint16_t start_hw; uint16_t end; uint64_t rp; uint64_t rp_hw; int ee = gsi_ctx->per.ee; uint16_t used; uint16_t used_hw; rp_hw = gsi_readl(gsi_ctx->base + if (!ctx->evtr) { rp = gsi_readl(gsi_ctx->base + GSI_EE_n_GSI_CH_k_CNTXT_4_OFFS(ctx->props.ch_id, ee)); rp_hw |= ((uint64_t)gsi_readl(gsi_ctx->base + GSI_EE_n_GSI_CH_k_CNTXT_5_OFFS(ctx->props.ch_id, ee))) << 32; rp |= ctx->ring.rp & 0xFFFFFFFF00000000; if (!ctx->evtr) { rp = rp_hw; ctx->ring.rp = rp; } else { rp = ctx->ring.rp_local; } start = gsi_find_idx_from_addr(&ctx->ring, rp); start_hw = gsi_find_idx_from_addr(&ctx->ring, rp_hw); end = gsi_find_idx_from_addr(&ctx->ring, ctx->ring.wp_local); if (end >= start) Loading @@ -2158,13 +2173,7 @@ static void __gsi_query_channel_free_re(struct gsi_chan_ctx *ctx, else used = ctx->ring.max_num_elem + 1 - (start - end); if (end >= start_hw) used_hw = end - start_hw; else used_hw = ctx->ring.max_num_elem + 1 - (start_hw - end); *num_free_re = ctx->ring.max_num_elem - used; gsi_update_ch_dp_stats(ctx, used_hw); } int gsi_query_channel_info(unsigned long chan_hdl, Loading Loading @@ -2274,14 +2283,12 @@ int gsi_is_channel_empty(unsigned long chan_hdl, bool *is_empty) rp = gsi_readl(gsi_ctx->base + GSI_EE_n_GSI_CH_k_CNTXT_4_OFFS(ctx->props.ch_id, ee)); rp |= ((uint64_t)gsi_readl(gsi_ctx->base + GSI_EE_n_GSI_CH_k_CNTXT_5_OFFS(ctx->props.ch_id, ee))) << 32; rp |= ctx->ring.rp & 0xFFFFFFFF00000000; ctx->ring.rp = rp; wp = gsi_readl(gsi_ctx->base + GSI_EE_n_GSI_CH_k_CNTXT_6_OFFS(ctx->props.ch_id, ee)); wp |= ((uint64_t)gsi_readl(gsi_ctx->base + GSI_EE_n_GSI_CH_k_CNTXT_7_OFFS(ctx->props.ch_id, ee))) << 32; wp |= ctx->ring.wp & 0xFFFFFFFF00000000; ctx->ring.wp = wp; if (ctx->props.dir == GSI_CHAN_DIR_FROM_GSI) Loading Loading @@ -2420,6 +2427,9 @@ int gsi_start_xfer(unsigned long chan_hdl) return -GSI_STATUS_UNSUPPORTED_OP; } if (ctx->ring.wp == ctx->ring.wp_local) return GSI_STATUS_SUCCESS; gsi_ring_chan_doorbell(ctx); return GSI_STATUS_SUCCESS; Loading Loading @@ -2457,19 +2467,22 @@ int gsi_poll_channel(unsigned long chan_hdl, } spin_lock_irqsave(&ctx->evtr->ring.slock, flags); if (ctx->evtr->ring.rp == ctx->evtr->ring.rp_local) { /* update rp to see of we have anything new to process */ rp = gsi_readl(gsi_ctx->base + GSI_EE_n_EV_CH_k_CNTXT_4_OFFS(ctx->evtr->id, ee)); rp |= ((uint64_t)gsi_readl(gsi_ctx->base + GSI_EE_n_EV_CH_k_CNTXT_5_OFFS(ctx->evtr->id, ee))) << 32; rp |= ctx->ring.rp & 0xFFFFFFFF00000000; ctx->evtr->ring.rp = rp; if (rp == ctx->evtr->ring.rp_local) { } if (ctx->evtr->ring.rp == ctx->evtr->ring.rp_local) { spin_unlock_irqrestore(&ctx->evtr->ring.slock, flags); ctx->stats.poll_empty++; return GSI_STATUS_POLL_EMPTY; } gsi_process_evt_re(ctx->evtr, notify, false); gsi_ring_evt_doorbell(ctx->evtr); spin_unlock_irqrestore(&ctx->evtr->ring.slock, flags); ctx->stats.poll_ok++; Loading drivers/platform/msm/gsi/gsi_dbg.c +1 −7 Original line number Diff line number Diff line Loading @@ -490,11 +490,6 @@ static ssize_t gsi_enable_dp_stats(struct file *file, goto error; } if (gsi_ctx->chan[ch_id].props.prot == GSI_CHAN_PROT_GPI) { TERR("valid for non GPI channels only\n"); goto error; } if (gsi_ctx->chan[ch_id].enable_dp_stats == enable) { TERR("ch_%d: already enabled/disabled\n", ch_id); return -EFAULT; Loading Loading @@ -631,7 +626,7 @@ static void gsi_dbg_update_ch_dp_stats(struct gsi_chan_ctx *ctx) else used_hw = ctx->ring.max_num_elem + 1 - (start_hw - end_hw); TERR("ch %d used %d\n", ctx->props.ch_id, used_hw); TDBG("ch %d used %d\n", ctx->props.ch_id, used_hw); gsi_update_ch_dp_stats(ctx, used_hw); } Loading @@ -641,7 +636,6 @@ static void gsi_wq_update_dp_stats(struct work_struct *work) 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) gsi_dbg_update_ch_dp_stats(&gsi_ctx->chan[ch_id]); } Loading Loading
drivers/platform/msm/gsi/gsi.c +43 −30 Original line number Diff line number Diff line Loading @@ -415,6 +415,16 @@ static void gsi_ring_chan_doorbell(struct gsi_chan_ctx *ctx) { uint32_t val; /* * allocate new events for this channel first * before submitting the new TREs. * for TO_GSI channels the event ring doorbell is rang as part of * interrupt handling. */ if (ctx->evtr && ctx->props.dir == GSI_CHAN_DIR_FROM_GSI) gsi_ring_evt_doorbell(ctx->evtr); ctx->ring.wp = ctx->ring.wp_local; /* write order MUST be MSB followed by LSB */ val = ((ctx->ring.wp_local >> 32) & GSI_EE_n_GSI_CH_k_DOORBELL_1_WRITE_PTR_MSB_BMSK) << Loading Loading @@ -470,8 +480,8 @@ static void gsi_handle_ieob(int ee) cntr = 0; rp = gsi_readl(gsi_ctx->base + GSI_EE_n_EV_CH_k_CNTXT_4_OFFS(i, ee)); rp |= ((uint64_t)gsi_readl(gsi_ctx->base + GSI_EE_n_EV_CH_k_CNTXT_5_OFFS(i, ee))) << 32; rp |= ctx->ring.rp & 0xFFFFFFFF00000000; ctx->ring.rp = rp; while (ctx->ring.rp_local != rp) { ++cntr; Loading Loading @@ -1529,6 +1539,7 @@ static void gsi_init_chan_ring(struct gsi_chan_props *props, static int gsi_validate_channel_props(struct gsi_chan_props *props) { uint64_t ra; uint64_t last; if (props->ch_id >= gsi_ctx->max_ch) { GSIERR("ch_id %u invalid\n", props->ch_id); Loading Loading @@ -1556,6 +1567,17 @@ static int gsi_validate_channel_props(struct gsi_chan_props *props) return -GSI_STATUS_INVALID_PARAMS; } last = props->ring_base_addr + props->ring_len - props->re_size; /* MSB should stay same within the ring */ if ((props->ring_base_addr & 0xFFFFFFFF00000000ULL) != (last & 0xFFFFFFFF00000000ULL)) { GSIERR("MSB is not fixed on ring base 0x%llx size 0x%x\n", props->ring_base_addr, props->ring_len); return -GSI_STATUS_INVALID_PARAMS; } if (props->prot == GSI_CHAN_PROT_GPI && !props->ring_base_vaddr) { GSIERR("protocol %u requires ring base VA\n", props->prot); Loading Loading @@ -2128,29 +2150,22 @@ static void __gsi_query_channel_free_re(struct gsi_chan_ctx *ctx, uint16_t *num_free_re) { uint16_t start; uint16_t start_hw; uint16_t end; uint64_t rp; uint64_t rp_hw; int ee = gsi_ctx->per.ee; uint16_t used; uint16_t used_hw; rp_hw = gsi_readl(gsi_ctx->base + if (!ctx->evtr) { rp = gsi_readl(gsi_ctx->base + GSI_EE_n_GSI_CH_k_CNTXT_4_OFFS(ctx->props.ch_id, ee)); rp_hw |= ((uint64_t)gsi_readl(gsi_ctx->base + GSI_EE_n_GSI_CH_k_CNTXT_5_OFFS(ctx->props.ch_id, ee))) << 32; rp |= ctx->ring.rp & 0xFFFFFFFF00000000; if (!ctx->evtr) { rp = rp_hw; ctx->ring.rp = rp; } else { rp = ctx->ring.rp_local; } start = gsi_find_idx_from_addr(&ctx->ring, rp); start_hw = gsi_find_idx_from_addr(&ctx->ring, rp_hw); end = gsi_find_idx_from_addr(&ctx->ring, ctx->ring.wp_local); if (end >= start) Loading @@ -2158,13 +2173,7 @@ static void __gsi_query_channel_free_re(struct gsi_chan_ctx *ctx, else used = ctx->ring.max_num_elem + 1 - (start - end); if (end >= start_hw) used_hw = end - start_hw; else used_hw = ctx->ring.max_num_elem + 1 - (start_hw - end); *num_free_re = ctx->ring.max_num_elem - used; gsi_update_ch_dp_stats(ctx, used_hw); } int gsi_query_channel_info(unsigned long chan_hdl, Loading Loading @@ -2274,14 +2283,12 @@ int gsi_is_channel_empty(unsigned long chan_hdl, bool *is_empty) rp = gsi_readl(gsi_ctx->base + GSI_EE_n_GSI_CH_k_CNTXT_4_OFFS(ctx->props.ch_id, ee)); rp |= ((uint64_t)gsi_readl(gsi_ctx->base + GSI_EE_n_GSI_CH_k_CNTXT_5_OFFS(ctx->props.ch_id, ee))) << 32; rp |= ctx->ring.rp & 0xFFFFFFFF00000000; ctx->ring.rp = rp; wp = gsi_readl(gsi_ctx->base + GSI_EE_n_GSI_CH_k_CNTXT_6_OFFS(ctx->props.ch_id, ee)); wp |= ((uint64_t)gsi_readl(gsi_ctx->base + GSI_EE_n_GSI_CH_k_CNTXT_7_OFFS(ctx->props.ch_id, ee))) << 32; wp |= ctx->ring.wp & 0xFFFFFFFF00000000; ctx->ring.wp = wp; if (ctx->props.dir == GSI_CHAN_DIR_FROM_GSI) Loading Loading @@ -2420,6 +2427,9 @@ int gsi_start_xfer(unsigned long chan_hdl) return -GSI_STATUS_UNSUPPORTED_OP; } if (ctx->ring.wp == ctx->ring.wp_local) return GSI_STATUS_SUCCESS; gsi_ring_chan_doorbell(ctx); return GSI_STATUS_SUCCESS; Loading Loading @@ -2457,19 +2467,22 @@ int gsi_poll_channel(unsigned long chan_hdl, } spin_lock_irqsave(&ctx->evtr->ring.slock, flags); if (ctx->evtr->ring.rp == ctx->evtr->ring.rp_local) { /* update rp to see of we have anything new to process */ rp = gsi_readl(gsi_ctx->base + GSI_EE_n_EV_CH_k_CNTXT_4_OFFS(ctx->evtr->id, ee)); rp |= ((uint64_t)gsi_readl(gsi_ctx->base + GSI_EE_n_EV_CH_k_CNTXT_5_OFFS(ctx->evtr->id, ee))) << 32; rp |= ctx->ring.rp & 0xFFFFFFFF00000000; ctx->evtr->ring.rp = rp; if (rp == ctx->evtr->ring.rp_local) { } if (ctx->evtr->ring.rp == ctx->evtr->ring.rp_local) { spin_unlock_irqrestore(&ctx->evtr->ring.slock, flags); ctx->stats.poll_empty++; return GSI_STATUS_POLL_EMPTY; } gsi_process_evt_re(ctx->evtr, notify, false); gsi_ring_evt_doorbell(ctx->evtr); spin_unlock_irqrestore(&ctx->evtr->ring.slock, flags); ctx->stats.poll_ok++; Loading
drivers/platform/msm/gsi/gsi_dbg.c +1 −7 Original line number Diff line number Diff line Loading @@ -490,11 +490,6 @@ static ssize_t gsi_enable_dp_stats(struct file *file, goto error; } if (gsi_ctx->chan[ch_id].props.prot == GSI_CHAN_PROT_GPI) { TERR("valid for non GPI channels only\n"); goto error; } if (gsi_ctx->chan[ch_id].enable_dp_stats == enable) { TERR("ch_%d: already enabled/disabled\n", ch_id); return -EFAULT; Loading Loading @@ -631,7 +626,7 @@ static void gsi_dbg_update_ch_dp_stats(struct gsi_chan_ctx *ctx) else used_hw = ctx->ring.max_num_elem + 1 - (start_hw - end_hw); TERR("ch %d used %d\n", ctx->props.ch_id, used_hw); TDBG("ch %d used %d\n", ctx->props.ch_id, used_hw); gsi_update_ch_dp_stats(ctx, used_hw); } Loading @@ -641,7 +636,6 @@ static void gsi_wq_update_dp_stats(struct work_struct *work) 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) gsi_dbg_update_ch_dp_stats(&gsi_ctx->chan[ch_id]); } Loading