diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2017-02-23 21:35:58 -0800 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-02-23 21:35:58 -0800 |
commit | c110184f5093940a90c5d2abf3baa05b6662dee2 (patch) | |
tree | e1e6f6332020305e26dfbd005ed0c135396b7ee8 /drivers | |
parent | 53d85c3a8fca105f86dcc161bc9fc3beed4619fa (diff) | |
parent | 3e67e235eab1762b562f0e359b9cde9b1302f32d (diff) |
Merge "msm: gsi: add support for generic commands"
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/platform/msm/gsi/gsi.c | 70 | ||||
-rw-r--r-- | drivers/platform/msm/gsi/gsi.h | 27 | ||||
-rw-r--r-- | drivers/platform/msm/gsi/gsi_reg.h | 6 |
3 files changed, 97 insertions, 6 deletions
diff --git a/drivers/platform/msm/gsi/gsi.c b/drivers/platform/msm/gsi/gsi.c index 188388bc97a0..23b0428bcf34 100644 --- a/drivers/platform/msm/gsi/gsi.c +++ b/drivers/platform/msm/gsi/gsi.c @@ -264,6 +264,11 @@ static void gsi_handle_glob_err(uint32_t err) } } +static void gsi_handle_gp_int1(void) +{ + complete(&gsi_ctx->gen_ee_cmd_compl); +} + static void gsi_handle_glob_ee(int ee) { uint32_t val; @@ -288,8 +293,7 @@ static void gsi_handle_glob_ee(int ee) } if (val & GSI_EE_n_CNTXT_GLOB_IRQ_EN_GP_INT1_BMSK) { - notify.evt_id = GSI_PER_EVT_GLOB_GP1; - gsi_ctx->per.notify_cb(¬ify); + gsi_handle_gp_int1(); } if (val & GSI_EE_n_CNTXT_GLOB_IRQ_EN_GP_INT2_BMSK) { @@ -2745,6 +2749,67 @@ void gsi_get_inst_ram_offset_and_size(unsigned long *base_offset, } EXPORT_SYMBOL(gsi_get_inst_ram_offset_and_size); +int gsi_halt_channel_ee(unsigned int chan_idx, unsigned int ee, int *code) +{ + enum gsi_generic_ee_cmd_opcode op = GSI_GEN_EE_CMD_HALT_CHANNEL; + uint32_t val; + int res; + + if (!gsi_ctx) { + pr_err("%s:%d gsi context not allocated\n", __func__, __LINE__); + return -GSI_STATUS_NODEV; + } + + if (chan_idx >= gsi_ctx->max_ch || !code) { + GSIERR("bad params chan_idx=%d\n", chan_idx); + return -GSI_STATUS_INVALID_PARAMS; + } + + mutex_lock(&gsi_ctx->mlock); + reinit_completion(&gsi_ctx->gen_ee_cmd_compl); + + /* invalidate the response */ + gsi_ctx->scratch.word0.val = gsi_readl(gsi_ctx->base + + GSI_EE_n_CNTXT_SCRATCH_0_OFFS(gsi_ctx->per.ee)); + gsi_ctx->scratch.word0.s.generic_ee_cmd_return_code = 0; + gsi_writel(gsi_ctx->scratch.word0.val, gsi_ctx->base + + GSI_EE_n_CNTXT_SCRATCH_0_OFFS(gsi_ctx->per.ee)); + + gsi_ctx->gen_ee_cmd_dbg.halt_channel++; + val = (((op << GSI_EE_n_GSI_EE_GENERIC_CMD_OPCODE_SHFT) & + GSI_EE_n_GSI_EE_GENERIC_CMD_OPCODE_BMSK) | + ((chan_idx << GSI_EE_n_GSI_EE_GENERIC_CMD_VIRT_CHAN_IDX_SHFT) & + GSI_EE_n_GSI_EE_GENERIC_CMD_VIRT_CHAN_IDX_BMSK) | + ((ee << GSI_EE_n_GSI_EE_GENERIC_CMD_EE_SHFT) & + GSI_EE_n_GSI_EE_GENERIC_CMD_EE_BMSK)); + gsi_writel(val, gsi_ctx->base + + GSI_EE_n_GSI_EE_GENERIC_CMD_OFFS(gsi_ctx->per.ee)); + + res = wait_for_completion_timeout(&gsi_ctx->gen_ee_cmd_compl, + msecs_to_jiffies(GSI_CMD_TIMEOUT)); + if (res == 0) { + GSIERR("chan_idx=%u ee=%u timed out\n", chan_idx, ee); + res = -GSI_STATUS_TIMED_OUT; + goto free_lock; + } + + gsi_ctx->scratch.word0.val = gsi_readl(gsi_ctx->base + + GSI_EE_n_CNTXT_SCRATCH_0_OFFS(gsi_ctx->per.ee)); + if (gsi_ctx->scratch.word0.s.generic_ee_cmd_return_code == 0) { + GSIERR("No response received\n"); + res = -GSI_STATUS_ERROR; + goto free_lock; + } + + res = GSI_STATUS_SUCCESS; + *code = gsi_ctx->scratch.word0.s.generic_ee_cmd_return_code; +free_lock: + mutex_unlock(&gsi_ctx->mlock); + + return res; +} +EXPORT_SYMBOL(gsi_halt_channel_ee); + static int msm_gsi_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -2757,6 +2822,7 @@ static int msm_gsi_probe(struct platform_device *pdev) } gsi_ctx->dev = dev; + init_completion(&gsi_ctx->gen_ee_cmd_compl); gsi_debugfs_init(); return 0; diff --git a/drivers/platform/msm/gsi/gsi.h b/drivers/platform/msm/gsi/gsi.h index 750ae2b329d3..d0eb162c49cf 100644 --- a/drivers/platform/msm/gsi/gsi.h +++ b/drivers/platform/msm/gsi/gsi.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -115,9 +115,12 @@ struct gsi_evt_ctx { struct gsi_ee_scratch { union __packed { struct { - uint32_t resvd1:15; + uint32_t inter_ee_cmd_return_code:3; + uint32_t resvd1:2; + uint32_t generic_ee_cmd_return_code:3; + uint32_t resvd2:7; uint32_t max_usb_pkt_size:1; - uint32_t resvd2:8; + uint32_t resvd3:8; uint32_t mhi_base_chan_idx:8; } s; uint32_t val; @@ -135,6 +138,10 @@ struct ch_debug_stats { unsigned long cmd_completed; }; +struct gsi_generic_ee_cmd_debug_stats { + unsigned long halt_channel; +}; + struct gsi_ctx { void __iomem *base; struct device *dev; @@ -143,6 +150,7 @@ struct gsi_ctx { struct gsi_chan_ctx chan[GSI_CHAN_MAX]; struct ch_debug_stats ch_dbg[GSI_CHAN_MAX]; struct gsi_evt_ctx evtr[GSI_EVT_RING_MAX]; + struct gsi_generic_ee_cmd_debug_stats gen_ee_cmd_dbg; struct mutex mlock; spinlock_t slock; unsigned long evt_bmap; @@ -154,6 +162,7 @@ struct gsi_ctx { struct workqueue_struct *dp_stat_wq; u32 max_ch; u32 max_ev; + struct completion gen_ee_cmd_compl; }; enum gsi_re_type { @@ -227,6 +236,18 @@ enum gsi_evt_ch_cmd_opcode { GSI_EVT_DE_ALLOC = 0xa, }; +enum gsi_generic_ee_cmd_opcode { + GSI_GEN_EE_CMD_HALT_CHANNEL = 0x1, +}; + +enum gsi_generic_ee_cmd_return_code { + GSI_GEN_EE_CMD_RETURN_CODE_SUCCESS = 0x1, + GSI_GEN_EE_CMD_RETURN_CODE_CHANNEL_NOT_RUNNING = 0x2, + GSI_GEN_EE_CMD_RETURN_CODE_INCORRECT_DIRECTION = 0x3, + GSI_GEN_EE_CMD_RETURN_CODE_INCORRECT_CHANNEL_TYPE = 0x4, + GSI_GEN_EE_CMD_RETURN_CODE_INCORRECT_CHANNEL_INDEX = 0x5, +}; + extern struct gsi_ctx *gsi_ctx; void gsi_debugfs_init(void); uint16_t gsi_find_idx_from_addr(struct gsi_ring_ctx *ctx, uint64_t addr); diff --git a/drivers/platform/msm/gsi/gsi_reg.h b/drivers/platform/msm/gsi/gsi_reg.h index 1acaf74a0968..d0462aad72d2 100644 --- a/drivers/platform/msm/gsi/gsi_reg.h +++ b/drivers/platform/msm/gsi/gsi_reg.h @@ -1365,8 +1365,12 @@ (GSI_GSI_REG_BASE_OFFS + 0x0001f018 + 0x4000 * (n)) #define GSI_EE_n_GSI_EE_GENERIC_CMD_RMSK 0xffffffff #define GSI_EE_n_GSI_EE_GENERIC_CMD_MAXn 3 -#define GSI_EE_n_GSI_EE_GENERIC_CMD_OPCODE_BMSK 0xffffffff +#define GSI_EE_n_GSI_EE_GENERIC_CMD_OPCODE_BMSK 0x1f #define GSI_EE_n_GSI_EE_GENERIC_CMD_OPCODE_SHFT 0x0 +#define GSI_EE_n_GSI_EE_GENERIC_CMD_VIRT_CHAN_IDX_BMSK 0x3e0 +#define GSI_EE_n_GSI_EE_GENERIC_CMD_VIRT_CHAN_IDX_SHFT 0x5 +#define GSI_EE_n_GSI_EE_GENERIC_CMD_EE_BMSK 0x3c00 +#define GSI_EE_n_GSI_EE_GENERIC_CMD_EE_SHFT 0xa /* v1.0 */ #define GSI_V1_0_EE_n_GSI_HW_PARAM_OFFS(n) \ |