From patchwork Sat Feb 12 18:20:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 542178 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 35BF8C433F5 for ; Sat, 12 Feb 2022 18:21:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229597AbiBLSVx (ORCPT ); Sat, 12 Feb 2022 13:21:53 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:44722 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229587AbiBLSVv (ORCPT ); Sat, 12 Feb 2022 13:21:51 -0500 Received: from mail-pj1-x102b.google.com (mail-pj1-x102b.google.com [IPv6:2607:f8b0:4864:20::102b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ED16254189 for ; Sat, 12 Feb 2022 10:21:47 -0800 (PST) Received: by mail-pj1-x102b.google.com with SMTP id c5-20020a17090a1d0500b001b904a7046dso13458062pjd.1 for ; Sat, 12 Feb 2022 10:21:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=x7DQ/ZJ2gQOCs8afpwgV3IUsPGlYg0pNNMCW2zNhUO8=; b=WYLrcsL4z93Z79+6TZmR1sVn94tNgubl+JfaCtqejObohJL+hcAyUh2RWSDzlpwEr+ 1lsptBo9XrX0q94C9ENxJCybs2WAo4k5EOvR2VFZV6JhrIxtDcaX6hlxryb1/gWwI5c9 3JyBQDEXfL5LwEbsdEbQj1/4nfsSZ3/ZEEEtdOaZhYjrLXIEkCGc8l2X3KYPqgAgR2re piR+uv8ZxFo9C1Z9rN07f1KomwTl/RO2BMuQZI3tvXo1XOg8+GVlyCxfbP0kEYpBk8L5 1tjo/7gSqaywFI9hP8JPaAgTNsNA8v7gZC2cRTgu5CweLwyer/c1iy2df/nq9sJ9W0q1 zPKQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=x7DQ/ZJ2gQOCs8afpwgV3IUsPGlYg0pNNMCW2zNhUO8=; b=T3ay2zy/yl72ntMyMojVebGUMAiAaBNV7ldxOA+axaRPC/hvj/pQFdMtXBAjUL1xnQ s7t/xGSYO90pG6btvyMbzNObq3rFvYdod4sfIMDOWSSecd8LGYTsDJX7tGkUQ5T2GVpZ rJPbO1T9tf70ociINoIfbRmnKcbGaY9U6pgVkM/XelV3g9D/mlCK4kJ5qw2Yt3QVnbsz mZE3fmhE6o1tS5hy1mlkPU8D7PKJXgp6uFQ5fQDZX0B26SyhNCW1SRYa+jcp+/2UZR55 NUG0HpbKIrvPK1OZb6Nan1pyaUeNyZKyOzee+Ybs5kYgq+Nt93y1/XpIKmhTldUjAF/o 86qQ== X-Gm-Message-State: AOAM530jBORCgJ0pOr2HaZF5+Iu3N2Yl0eZVudtv08+FAKo6yLcvgE1v WZ5A4OWzRsjcpWTsgIQg32nw X-Google-Smtp-Source: ABdhPJwjJuEzA3rG6VR1TZ2r3vKn3OMJXR3L5Y4wVNt3Gz785c7ZEDqOc9RN+ePb0Lq/fNq4vW0iPw== X-Received: by 2002:a17:902:bcca:: with SMTP id o10mr6894783pls.147.1644690107434; Sat, 12 Feb 2022 10:21:47 -0800 (PST) Received: from localhost.localdomain ([27.111.75.57]) by smtp.gmail.com with ESMTPSA id g12sm14961987pfj.148.2022.02.12.10.21.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Feb 2022 10:21:47 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Paul Davey , Manivannan Sadhasivam , Hemant Kumar , stable@vger.kernel.org, Manivannan Sadhasivam Subject: [PATCH v3 01/25] bus: mhi: Fix pm_state conversion to string Date: Sat, 12 Feb 2022 23:50:53 +0530 Message-Id: <20220212182117.49438-2-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> References: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org From: Paul Davey On big endian architectures the mhi debugfs files which report pm state give "Invalid State" for all states. This is caused by using find_last_bit which takes an unsigned long* while the state is passed in as an enum mhi_pm_state which will be of int size. Fix by using __fls to pass the value of state instead of find_last_bit. Fixes: a6e2e3522f29 ("bus: mhi: core: Add support for PM state transitions") Signed-off-by: Paul Davey Reviewed-by: Manivannan Sadhasivam Reviewed-by: Hemant Kumar Cc: stable@vger.kernel.org Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/core/init.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/bus/mhi/core/init.c b/drivers/bus/mhi/core/init.c index 046f407dc5d6..af484b03558a 100644 --- a/drivers/bus/mhi/core/init.c +++ b/drivers/bus/mhi/core/init.c @@ -79,10 +79,12 @@ static const char * const mhi_pm_state_str[] = { const char *to_mhi_pm_state_str(enum mhi_pm_state state) { - unsigned long pm_state = state; - int index = find_last_bit(&pm_state, 32); + int index; - if (index >= ARRAY_SIZE(mhi_pm_state_str)) + if (state) + index = __fls(state); + + if (!state || index >= ARRAY_SIZE(mhi_pm_state_str)) return "Invalid State"; return mhi_pm_state_str[index]; From patchwork Sat Feb 12 18:20:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 542595 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EFEB7C433F5 for ; Sat, 12 Feb 2022 18:21:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229620AbiBLSV7 (ORCPT ); Sat, 12 Feb 2022 13:21:59 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:44932 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229609AbiBLSV6 (ORCPT ); Sat, 12 Feb 2022 13:21:58 -0500 Received: from mail-pf1-x431.google.com (mail-pf1-x431.google.com [IPv6:2607:f8b0:4864:20::431]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 98EF25A58F for ; Sat, 12 Feb 2022 10:21:52 -0800 (PST) Received: by mail-pf1-x431.google.com with SMTP id l19so16141058pfu.2 for ; Sat, 12 Feb 2022 10:21:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=1jiDymegMfFeDjwkyFQLvd6t3JfuBkI8jUbh1cojaZA=; b=KBnrpinDpb8vo21iSQe58N9P/xJ2ScjDhxqTYeKNJ27mD5secedjo6FZUQCsBBcFb2 kL7y2W8cWIanxa0VDhEuDmyKm+Ctt/oGv3WYJJppZJJqAem/wNK/lIzcpZlzKHMDskUq mpXsDv9DFMm475EH4NuTThY8Bah9pNZfN7quFpfb/w4rG5zpKRMJPETiVxQDK5FuEmRN N93JFalgv26QLO7cvsNnLFGkvbKx8JUJegTb47Te1u/TemmqeKs3m5blsNu/Ss9R1a5M 03/6fntbswJWfzmOczug1h/ntpfpTl7KO/YjtrB70sYq03sI8neojOagVxSZmmAyumB9 EKHg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=1jiDymegMfFeDjwkyFQLvd6t3JfuBkI8jUbh1cojaZA=; b=l6RGb4VbF+07OyyAgMORdluj67aiQhz7rS9LCwgn7A5+QFycR6Ro9oKYhh/E5mIFU0 +CMUDJu7pJlwZDIlnjaMUn8buFUVB8kHtEgp3YIen5u6oqbkNCWA1PsqGHT5l1bFa/RU Tx4cntXE1DHynNzCchmAY0hyfr0VFvnisL7TrrDCPfr2m9zGOFW+v1HpF7EylPwmSgWL So7tIaJh5IJTAkb+CGPhIVSmayVZI+qiO3L7HnxUJtTqDb0foUnt59uzNAYskOXP+i9b Gqnlcj/afX7VHT66QSZ04mJIWHV3eINwcKxbLJ6xheFbdje/zJU/lQwMXPDzRehkw6Fu WAtg== X-Gm-Message-State: AOAM531UDENeRhwjQp9HlMu6UoRNb9t000R0qdI/jYLAS3CHcEfnX5Vc u2CQI0vkUOS9OkFJu0fcMHzU X-Google-Smtp-Source: ABdhPJyUtiN6A2Qjoc4kyrpTWE3oAzQp1Nym4vpIZnaYmyoV3xREREIUwQk+pBWbKuA7xhMkvGvC/A== X-Received: by 2002:a05:6a00:1902:: with SMTP id y2mr7070250pfi.57.1644690111952; Sat, 12 Feb 2022 10:21:51 -0800 (PST) Received: from localhost.localdomain ([27.111.75.57]) by smtp.gmail.com with ESMTPSA id g12sm14961987pfj.148.2022.02.12.10.21.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Feb 2022 10:21:51 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Paul Davey , stable@vger.kernel.org, Manivannan Sadhasivam Subject: [PATCH v3 02/25] bus: mhi: Fix MHI DMA structure endianness Date: Sat, 12 Feb 2022 23:50:54 +0530 Message-Id: <20220212182117.49438-3-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> References: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org From: Paul Davey The MHI driver does not work on big endian architectures. The controller never transitions into mission mode. This appears to be due to the modem device expecting the various contexts and transfer rings to have fields in little endian order in memory, but the driver constructs them in native endianness. Fix MHI event, channel and command contexts and TRE handling macros to use explicit conversion to little endian. Mark fields in relevant structures as little endian to document this requirement. Fixes: a6e2e3522f29 ("bus: mhi: core: Add support for PM state transitions") Fixes: 6cd330ae76ff ("bus: mhi: core: Add support for ringing channel/event ring doorbells") Signed-off-by: Paul Davey Cc: stable@vger.kernel.org Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/core/debugfs.c | 26 +++---- drivers/bus/mhi/core/init.c | 36 +++++----- drivers/bus/mhi/core/internal.h | 119 ++++++++++++++++---------------- drivers/bus/mhi/core/main.c | 22 +++--- drivers/bus/mhi/core/pm.c | 4 +- 5 files changed, 104 insertions(+), 103 deletions(-) diff --git a/drivers/bus/mhi/core/debugfs.c b/drivers/bus/mhi/core/debugfs.c index 858d7516410b..d818586c229d 100644 --- a/drivers/bus/mhi/core/debugfs.c +++ b/drivers/bus/mhi/core/debugfs.c @@ -60,16 +60,16 @@ static int mhi_debugfs_events_show(struct seq_file *m, void *d) } seq_printf(m, "Index: %d intmod count: %lu time: %lu", - i, (er_ctxt->intmod & EV_CTX_INTMODC_MASK) >> + i, (le32_to_cpu(er_ctxt->intmod) & EV_CTX_INTMODC_MASK) >> EV_CTX_INTMODC_SHIFT, - (er_ctxt->intmod & EV_CTX_INTMODT_MASK) >> + (le32_to_cpu(er_ctxt->intmod) & EV_CTX_INTMODT_MASK) >> EV_CTX_INTMODT_SHIFT); - seq_printf(m, " base: 0x%0llx len: 0x%llx", er_ctxt->rbase, - er_ctxt->rlen); + seq_printf(m, " base: 0x%0llx len: 0x%llx", le64_to_cpu(er_ctxt->rbase), + le64_to_cpu(er_ctxt->rlen)); - seq_printf(m, " rp: 0x%llx wp: 0x%llx", er_ctxt->rp, - er_ctxt->wp); + seq_printf(m, " rp: 0x%llx wp: 0x%llx", le64_to_cpu(er_ctxt->rp), + le64_to_cpu(er_ctxt->wp)); seq_printf(m, " local rp: 0x%pK db: 0x%pad\n", ring->rp, &mhi_event->db_cfg.db_val); @@ -106,18 +106,18 @@ static int mhi_debugfs_channels_show(struct seq_file *m, void *d) seq_printf(m, "%s(%u) state: 0x%lx brstmode: 0x%lx pollcfg: 0x%lx", - mhi_chan->name, mhi_chan->chan, (chan_ctxt->chcfg & + mhi_chan->name, mhi_chan->chan, (le32_to_cpu(chan_ctxt->chcfg) & CHAN_CTX_CHSTATE_MASK) >> CHAN_CTX_CHSTATE_SHIFT, - (chan_ctxt->chcfg & CHAN_CTX_BRSTMODE_MASK) >> - CHAN_CTX_BRSTMODE_SHIFT, (chan_ctxt->chcfg & + (le32_to_cpu(chan_ctxt->chcfg) & CHAN_CTX_BRSTMODE_MASK) >> + CHAN_CTX_BRSTMODE_SHIFT, (le32_to_cpu(chan_ctxt->chcfg) & CHAN_CTX_POLLCFG_MASK) >> CHAN_CTX_POLLCFG_SHIFT); - seq_printf(m, " type: 0x%x event ring: %u", chan_ctxt->chtype, - chan_ctxt->erindex); + seq_printf(m, " type: 0x%x event ring: %u", le32_to_cpu(chan_ctxt->chtype), + le32_to_cpu(chan_ctxt->erindex)); seq_printf(m, " base: 0x%llx len: 0x%llx rp: 0x%llx wp: 0x%llx", - chan_ctxt->rbase, chan_ctxt->rlen, chan_ctxt->rp, - chan_ctxt->wp); + le64_to_cpu(chan_ctxt->rbase), le64_to_cpu(chan_ctxt->rlen), + le64_to_cpu(chan_ctxt->rp), le64_to_cpu(chan_ctxt->wp)); seq_printf(m, " local rp: 0x%pK local wp: 0x%pK db: 0x%pad\n", ring->rp, ring->wp, diff --git a/drivers/bus/mhi/core/init.c b/drivers/bus/mhi/core/init.c index af484b03558a..4bd62f32695d 100644 --- a/drivers/bus/mhi/core/init.c +++ b/drivers/bus/mhi/core/init.c @@ -293,17 +293,17 @@ int mhi_init_dev_ctxt(struct mhi_controller *mhi_cntrl) if (mhi_chan->offload_ch) continue; - tmp = chan_ctxt->chcfg; + tmp = le32_to_cpu(chan_ctxt->chcfg); tmp &= ~CHAN_CTX_CHSTATE_MASK; tmp |= (MHI_CH_STATE_DISABLED << CHAN_CTX_CHSTATE_SHIFT); tmp &= ~CHAN_CTX_BRSTMODE_MASK; tmp |= (mhi_chan->db_cfg.brstmode << CHAN_CTX_BRSTMODE_SHIFT); tmp &= ~CHAN_CTX_POLLCFG_MASK; tmp |= (mhi_chan->db_cfg.pollcfg << CHAN_CTX_POLLCFG_SHIFT); - chan_ctxt->chcfg = tmp; + chan_ctxt->chcfg = cpu_to_le32(tmp); - chan_ctxt->chtype = mhi_chan->type; - chan_ctxt->erindex = mhi_chan->er_index; + chan_ctxt->chtype = cpu_to_le32(mhi_chan->type); + chan_ctxt->erindex = cpu_to_le32(mhi_chan->er_index); mhi_chan->ch_state = MHI_CH_STATE_DISABLED; mhi_chan->tre_ring.db_addr = (void __iomem *)&chan_ctxt->wp; @@ -328,14 +328,14 @@ int mhi_init_dev_ctxt(struct mhi_controller *mhi_cntrl) if (mhi_event->offload_ev) continue; - tmp = er_ctxt->intmod; + tmp = le32_to_cpu(er_ctxt->intmod); tmp &= ~EV_CTX_INTMODC_MASK; tmp &= ~EV_CTX_INTMODT_MASK; tmp |= (mhi_event->intmod << EV_CTX_INTMODT_SHIFT); - er_ctxt->intmod = tmp; + er_ctxt->intmod = cpu_to_le32(tmp); - er_ctxt->ertype = MHI_ER_TYPE_VALID; - er_ctxt->msivec = mhi_event->irq; + er_ctxt->ertype = cpu_to_le32(MHI_ER_TYPE_VALID); + er_ctxt->msivec = cpu_to_le32(mhi_event->irq); mhi_event->db_cfg.db_mode = true; ring->el_size = sizeof(struct mhi_tre); @@ -349,9 +349,9 @@ int mhi_init_dev_ctxt(struct mhi_controller *mhi_cntrl) * ring is empty */ ring->rp = ring->wp = ring->base; - er_ctxt->rbase = ring->iommu_base; + er_ctxt->rbase = cpu_to_le64(ring->iommu_base); er_ctxt->rp = er_ctxt->wp = er_ctxt->rbase; - er_ctxt->rlen = ring->len; + er_ctxt->rlen = cpu_to_le64(ring->len); ring->ctxt_wp = &er_ctxt->wp; } @@ -378,9 +378,9 @@ int mhi_init_dev_ctxt(struct mhi_controller *mhi_cntrl) goto error_alloc_cmd; ring->rp = ring->wp = ring->base; - cmd_ctxt->rbase = ring->iommu_base; + cmd_ctxt->rbase = cpu_to_le64(ring->iommu_base); cmd_ctxt->rp = cmd_ctxt->wp = cmd_ctxt->rbase; - cmd_ctxt->rlen = ring->len; + cmd_ctxt->rlen = cpu_to_le64(ring->len); ring->ctxt_wp = &cmd_ctxt->wp; } @@ -581,10 +581,10 @@ void mhi_deinit_chan_ctxt(struct mhi_controller *mhi_cntrl, chan_ctxt->rp = 0; chan_ctxt->wp = 0; - tmp = chan_ctxt->chcfg; + tmp = le32_to_cpu(chan_ctxt->chcfg); tmp &= ~CHAN_CTX_CHSTATE_MASK; tmp |= (MHI_CH_STATE_DISABLED << CHAN_CTX_CHSTATE_SHIFT); - chan_ctxt->chcfg = tmp; + chan_ctxt->chcfg = cpu_to_le32(tmp); /* Update to all cores */ smp_wmb(); @@ -618,14 +618,14 @@ int mhi_init_chan_ctxt(struct mhi_controller *mhi_cntrl, return -ENOMEM; } - tmp = chan_ctxt->chcfg; + tmp = le32_to_cpu(chan_ctxt->chcfg); tmp &= ~CHAN_CTX_CHSTATE_MASK; tmp |= (MHI_CH_STATE_ENABLED << CHAN_CTX_CHSTATE_SHIFT); - chan_ctxt->chcfg = tmp; + chan_ctxt->chcfg = cpu_to_le32(tmp); - chan_ctxt->rbase = tre_ring->iommu_base; + chan_ctxt->rbase = cpu_to_le64(tre_ring->iommu_base); chan_ctxt->rp = chan_ctxt->wp = chan_ctxt->rbase; - chan_ctxt->rlen = tre_ring->len; + chan_ctxt->rlen = cpu_to_le64(tre_ring->len); tre_ring->ctxt_wp = &chan_ctxt->wp; tre_ring->rp = tre_ring->wp = tre_ring->base; diff --git a/drivers/bus/mhi/core/internal.h b/drivers/bus/mhi/core/internal.h index e2e10474a9d9..fa64340a8997 100644 --- a/drivers/bus/mhi/core/internal.h +++ b/drivers/bus/mhi/core/internal.h @@ -209,14 +209,14 @@ extern struct bus_type mhi_bus_type; #define EV_CTX_INTMODT_MASK GENMASK(31, 16) #define EV_CTX_INTMODT_SHIFT 16 struct mhi_event_ctxt { - __u32 intmod; - __u32 ertype; - __u32 msivec; - - __u64 rbase __packed __aligned(4); - __u64 rlen __packed __aligned(4); - __u64 rp __packed __aligned(4); - __u64 wp __packed __aligned(4); + __le32 intmod; + __le32 ertype; + __le32 msivec; + + __le64 rbase __packed __aligned(4); + __le64 rlen __packed __aligned(4); + __le64 rp __packed __aligned(4); + __le64 wp __packed __aligned(4); }; #define CHAN_CTX_CHSTATE_MASK GENMASK(7, 0) @@ -227,25 +227,25 @@ struct mhi_event_ctxt { #define CHAN_CTX_POLLCFG_SHIFT 10 #define CHAN_CTX_RESERVED_MASK GENMASK(31, 16) struct mhi_chan_ctxt { - __u32 chcfg; - __u32 chtype; - __u32 erindex; - - __u64 rbase __packed __aligned(4); - __u64 rlen __packed __aligned(4); - __u64 rp __packed __aligned(4); - __u64 wp __packed __aligned(4); + __le32 chcfg; + __le32 chtype; + __le32 erindex; + + __le64 rbase __packed __aligned(4); + __le64 rlen __packed __aligned(4); + __le64 rp __packed __aligned(4); + __le64 wp __packed __aligned(4); }; struct mhi_cmd_ctxt { - __u32 reserved0; - __u32 reserved1; - __u32 reserved2; - - __u64 rbase __packed __aligned(4); - __u64 rlen __packed __aligned(4); - __u64 rp __packed __aligned(4); - __u64 wp __packed __aligned(4); + __le32 reserved0; + __le32 reserved1; + __le32 reserved2; + + __le64 rbase __packed __aligned(4); + __le64 rlen __packed __aligned(4); + __le64 rp __packed __aligned(4); + __le64 wp __packed __aligned(4); }; struct mhi_ctxt { @@ -258,8 +258,8 @@ struct mhi_ctxt { }; struct mhi_tre { - u64 ptr; - u32 dword[2]; + __le64 ptr; + __le32 dword[2]; }; struct bhi_vec_entry { @@ -277,57 +277,58 @@ enum mhi_cmd_type { /* No operation command */ #define MHI_TRE_CMD_NOOP_PTR (0) #define MHI_TRE_CMD_NOOP_DWORD0 (0) -#define MHI_TRE_CMD_NOOP_DWORD1 (MHI_CMD_NOP << 16) +#define MHI_TRE_CMD_NOOP_DWORD1 (cpu_to_le32(MHI_CMD_NOP << 16)) /* Channel reset command */ #define MHI_TRE_CMD_RESET_PTR (0) #define MHI_TRE_CMD_RESET_DWORD0 (0) -#define MHI_TRE_CMD_RESET_DWORD1(chid) ((chid << 24) | \ - (MHI_CMD_RESET_CHAN << 16)) +#define MHI_TRE_CMD_RESET_DWORD1(chid) (cpu_to_le32((chid << 24) | \ + (MHI_CMD_RESET_CHAN << 16))) /* Channel stop command */ #define MHI_TRE_CMD_STOP_PTR (0) #define MHI_TRE_CMD_STOP_DWORD0 (0) -#define MHI_TRE_CMD_STOP_DWORD1(chid) ((chid << 24) | \ - (MHI_CMD_STOP_CHAN << 16)) +#define MHI_TRE_CMD_STOP_DWORD1(chid) (cpu_to_le32((chid << 24) | \ + (MHI_CMD_STOP_CHAN << 16))) /* Channel start command */ #define MHI_TRE_CMD_START_PTR (0) #define MHI_TRE_CMD_START_DWORD0 (0) -#define MHI_TRE_CMD_START_DWORD1(chid) ((chid << 24) | \ - (MHI_CMD_START_CHAN << 16)) +#define MHI_TRE_CMD_START_DWORD1(chid) (cpu_to_le32((chid << 24) | \ + (MHI_CMD_START_CHAN << 16))) -#define MHI_TRE_GET_CMD_CHID(tre) (((tre)->dword[1] >> 24) & 0xFF) -#define MHI_TRE_GET_CMD_TYPE(tre) (((tre)->dword[1] >> 16) & 0xFF) +#define MHI_TRE_GET_DWORD(tre, word) (le32_to_cpu((tre)->dword[(word)])) +#define MHI_TRE_GET_CMD_CHID(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 24) & 0xFF) +#define MHI_TRE_GET_CMD_TYPE(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 16) & 0xFF) /* Event descriptor macros */ -#define MHI_TRE_EV_PTR(ptr) (ptr) -#define MHI_TRE_EV_DWORD0(code, len) ((code << 24) | len) -#define MHI_TRE_EV_DWORD1(chid, type) ((chid << 24) | (type << 16)) -#define MHI_TRE_GET_EV_PTR(tre) ((tre)->ptr) -#define MHI_TRE_GET_EV_CODE(tre) (((tre)->dword[0] >> 24) & 0xFF) -#define MHI_TRE_GET_EV_LEN(tre) ((tre)->dword[0] & 0xFFFF) -#define MHI_TRE_GET_EV_CHID(tre) (((tre)->dword[1] >> 24) & 0xFF) -#define MHI_TRE_GET_EV_TYPE(tre) (((tre)->dword[1] >> 16) & 0xFF) -#define MHI_TRE_GET_EV_STATE(tre) (((tre)->dword[0] >> 24) & 0xFF) -#define MHI_TRE_GET_EV_EXECENV(tre) (((tre)->dword[0] >> 24) & 0xFF) -#define MHI_TRE_GET_EV_SEQ(tre) ((tre)->dword[0]) -#define MHI_TRE_GET_EV_TIME(tre) ((tre)->ptr) -#define MHI_TRE_GET_EV_COOKIE(tre) lower_32_bits((tre)->ptr) -#define MHI_TRE_GET_EV_VEID(tre) (((tre)->dword[0] >> 16) & 0xFF) -#define MHI_TRE_GET_EV_LINKSPEED(tre) (((tre)->dword[1] >> 24) & 0xFF) -#define MHI_TRE_GET_EV_LINKWIDTH(tre) ((tre)->dword[0] & 0xFF) +#define MHI_TRE_EV_PTR(ptr) (cpu_to_le64(ptr)) +#define MHI_TRE_EV_DWORD0(code, len) (cpu_to_le32((code << 24) | len)) +#define MHI_TRE_EV_DWORD1(chid, type) (cpu_to_le32((chid << 24) | (type << 16))) +#define MHI_TRE_GET_EV_PTR(tre) (le64_to_cpu((tre)->ptr)) +#define MHI_TRE_GET_EV_CODE(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 24) & 0xFF) +#define MHI_TRE_GET_EV_LEN(tre) (MHI_TRE_GET_DWORD(tre, 0) & 0xFFFF) +#define MHI_TRE_GET_EV_CHID(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 24) & 0xFF) +#define MHI_TRE_GET_EV_TYPE(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 16) & 0xFF) +#define MHI_TRE_GET_EV_STATE(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 24) & 0xFF) +#define MHI_TRE_GET_EV_EXECENV(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 24) & 0xFF) +#define MHI_TRE_GET_EV_SEQ(tre) MHI_TRE_GET_DWORD(tre, 0) +#define MHI_TRE_GET_EV_TIME(tre) (MHI_TRE_GET_EV_PTR(tre)) +#define MHI_TRE_GET_EV_COOKIE(tre) lower_32_bits(MHI_TRE_GET_EV_PTR(tre)) +#define MHI_TRE_GET_EV_VEID(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 16) & 0xFF) +#define MHI_TRE_GET_EV_LINKSPEED(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 24) & 0xFF) +#define MHI_TRE_GET_EV_LINKWIDTH(tre) (MHI_TRE_GET_DWORD(tre, 0) & 0xFF) /* Transfer descriptor macros */ -#define MHI_TRE_DATA_PTR(ptr) (ptr) -#define MHI_TRE_DATA_DWORD0(len) (len & MHI_MAX_MTU) -#define MHI_TRE_DATA_DWORD1(bei, ieot, ieob, chain) ((2 << 16) | (bei << 10) \ - | (ieot << 9) | (ieob << 8) | chain) +#define MHI_TRE_DATA_PTR(ptr) (cpu_to_le64(ptr)) +#define MHI_TRE_DATA_DWORD0(len) (cpu_to_le32(len & MHI_MAX_MTU)) +#define MHI_TRE_DATA_DWORD1(bei, ieot, ieob, chain) (cpu_to_le32((2 << 16) | (bei << 10) \ + | (ieot << 9) | (ieob << 8) | chain)) /* RSC transfer descriptor macros */ -#define MHI_RSCTRE_DATA_PTR(ptr, len) (((u64)len << 48) | ptr) -#define MHI_RSCTRE_DATA_DWORD0(cookie) (cookie) -#define MHI_RSCTRE_DATA_DWORD1 (MHI_PKT_TYPE_COALESCING << 16) +#define MHI_RSCTRE_DATA_PTR(ptr, len) (cpu_to_le64(((u64)len << 48) | ptr)) +#define MHI_RSCTRE_DATA_DWORD0(cookie) (cpu_to_le32(cookie)) +#define MHI_RSCTRE_DATA_DWORD1 (cpu_to_le32(MHI_PKT_TYPE_COALESCING << 16)) enum mhi_pkt_type { MHI_PKT_TYPE_INVALID = 0x0, @@ -500,7 +501,7 @@ struct state_transition { struct mhi_ring { dma_addr_t dma_handle; dma_addr_t iommu_base; - u64 *ctxt_wp; /* point to ctxt wp */ + __le64 *ctxt_wp; /* point to ctxt wp */ void *pre_aligned; void *base; void *rp; diff --git a/drivers/bus/mhi/core/main.c b/drivers/bus/mhi/core/main.c index ffde617f93a3..85f4f7c8d7c6 100644 --- a/drivers/bus/mhi/core/main.c +++ b/drivers/bus/mhi/core/main.c @@ -114,7 +114,7 @@ void mhi_ring_er_db(struct mhi_event *mhi_event) struct mhi_ring *ring = &mhi_event->ring; mhi_event->db_cfg.process_db(mhi_event->mhi_cntrl, &mhi_event->db_cfg, - ring->db_addr, *ring->ctxt_wp); + ring->db_addr, le64_to_cpu(*ring->ctxt_wp)); } void mhi_ring_cmd_db(struct mhi_controller *mhi_cntrl, struct mhi_cmd *mhi_cmd) @@ -123,7 +123,7 @@ void mhi_ring_cmd_db(struct mhi_controller *mhi_cntrl, struct mhi_cmd *mhi_cmd) struct mhi_ring *ring = &mhi_cmd->ring; db = ring->iommu_base + (ring->wp - ring->base); - *ring->ctxt_wp = db; + *ring->ctxt_wp = cpu_to_le64(db); mhi_write_db(mhi_cntrl, ring->db_addr, db); } @@ -140,7 +140,7 @@ void mhi_ring_chan_db(struct mhi_controller *mhi_cntrl, * before letting h/w know there is new element to fetch. */ dma_wmb(); - *ring->ctxt_wp = db; + *ring->ctxt_wp = cpu_to_le64(db); mhi_chan->db_cfg.process_db(mhi_cntrl, &mhi_chan->db_cfg, ring->db_addr, db); @@ -432,7 +432,7 @@ irqreturn_t mhi_irq_handler(int irq_number, void *dev) struct mhi_event_ctxt *er_ctxt = &mhi_cntrl->mhi_ctxt->er_ctxt[mhi_event->er_index]; struct mhi_ring *ev_ring = &mhi_event->ring; - dma_addr_t ptr = er_ctxt->rp; + dma_addr_t ptr = le64_to_cpu(er_ctxt->rp); void *dev_rp; if (!is_valid_ring_ptr(ev_ring, ptr)) { @@ -537,14 +537,14 @@ static void mhi_recycle_ev_ring_element(struct mhi_controller *mhi_cntrl, /* Update the WP */ ring->wp += ring->el_size; - ctxt_wp = *ring->ctxt_wp + ring->el_size; + ctxt_wp = le64_to_cpu(*ring->ctxt_wp) + ring->el_size; if (ring->wp >= (ring->base + ring->len)) { ring->wp = ring->base; ctxt_wp = ring->iommu_base; } - *ring->ctxt_wp = ctxt_wp; + *ring->ctxt_wp = cpu_to_le64(ctxt_wp); /* Update the RP */ ring->rp += ring->el_size; @@ -801,7 +801,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl, struct device *dev = &mhi_cntrl->mhi_dev->dev; u32 chan; int count = 0; - dma_addr_t ptr = er_ctxt->rp; + dma_addr_t ptr = le64_to_cpu(er_ctxt->rp); /* * This is a quick check to avoid unnecessary event processing @@ -940,7 +940,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl, mhi_recycle_ev_ring_element(mhi_cntrl, ev_ring); local_rp = ev_ring->rp; - ptr = er_ctxt->rp; + ptr = le64_to_cpu(er_ctxt->rp); if (!is_valid_ring_ptr(ev_ring, ptr)) { dev_err(&mhi_cntrl->mhi_dev->dev, "Event ring rp points outside of the event ring\n"); @@ -970,7 +970,7 @@ int mhi_process_data_event_ring(struct mhi_controller *mhi_cntrl, int count = 0; u32 chan; struct mhi_chan *mhi_chan; - dma_addr_t ptr = er_ctxt->rp; + dma_addr_t ptr = le64_to_cpu(er_ctxt->rp); if (unlikely(MHI_EVENT_ACCESS_INVALID(mhi_cntrl->pm_state))) return -EIO; @@ -1011,7 +1011,7 @@ int mhi_process_data_event_ring(struct mhi_controller *mhi_cntrl, mhi_recycle_ev_ring_element(mhi_cntrl, ev_ring); local_rp = ev_ring->rp; - ptr = er_ctxt->rp; + ptr = le64_to_cpu(er_ctxt->rp); if (!is_valid_ring_ptr(ev_ring, ptr)) { dev_err(&mhi_cntrl->mhi_dev->dev, "Event ring rp points outside of the event ring\n"); @@ -1533,7 +1533,7 @@ static void mhi_mark_stale_events(struct mhi_controller *mhi_cntrl, /* mark all stale events related to channel as STALE event */ spin_lock_irqsave(&mhi_event->lock, flags); - ptr = er_ctxt->rp; + ptr = le64_to_cpu(er_ctxt->rp); if (!is_valid_ring_ptr(ev_ring, ptr)) { dev_err(&mhi_cntrl->mhi_dev->dev, "Event ring rp points outside of the event ring\n"); diff --git a/drivers/bus/mhi/core/pm.c b/drivers/bus/mhi/core/pm.c index 4aae0baea008..c35c5ddc7220 100644 --- a/drivers/bus/mhi/core/pm.c +++ b/drivers/bus/mhi/core/pm.c @@ -218,7 +218,7 @@ int mhi_ready_state_transition(struct mhi_controller *mhi_cntrl) continue; ring->wp = ring->base + ring->len - ring->el_size; - *ring->ctxt_wp = ring->iommu_base + ring->len - ring->el_size; + *ring->ctxt_wp = cpu_to_le64(ring->iommu_base + ring->len - ring->el_size); /* Update all cores */ smp_wmb(); @@ -420,7 +420,7 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl) continue; ring->wp = ring->base + ring->len - ring->el_size; - *ring->ctxt_wp = ring->iommu_base + ring->len - ring->el_size; + *ring->ctxt_wp = cpu_to_le64(ring->iommu_base + ring->len - ring->el_size); /* Update to all cores */ smp_wmb(); From patchwork Sat Feb 12 18:20:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 542177 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0465BC4332F for ; Sat, 12 Feb 2022 18:22:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229639AbiBLSWD (ORCPT ); Sat, 12 Feb 2022 13:22:03 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:45096 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229614AbiBLSWC (ORCPT ); Sat, 12 Feb 2022 13:22:02 -0500 Received: from mail-pj1-x1034.google.com (mail-pj1-x1034.google.com [IPv6:2607:f8b0:4864:20::1034]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 437295A5BC for ; Sat, 12 Feb 2022 10:21:58 -0800 (PST) Received: by mail-pj1-x1034.google.com with SMTP id v4so10874923pjh.2 for ; Sat, 12 Feb 2022 10:21:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=7ok1k9pQCzWci1MKP3xrf+KxWEUg4H3+jdbuzeHSCcU=; b=rDW59zzthMHIwuoDTyahs56Deb/SPTP28qxv7JVUQbuc3je76sGBJPkwPu2xNz/IG3 Pt/gdPdCAUpb60vbPJnSw860V2D53X40CaHrncMdmw7U00unaxbD2cAWWVRbZ8Y044dg jdZhiCOEOdeYCrtFOE91GJBk1s4If3d/oUn6u0Qxi/Y+BrIzb9TEL+lDqBZOZX8TZa9Y HRj6eZNXsZ3JKXKhP5F8H2oswB7AwV5kARgVqbNx/nPPPCeyW3HEFSWQVdo7BFfNxLJ/ yPMBWX87BWm3YhMgM40DnnWr/teMIvfyv9mLVwAbvFTtKZYHvzH1pSRz52YSPtSskQ7R x5EA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=7ok1k9pQCzWci1MKP3xrf+KxWEUg4H3+jdbuzeHSCcU=; b=vo8jrLIcyzvrQU3kdD5PMeiQHWTRhMvqaSfZWlOT37yyjpgDONOEWxc3y+wvnTn165 UL/ofclfyIyAMJDB8a9HZaRM8I90gOofrJofZwPrUAGQT54BSBMvyft/ACT15u8ocrMB wnC+R5XRrJ5bBh/Nz2MN1U1feDMi336oBPDyIh21TE1BSzrBIis4ANYfuELWfLfmnMiT P5P1CedveI/PYN8RC0p83NY9RMn09qbdjY1j9rIgoJtvKzoNXOReyXY2k2g56GPqSpgq kiew1859FEZPBwNTQ/CmSEyxwua9iw0EnyGu1p+25Pxdpg9LsZ7MTz6xKCIYhhII1OJ2 IaAA== X-Gm-Message-State: AOAM532BoyPT8ZXucckoyJz51xHPY9qVXM84+JCOciLh/dPqtkoUMJrB FJb19HyRORVN3KGkflVACiXG X-Google-Smtp-Source: ABdhPJxKn4JgojjFktM7VtXWMFngca+NMAbDxeq0U09ybu7ghhhjIMYu3ysSV5hS+60LtbFuvoOl0A== X-Received: by 2002:a17:90b:3810:: with SMTP id mq16mr6448375pjb.26.1644690117738; Sat, 12 Feb 2022 10:21:57 -0800 (PST) Received: from localhost.localdomain ([27.111.75.57]) by smtp.gmail.com with ESMTPSA id g12sm14961987pfj.148.2022.02.12.10.21.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Feb 2022 10:21:57 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam , Hemant Kumar Subject: [PATCH v3 03/25] bus: mhi: Move host MHI code to "host" directory Date: Sat, 12 Feb 2022 23:50:55 +0530 Message-Id: <20220212182117.49438-4-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> References: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org In preparation of the endpoint MHI support, let's move the host MHI code to its own "host" directory and adjust the toplevel MHI Kconfig & Makefile. While at it, let's also move the "pci_generic" driver to "host" directory as it is a host MHI controller driver. Reviewed-by: Hemant Kumar Signed-off-by: Manivannan Sadhasivam Reviewed-by: Alex Elder --- drivers/bus/Makefile | 2 +- drivers/bus/mhi/Kconfig | 27 ++------------------ drivers/bus/mhi/Makefile | 8 ++---- drivers/bus/mhi/host/Kconfig | 31 +++++++++++++++++++++++ drivers/bus/mhi/{core => host}/Makefile | 4 ++- drivers/bus/mhi/{core => host}/boot.c | 0 drivers/bus/mhi/{core => host}/debugfs.c | 0 drivers/bus/mhi/{core => host}/init.c | 0 drivers/bus/mhi/{core => host}/internal.h | 0 drivers/bus/mhi/{core => host}/main.c | 0 drivers/bus/mhi/{ => host}/pci_generic.c | 0 drivers/bus/mhi/{core => host}/pm.c | 0 12 files changed, 39 insertions(+), 33 deletions(-) create mode 100644 drivers/bus/mhi/host/Kconfig rename drivers/bus/mhi/{core => host}/Makefile (54%) rename drivers/bus/mhi/{core => host}/boot.c (100%) rename drivers/bus/mhi/{core => host}/debugfs.c (100%) rename drivers/bus/mhi/{core => host}/init.c (100%) rename drivers/bus/mhi/{core => host}/internal.h (100%) rename drivers/bus/mhi/{core => host}/main.c (100%) rename drivers/bus/mhi/{ => host}/pci_generic.c (100%) rename drivers/bus/mhi/{core => host}/pm.c (100%) diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile index 52c2f35a26a9..16da51130d1a 100644 --- a/drivers/bus/Makefile +++ b/drivers/bus/Makefile @@ -39,4 +39,4 @@ obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress-config.o obj-$(CONFIG_DA8XX_MSTPRI) += da8xx-mstpri.o # MHI -obj-$(CONFIG_MHI_BUS) += mhi/ +obj-y += mhi/ diff --git a/drivers/bus/mhi/Kconfig b/drivers/bus/mhi/Kconfig index da5cd0c9fc62..4748df7f9cd5 100644 --- a/drivers/bus/mhi/Kconfig +++ b/drivers/bus/mhi/Kconfig @@ -2,30 +2,7 @@ # # MHI bus # -# Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. +# Copyright (c) 2021, Linaro Ltd. # -config MHI_BUS - tristate "Modem Host Interface (MHI) bus" - help - Bus driver for MHI protocol. Modem Host Interface (MHI) is a - communication protocol used by the host processors to control - and communicate with modem devices over a high speed peripheral - bus or shared memory. - -config MHI_BUS_DEBUG - bool "Debugfs support for the MHI bus" - depends on MHI_BUS && DEBUG_FS - help - Enable debugfs support for use with the MHI transport. Allows - reading and/or modifying some values within the MHI controller - for debug and test purposes. - -config MHI_BUS_PCI_GENERIC - tristate "MHI PCI controller driver" - depends on MHI_BUS - depends on PCI - help - This driver provides MHI PCI controller driver for devices such as - Qualcomm SDX55 based PCIe modems. - +source "drivers/bus/mhi/host/Kconfig" diff --git a/drivers/bus/mhi/Makefile b/drivers/bus/mhi/Makefile index 0a2d778d6fb4..5f5708a249f5 100644 --- a/drivers/bus/mhi/Makefile +++ b/drivers/bus/mhi/Makefile @@ -1,6 +1,2 @@ -# core layer -obj-y += core/ - -obj-$(CONFIG_MHI_BUS_PCI_GENERIC) += mhi_pci_generic.o -mhi_pci_generic-y += pci_generic.o - +# Host MHI stack +obj-y += host/ diff --git a/drivers/bus/mhi/host/Kconfig b/drivers/bus/mhi/host/Kconfig new file mode 100644 index 000000000000..da5cd0c9fc62 --- /dev/null +++ b/drivers/bus/mhi/host/Kconfig @@ -0,0 +1,31 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# MHI bus +# +# Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. +# + +config MHI_BUS + tristate "Modem Host Interface (MHI) bus" + help + Bus driver for MHI protocol. Modem Host Interface (MHI) is a + communication protocol used by the host processors to control + and communicate with modem devices over a high speed peripheral + bus or shared memory. + +config MHI_BUS_DEBUG + bool "Debugfs support for the MHI bus" + depends on MHI_BUS && DEBUG_FS + help + Enable debugfs support for use with the MHI transport. Allows + reading and/or modifying some values within the MHI controller + for debug and test purposes. + +config MHI_BUS_PCI_GENERIC + tristate "MHI PCI controller driver" + depends on MHI_BUS + depends on PCI + help + This driver provides MHI PCI controller driver for devices such as + Qualcomm SDX55 based PCIe modems. + diff --git a/drivers/bus/mhi/core/Makefile b/drivers/bus/mhi/host/Makefile similarity index 54% rename from drivers/bus/mhi/core/Makefile rename to drivers/bus/mhi/host/Makefile index c3feb4130aa3..859c2f38451c 100644 --- a/drivers/bus/mhi/core/Makefile +++ b/drivers/bus/mhi/host/Makefile @@ -1,4 +1,6 @@ obj-$(CONFIG_MHI_BUS) += mhi.o - mhi-y := init.o main.o pm.o boot.o mhi-$(CONFIG_MHI_BUS_DEBUG) += debugfs.o + +obj-$(CONFIG_MHI_BUS_PCI_GENERIC) += mhi_pci_generic.o +mhi_pci_generic-y += pci_generic.o diff --git a/drivers/bus/mhi/core/boot.c b/drivers/bus/mhi/host/boot.c similarity index 100% rename from drivers/bus/mhi/core/boot.c rename to drivers/bus/mhi/host/boot.c diff --git a/drivers/bus/mhi/core/debugfs.c b/drivers/bus/mhi/host/debugfs.c similarity index 100% rename from drivers/bus/mhi/core/debugfs.c rename to drivers/bus/mhi/host/debugfs.c diff --git a/drivers/bus/mhi/core/init.c b/drivers/bus/mhi/host/init.c similarity index 100% rename from drivers/bus/mhi/core/init.c rename to drivers/bus/mhi/host/init.c diff --git a/drivers/bus/mhi/core/internal.h b/drivers/bus/mhi/host/internal.h similarity index 100% rename from drivers/bus/mhi/core/internal.h rename to drivers/bus/mhi/host/internal.h diff --git a/drivers/bus/mhi/core/main.c b/drivers/bus/mhi/host/main.c similarity index 100% rename from drivers/bus/mhi/core/main.c rename to drivers/bus/mhi/host/main.c diff --git a/drivers/bus/mhi/pci_generic.c b/drivers/bus/mhi/host/pci_generic.c similarity index 100% rename from drivers/bus/mhi/pci_generic.c rename to drivers/bus/mhi/host/pci_generic.c diff --git a/drivers/bus/mhi/core/pm.c b/drivers/bus/mhi/host/pm.c similarity index 100% rename from drivers/bus/mhi/core/pm.c rename to drivers/bus/mhi/host/pm.c From patchwork Sat Feb 12 18:20:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 542594 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7B3C5C433F5 for ; Sat, 12 Feb 2022 18:22:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229606AbiBLSWN (ORCPT ); Sat, 12 Feb 2022 13:22:13 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:45418 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229679AbiBLSWL (ORCPT ); Sat, 12 Feb 2022 13:22:11 -0500 Received: from mail-pj1-x1035.google.com (mail-pj1-x1035.google.com [IPv6:2607:f8b0:4864:20::1035]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 112535F8E0 for ; Sat, 12 Feb 2022 10:22:04 -0800 (PST) Received: by mail-pj1-x1035.google.com with SMTP id t14-20020a17090a3e4e00b001b8f6032d96so11844540pjm.2 for ; Sat, 12 Feb 2022 10:22:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=cGQSDhdU/VUiCgxjKsrYQ6T6ZSVoqze1ynzNfFCo8J0=; b=DhI2MpZWJZ+jYk4sYly+K1Z7scW6UhRSbiiQA6OLedXS39MXnmD2qR34f+4idOkLXB ICtMvSFyHldPxieF58RaZcHb0SYBOCr4miNocMTCcfo6nJPe8b83h+VxefRY4hppb7BT dGZdF7dC/HavmID9BlFLz9cFwwkogp1mIJYjINGZSmMeVHm82KvfZPZNHNq0a1T40Co/ Gv2x8yXEwCJiI3a2OkUUsTQO5syBHPNG44MMor/g2IjHeGaOYXMNXqbPbvZsJwb24W2x mZJ0allZN6wJWieFNsWAqE42x0eNYOD2fvLtN0o/mSci8A8/jYft2Pi2V6+YHk6BNEWg C/aw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=cGQSDhdU/VUiCgxjKsrYQ6T6ZSVoqze1ynzNfFCo8J0=; b=ffv5cETgH2LGlX50F6cUdNbZ8V6P4Wpm1p0DOdLirPWqXYtQJG0vywG6uRTQxIZlwy EcP48jtsHFmqAnMkSEJgDUM2iaKh5cSWxr3eM7g5cEnkHlUGydkndc0ekTqtyOEnn+88 csrHXYCtlxQ9aF42dyH42TtDq8UbVruiZ2UZnVfdG8ZVU7cgPA8dlAO4njtxim2S+6mB k5tVgRL4pd4nGh5fpXTl//B+EDQ8zpRu9YAFgLh6/nEyvwPnfZfdoTJaFj3WBXz2to5E hOiZ+NFo+ogaMndXrzc0UUpB6ligl5m7GNjvviAePDt79xtngUU9lSC/7wKQ+KcuxcxN Gagg== X-Gm-Message-State: AOAM531mENPl/F4MK4IqRzQ3ZnisA1WYG/uulCk0+RAG+R5w0gzml2kp Tz0Gx8+AIt2HKHYmemGAbH8B X-Google-Smtp-Source: ABdhPJwIEv6hA2vrcGaMyWVmw2UstQpntZzIAZo3+61M/ex11zRhbm9q5caSjDOHjoDW1i9Ry8l6tg== X-Received: by 2002:a17:90b:4a06:: with SMTP id kk6mr6347563pjb.236.1644690123444; Sat, 12 Feb 2022 10:22:03 -0800 (PST) Received: from localhost.localdomain ([27.111.75.57]) by smtp.gmail.com with ESMTPSA id g12sm14961987pfj.148.2022.02.12.10.21.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Feb 2022 10:22:03 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v3 04/25] bus: mhi: Move common MHI definitions out of host directory Date: Sat, 12 Feb 2022 23:50:56 +0530 Message-Id: <20220212182117.49438-5-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> References: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Move the common MHI definitions in host "internal.h" to "common.h" so that the endpoint code can make use of them. This also avoids duplicating the definitions in the endpoint stack. Still, the MHI register definitions are not moved since the offsets vary between host and endpoint. Signed-off-by: Manivannan Sadhasivam Reviewed-by: Alex Elder --- drivers/bus/mhi/common.h | 167 ++++++++++++++++++++++++++++++++ drivers/bus/mhi/host/internal.h | 155 +---------------------------- 2 files changed, 168 insertions(+), 154 deletions(-) create mode 100644 drivers/bus/mhi/common.h diff --git a/drivers/bus/mhi/common.h b/drivers/bus/mhi/common.h new file mode 100644 index 000000000000..0d13a202d334 --- /dev/null +++ b/drivers/bus/mhi/common.h @@ -0,0 +1,167 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2021, Linaro Ltd. + * + */ + +#ifndef _MHI_COMMON_H +#define _MHI_COMMON_H + +#include + +/* Command Ring Element macros */ +/* No operation command */ +#define MHI_TRE_CMD_NOOP_PTR (0) +#define MHI_TRE_CMD_NOOP_DWORD0 (0) +#define MHI_TRE_CMD_NOOP_DWORD1 (cpu_to_le32(MHI_CMD_NOP << 16)) + +/* Channel reset command */ +#define MHI_TRE_CMD_RESET_PTR (0) +#define MHI_TRE_CMD_RESET_DWORD0 (0) +#define MHI_TRE_CMD_RESET_DWORD1(chid) (cpu_to_le32((chid << 24) | \ + (MHI_CMD_RESET_CHAN << 16))) + +/* Channel stop command */ +#define MHI_TRE_CMD_STOP_PTR (0) +#define MHI_TRE_CMD_STOP_DWORD0 (0) +#define MHI_TRE_CMD_STOP_DWORD1(chid) (cpu_to_le32((chid << 24) | \ + (MHI_CMD_STOP_CHAN << 16))) + +/* Channel start command */ +#define MHI_TRE_CMD_START_PTR (0) +#define MHI_TRE_CMD_START_DWORD0 (0) +#define MHI_TRE_CMD_START_DWORD1(chid) (cpu_to_le32((chid << 24) | \ + (MHI_CMD_START_CHAN << 16))) + +#define MHI_TRE_GET_DWORD(tre, word) (le32_to_cpu((tre)->dword[(word)])) +#define MHI_TRE_GET_CMD_CHID(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 24) & 0xFF) +#define MHI_TRE_GET_CMD_TYPE(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 16) & 0xFF) + +/* Event descriptor macros */ +#define MHI_TRE_EV_PTR(ptr) (cpu_to_le64(ptr)) +#define MHI_TRE_EV_DWORD0(code, len) (cpu_to_le32((code << 24) | len)) +#define MHI_TRE_EV_DWORD1(chid, type) (cpu_to_le32((chid << 24) | (type << 16))) +#define MHI_TRE_GET_EV_PTR(tre) (le64_to_cpu((tre)->ptr)) +#define MHI_TRE_GET_EV_CODE(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 24) & 0xFF) +#define MHI_TRE_GET_EV_LEN(tre) (MHI_TRE_GET_DWORD(tre, 0) & 0xFFFF) +#define MHI_TRE_GET_EV_CHID(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 24) & 0xFF) +#define MHI_TRE_GET_EV_TYPE(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 16) & 0xFF) +#define MHI_TRE_GET_EV_STATE(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 24) & 0xFF) +#define MHI_TRE_GET_EV_EXECENV(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 24) & 0xFF) +#define MHI_TRE_GET_EV_SEQ(tre) MHI_TRE_GET_DWORD(tre, 0) +#define MHI_TRE_GET_EV_TIME(tre) (MHI_TRE_GET_EV_PTR(tre)) +#define MHI_TRE_GET_EV_COOKIE(tre) lower_32_bits(MHI_TRE_GET_EV_PTR(tre)) +#define MHI_TRE_GET_EV_VEID(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 16) & 0xFF) +#define MHI_TRE_GET_EV_LINKSPEED(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 24) & 0xFF) +#define MHI_TRE_GET_EV_LINKWIDTH(tre) (MHI_TRE_GET_DWORD(tre, 0) & 0xFF) + +/* Transfer descriptor macros */ +#define MHI_TRE_DATA_PTR(ptr) (cpu_to_le64(ptr)) +#define MHI_TRE_DATA_DWORD0(len) (cpu_to_le32(len & MHI_MAX_MTU)) +#define MHI_TRE_DATA_DWORD1(bei, ieot, ieob, chain) (cpu_to_le32((2 << 16) | (bei << 10) \ + | (ieot << 9) | (ieob << 8) | chain)) + +/* RSC transfer descriptor macros */ +#define MHI_RSCTRE_DATA_PTR(ptr, len) (cpu_to_le64(((u64)len << 48) | ptr)) +#define MHI_RSCTRE_DATA_DWORD0(cookie) (cpu_to_le32(cookie)) +#define MHI_RSCTRE_DATA_DWORD1 (cpu_to_le32(MHI_PKT_TYPE_COALESCING << 16)) + +enum mhi_pkt_type { + MHI_PKT_TYPE_INVALID = 0x0, + MHI_PKT_TYPE_NOOP_CMD = 0x1, + MHI_PKT_TYPE_TRANSFER = 0x2, + MHI_PKT_TYPE_COALESCING = 0x8, + MHI_PKT_TYPE_RESET_CHAN_CMD = 0x10, + MHI_PKT_TYPE_STOP_CHAN_CMD = 0x11, + MHI_PKT_TYPE_START_CHAN_CMD = 0x12, + MHI_PKT_TYPE_STATE_CHANGE_EVENT = 0x20, + MHI_PKT_TYPE_CMD_COMPLETION_EVENT = 0x21, + MHI_PKT_TYPE_TX_EVENT = 0x22, + MHI_PKT_TYPE_RSC_TX_EVENT = 0x28, + MHI_PKT_TYPE_EE_EVENT = 0x40, + MHI_PKT_TYPE_TSYNC_EVENT = 0x48, + MHI_PKT_TYPE_BW_REQ_EVENT = 0x50, + MHI_PKT_TYPE_STALE_EVENT, /* internal event */ +}; + +/* MHI transfer completion events */ +enum mhi_ev_ccs { + MHI_EV_CC_INVALID = 0x0, + MHI_EV_CC_SUCCESS = 0x1, + MHI_EV_CC_EOT = 0x2, /* End of transfer event */ + MHI_EV_CC_OVERFLOW = 0x3, + MHI_EV_CC_EOB = 0x4, /* End of block event */ + MHI_EV_CC_OOB = 0x5, /* Out of block event */ + MHI_EV_CC_DB_MODE = 0x6, + MHI_EV_CC_UNDEFINED_ERR = 0x10, + MHI_EV_CC_BAD_TRE = 0x11, +}; + +/* Channel state */ +enum mhi_ch_state { + MHI_CH_STATE_DISABLED, + MHI_CH_STATE_ENABLED, + MHI_CH_STATE_RUNNING, + MHI_CH_STATE_SUSPENDED, + MHI_CH_STATE_STOP, + MHI_CH_STATE_ERROR, +}; + +enum mhi_cmd_type { + MHI_CMD_NOP = 1, + MHI_CMD_RESET_CHAN = 16, + MHI_CMD_STOP_CHAN = 17, + MHI_CMD_START_CHAN = 18, +}; + +#define EV_CTX_RESERVED_MASK GENMASK(7, 0) +#define EV_CTX_INTMODC_MASK GENMASK(15, 8) +#define EV_CTX_INTMODC_SHIFT 8 +#define EV_CTX_INTMODT_MASK GENMASK(31, 16) +#define EV_CTX_INTMODT_SHIFT 16 +struct mhi_event_ctxt { + __le32 intmod; + __le32 ertype; + __le32 msivec; + + __le64 rbase __packed __aligned(4); + __le64 rlen __packed __aligned(4); + __le64 rp __packed __aligned(4); + __le64 wp __packed __aligned(4); +}; + +#define CHAN_CTX_CHSTATE_MASK GENMASK(7, 0) +#define CHAN_CTX_CHSTATE_SHIFT 0 +#define CHAN_CTX_BRSTMODE_MASK GENMASK(9, 8) +#define CHAN_CTX_BRSTMODE_SHIFT 8 +#define CHAN_CTX_POLLCFG_MASK GENMASK(15, 10) +#define CHAN_CTX_POLLCFG_SHIFT 10 +#define CHAN_CTX_RESERVED_MASK GENMASK(31, 16) +struct mhi_chan_ctxt { + __le32 chcfg; + __le32 chtype; + __le32 erindex; + + __le64 rbase __packed __aligned(4); + __le64 rlen __packed __aligned(4); + __le64 rp __packed __aligned(4); + __le64 wp __packed __aligned(4); +}; + +struct mhi_cmd_ctxt { + __le32 reserved0; + __le32 reserved1; + __le32 reserved2; + + __le64 rbase __packed __aligned(4); + __le64 rlen __packed __aligned(4); + __le64 rp __packed __aligned(4); + __le64 wp __packed __aligned(4); +}; + +extern const char * const mhi_state_str[MHI_STATE_MAX]; +#define TO_MHI_STATE_STR(state) ((state >= MHI_STATE_MAX || \ + !mhi_state_str[state]) ? \ + "INVALID_STATE" : mhi_state_str[state]) + +#endif /* _MHI_COMMON_H */ diff --git a/drivers/bus/mhi/host/internal.h b/drivers/bus/mhi/host/internal.h index fa64340a8997..622de6ba1a0b 100644 --- a/drivers/bus/mhi/host/internal.h +++ b/drivers/bus/mhi/host/internal.h @@ -7,7 +7,7 @@ #ifndef _MHI_INT_H #define _MHI_INT_H -#include +#include "../common.h" extern struct bus_type mhi_bus_type; @@ -203,51 +203,6 @@ extern struct bus_type mhi_bus_type; #define SOC_HW_VERSION_MINOR_VER_BMSK (0x000000FF) #define SOC_HW_VERSION_MINOR_VER_SHFT (0) -#define EV_CTX_RESERVED_MASK GENMASK(7, 0) -#define EV_CTX_INTMODC_MASK GENMASK(15, 8) -#define EV_CTX_INTMODC_SHIFT 8 -#define EV_CTX_INTMODT_MASK GENMASK(31, 16) -#define EV_CTX_INTMODT_SHIFT 16 -struct mhi_event_ctxt { - __le32 intmod; - __le32 ertype; - __le32 msivec; - - __le64 rbase __packed __aligned(4); - __le64 rlen __packed __aligned(4); - __le64 rp __packed __aligned(4); - __le64 wp __packed __aligned(4); -}; - -#define CHAN_CTX_CHSTATE_MASK GENMASK(7, 0) -#define CHAN_CTX_CHSTATE_SHIFT 0 -#define CHAN_CTX_BRSTMODE_MASK GENMASK(9, 8) -#define CHAN_CTX_BRSTMODE_SHIFT 8 -#define CHAN_CTX_POLLCFG_MASK GENMASK(15, 10) -#define CHAN_CTX_POLLCFG_SHIFT 10 -#define CHAN_CTX_RESERVED_MASK GENMASK(31, 16) -struct mhi_chan_ctxt { - __le32 chcfg; - __le32 chtype; - __le32 erindex; - - __le64 rbase __packed __aligned(4); - __le64 rlen __packed __aligned(4); - __le64 rp __packed __aligned(4); - __le64 wp __packed __aligned(4); -}; - -struct mhi_cmd_ctxt { - __le32 reserved0; - __le32 reserved1; - __le32 reserved2; - - __le64 rbase __packed __aligned(4); - __le64 rlen __packed __aligned(4); - __le64 rp __packed __aligned(4); - __le64 wp __packed __aligned(4); -}; - struct mhi_ctxt { struct mhi_event_ctxt *er_ctxt; struct mhi_chan_ctxt *chan_ctxt; @@ -267,109 +222,6 @@ struct bhi_vec_entry { u64 size; }; -enum mhi_cmd_type { - MHI_CMD_NOP = 1, - MHI_CMD_RESET_CHAN = 16, - MHI_CMD_STOP_CHAN = 17, - MHI_CMD_START_CHAN = 18, -}; - -/* No operation command */ -#define MHI_TRE_CMD_NOOP_PTR (0) -#define MHI_TRE_CMD_NOOP_DWORD0 (0) -#define MHI_TRE_CMD_NOOP_DWORD1 (cpu_to_le32(MHI_CMD_NOP << 16)) - -/* Channel reset command */ -#define MHI_TRE_CMD_RESET_PTR (0) -#define MHI_TRE_CMD_RESET_DWORD0 (0) -#define MHI_TRE_CMD_RESET_DWORD1(chid) (cpu_to_le32((chid << 24) | \ - (MHI_CMD_RESET_CHAN << 16))) - -/* Channel stop command */ -#define MHI_TRE_CMD_STOP_PTR (0) -#define MHI_TRE_CMD_STOP_DWORD0 (0) -#define MHI_TRE_CMD_STOP_DWORD1(chid) (cpu_to_le32((chid << 24) | \ - (MHI_CMD_STOP_CHAN << 16))) - -/* Channel start command */ -#define MHI_TRE_CMD_START_PTR (0) -#define MHI_TRE_CMD_START_DWORD0 (0) -#define MHI_TRE_CMD_START_DWORD1(chid) (cpu_to_le32((chid << 24) | \ - (MHI_CMD_START_CHAN << 16))) - -#define MHI_TRE_GET_DWORD(tre, word) (le32_to_cpu((tre)->dword[(word)])) -#define MHI_TRE_GET_CMD_CHID(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 24) & 0xFF) -#define MHI_TRE_GET_CMD_TYPE(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 16) & 0xFF) - -/* Event descriptor macros */ -#define MHI_TRE_EV_PTR(ptr) (cpu_to_le64(ptr)) -#define MHI_TRE_EV_DWORD0(code, len) (cpu_to_le32((code << 24) | len)) -#define MHI_TRE_EV_DWORD1(chid, type) (cpu_to_le32((chid << 24) | (type << 16))) -#define MHI_TRE_GET_EV_PTR(tre) (le64_to_cpu((tre)->ptr)) -#define MHI_TRE_GET_EV_CODE(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 24) & 0xFF) -#define MHI_TRE_GET_EV_LEN(tre) (MHI_TRE_GET_DWORD(tre, 0) & 0xFFFF) -#define MHI_TRE_GET_EV_CHID(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 24) & 0xFF) -#define MHI_TRE_GET_EV_TYPE(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 16) & 0xFF) -#define MHI_TRE_GET_EV_STATE(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 24) & 0xFF) -#define MHI_TRE_GET_EV_EXECENV(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 24) & 0xFF) -#define MHI_TRE_GET_EV_SEQ(tre) MHI_TRE_GET_DWORD(tre, 0) -#define MHI_TRE_GET_EV_TIME(tre) (MHI_TRE_GET_EV_PTR(tre)) -#define MHI_TRE_GET_EV_COOKIE(tre) lower_32_bits(MHI_TRE_GET_EV_PTR(tre)) -#define MHI_TRE_GET_EV_VEID(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 16) & 0xFF) -#define MHI_TRE_GET_EV_LINKSPEED(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 24) & 0xFF) -#define MHI_TRE_GET_EV_LINKWIDTH(tre) (MHI_TRE_GET_DWORD(tre, 0) & 0xFF) - -/* Transfer descriptor macros */ -#define MHI_TRE_DATA_PTR(ptr) (cpu_to_le64(ptr)) -#define MHI_TRE_DATA_DWORD0(len) (cpu_to_le32(len & MHI_MAX_MTU)) -#define MHI_TRE_DATA_DWORD1(bei, ieot, ieob, chain) (cpu_to_le32((2 << 16) | (bei << 10) \ - | (ieot << 9) | (ieob << 8) | chain)) - -/* RSC transfer descriptor macros */ -#define MHI_RSCTRE_DATA_PTR(ptr, len) (cpu_to_le64(((u64)len << 48) | ptr)) -#define MHI_RSCTRE_DATA_DWORD0(cookie) (cpu_to_le32(cookie)) -#define MHI_RSCTRE_DATA_DWORD1 (cpu_to_le32(MHI_PKT_TYPE_COALESCING << 16)) - -enum mhi_pkt_type { - MHI_PKT_TYPE_INVALID = 0x0, - MHI_PKT_TYPE_NOOP_CMD = 0x1, - MHI_PKT_TYPE_TRANSFER = 0x2, - MHI_PKT_TYPE_COALESCING = 0x8, - MHI_PKT_TYPE_RESET_CHAN_CMD = 0x10, - MHI_PKT_TYPE_STOP_CHAN_CMD = 0x11, - MHI_PKT_TYPE_START_CHAN_CMD = 0x12, - MHI_PKT_TYPE_STATE_CHANGE_EVENT = 0x20, - MHI_PKT_TYPE_CMD_COMPLETION_EVENT = 0x21, - MHI_PKT_TYPE_TX_EVENT = 0x22, - MHI_PKT_TYPE_RSC_TX_EVENT = 0x28, - MHI_PKT_TYPE_EE_EVENT = 0x40, - MHI_PKT_TYPE_TSYNC_EVENT = 0x48, - MHI_PKT_TYPE_BW_REQ_EVENT = 0x50, - MHI_PKT_TYPE_STALE_EVENT, /* internal event */ -}; - -/* MHI transfer completion events */ -enum mhi_ev_ccs { - MHI_EV_CC_INVALID = 0x0, - MHI_EV_CC_SUCCESS = 0x1, - MHI_EV_CC_EOT = 0x2, /* End of transfer event */ - MHI_EV_CC_OVERFLOW = 0x3, - MHI_EV_CC_EOB = 0x4, /* End of block event */ - MHI_EV_CC_OOB = 0x5, /* Out of block event */ - MHI_EV_CC_DB_MODE = 0x6, - MHI_EV_CC_UNDEFINED_ERR = 0x10, - MHI_EV_CC_BAD_TRE = 0x11, -}; - -enum mhi_ch_state { - MHI_CH_STATE_DISABLED = 0x0, - MHI_CH_STATE_ENABLED = 0x1, - MHI_CH_STATE_RUNNING = 0x2, - MHI_CH_STATE_SUSPENDED = 0x3, - MHI_CH_STATE_STOP = 0x4, - MHI_CH_STATE_ERROR = 0x5, -}; - enum mhi_ch_state_type { MHI_CH_STATE_TYPE_RESET, MHI_CH_STATE_TYPE_STOP, @@ -411,11 +263,6 @@ extern const char * const dev_state_tran_str[DEV_ST_TRANSITION_MAX]; #define TO_DEV_STATE_TRANS_STR(state) (((state) >= DEV_ST_TRANSITION_MAX) ? \ "INVALID_STATE" : dev_state_tran_str[state]) -extern const char * const mhi_state_str[MHI_STATE_MAX]; -#define TO_MHI_STATE_STR(state) ((state >= MHI_STATE_MAX || \ - !mhi_state_str[state]) ? \ - "INVALID_STATE" : mhi_state_str[state]) - /* internal power states */ enum mhi_pm_state { MHI_PM_STATE_DISABLE, From patchwork Sat Feb 12 18:20:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 542176 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 20F39C433F5 for ; Sat, 12 Feb 2022 18:22:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229674AbiBLSWP (ORCPT ); Sat, 12 Feb 2022 13:22:15 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:45370 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229640AbiBLSWO (ORCPT ); Sat, 12 Feb 2022 13:22:14 -0500 Received: from mail-pj1-x102d.google.com (mail-pj1-x102d.google.com [IPv6:2607:f8b0:4864:20::102d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B16275B8BE for ; Sat, 12 Feb 2022 10:22:08 -0800 (PST) Received: by mail-pj1-x102d.google.com with SMTP id n19-20020a17090ade9300b001b9892a7bf9so2593105pjv.5 for ; Sat, 12 Feb 2022 10:22:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=XL8iANerwUqfjAmRDN5JLJlwsSK7yuUEl1pJQa2iTKo=; b=RWtA+y58In7PePNDhkBypH49VACslI/2SNRrLINIgmrwmpPDIRZPEoGxwH184DWsRr cYUEgRmorxCM3Aoo2iwRG7H4lImpPSy0OJm1ckGH/0UM5fJu8gpl0VHTgymEoeakL18I MSpCYbPTOvxkUOqmgmW6q/I2BtG6zzbApdMNs4X1kftOiLb2kZa0Iw3Of44d4dNVyEh8 cTZVVtYkMKQpKlOE0KuT1X4m70CVrpDXPKkB/e+J2bYBZrXoJt3w51/3qs/hcpQND1nu GJWmPfe77cMZ0uxJNkSOdpSK0yFCq5I8ODoKohmmv+B2VSdrAR1mtUblKTL0jT6oCix1 uQNg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=XL8iANerwUqfjAmRDN5JLJlwsSK7yuUEl1pJQa2iTKo=; b=q1H7hKRYdTv44QHMgWI2ZbTtNzS7WKgj17kWx4uxfmqjESzYuWe54aYFS9roXLhlSh AMNztntQ6P7tDJK7FjOcMl28GXBrTtGSxefaAcSehOqg64QGd5uQ9Ewva2L4S9/8DP8z e6/if9rOgVjpzAorGc+DYgOLPepqeHVHmwK/cEcTNTUYFZ5KdXtXs7bM9McEG1STwrAl 1vZ+wx+hzwfdIVvdaOaIj8iyjGsLYFXoJ0dnZ7tTZukHdaKWHcmAePbI06dXvmT8kyPR /I9GaPWZ1mzgA/a3DXvHgWrCTDNTrTaqa/UvTrgJN18JybkuOAdX3oU1r9Gn5jWFZF8+ 1U0Q== X-Gm-Message-State: AOAM530eZzSBiWj50RgEndUDUUft/pOaILxSrXaafcvBgkBuV3TUb9CK uZ2LWol6JzcKi6WcthzlQrbn X-Google-Smtp-Source: ABdhPJyYtq0xGKVJ9EzMsMV1LKDwmNpTICImAtR+oPyS7yLSD8ULBU2h1+ykBXI9ouxi0GQR0ZV/Og== X-Received: by 2002:a17:90a:4811:: with SMTP id a17mr6238337pjh.159.1644690128180; Sat, 12 Feb 2022 10:22:08 -0800 (PST) Received: from localhost.localdomain ([27.111.75.57]) by smtp.gmail.com with ESMTPSA id g12sm14961987pfj.148.2022.02.12.10.22.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Feb 2022 10:22:07 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v3 05/25] bus: mhi: Make mhi_state_str[] array static inline and move to common.h Date: Sat, 12 Feb 2022 23:50:57 +0530 Message-Id: <20220212182117.49438-6-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> References: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org mhi_state_str[] array could be used by MHI endpoint stack also. So let's make the array as "static inline function" and move it inside the "common.h" header so that the endpoint stack could also make use of it. Signed-off-by: Manivannan Sadhasivam Reviewed-by: Hemant Kumar --- drivers/bus/mhi/common.h | 29 +++++++++++++++++++++++++---- drivers/bus/mhi/host/boot.c | 2 +- drivers/bus/mhi/host/debugfs.c | 6 +++--- drivers/bus/mhi/host/init.c | 12 ------------ drivers/bus/mhi/host/main.c | 8 ++++---- drivers/bus/mhi/host/pm.c | 14 +++++++------- 6 files changed, 40 insertions(+), 31 deletions(-) diff --git a/drivers/bus/mhi/common.h b/drivers/bus/mhi/common.h index 0d13a202d334..288e47168649 100644 --- a/drivers/bus/mhi/common.h +++ b/drivers/bus/mhi/common.h @@ -159,9 +159,30 @@ struct mhi_cmd_ctxt { __le64 wp __packed __aligned(4); }; -extern const char * const mhi_state_str[MHI_STATE_MAX]; -#define TO_MHI_STATE_STR(state) ((state >= MHI_STATE_MAX || \ - !mhi_state_str[state]) ? \ - "INVALID_STATE" : mhi_state_str[state]) +static inline const char * const mhi_state_str(enum mhi_state state) +{ + switch (state) { + case MHI_STATE_RESET: + return "RESET"; + case MHI_STATE_READY: + return "READY"; + case MHI_STATE_M0: + return "M0"; + case MHI_STATE_M1: + return "M1"; + case MHI_STATE_M2: + return"M2"; + case MHI_STATE_M3: + return"M3"; + case MHI_STATE_M3_FAST: + return"M3 FAST"; + case MHI_STATE_BHI: + return"BHI"; + case MHI_STATE_SYS_ERR: + return "SYS ERROR"; + default: + return "Unknown state"; + } +}; #endif /* _MHI_COMMON_H */ diff --git a/drivers/bus/mhi/host/boot.c b/drivers/bus/mhi/host/boot.c index 74295d3cc662..93cb705614c6 100644 --- a/drivers/bus/mhi/host/boot.c +++ b/drivers/bus/mhi/host/boot.c @@ -68,7 +68,7 @@ static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl) dev_dbg(dev, "Entered with pm_state:%s dev_state:%s ee:%s\n", to_mhi_pm_state_str(mhi_cntrl->pm_state), - TO_MHI_STATE_STR(mhi_cntrl->dev_state), + mhi_state_str(mhi_cntrl->dev_state), TO_MHI_EXEC_STR(mhi_cntrl->ee)); /* diff --git a/drivers/bus/mhi/host/debugfs.c b/drivers/bus/mhi/host/debugfs.c index d818586c229d..399d0db1f1eb 100644 --- a/drivers/bus/mhi/host/debugfs.c +++ b/drivers/bus/mhi/host/debugfs.c @@ -20,7 +20,7 @@ static int mhi_debugfs_states_show(struct seq_file *m, void *d) seq_printf(m, "PM state: %s Device: %s MHI state: %s EE: %s wake: %s\n", to_mhi_pm_state_str(mhi_cntrl->pm_state), mhi_is_active(mhi_cntrl) ? "Active" : "Inactive", - TO_MHI_STATE_STR(mhi_cntrl->dev_state), + mhi_state_str(mhi_cntrl->dev_state), TO_MHI_EXEC_STR(mhi_cntrl->ee), mhi_cntrl->wake_set ? "true" : "false"); @@ -206,13 +206,13 @@ static int mhi_debugfs_regdump_show(struct seq_file *m, void *d) seq_printf(m, "Host PM state: %s Device state: %s EE: %s\n", to_mhi_pm_state_str(mhi_cntrl->pm_state), - TO_MHI_STATE_STR(mhi_cntrl->dev_state), + mhi_state_str(mhi_cntrl->dev_state), TO_MHI_EXEC_STR(mhi_cntrl->ee)); state = mhi_get_mhi_state(mhi_cntrl); ee = mhi_get_exec_env(mhi_cntrl); seq_printf(m, "Device EE: %s state: %s\n", TO_MHI_EXEC_STR(ee), - TO_MHI_STATE_STR(state)); + mhi_state_str(state)); for (i = 0; regs[i].name; i++) { if (!regs[i].base) diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c index 4bd62f32695d..0e301f3f305e 100644 --- a/drivers/bus/mhi/host/init.c +++ b/drivers/bus/mhi/host/init.c @@ -44,18 +44,6 @@ const char * const dev_state_tran_str[DEV_ST_TRANSITION_MAX] = { [DEV_ST_TRANSITION_DISABLE] = "DISABLE", }; -const char * const mhi_state_str[MHI_STATE_MAX] = { - [MHI_STATE_RESET] = "RESET", - [MHI_STATE_READY] = "READY", - [MHI_STATE_M0] = "M0", - [MHI_STATE_M1] = "M1", - [MHI_STATE_M2] = "M2", - [MHI_STATE_M3] = "M3", - [MHI_STATE_M3_FAST] = "M3 FAST", - [MHI_STATE_BHI] = "BHI", - [MHI_STATE_SYS_ERR] = "SYS ERROR", -}; - const char * const mhi_ch_state_type_str[MHI_CH_STATE_TYPE_MAX] = { [MHI_CH_STATE_TYPE_RESET] = "RESET", [MHI_CH_STATE_TYPE_STOP] = "STOP", diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c index 85f4f7c8d7c6..e436c2993d97 100644 --- a/drivers/bus/mhi/host/main.c +++ b/drivers/bus/mhi/host/main.c @@ -479,8 +479,8 @@ irqreturn_t mhi_intvec_threaded_handler(int irq_number, void *priv) ee = mhi_get_exec_env(mhi_cntrl); dev_dbg(dev, "local ee: %s state: %s device ee: %s state: %s\n", TO_MHI_EXEC_STR(mhi_cntrl->ee), - TO_MHI_STATE_STR(mhi_cntrl->dev_state), - TO_MHI_EXEC_STR(ee), TO_MHI_STATE_STR(state)); + mhi_state_str(mhi_cntrl->dev_state), + TO_MHI_EXEC_STR(ee), mhi_state_str(state)); if (state == MHI_STATE_SYS_ERR) { dev_dbg(dev, "System error detected\n"); @@ -846,7 +846,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl, new_state = MHI_TRE_GET_EV_STATE(local_rp); dev_dbg(dev, "State change event to state: %s\n", - TO_MHI_STATE_STR(new_state)); + mhi_state_str(new_state)); switch (new_state) { case MHI_STATE_M0: @@ -873,7 +873,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl, } default: dev_err(dev, "Invalid state: %s\n", - TO_MHI_STATE_STR(new_state)); + mhi_state_str(new_state)); } break; diff --git a/drivers/bus/mhi/host/pm.c b/drivers/bus/mhi/host/pm.c index c35c5ddc7220..088ade0f3e0b 100644 --- a/drivers/bus/mhi/host/pm.c +++ b/drivers/bus/mhi/host/pm.c @@ -545,7 +545,7 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl) dev_dbg(dev, "Exiting with PM state: %s, MHI state: %s\n", to_mhi_pm_state_str(mhi_cntrl->pm_state), - TO_MHI_STATE_STR(mhi_cntrl->dev_state)); + mhi_state_str(mhi_cntrl->dev_state)); mutex_unlock(&mhi_cntrl->pm_mutex); } @@ -689,7 +689,7 @@ static void mhi_pm_sys_error_transition(struct mhi_controller *mhi_cntrl) exit_sys_error_transition: dev_dbg(dev, "Exiting with PM state: %s, MHI state: %s\n", to_mhi_pm_state_str(mhi_cntrl->pm_state), - TO_MHI_STATE_STR(mhi_cntrl->dev_state)); + mhi_state_str(mhi_cntrl->dev_state)); mutex_unlock(&mhi_cntrl->pm_mutex); } @@ -864,7 +864,7 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl) if (!ret || MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) { dev_err(dev, "Did not enter M3 state, MHI state: %s, PM state: %s\n", - TO_MHI_STATE_STR(mhi_cntrl->dev_state), + mhi_state_str(mhi_cntrl->dev_state), to_mhi_pm_state_str(mhi_cntrl->pm_state)); return -EIO; } @@ -890,7 +890,7 @@ static int __mhi_pm_resume(struct mhi_controller *mhi_cntrl, bool force) dev_dbg(dev, "Entered with PM state: %s, MHI state: %s\n", to_mhi_pm_state_str(mhi_cntrl->pm_state), - TO_MHI_STATE_STR(mhi_cntrl->dev_state)); + mhi_state_str(mhi_cntrl->dev_state)); if (mhi_cntrl->pm_state == MHI_PM_DISABLE) return 0; @@ -900,7 +900,7 @@ static int __mhi_pm_resume(struct mhi_controller *mhi_cntrl, bool force) if (mhi_get_mhi_state(mhi_cntrl) != MHI_STATE_M3) { dev_warn(dev, "Resuming from non M3 state (%s)\n", - TO_MHI_STATE_STR(mhi_get_mhi_state(mhi_cntrl))); + mhi_state_str(mhi_get_mhi_state(mhi_cntrl))); if (!force) return -EINVAL; } @@ -937,7 +937,7 @@ static int __mhi_pm_resume(struct mhi_controller *mhi_cntrl, bool force) if (!ret || MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) { dev_err(dev, "Did not enter M0 state, MHI state: %s, PM state: %s\n", - TO_MHI_STATE_STR(mhi_cntrl->dev_state), + mhi_state_str(mhi_cntrl->dev_state), to_mhi_pm_state_str(mhi_cntrl->pm_state)); return -EIO; } @@ -1088,7 +1088,7 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl) state = mhi_get_mhi_state(mhi_cntrl); dev_dbg(dev, "Attempting power on with EE: %s, state: %s\n", - TO_MHI_EXEC_STR(current_ee), TO_MHI_STATE_STR(state)); + TO_MHI_EXEC_STR(current_ee), mhi_state_str(state)); if (state == MHI_STATE_SYS_ERR) { mhi_set_mhi_state(mhi_cntrl, MHI_STATE_RESET); From patchwork Sat Feb 12 18:20:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 542593 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4684EC433F5 for ; Sat, 12 Feb 2022 18:22:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229691AbiBLSWX (ORCPT ); Sat, 12 Feb 2022 13:22:23 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:45740 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229699AbiBLSWW (ORCPT ); Sat, 12 Feb 2022 13:22:22 -0500 Received: from mail-pf1-x433.google.com (mail-pf1-x433.google.com [IPv6:2607:f8b0:4864:20::433]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 770AB5E152 for ; Sat, 12 Feb 2022 10:22:13 -0800 (PST) Received: by mail-pf1-x433.google.com with SMTP id t36so11133338pfg.0 for ; Sat, 12 Feb 2022 10:22:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Iocb06fX71DKsU3dVtYliiT3cGRX62sk9BgzsTqJWWs=; b=fSM//MrasLR3DrFHwbEAsUx45I2gf/rNL+gHf24I1eNR7JEkNYwzBqsmmyGu3zS6Go so54SwDvT69NILPbYnZYTTp90eCLKLTEgU0FZMgBxZ/OwC/uNWBncFJurwXeIWoNJwAZ 1uyj1Efj6LWOVdQvqSNrw3bBD+pcao+8gpOr2S9PYXKilJSIEIPo83wU34I2GEj/s3Yc cLEl+gQdBVPA23SFhCVqe79OpZE44Ca71WIcQN5YWSLKIJAa/TFn9ktYgxwkQdq3kAGS 1DJHABt5l+bTS040f276VsGGPuRtkxUOKHh1vu5VoNr75Nc6t6DUCbuSHoYyaOf/EPc4 ZoQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Iocb06fX71DKsU3dVtYliiT3cGRX62sk9BgzsTqJWWs=; b=39OC5ZYhhukiWuPx1opjnqVpAIruYgRk0ZNBdFhgt4uNQ49/tN4mQfqqK9ClDfnUMW OV4tucdHSTPOJJg6h8p6vtHL46Sy2JpZa5osjy9YRFcII4rZ5hf7AfINaN6LgJ3bplyp kk5KdPqiUgzX2MU80WJZhlr3yL0jzuFH1B54IWBqTV+Vf80giILb+zzT7D8rGupjWHNM U0jVel1Nm3c5EAHw8x0nr4CFMrvxFEX6jHWlZqk7iY3paZjuL9rWzF6af+y6wI+Fsga6 14K9Ogl7svGSuHvr1w7mDjcV5MVYk8FuVoOSmpS5cOd53FKU78598lzITDN5oiF3Hi2f 6PGw== X-Gm-Message-State: AOAM531FATq/Rwp0plNSO7Mx8jNjZE1bgrvBDK6AJIZIZH3nXw141ODI 3QRDjdNmxvPqOHY5Fd3EigP5 X-Google-Smtp-Source: ABdhPJyUGeTDKQpcfZViTsZZfq+s4Mf9Cw0X10A6Wzfu98tCCxQCpK1AJCU32xBpFetVQ1+s5hjItw== X-Received: by 2002:a63:600c:: with SMTP id u12mr5780674pgb.34.1644690132855; Sat, 12 Feb 2022 10:22:12 -0800 (PST) Received: from localhost.localdomain ([27.111.75.57]) by smtp.gmail.com with ESMTPSA id g12sm14961987pfj.148.2022.02.12.10.22.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Feb 2022 10:22:12 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v3 06/25] bus: mhi: Cleanup the register definitions used in headers Date: Sat, 12 Feb 2022 23:50:58 +0530 Message-Id: <20220212182117.49438-7-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> References: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Cleanup includes: 1. Moving the MHI register definitions to common.h header with REG_ prefix and using them in the host/internal.h file as an alias. This makes it possible to reuse the register definitions in EP stack that differs by a fixed offset. 2. Using the GENMASK macro for masks 3. Removing brackets for single values 4. Using lowercase for hex values 5. Using two digits for hex values where applicable Signed-off-by: Manivannan Sadhasivam Reviewed-by: Alex Elder --- drivers/bus/mhi/common.h | 243 ++++++++++++++++++++++++----- drivers/bus/mhi/host/internal.h | 265 +++++++++----------------------- 2 files changed, 278 insertions(+), 230 deletions(-) diff --git a/drivers/bus/mhi/common.h b/drivers/bus/mhi/common.h index 288e47168649..f226f06d4ff9 100644 --- a/drivers/bus/mhi/common.h +++ b/drivers/bus/mhi/common.h @@ -9,62 +9,223 @@ #include +/* MHI registers */ +#define REG_MHIREGLEN 0x00 +#define REG_MHIVER 0x08 +#define REG_MHICFG 0x10 +#define REG_CHDBOFF 0x18 +#define REG_ERDBOFF 0x20 +#define REG_BHIOFF 0x28 +#define REG_BHIEOFF 0x2c +#define REG_DEBUGOFF 0x30 +#define REG_MHICTRL 0x38 +#define REG_MHISTATUS 0x48 +#define REG_CCABAP_LOWER 0x58 +#define REG_CCABAP_HIGHER 0x5c +#define REG_ECABAP_LOWER 0x60 +#define REG_ECABAP_HIGHER 0x64 +#define REG_CRCBAP_LOWER 0x68 +#define REG_CRCBAP_HIGHER 0x6c +#define REG_CRDB_LOWER 0x70 +#define REG_CRDB_HIGHER 0x74 +#define REG_MHICTRLBASE_LOWER 0x80 +#define REG_MHICTRLBASE_HIGHER 0x84 +#define REG_MHICTRLLIMIT_LOWER 0x88 +#define REG_MHICTRLLIMIT_HIGHER 0x8c +#define REG_MHIDATABASE_LOWER 0x98 +#define REG_MHIDATABASE_HIGHER 0x9c +#define REG_MHIDATALIMIT_LOWER 0xa0 +#define REG_MHIDATALIMIT_HIGHER 0xa4 + +/* MHI BHI registers */ +#define REG_BHI_BHIVERSION_MINOR 0x00 +#define REG_BHI_BHIVERSION_MAJOR 0x04 +#define REG_BHI_IMGADDR_LOW 0x08 +#define REG_BHI_IMGADDR_HIGH 0x0c +#define REG_BHI_IMGSIZE 0x10 +#define REG_BHI_RSVD1 0x14 +#define REG_BHI_IMGTXDB 0x18 +#define REG_BHI_RSVD2 0x1c +#define REG_BHI_INTVEC 0x20 +#define REG_BHI_RSVD3 0x24 +#define REG_BHI_EXECENV 0x28 +#define REG_BHI_STATUS 0x2c +#define REG_BHI_ERRCODE 0x30 +#define REG_BHI_ERRDBG1 0x34 +#define REG_BHI_ERRDBG2 0x38 +#define REG_BHI_ERRDBG3 0x3c +#define REG_BHI_SERIALNU 0x40 +#define REG_BHI_SBLANTIROLLVER 0x44 +#define REG_BHI_NUMSEG 0x48 +#define REG_BHI_MSMHWID(n) (0x4c + (0x4 * (n))) +#define REG_BHI_OEMPKHASH(n) (0x64 + (0x4 * (n))) +#define REG_BHI_RSVD5 0xc4 + +/* BHI register bits */ +#define BHI_TXDB_SEQNUM_BMSK GENMASK(29, 0) +#define BHI_TXDB_SEQNUM_SHFT 0 +#define BHI_STATUS_MASK GENMASK(31, 30) +#define BHI_STATUS_SHIFT 30 +#define BHI_STATUS_ERROR 0x03 +#define BHI_STATUS_SUCCESS 0x02 +#define BHI_STATUS_RESET 0x00 + +/* MHI BHIE registers */ +#define REG_BHIE_MSMSOCID_OFFS 0x00 +#define REG_BHIE_TXVECADDR_LOW_OFFS 0x2c +#define REG_BHIE_TXVECADDR_HIGH_OFFS 0x30 +#define REG_BHIE_TXVECSIZE_OFFS 0x34 +#define REG_BHIE_TXVECDB_OFFS 0x3c +#define REG_BHIE_TXVECSTATUS_OFFS 0x44 +#define REG_BHIE_RXVECADDR_LOW_OFFS 0x60 +#define REG_BHIE_RXVECADDR_HIGH_OFFS 0x64 +#define REG_BHIE_RXVECSIZE_OFFS 0x68 +#define REG_BHIE_RXVECDB_OFFS 0x70 +#define REG_BHIE_RXVECSTATUS_OFFS 0x78 + +/* BHIE register bits */ +#define BHIE_TXVECDB_SEQNUM_BMSK GENMASK(29, 0) +#define BHIE_TXVECDB_SEQNUM_SHFT 0 +#define BHIE_TXVECSTATUS_SEQNUM_BMSK GENMASK(29, 0) +#define BHIE_TXVECSTATUS_SEQNUM_SHFT 0 +#define BHIE_TXVECSTATUS_STATUS_BMSK GENMASK(31, 30) +#define BHIE_TXVECSTATUS_STATUS_SHFT 30 +#define BHIE_TXVECSTATUS_STATUS_RESET 0x00 +#define BHIE_TXVECSTATUS_STATUS_XFER_COMPL 0x02 +#define BHIE_TXVECSTATUS_STATUS_ERROR 0x03 +#define BHIE_RXVECDB_SEQNUM_BMSK GENMASK(29, 0) +#define BHIE_RXVECDB_SEQNUM_SHFT 0 +#define BHIE_RXVECSTATUS_SEQNUM_BMSK GENMASK(29, 0) +#define BHIE_RXVECSTATUS_SEQNUM_SHFT 0 +#define BHIE_RXVECSTATUS_STATUS_BMSK GENMASK(31, 30) +#define BHIE_RXVECSTATUS_STATUS_SHFT 30 +#define BHIE_RXVECSTATUS_STATUS_RESET 0x00 +#define BHIE_RXVECSTATUS_STATUS_XFER_COMPL 0x02 +#define BHIE_RXVECSTATUS_STATUS_ERROR 0x03 + +/* MHI register bits */ +#define MHIREGLEN_MHIREGLEN_MASK GENMASK(31, 0) +#define MHIREGLEN_MHIREGLEN_SHIFT 0 +#define MHIVER_MHIVER_MASK GENMASK(31, 0) +#define MHIVER_MHIVER_SHIFT 0 +#define MHICFG_NHWER_MASK GENMASK(31, 24) +#define MHICFG_NHWER_SHIFT 24 +#define MHICFG_NER_MASK GENMASK(23, 16) +#define MHICFG_NER_SHIFT 16 +#define MHICFG_NHWCH_MASK GENMASK(15, 8) +#define MHICFG_NHWCH_SHIFT 8 +#define MHICFG_NCH_MASK GENMASK(7, 0) +#define MHICFG_NCH_SHIFT 0 +#define CHDBOFF_CHDBOFF_MASK GENMASK(31, 0) +#define CHDBOFF_CHDBOFF_SHIFT 0 +#define ERDBOFF_ERDBOFF_MASK GENMASK(31, 0) +#define ERDBOFF_ERDBOFF_SHIFT 0 +#define BHIOFF_BHIOFF_MASK GENMASK(31, 0) +#define BHIOFF_BHIOFF_SHIFT 0 +#define BHIEOFF_BHIEOFF_MASK GENMASK(31, 0) +#define BHIEOFF_BHIEOFF_SHIFT 0 +#define DEBUGOFF_DEBUGOFF_MASK GENMASK(31, 0) +#define DEBUGOFF_DEBUGOFF_SHIFT 0 +#define MHICTRL_MHISTATE_MASK GENMASK(15, 8) +#define MHICTRL_MHISTATE_SHIFT 8 +#define MHICTRL_RESET_MASK BIT(1) +#define MHICTRL_RESET_SHIFT 1 +#define MHISTATUS_MHISTATE_MASK GENMASK(15, 8) +#define MHISTATUS_MHISTATE_SHIFT 8 +#define MHISTATUS_SYSERR_MASK BIT(2) +#define MHISTATUS_SYSERR_SHIFT 2 +#define MHISTATUS_READY_MASK BIT(0) +#define MHISTATUS_READY_SHIFT 0 +#define CCABAP_LOWER_CCABAP_LOWER_MASK GENMASK(31, 0) +#define CCABAP_LOWER_CCABAP_LOWER_SHIFT 0 +#define CCABAP_HIGHER_CCABAP_HIGHER_MASK GENMASK(31, 0) +#define CCABAP_HIGHER_CCABAP_HIGHER_SHIFT 0 +#define ECABAP_LOWER_ECABAP_LOWER_MASK GENMASK(31, 0) +#define ECABAP_LOWER_ECABAP_LOWER_SHIFT 0 +#define ECABAP_HIGHER_ECABAP_HIGHER_MASK GENMASK(31, 0) +#define ECABAP_HIGHER_ECABAP_HIGHER_SHIFT 0 +#define CRCBAP_LOWER_CRCBAP_LOWER_MASK GENMASK(31, 0) +#define CRCBAP_LOWER_CRCBAP_LOWER_SHIFT 0 +#define CRCBAP_HIGHER_CRCBAP_HIGHER_MASK GENMASK(31, 0) +#define CRCBAP_HIGHER_CRCBAP_HIGHER_SHIFT 0 +#define CRDB_LOWER_CRDB_LOWER_MASK GENMASK(31, 0) +#define CRDB_LOWER_CRDB_LOWER_SHIFT 0 +#define CRDB_HIGHER_CRDB_HIGHER_MASK GENMASK(31, 0) +#define CRDB_HIGHER_CRDB_HIGHER_SHIFT 0 +#define MHICTRLBASE_LOWER_MHICTRLBASE_LOWER_MASK GENMASK(31, 0) +#define MHICTRLBASE_LOWER_MHICTRLBASE_LOWER_SHIFT 0 +#define MHICTRLBASE_HIGHER_MHICTRLBASE_HIGHER_MASK GENMASK(31, 0) +#define MHICTRLBASE_HIGHER_MHICTRLBASE_HIGHER_SHIFT 0 +#define MHICTRLLIMIT_LOWER_MHICTRLLIMIT_LOWER_MASK GENMASK(31, 0) +#define MHICTRLLIMIT_LOWER_MHICTRLLIMIT_LOWER_SHIFT 0 +#define MHICTRLLIMIT_HIGHER_MHICTRLLIMIT_HIGHER_MASK GENMASK(31, 0) +#define MHICTRLLIMIT_HIGHER_MHICTRLLIMIT_HIGHER_SHIFT 0 +#define MHIDATABASE_LOWER_MHIDATABASE_LOWER_MASK GENMASK(31, 0) +#define MHIDATABASE_LOWER_MHIDATABASE_LOWER_SHIFT 0 +#define MHIDATABASE_HIGHER_MHIDATABASE_HIGHER_MASK GENMASK(31, 0) +#define MHIDATABASE_HIGHER_MHIDATABASE_HIGHER_SHIFT 0 +#define MHIDATALIMIT_LOWER_MHIDATALIMIT_LOWER_MASK GENMASK(31, 0) +#define MHIDATALIMIT_LOWER_MHIDATALIMIT_LOWER_SHIFT 0 +#define MHIDATALIMIT_HIGHER_MHIDATALIMIT_HIGHER_MASK GENMASK(31, 0) +#define MHIDATALIMIT_HIGHER_MHIDATALIMIT_HIGHER_SHIFT 0 + /* Command Ring Element macros */ /* No operation command */ -#define MHI_TRE_CMD_NOOP_PTR (0) -#define MHI_TRE_CMD_NOOP_DWORD0 (0) -#define MHI_TRE_CMD_NOOP_DWORD1 (cpu_to_le32(MHI_CMD_NOP << 16)) +#define MHI_TRE_CMD_NOOP_PTR 0 +#define MHI_TRE_CMD_NOOP_DWORD0 0 +#define MHI_TRE_CMD_NOOP_DWORD1 cpu_to_le32(MHI_CMD_NOP << 16) /* Channel reset command */ -#define MHI_TRE_CMD_RESET_PTR (0) -#define MHI_TRE_CMD_RESET_DWORD0 (0) -#define MHI_TRE_CMD_RESET_DWORD1(chid) (cpu_to_le32((chid << 24) | \ - (MHI_CMD_RESET_CHAN << 16))) +#define MHI_TRE_CMD_RESET_PTR 0 +#define MHI_TRE_CMD_RESET_DWORD0 0 +#define MHI_TRE_CMD_RESET_DWORD1(chid) (cpu_to_le32((chid << 24) | \ + (MHI_CMD_RESET_CHAN << 16))) /* Channel stop command */ -#define MHI_TRE_CMD_STOP_PTR (0) -#define MHI_TRE_CMD_STOP_DWORD0 (0) -#define MHI_TRE_CMD_STOP_DWORD1(chid) (cpu_to_le32((chid << 24) | \ - (MHI_CMD_STOP_CHAN << 16))) +#define MHI_TRE_CMD_STOP_PTR 0 +#define MHI_TRE_CMD_STOP_DWORD0 0 +#define MHI_TRE_CMD_STOP_DWORD1(chid) (cpu_to_le32((chid << 24) | \ + (MHI_CMD_STOP_CHAN << 16))) /* Channel start command */ -#define MHI_TRE_CMD_START_PTR (0) -#define MHI_TRE_CMD_START_DWORD0 (0) -#define MHI_TRE_CMD_START_DWORD1(chid) (cpu_to_le32((chid << 24) | \ - (MHI_CMD_START_CHAN << 16))) +#define MHI_TRE_CMD_START_PTR 0 +#define MHI_TRE_CMD_START_DWORD0 0 +#define MHI_TRE_CMD_START_DWORD1(chid) (cpu_to_le32((chid << 24) | \ + (MHI_CMD_START_CHAN << 16))) -#define MHI_TRE_GET_DWORD(tre, word) (le32_to_cpu((tre)->dword[(word)])) -#define MHI_TRE_GET_CMD_CHID(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 24) & 0xFF) -#define MHI_TRE_GET_CMD_TYPE(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 16) & 0xFF) +#define MHI_TRE_GET_DWORD(tre, word) le32_to_cpu((tre)->dword[(word)]) +#define MHI_TRE_GET_CMD_CHID(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 24) & 0xFF) +#define MHI_TRE_GET_CMD_TYPE(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 16) & 0xFF) /* Event descriptor macros */ -#define MHI_TRE_EV_PTR(ptr) (cpu_to_le64(ptr)) -#define MHI_TRE_EV_DWORD0(code, len) (cpu_to_le32((code << 24) | len)) -#define MHI_TRE_EV_DWORD1(chid, type) (cpu_to_le32((chid << 24) | (type << 16))) -#define MHI_TRE_GET_EV_PTR(tre) (le64_to_cpu((tre)->ptr)) -#define MHI_TRE_GET_EV_CODE(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 24) & 0xFF) -#define MHI_TRE_GET_EV_LEN(tre) (MHI_TRE_GET_DWORD(tre, 0) & 0xFFFF) -#define MHI_TRE_GET_EV_CHID(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 24) & 0xFF) -#define MHI_TRE_GET_EV_TYPE(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 16) & 0xFF) -#define MHI_TRE_GET_EV_STATE(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 24) & 0xFF) -#define MHI_TRE_GET_EV_EXECENV(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 24) & 0xFF) -#define MHI_TRE_GET_EV_SEQ(tre) MHI_TRE_GET_DWORD(tre, 0) -#define MHI_TRE_GET_EV_TIME(tre) (MHI_TRE_GET_EV_PTR(tre)) -#define MHI_TRE_GET_EV_COOKIE(tre) lower_32_bits(MHI_TRE_GET_EV_PTR(tre)) -#define MHI_TRE_GET_EV_VEID(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 16) & 0xFF) -#define MHI_TRE_GET_EV_LINKSPEED(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 24) & 0xFF) -#define MHI_TRE_GET_EV_LINKWIDTH(tre) (MHI_TRE_GET_DWORD(tre, 0) & 0xFF) +/* Transfer completion event */ +#define MHI_TRE_EV_PTR(ptr) cpu_to_le64(ptr) +#define MHI_TRE_EV_DWORD0(code, len) cpu_to_le32((code << 24) | len) +#define MHI_TRE_EV_DWORD1(chid, type) cpu_to_le32((chid << 24) | (type << 16)) +#define MHI_TRE_GET_EV_PTR(tre) le64_to_cpu((tre)->ptr) +#define MHI_TRE_GET_EV_CODE(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 24) & 0xFF) +#define MHI_TRE_GET_EV_LEN(tre) (MHI_TRE_GET_DWORD(tre, 0) & 0xFFFF) +#define MHI_TRE_GET_EV_CHID(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 24) & 0xFF) +#define MHI_TRE_GET_EV_TYPE(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 16) & 0xFF) +#define MHI_TRE_GET_EV_STATE(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 24) & 0xFF) +#define MHI_TRE_GET_EV_EXECENV(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 24) & 0xFF) +#define MHI_TRE_GET_EV_SEQ(tre) MHI_TRE_GET_DWORD(tre, 0) +#define MHI_TRE_GET_EV_TIME(tre) MHI_TRE_GET_EV_PTR(tre) +#define MHI_TRE_GET_EV_COOKIE(tre) lower_32_bits(MHI_TRE_GET_EV_PTR(tre)) +#define MHI_TRE_GET_EV_VEID(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 16) & 0xFF) +#define MHI_TRE_GET_EV_LINKSPEED(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 24) & 0xFF) +#define MHI_TRE_GET_EV_LINKWIDTH(tre) (MHI_TRE_GET_DWORD(tre, 0) & 0xFF) /* Transfer descriptor macros */ -#define MHI_TRE_DATA_PTR(ptr) (cpu_to_le64(ptr)) -#define MHI_TRE_DATA_DWORD0(len) (cpu_to_le32(len & MHI_MAX_MTU)) -#define MHI_TRE_DATA_DWORD1(bei, ieot, ieob, chain) (cpu_to_le32((2 << 16) | (bei << 10) \ - | (ieot << 9) | (ieob << 8) | chain)) +#define MHI_TRE_DATA_PTR(ptr) cpu_to_le64(ptr) +#define MHI_TRE_DATA_DWORD0(len) cpu_to_le32(len & MHI_MAX_MTU) +#define MHI_TRE_DATA_DWORD1(bei, ieot, ieob, chain) (cpu_to_le32((2 << 16) | (bei << 10) \ + | (ieot << 9) | (ieob << 8) | chain)) /* RSC transfer descriptor macros */ -#define MHI_RSCTRE_DATA_PTR(ptr, len) (cpu_to_le64(((u64)len << 48) | ptr)) -#define MHI_RSCTRE_DATA_DWORD0(cookie) (cpu_to_le32(cookie)) -#define MHI_RSCTRE_DATA_DWORD1 (cpu_to_le32(MHI_PKT_TYPE_COALESCING << 16)) +#define MHI_RSCTRE_DATA_PTR(ptr, len) cpu_to_le64(((u64)len << 48) | ptr) +#define MHI_RSCTRE_DATA_DWORD0(cookie) cpu_to_le32(cookie) +#define MHI_RSCTRE_DATA_DWORD1 cpu_to_le32(MHI_PKT_TYPE_COALESCING << 16) enum mhi_pkt_type { MHI_PKT_TYPE_INVALID = 0x0, diff --git a/drivers/bus/mhi/host/internal.h b/drivers/bus/mhi/host/internal.h index 622de6ba1a0b..762055a6ec9f 100644 --- a/drivers/bus/mhi/host/internal.h +++ b/drivers/bus/mhi/host/internal.h @@ -11,197 +11,84 @@ extern struct bus_type mhi_bus_type; -#define MHIREGLEN (0x0) -#define MHIREGLEN_MHIREGLEN_MASK (0xFFFFFFFF) -#define MHIREGLEN_MHIREGLEN_SHIFT (0) - -#define MHIVER (0x8) -#define MHIVER_MHIVER_MASK (0xFFFFFFFF) -#define MHIVER_MHIVER_SHIFT (0) - -#define MHICFG (0x10) -#define MHICFG_NHWER_MASK (0xFF000000) -#define MHICFG_NHWER_SHIFT (24) -#define MHICFG_NER_MASK (0xFF0000) -#define MHICFG_NER_SHIFT (16) -#define MHICFG_NHWCH_MASK (0xFF00) -#define MHICFG_NHWCH_SHIFT (8) -#define MHICFG_NCH_MASK (0xFF) -#define MHICFG_NCH_SHIFT (0) - -#define CHDBOFF (0x18) -#define CHDBOFF_CHDBOFF_MASK (0xFFFFFFFF) -#define CHDBOFF_CHDBOFF_SHIFT (0) - -#define ERDBOFF (0x20) -#define ERDBOFF_ERDBOFF_MASK (0xFFFFFFFF) -#define ERDBOFF_ERDBOFF_SHIFT (0) - -#define BHIOFF (0x28) -#define BHIOFF_BHIOFF_MASK (0xFFFFFFFF) -#define BHIOFF_BHIOFF_SHIFT (0) - -#define BHIEOFF (0x2C) -#define BHIEOFF_BHIEOFF_MASK (0xFFFFFFFF) -#define BHIEOFF_BHIEOFF_SHIFT (0) - -#define DEBUGOFF (0x30) -#define DEBUGOFF_DEBUGOFF_MASK (0xFFFFFFFF) -#define DEBUGOFF_DEBUGOFF_SHIFT (0) - -#define MHICTRL (0x38) -#define MHICTRL_MHISTATE_MASK (0x0000FF00) -#define MHICTRL_MHISTATE_SHIFT (8) -#define MHICTRL_RESET_MASK (0x2) -#define MHICTRL_RESET_SHIFT (1) - -#define MHISTATUS (0x48) -#define MHISTATUS_MHISTATE_MASK (0x0000FF00) -#define MHISTATUS_MHISTATE_SHIFT (8) -#define MHISTATUS_SYSERR_MASK (0x4) -#define MHISTATUS_SYSERR_SHIFT (2) -#define MHISTATUS_READY_MASK (0x1) -#define MHISTATUS_READY_SHIFT (0) - -#define CCABAP_LOWER (0x58) -#define CCABAP_LOWER_CCABAP_LOWER_MASK (0xFFFFFFFF) -#define CCABAP_LOWER_CCABAP_LOWER_SHIFT (0) - -#define CCABAP_HIGHER (0x5C) -#define CCABAP_HIGHER_CCABAP_HIGHER_MASK (0xFFFFFFFF) -#define CCABAP_HIGHER_CCABAP_HIGHER_SHIFT (0) - -#define ECABAP_LOWER (0x60) -#define ECABAP_LOWER_ECABAP_LOWER_MASK (0xFFFFFFFF) -#define ECABAP_LOWER_ECABAP_LOWER_SHIFT (0) - -#define ECABAP_HIGHER (0x64) -#define ECABAP_HIGHER_ECABAP_HIGHER_MASK (0xFFFFFFFF) -#define ECABAP_HIGHER_ECABAP_HIGHER_SHIFT (0) - -#define CRCBAP_LOWER (0x68) -#define CRCBAP_LOWER_CRCBAP_LOWER_MASK (0xFFFFFFFF) -#define CRCBAP_LOWER_CRCBAP_LOWER_SHIFT (0) - -#define CRCBAP_HIGHER (0x6C) -#define CRCBAP_HIGHER_CRCBAP_HIGHER_MASK (0xFFFFFFFF) -#define CRCBAP_HIGHER_CRCBAP_HIGHER_SHIFT (0) - -#define CRDB_LOWER (0x70) -#define CRDB_LOWER_CRDB_LOWER_MASK (0xFFFFFFFF) -#define CRDB_LOWER_CRDB_LOWER_SHIFT (0) - -#define CRDB_HIGHER (0x74) -#define CRDB_HIGHER_CRDB_HIGHER_MASK (0xFFFFFFFF) -#define CRDB_HIGHER_CRDB_HIGHER_SHIFT (0) - -#define MHICTRLBASE_LOWER (0x80) -#define MHICTRLBASE_LOWER_MHICTRLBASE_LOWER_MASK (0xFFFFFFFF) -#define MHICTRLBASE_LOWER_MHICTRLBASE_LOWER_SHIFT (0) - -#define MHICTRLBASE_HIGHER (0x84) -#define MHICTRLBASE_HIGHER_MHICTRLBASE_HIGHER_MASK (0xFFFFFFFF) -#define MHICTRLBASE_HIGHER_MHICTRLBASE_HIGHER_SHIFT (0) - -#define MHICTRLLIMIT_LOWER (0x88) -#define MHICTRLLIMIT_LOWER_MHICTRLLIMIT_LOWER_MASK (0xFFFFFFFF) -#define MHICTRLLIMIT_LOWER_MHICTRLLIMIT_LOWER_SHIFT (0) - -#define MHICTRLLIMIT_HIGHER (0x8C) -#define MHICTRLLIMIT_HIGHER_MHICTRLLIMIT_HIGHER_MASK (0xFFFFFFFF) -#define MHICTRLLIMIT_HIGHER_MHICTRLLIMIT_HIGHER_SHIFT (0) - -#define MHIDATABASE_LOWER (0x98) -#define MHIDATABASE_LOWER_MHIDATABASE_LOWER_MASK (0xFFFFFFFF) -#define MHIDATABASE_LOWER_MHIDATABASE_LOWER_SHIFT (0) - -#define MHIDATABASE_HIGHER (0x9C) -#define MHIDATABASE_HIGHER_MHIDATABASE_HIGHER_MASK (0xFFFFFFFF) -#define MHIDATABASE_HIGHER_MHIDATABASE_HIGHER_SHIFT (0) - -#define MHIDATALIMIT_LOWER (0xA0) -#define MHIDATALIMIT_LOWER_MHIDATALIMIT_LOWER_MASK (0xFFFFFFFF) -#define MHIDATALIMIT_LOWER_MHIDATALIMIT_LOWER_SHIFT (0) - -#define MHIDATALIMIT_HIGHER (0xA4) -#define MHIDATALIMIT_HIGHER_MHIDATALIMIT_HIGHER_MASK (0xFFFFFFFF) -#define MHIDATALIMIT_HIGHER_MHIDATALIMIT_HIGHER_SHIFT (0) +/* MHI registers */ +#define MHIREGLEN REG_MHIREGLEN +#define MHIVER REG_MHIVER +#define MHICFG REG_MHICFG +#define CHDBOFF REG_CHDBOFF +#define ERDBOFF REG_ERDBOFF +#define BHIOFF REG_BHIOFF +#define BHIEOFF REG_BHIEOFF +#define DEBUGOFF REG_DEBUGOFF +#define MHICTRL REG_MHICTRL +#define MHISTATUS REG_MHISTATUS +#define CCABAP_LOWER REG_CCABAP_LOWER +#define CCABAP_HIGHER REG_CCABAP_HIGHER +#define ECABAP_LOWER REG_ECABAP_LOWER +#define ECABAP_HIGHER REG_ECABAP_HIGHER +#define CRCBAP_LOWER REG_CRCBAP_LOWER +#define CRCBAP_HIGHER REG_CRCBAP_HIGHER +#define CRDB_LOWER REG_CRDB_LOWER +#define CRDB_HIGHER REG_CRDB_HIGHER +#define MHICTRLBASE_LOWER REG_MHICTRLBASE_LOWER +#define MHICTRLBASE_HIGHER REG_MHICTRLBASE_HIGHER +#define MHICTRLLIMIT_LOWER REG_MHICTRLLIMIT_LOWER +#define MHICTRLLIMIT_HIGHER REG_MHICTRLLIMIT_HIGHER +#define MHIDATABASE_LOWER REG_MHIDATABASE_LOWER +#define MHIDATABASE_HIGHER REG_MHIDATABASE_HIGHER +#define MHIDATALIMIT_LOWER REG_MHIDATALIMIT_LOWER +#define MHIDATALIMIT_HIGHER REG_MHIDATALIMIT_HIGHER /* Host request register */ -#define MHI_SOC_RESET_REQ_OFFSET (0xB0) -#define MHI_SOC_RESET_REQ BIT(0) - -/* MHI BHI offfsets */ -#define BHI_BHIVERSION_MINOR (0x00) -#define BHI_BHIVERSION_MAJOR (0x04) -#define BHI_IMGADDR_LOW (0x08) -#define BHI_IMGADDR_HIGH (0x0C) -#define BHI_IMGSIZE (0x10) -#define BHI_RSVD1 (0x14) -#define BHI_IMGTXDB (0x18) -#define BHI_TXDB_SEQNUM_BMSK (0x3FFFFFFF) -#define BHI_TXDB_SEQNUM_SHFT (0) -#define BHI_RSVD2 (0x1C) -#define BHI_INTVEC (0x20) -#define BHI_RSVD3 (0x24) -#define BHI_EXECENV (0x28) -#define BHI_STATUS (0x2C) -#define BHI_ERRCODE (0x30) -#define BHI_ERRDBG1 (0x34) -#define BHI_ERRDBG2 (0x38) -#define BHI_ERRDBG3 (0x3C) -#define BHI_SERIALNU (0x40) -#define BHI_SBLANTIROLLVER (0x44) -#define BHI_NUMSEG (0x48) -#define BHI_MSMHWID(n) (0x4C + (0x4 * (n))) -#define BHI_OEMPKHASH(n) (0x64 + (0x4 * (n))) -#define BHI_RSVD5 (0xC4) -#define BHI_STATUS_MASK (0xC0000000) -#define BHI_STATUS_SHIFT (30) -#define BHI_STATUS_ERROR (3) -#define BHI_STATUS_SUCCESS (2) -#define BHI_STATUS_RESET (0) - -/* MHI BHIE offsets */ -#define BHIE_MSMSOCID_OFFS (0x0000) -#define BHIE_TXVECADDR_LOW_OFFS (0x002C) -#define BHIE_TXVECADDR_HIGH_OFFS (0x0030) -#define BHIE_TXVECSIZE_OFFS (0x0034) -#define BHIE_TXVECDB_OFFS (0x003C) -#define BHIE_TXVECDB_SEQNUM_BMSK (0x3FFFFFFF) -#define BHIE_TXVECDB_SEQNUM_SHFT (0) -#define BHIE_TXVECSTATUS_OFFS (0x0044) -#define BHIE_TXVECSTATUS_SEQNUM_BMSK (0x3FFFFFFF) -#define BHIE_TXVECSTATUS_SEQNUM_SHFT (0) -#define BHIE_TXVECSTATUS_STATUS_BMSK (0xC0000000) -#define BHIE_TXVECSTATUS_STATUS_SHFT (30) -#define BHIE_TXVECSTATUS_STATUS_RESET (0x00) -#define BHIE_TXVECSTATUS_STATUS_XFER_COMPL (0x02) -#define BHIE_TXVECSTATUS_STATUS_ERROR (0x03) -#define BHIE_RXVECADDR_LOW_OFFS (0x0060) -#define BHIE_RXVECADDR_HIGH_OFFS (0x0064) -#define BHIE_RXVECSIZE_OFFS (0x0068) -#define BHIE_RXVECDB_OFFS (0x0070) -#define BHIE_RXVECDB_SEQNUM_BMSK (0x3FFFFFFF) -#define BHIE_RXVECDB_SEQNUM_SHFT (0) -#define BHIE_RXVECSTATUS_OFFS (0x0078) -#define BHIE_RXVECSTATUS_SEQNUM_BMSK (0x3FFFFFFF) -#define BHIE_RXVECSTATUS_SEQNUM_SHFT (0) -#define BHIE_RXVECSTATUS_STATUS_BMSK (0xC0000000) -#define BHIE_RXVECSTATUS_STATUS_SHFT (30) -#define BHIE_RXVECSTATUS_STATUS_RESET (0x00) -#define BHIE_RXVECSTATUS_STATUS_XFER_COMPL (0x02) -#define BHIE_RXVECSTATUS_STATUS_ERROR (0x03) - -#define SOC_HW_VERSION_OFFS (0x224) -#define SOC_HW_VERSION_FAM_NUM_BMSK (0xF0000000) -#define SOC_HW_VERSION_FAM_NUM_SHFT (28) -#define SOC_HW_VERSION_DEV_NUM_BMSK (0x0FFF0000) -#define SOC_HW_VERSION_DEV_NUM_SHFT (16) -#define SOC_HW_VERSION_MAJOR_VER_BMSK (0x0000FF00) -#define SOC_HW_VERSION_MAJOR_VER_SHFT (8) -#define SOC_HW_VERSION_MINOR_VER_BMSK (0x000000FF) -#define SOC_HW_VERSION_MINOR_VER_SHFT (0) +#define MHI_SOC_RESET_REQ_OFFSET 0xb0 +#define MHI_SOC_RESET_REQ BIT(0) + +/* MHI BHI registers */ +#define BHI_BHIVERSION_MINOR REG_BHI_BHIVERSION_MINOR +#define BHI_BHIVERSION_MAJOR REG_BHI_BHIVERSION_MAJOR +#define BHI_IMGADDR_LOW REG_BHI_IMGADDR_LOW +#define BHI_IMGADDR_HIGH REG_BHI_IMGADDR_HIGH +#define BHI_IMGSIZE REG_BHI_IMGSIZE +#define BHI_RSVD1 REG_BHI_RSVD1 +#define BHI_IMGTXDB REG_BHI_IMGTXDB +#define BHI_RSVD2 REG_BHI_RSVD2 +#define BHI_INTVEC REG_BHI_INTVEC +#define BHI_RSVD3 REG_BHI_RSVD3 +#define BHI_EXECENV REG_BHI_EXECENV +#define BHI_STATUS REG_BHI_STATUS +#define BHI_ERRCODE REG_BHI_ERRCODE +#define BHI_ERRDBG1 REG_BHI_ERRDBG1 +#define BHI_ERRDBG2 REG_BHI_ERRDBG2 +#define BHI_ERRDBG3 REG_BHI_ERRDBG3 +#define BHI_SERIALNU REG_BHI_SERIALNU +#define BHI_SBLANTIROLLVER REG_BHI_SBLANTIROLLVER +#define BHI_NUMSEG REG_BHI_NUMSEG +#define BHI_MSMHWID(n) REG_BHI_MSMHWID(n) +#define BHI_OEMPKHASH(n) REG_BHI_OEMPKHASH(n) +#define BHI_RSVD5 REG_BHI_RSVD5 + +/* MHI BHIE registers */ +#define BHIE_MSMSOCID_OFFS REG_BHIE_MSMSOCID_OFFS +#define BHIE_TXVECADDR_LOW_OFFS REG_BHIE_TXVECADDR_LOW_OFFS +#define BHIE_TXVECADDR_HIGH_OFFS REG_BHIE_TXVECADDR_HIGH_OFFS +#define BHIE_TXVECSIZE_OFFS REG_BHIE_TXVECSIZE_OFFS +#define BHIE_TXVECDB_OFFS REG_BHIE_TXVECDB_OFFS +#define BHIE_TXVECSTATUS_OFFS REG_BHIE_TXVECSTATUS_OFFS +#define BHIE_RXVECADDR_LOW_OFFS REG_BHIE_RXVECADDR_LOW_OFFS +#define BHIE_RXVECADDR_HIGH_OFFS REG_BHIE_RXVECADDR_HIGH_OFFS +#define BHIE_RXVECSIZE_OFFS REG_BHIE_RXVECSIZE_OFFS +#define BHIE_RXVECDB_OFFS REG_BHIE_RXVECDB_OFFS +#define BHIE_RXVECSTATUS_OFFS REG_BHIE_RXVECSTATUS_OFFS + +#define SOC_HW_VERSION_OFFS 0x224 +#define SOC_HW_VERSION_FAM_NUM_BMSK GENMASK(31, 28) +#define SOC_HW_VERSION_FAM_NUM_SHFT 28 +#define SOC_HW_VERSION_DEV_NUM_BMSK GENMASK(27, 16) +#define SOC_HW_VERSION_DEV_NUM_SHFT 16 +#define SOC_HW_VERSION_MAJOR_VER_BMSK GENMASK(15, 8) +#define SOC_HW_VERSION_MAJOR_VER_SHFT 8 +#define SOC_HW_VERSION_MINOR_VER_BMSK GENMASK(7, 0) +#define SOC_HW_VERSION_MINOR_VER_SHFT 0 struct mhi_ctxt { struct mhi_event_ctxt *er_ctxt; From patchwork Sat Feb 12 18:20:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 542175 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CE156C433EF for ; Sat, 12 Feb 2022 18:22:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229698AbiBLSW0 (ORCPT ); Sat, 12 Feb 2022 13:22:26 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:45782 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229741AbiBLSWX (ORCPT ); Sat, 12 Feb 2022 13:22:23 -0500 Received: from mail-pj1-x102d.google.com (mail-pj1-x102d.google.com [IPv6:2607:f8b0:4864:20::102d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 13C785FF32 for ; Sat, 12 Feb 2022 10:22:18 -0800 (PST) Received: by mail-pj1-x102d.google.com with SMTP id t14-20020a17090a3e4e00b001b8f6032d96so11844845pjm.2 for ; Sat, 12 Feb 2022 10:22:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=8Zi9SnCciv4Kn+M41rOQILSsrsT8jJ4XY3WeSAHk2yc=; b=DgYThDX74915Rh8/337NOwZPR4FpMJrx5Yle734cli4nygjOEcJ02NfwP2nrkqLFYS xq+aDagJ8MHuXEPPK7jHewUAzQhjZKZCyqNg7CAGyJ8NjTiPS2aecvzWNlkK9YEFaGdL SDF6ptuOWLoHeRVIFllFkkt2sX/32FPaOnsU4WZzL4qyo2tR6lrKR5ySUSW8XBvkMSRw R0WY0BLbclR+5Ks5OFKCyCqiqY7O1M/DD8OABVIkoQU8pjvcBPlNACZhhU/VO9pko8VR +XtAsEV883U/u3oVgvFFQugLgJSNXDgSWnHBpzrYlTVLv0TRUvNFwrrLn3hcwG3WoqMO vpUg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=8Zi9SnCciv4Kn+M41rOQILSsrsT8jJ4XY3WeSAHk2yc=; b=gcsQoU0/K2bZmfpuGs1aXkaf7M/q/df5Zbj6OhyWhQhyzcjD2Rvxo27fYH23wQmivs ECWULQKWJK2TlstXxE9t7aca1Wi1LlCzOMIaWaAZZTXW3VQ7ttjKCQT+E5naKcV5JiZS wu/0XXybZFeTOuqp6zhbee8xpo70frvJ6mKgDapNC+KN3hi7n3IGq6V9WAM8y1fN6wnR 4DUVQ7vV1q8Sbzre6jOt+0IHZ9ZfYeelEVogPoJ2+HBLHPXsArBB6t9+pTHSobF87ofg ZZsHdqrK/1N9j97nSLNIEKo3svuILtJuCqkTGSuxRSMNULikp757o7R2bFwrjtJkAaO6 MPBA== X-Gm-Message-State: AOAM532+w9hP2myaxVKegjNZYftELVh+Vghey82xawyFjDUGlnMFNGqv VgCNdUNaaMcPsp6CZ8o0KIcs X-Google-Smtp-Source: ABdhPJyJIcmhFQbiffPjDmNATBkX334sLcOJuufDPzAnAmMfD65TFSOkgIRb8oHbSpbbHjBqaSfN9Q== X-Received: by 2002:a17:902:d48b:: with SMTP id c11mr2904731plg.109.1644690137420; Sat, 12 Feb 2022 10:22:17 -0800 (PST) Received: from localhost.localdomain ([27.111.75.57]) by smtp.gmail.com with ESMTPSA id g12sm14961987pfj.148.2022.02.12.10.22.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Feb 2022 10:22:17 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v3 07/25] bus: mhi: Get rid of SHIFT macros and use bitfield operations Date: Sat, 12 Feb 2022 23:50:59 +0530 Message-Id: <20220212182117.49438-8-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> References: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Instead of using the hardcoded SHIFT values, use the bitfield macros to derive the shift value from mask during build time. For shift values that cannot be determined during build time, "__ffs()" helper is used find the shift value in runtime. Suggested-by: Alex Elder Signed-off-by: Manivannan Sadhasivam Reviewed-by: Alex Elder --- drivers/bus/mhi/common.h | 45 ---------------------- drivers/bus/mhi/host/boot.c | 15 ++------ drivers/bus/mhi/host/debugfs.c | 10 ++--- drivers/bus/mhi/host/init.c | 67 +++++++++++++++------------------ drivers/bus/mhi/host/internal.h | 10 ++--- drivers/bus/mhi/host/main.c | 16 ++++---- drivers/bus/mhi/host/pm.c | 18 +++------ 7 files changed, 55 insertions(+), 126 deletions(-) diff --git a/drivers/bus/mhi/common.h b/drivers/bus/mhi/common.h index f226f06d4ff9..728c82928d8d 100644 --- a/drivers/bus/mhi/common.h +++ b/drivers/bus/mhi/common.h @@ -63,9 +63,7 @@ /* BHI register bits */ #define BHI_TXDB_SEQNUM_BMSK GENMASK(29, 0) -#define BHI_TXDB_SEQNUM_SHFT 0 #define BHI_STATUS_MASK GENMASK(31, 30) -#define BHI_STATUS_SHIFT 30 #define BHI_STATUS_ERROR 0x03 #define BHI_STATUS_SUCCESS 0x02 #define BHI_STATUS_RESET 0x00 @@ -85,89 +83,51 @@ /* BHIE register bits */ #define BHIE_TXVECDB_SEQNUM_BMSK GENMASK(29, 0) -#define BHIE_TXVECDB_SEQNUM_SHFT 0 #define BHIE_TXVECSTATUS_SEQNUM_BMSK GENMASK(29, 0) -#define BHIE_TXVECSTATUS_SEQNUM_SHFT 0 #define BHIE_TXVECSTATUS_STATUS_BMSK GENMASK(31, 30) -#define BHIE_TXVECSTATUS_STATUS_SHFT 30 #define BHIE_TXVECSTATUS_STATUS_RESET 0x00 #define BHIE_TXVECSTATUS_STATUS_XFER_COMPL 0x02 #define BHIE_TXVECSTATUS_STATUS_ERROR 0x03 #define BHIE_RXVECDB_SEQNUM_BMSK GENMASK(29, 0) -#define BHIE_RXVECDB_SEQNUM_SHFT 0 #define BHIE_RXVECSTATUS_SEQNUM_BMSK GENMASK(29, 0) -#define BHIE_RXVECSTATUS_SEQNUM_SHFT 0 #define BHIE_RXVECSTATUS_STATUS_BMSK GENMASK(31, 30) -#define BHIE_RXVECSTATUS_STATUS_SHFT 30 #define BHIE_RXVECSTATUS_STATUS_RESET 0x00 #define BHIE_RXVECSTATUS_STATUS_XFER_COMPL 0x02 #define BHIE_RXVECSTATUS_STATUS_ERROR 0x03 /* MHI register bits */ #define MHIREGLEN_MHIREGLEN_MASK GENMASK(31, 0) -#define MHIREGLEN_MHIREGLEN_SHIFT 0 #define MHIVER_MHIVER_MASK GENMASK(31, 0) -#define MHIVER_MHIVER_SHIFT 0 #define MHICFG_NHWER_MASK GENMASK(31, 24) -#define MHICFG_NHWER_SHIFT 24 #define MHICFG_NER_MASK GENMASK(23, 16) -#define MHICFG_NER_SHIFT 16 #define MHICFG_NHWCH_MASK GENMASK(15, 8) -#define MHICFG_NHWCH_SHIFT 8 #define MHICFG_NCH_MASK GENMASK(7, 0) -#define MHICFG_NCH_SHIFT 0 #define CHDBOFF_CHDBOFF_MASK GENMASK(31, 0) -#define CHDBOFF_CHDBOFF_SHIFT 0 #define ERDBOFF_ERDBOFF_MASK GENMASK(31, 0) -#define ERDBOFF_ERDBOFF_SHIFT 0 #define BHIOFF_BHIOFF_MASK GENMASK(31, 0) -#define BHIOFF_BHIOFF_SHIFT 0 #define BHIEOFF_BHIEOFF_MASK GENMASK(31, 0) -#define BHIEOFF_BHIEOFF_SHIFT 0 #define DEBUGOFF_DEBUGOFF_MASK GENMASK(31, 0) -#define DEBUGOFF_DEBUGOFF_SHIFT 0 #define MHICTRL_MHISTATE_MASK GENMASK(15, 8) -#define MHICTRL_MHISTATE_SHIFT 8 #define MHICTRL_RESET_MASK BIT(1) -#define MHICTRL_RESET_SHIFT 1 #define MHISTATUS_MHISTATE_MASK GENMASK(15, 8) -#define MHISTATUS_MHISTATE_SHIFT 8 #define MHISTATUS_SYSERR_MASK BIT(2) -#define MHISTATUS_SYSERR_SHIFT 2 #define MHISTATUS_READY_MASK BIT(0) -#define MHISTATUS_READY_SHIFT 0 #define CCABAP_LOWER_CCABAP_LOWER_MASK GENMASK(31, 0) -#define CCABAP_LOWER_CCABAP_LOWER_SHIFT 0 #define CCABAP_HIGHER_CCABAP_HIGHER_MASK GENMASK(31, 0) -#define CCABAP_HIGHER_CCABAP_HIGHER_SHIFT 0 #define ECABAP_LOWER_ECABAP_LOWER_MASK GENMASK(31, 0) -#define ECABAP_LOWER_ECABAP_LOWER_SHIFT 0 #define ECABAP_HIGHER_ECABAP_HIGHER_MASK GENMASK(31, 0) -#define ECABAP_HIGHER_ECABAP_HIGHER_SHIFT 0 #define CRCBAP_LOWER_CRCBAP_LOWER_MASK GENMASK(31, 0) -#define CRCBAP_LOWER_CRCBAP_LOWER_SHIFT 0 #define CRCBAP_HIGHER_CRCBAP_HIGHER_MASK GENMASK(31, 0) -#define CRCBAP_HIGHER_CRCBAP_HIGHER_SHIFT 0 #define CRDB_LOWER_CRDB_LOWER_MASK GENMASK(31, 0) -#define CRDB_LOWER_CRDB_LOWER_SHIFT 0 #define CRDB_HIGHER_CRDB_HIGHER_MASK GENMASK(31, 0) -#define CRDB_HIGHER_CRDB_HIGHER_SHIFT 0 #define MHICTRLBASE_LOWER_MHICTRLBASE_LOWER_MASK GENMASK(31, 0) -#define MHICTRLBASE_LOWER_MHICTRLBASE_LOWER_SHIFT 0 #define MHICTRLBASE_HIGHER_MHICTRLBASE_HIGHER_MASK GENMASK(31, 0) -#define MHICTRLBASE_HIGHER_MHICTRLBASE_HIGHER_SHIFT 0 #define MHICTRLLIMIT_LOWER_MHICTRLLIMIT_LOWER_MASK GENMASK(31, 0) -#define MHICTRLLIMIT_LOWER_MHICTRLLIMIT_LOWER_SHIFT 0 #define MHICTRLLIMIT_HIGHER_MHICTRLLIMIT_HIGHER_MASK GENMASK(31, 0) -#define MHICTRLLIMIT_HIGHER_MHICTRLLIMIT_HIGHER_SHIFT 0 #define MHIDATABASE_LOWER_MHIDATABASE_LOWER_MASK GENMASK(31, 0) -#define MHIDATABASE_LOWER_MHIDATABASE_LOWER_SHIFT 0 #define MHIDATABASE_HIGHER_MHIDATABASE_HIGHER_MASK GENMASK(31, 0) -#define MHIDATABASE_HIGHER_MHIDATABASE_HIGHER_SHIFT 0 #define MHIDATALIMIT_LOWER_MHIDATALIMIT_LOWER_MASK GENMASK(31, 0) -#define MHIDATALIMIT_LOWER_MHIDATALIMIT_LOWER_SHIFT 0 #define MHIDATALIMIT_HIGHER_MHIDATALIMIT_HIGHER_MASK GENMASK(31, 0) -#define MHIDATALIMIT_HIGHER_MHIDATALIMIT_HIGHER_SHIFT 0 /* Command Ring Element macros */ /* No operation command */ @@ -277,9 +237,7 @@ enum mhi_cmd_type { #define EV_CTX_RESERVED_MASK GENMASK(7, 0) #define EV_CTX_INTMODC_MASK GENMASK(15, 8) -#define EV_CTX_INTMODC_SHIFT 8 #define EV_CTX_INTMODT_MASK GENMASK(31, 16) -#define EV_CTX_INTMODT_SHIFT 16 struct mhi_event_ctxt { __le32 intmod; __le32 ertype; @@ -292,11 +250,8 @@ struct mhi_event_ctxt { }; #define CHAN_CTX_CHSTATE_MASK GENMASK(7, 0) -#define CHAN_CTX_CHSTATE_SHIFT 0 #define CHAN_CTX_BRSTMODE_MASK GENMASK(9, 8) -#define CHAN_CTX_BRSTMODE_SHIFT 8 #define CHAN_CTX_POLLCFG_MASK GENMASK(15, 10) -#define CHAN_CTX_POLLCFG_SHIFT 10 #define CHAN_CTX_RESERVED_MASK GENMASK(31, 16) struct mhi_chan_ctxt { __le32 chcfg; diff --git a/drivers/bus/mhi/host/boot.c b/drivers/bus/mhi/host/boot.c index 93cb705614c6..b0da7ca4519c 100644 --- a/drivers/bus/mhi/host/boot.c +++ b/drivers/bus/mhi/host/boot.c @@ -46,8 +46,7 @@ void mhi_rddm_prepare(struct mhi_controller *mhi_cntrl, sequence_id = MHI_RANDOM_U32_NONZERO(BHIE_RXVECSTATUS_SEQNUM_BMSK); mhi_write_reg_field(mhi_cntrl, base, BHIE_RXVECDB_OFFS, - BHIE_RXVECDB_SEQNUM_BMSK, BHIE_RXVECDB_SEQNUM_SHFT, - sequence_id); + BHIE_RXVECDB_SEQNUM_BMSK, sequence_id); dev_dbg(dev, "Address: %p and len: 0x%zx sequence: %u\n", &mhi_buf->dma_addr, mhi_buf->len, sequence_id); @@ -127,9 +126,7 @@ static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl) while (retry--) { ret = mhi_read_reg_field(mhi_cntrl, base, BHIE_RXVECSTATUS_OFFS, - BHIE_RXVECSTATUS_STATUS_BMSK, - BHIE_RXVECSTATUS_STATUS_SHFT, - &rx_status); + BHIE_RXVECSTATUS_STATUS_BMSK, &rx_status); if (ret) return -EIO; @@ -168,7 +165,6 @@ int mhi_download_rddm_image(struct mhi_controller *mhi_cntrl, bool in_panic) mhi_read_reg_field(mhi_cntrl, base, BHIE_RXVECSTATUS_OFFS, BHIE_RXVECSTATUS_STATUS_BMSK, - BHIE_RXVECSTATUS_STATUS_SHFT, &rx_status) || rx_status, msecs_to_jiffies(mhi_cntrl->timeout_ms)); @@ -203,8 +199,7 @@ static int mhi_fw_load_bhie(struct mhi_controller *mhi_cntrl, mhi_write_reg(mhi_cntrl, base, BHIE_TXVECSIZE_OFFS, mhi_buf->len); mhi_write_reg_field(mhi_cntrl, base, BHIE_TXVECDB_OFFS, - BHIE_TXVECDB_SEQNUM_BMSK, BHIE_TXVECDB_SEQNUM_SHFT, - sequence_id); + BHIE_TXVECDB_SEQNUM_BMSK, sequence_id); read_unlock_bh(pm_lock); /* Wait for the image download to complete */ @@ -213,7 +208,6 @@ static int mhi_fw_load_bhie(struct mhi_controller *mhi_cntrl, mhi_read_reg_field(mhi_cntrl, base, BHIE_TXVECSTATUS_OFFS, BHIE_TXVECSTATUS_STATUS_BMSK, - BHIE_TXVECSTATUS_STATUS_SHFT, &tx_status) || tx_status, msecs_to_jiffies(mhi_cntrl->timeout_ms)); if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state) || @@ -265,8 +259,7 @@ static int mhi_fw_load_bhi(struct mhi_controller *mhi_cntrl, ret = wait_event_timeout(mhi_cntrl->state_event, MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state) || mhi_read_reg_field(mhi_cntrl, base, BHI_STATUS, - BHI_STATUS_MASK, BHI_STATUS_SHIFT, - &tx_status) || tx_status, + BHI_STATUS_MASK, &tx_status) || tx_status, msecs_to_jiffies(mhi_cntrl->timeout_ms)); if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) goto invalid_pm_state; diff --git a/drivers/bus/mhi/host/debugfs.c b/drivers/bus/mhi/host/debugfs.c index 399d0db1f1eb..cfec7811dfbb 100644 --- a/drivers/bus/mhi/host/debugfs.c +++ b/drivers/bus/mhi/host/debugfs.c @@ -61,9 +61,9 @@ static int mhi_debugfs_events_show(struct seq_file *m, void *d) seq_printf(m, "Index: %d intmod count: %lu time: %lu", i, (le32_to_cpu(er_ctxt->intmod) & EV_CTX_INTMODC_MASK) >> - EV_CTX_INTMODC_SHIFT, + __ffs(EV_CTX_INTMODC_MASK), (le32_to_cpu(er_ctxt->intmod) & EV_CTX_INTMODT_MASK) >> - EV_CTX_INTMODT_SHIFT); + __ffs(EV_CTX_INTMODT_MASK)); seq_printf(m, " base: 0x%0llx len: 0x%llx", le64_to_cpu(er_ctxt->rbase), le64_to_cpu(er_ctxt->rlen)); @@ -107,10 +107,10 @@ static int mhi_debugfs_channels_show(struct seq_file *m, void *d) seq_printf(m, "%s(%u) state: 0x%lx brstmode: 0x%lx pollcfg: 0x%lx", mhi_chan->name, mhi_chan->chan, (le32_to_cpu(chan_ctxt->chcfg) & - CHAN_CTX_CHSTATE_MASK) >> CHAN_CTX_CHSTATE_SHIFT, + CHAN_CTX_CHSTATE_MASK) >> __ffs(CHAN_CTX_CHSTATE_MASK), (le32_to_cpu(chan_ctxt->chcfg) & CHAN_CTX_BRSTMODE_MASK) >> - CHAN_CTX_BRSTMODE_SHIFT, (le32_to_cpu(chan_ctxt->chcfg) & - CHAN_CTX_POLLCFG_MASK) >> CHAN_CTX_POLLCFG_SHIFT); + __ffs(CHAN_CTX_BRSTMODE_MASK), (le32_to_cpu(chan_ctxt->chcfg) & + CHAN_CTX_POLLCFG_MASK) >> __ffs(CHAN_CTX_POLLCFG_MASK)); seq_printf(m, " type: 0x%x event ring: %u", le32_to_cpu(chan_ctxt->chtype), le32_to_cpu(chan_ctxt->erindex)); diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c index 0e301f3f305e..05e457d12446 100644 --- a/drivers/bus/mhi/host/init.c +++ b/drivers/bus/mhi/host/init.c @@ -4,6 +4,7 @@ * */ +#include #include #include #include @@ -283,11 +284,11 @@ int mhi_init_dev_ctxt(struct mhi_controller *mhi_cntrl) tmp = le32_to_cpu(chan_ctxt->chcfg); tmp &= ~CHAN_CTX_CHSTATE_MASK; - tmp |= (MHI_CH_STATE_DISABLED << CHAN_CTX_CHSTATE_SHIFT); + tmp |= FIELD_PREP(CHAN_CTX_CHSTATE_MASK, MHI_CH_STATE_DISABLED); tmp &= ~CHAN_CTX_BRSTMODE_MASK; - tmp |= (mhi_chan->db_cfg.brstmode << CHAN_CTX_BRSTMODE_SHIFT); + tmp |= FIELD_PREP(CHAN_CTX_BRSTMODE_MASK, mhi_chan->db_cfg.brstmode); tmp &= ~CHAN_CTX_POLLCFG_MASK; - tmp |= (mhi_chan->db_cfg.pollcfg << CHAN_CTX_POLLCFG_SHIFT); + tmp |= FIELD_PREP(CHAN_CTX_POLLCFG_MASK, mhi_chan->db_cfg.pollcfg); chan_ctxt->chcfg = cpu_to_le32(tmp); chan_ctxt->chtype = cpu_to_le32(mhi_chan->type); @@ -319,7 +320,7 @@ int mhi_init_dev_ctxt(struct mhi_controller *mhi_cntrl) tmp = le32_to_cpu(er_ctxt->intmod); tmp &= ~EV_CTX_INTMODC_MASK; tmp &= ~EV_CTX_INTMODT_MASK; - tmp |= (mhi_event->intmod << EV_CTX_INTMODT_SHIFT); + tmp |= FIELD_PREP(EV_CTX_INTMODT_MASK, mhi_event->intmod); er_ctxt->intmod = cpu_to_le32(tmp); er_ctxt->ertype = cpu_to_le32(MHI_ER_TYPE_VALID); @@ -425,71 +426,70 @@ int mhi_init_mmio(struct mhi_controller *mhi_cntrl) struct { u32 offset; u32 mask; - u32 shift; u32 val; } reg_info[] = { { - CCABAP_HIGHER, U32_MAX, 0, + CCABAP_HIGHER, U32_MAX, upper_32_bits(mhi_cntrl->mhi_ctxt->chan_ctxt_addr), }, { - CCABAP_LOWER, U32_MAX, 0, + CCABAP_LOWER, U32_MAX, lower_32_bits(mhi_cntrl->mhi_ctxt->chan_ctxt_addr), }, { - ECABAP_HIGHER, U32_MAX, 0, + ECABAP_HIGHER, U32_MAX, upper_32_bits(mhi_cntrl->mhi_ctxt->er_ctxt_addr), }, { - ECABAP_LOWER, U32_MAX, 0, + ECABAP_LOWER, U32_MAX, lower_32_bits(mhi_cntrl->mhi_ctxt->er_ctxt_addr), }, { - CRCBAP_HIGHER, U32_MAX, 0, + CRCBAP_HIGHER, U32_MAX, upper_32_bits(mhi_cntrl->mhi_ctxt->cmd_ctxt_addr), }, { - CRCBAP_LOWER, U32_MAX, 0, + CRCBAP_LOWER, U32_MAX, lower_32_bits(mhi_cntrl->mhi_ctxt->cmd_ctxt_addr), }, { - MHICFG, MHICFG_NER_MASK, MHICFG_NER_SHIFT, + MHICFG, MHICFG_NER_MASK, mhi_cntrl->total_ev_rings, }, { - MHICFG, MHICFG_NHWER_MASK, MHICFG_NHWER_SHIFT, + MHICFG, MHICFG_NHWER_MASK, mhi_cntrl->hw_ev_rings, }, { - MHICTRLBASE_HIGHER, U32_MAX, 0, + MHICTRLBASE_HIGHER, U32_MAX, upper_32_bits(mhi_cntrl->iova_start), }, { - MHICTRLBASE_LOWER, U32_MAX, 0, + MHICTRLBASE_LOWER, U32_MAX, lower_32_bits(mhi_cntrl->iova_start), }, { - MHIDATABASE_HIGHER, U32_MAX, 0, + MHIDATABASE_HIGHER, U32_MAX, upper_32_bits(mhi_cntrl->iova_start), }, { - MHIDATABASE_LOWER, U32_MAX, 0, + MHIDATABASE_LOWER, U32_MAX, lower_32_bits(mhi_cntrl->iova_start), }, { - MHICTRLLIMIT_HIGHER, U32_MAX, 0, + MHICTRLLIMIT_HIGHER, U32_MAX, upper_32_bits(mhi_cntrl->iova_stop), }, { - MHICTRLLIMIT_LOWER, U32_MAX, 0, + MHICTRLLIMIT_LOWER, U32_MAX, lower_32_bits(mhi_cntrl->iova_stop), }, { - MHIDATALIMIT_HIGHER, U32_MAX, 0, + MHIDATALIMIT_HIGHER, U32_MAX, upper_32_bits(mhi_cntrl->iova_stop), }, { - MHIDATALIMIT_LOWER, U32_MAX, 0, + MHIDATALIMIT_LOWER, U32_MAX, lower_32_bits(mhi_cntrl->iova_stop), }, { 0, 0, 0 } @@ -498,8 +498,7 @@ int mhi_init_mmio(struct mhi_controller *mhi_cntrl) dev_dbg(dev, "Initializing MHI registers\n"); /* Read channel db offset */ - ret = mhi_read_reg_field(mhi_cntrl, base, CHDBOFF, CHDBOFF_CHDBOFF_MASK, - CHDBOFF_CHDBOFF_SHIFT, &val); + ret = mhi_read_reg_field(mhi_cntrl, base, CHDBOFF, CHDBOFF_CHDBOFF_MASK, &val); if (ret) { dev_err(dev, "Unable to read CHDBOFF register\n"); return -EIO; @@ -515,8 +514,7 @@ int mhi_init_mmio(struct mhi_controller *mhi_cntrl) mhi_chan->tre_ring.db_addr = base + val; /* Read event ring db offset */ - ret = mhi_read_reg_field(mhi_cntrl, base, ERDBOFF, ERDBOFF_ERDBOFF_MASK, - ERDBOFF_ERDBOFF_SHIFT, &val); + ret = mhi_read_reg_field(mhi_cntrl, base, ERDBOFF, ERDBOFF_ERDBOFF_MASK, &val); if (ret) { dev_err(dev, "Unable to read ERDBOFF register\n"); return -EIO; @@ -537,8 +535,7 @@ int mhi_init_mmio(struct mhi_controller *mhi_cntrl) /* Write to MMIO registers */ for (i = 0; reg_info[i].offset; i++) mhi_write_reg_field(mhi_cntrl, base, reg_info[i].offset, - reg_info[i].mask, reg_info[i].shift, - reg_info[i].val); + reg_info[i].mask, reg_info[i].val); return 0; } @@ -571,7 +568,7 @@ void mhi_deinit_chan_ctxt(struct mhi_controller *mhi_cntrl, tmp = le32_to_cpu(chan_ctxt->chcfg); tmp &= ~CHAN_CTX_CHSTATE_MASK; - tmp |= (MHI_CH_STATE_DISABLED << CHAN_CTX_CHSTATE_SHIFT); + tmp |= FIELD_PREP(CHAN_CTX_CHSTATE_MASK, MHI_CH_STATE_DISABLED); chan_ctxt->chcfg = cpu_to_le32(tmp); /* Update to all cores */ @@ -608,7 +605,7 @@ int mhi_init_chan_ctxt(struct mhi_controller *mhi_cntrl, tmp = le32_to_cpu(chan_ctxt->chcfg); tmp &= ~CHAN_CTX_CHSTATE_MASK; - tmp |= (MHI_CH_STATE_ENABLED << CHAN_CTX_CHSTATE_SHIFT); + tmp |= FIELD_PREP(CHAN_CTX_CHSTATE_MASK, MHI_CH_STATE_ENABLED); chan_ctxt->chcfg = cpu_to_le32(tmp); chan_ctxt->rbase = cpu_to_le64(tre_ring->iommu_base); @@ -952,14 +949,10 @@ int mhi_register_controller(struct mhi_controller *mhi_cntrl, if (ret) goto err_destroy_wq; - mhi_cntrl->family_number = (soc_info & SOC_HW_VERSION_FAM_NUM_BMSK) >> - SOC_HW_VERSION_FAM_NUM_SHFT; - mhi_cntrl->device_number = (soc_info & SOC_HW_VERSION_DEV_NUM_BMSK) >> - SOC_HW_VERSION_DEV_NUM_SHFT; - mhi_cntrl->major_version = (soc_info & SOC_HW_VERSION_MAJOR_VER_BMSK) >> - SOC_HW_VERSION_MAJOR_VER_SHFT; - mhi_cntrl->minor_version = (soc_info & SOC_HW_VERSION_MINOR_VER_BMSK) >> - SOC_HW_VERSION_MINOR_VER_SHFT; + mhi_cntrl->family_number = FIELD_GET(SOC_HW_VERSION_FAM_NUM_BMSK, soc_info); + mhi_cntrl->device_number = FIELD_GET(SOC_HW_VERSION_DEV_NUM_BMSK, soc_info); + mhi_cntrl->major_version = FIELD_GET(SOC_HW_VERSION_MAJOR_VER_BMSK, soc_info); + mhi_cntrl->minor_version = FIELD_GET(SOC_HW_VERSION_MINOR_VER_BMSK, soc_info); mhi_cntrl->index = ida_alloc(&mhi_controller_ida, GFP_KERNEL); if (mhi_cntrl->index < 0) { diff --git a/drivers/bus/mhi/host/internal.h b/drivers/bus/mhi/host/internal.h index 762055a6ec9f..21381781d7c5 100644 --- a/drivers/bus/mhi/host/internal.h +++ b/drivers/bus/mhi/host/internal.h @@ -82,13 +82,9 @@ extern struct bus_type mhi_bus_type; #define SOC_HW_VERSION_OFFS 0x224 #define SOC_HW_VERSION_FAM_NUM_BMSK GENMASK(31, 28) -#define SOC_HW_VERSION_FAM_NUM_SHFT 28 #define SOC_HW_VERSION_DEV_NUM_BMSK GENMASK(27, 16) -#define SOC_HW_VERSION_DEV_NUM_SHFT 16 #define SOC_HW_VERSION_MAJOR_VER_BMSK GENMASK(15, 8) -#define SOC_HW_VERSION_MAJOR_VER_SHFT 8 #define SOC_HW_VERSION_MINOR_VER_BMSK GENMASK(7, 0) -#define SOC_HW_VERSION_MINOR_VER_SHFT 0 struct mhi_ctxt { struct mhi_event_ctxt *er_ctxt; @@ -393,14 +389,14 @@ int __must_check mhi_read_reg(struct mhi_controller *mhi_cntrl, void __iomem *base, u32 offset, u32 *out); int __must_check mhi_read_reg_field(struct mhi_controller *mhi_cntrl, void __iomem *base, u32 offset, u32 mask, - u32 shift, u32 *out); + u32 *out); int __must_check mhi_poll_reg_field(struct mhi_controller *mhi_cntrl, void __iomem *base, u32 offset, u32 mask, - u32 shift, u32 val, u32 delayus); + u32 val, u32 delayus); void mhi_write_reg(struct mhi_controller *mhi_cntrl, void __iomem *base, u32 offset, u32 val); void mhi_write_reg_field(struct mhi_controller *mhi_cntrl, void __iomem *base, - u32 offset, u32 mask, u32 shift, u32 val); + u32 offset, u32 mask, u32 val); void mhi_ring_er_db(struct mhi_event *mhi_event); void mhi_write_db(struct mhi_controller *mhi_cntrl, void __iomem *db_addr, dma_addr_t db_val); diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c index e436c2993d97..02ac5faf9178 100644 --- a/drivers/bus/mhi/host/main.c +++ b/drivers/bus/mhi/host/main.c @@ -24,7 +24,7 @@ int __must_check mhi_read_reg(struct mhi_controller *mhi_cntrl, int __must_check mhi_read_reg_field(struct mhi_controller *mhi_cntrl, void __iomem *base, u32 offset, - u32 mask, u32 shift, u32 *out) + u32 mask, u32 *out) { u32 tmp; int ret; @@ -33,21 +33,20 @@ int __must_check mhi_read_reg_field(struct mhi_controller *mhi_cntrl, if (ret) return ret; - *out = (tmp & mask) >> shift; + *out = (tmp & mask) >> __ffs(mask); return 0; } int __must_check mhi_poll_reg_field(struct mhi_controller *mhi_cntrl, void __iomem *base, u32 offset, - u32 mask, u32 shift, u32 val, u32 delayus) + u32 mask, u32 val, u32 delayus) { int ret; u32 out, retry = (mhi_cntrl->timeout_ms * 1000) / delayus; while (retry--) { - ret = mhi_read_reg_field(mhi_cntrl, base, offset, mask, shift, - &out); + ret = mhi_read_reg_field(mhi_cntrl, base, offset, mask, &out); if (ret) return ret; @@ -67,7 +66,7 @@ void mhi_write_reg(struct mhi_controller *mhi_cntrl, void __iomem *base, } void mhi_write_reg_field(struct mhi_controller *mhi_cntrl, void __iomem *base, - u32 offset, u32 mask, u32 shift, u32 val) + u32 offset, u32 mask, u32 val) { int ret; u32 tmp; @@ -77,7 +76,7 @@ void mhi_write_reg_field(struct mhi_controller *mhi_cntrl, void __iomem *base, return; tmp &= ~mask; - tmp |= (val << shift); + tmp |= (val << __ffs(mask)); mhi_write_reg(mhi_cntrl, base, offset, tmp); } @@ -159,8 +158,7 @@ enum mhi_state mhi_get_mhi_state(struct mhi_controller *mhi_cntrl) { u32 state; int ret = mhi_read_reg_field(mhi_cntrl, mhi_cntrl->regs, MHISTATUS, - MHISTATUS_MHISTATE_MASK, - MHISTATUS_MHISTATE_SHIFT, &state); + MHISTATUS_MHISTATE_MASK, &state); return ret ? MHI_STATE_MAX : state; } EXPORT_SYMBOL_GPL(mhi_get_mhi_state); diff --git a/drivers/bus/mhi/host/pm.c b/drivers/bus/mhi/host/pm.c index 088ade0f3e0b..3d90b8ecd3d9 100644 --- a/drivers/bus/mhi/host/pm.c +++ b/drivers/bus/mhi/host/pm.c @@ -131,11 +131,10 @@ void mhi_set_mhi_state(struct mhi_controller *mhi_cntrl, enum mhi_state state) { if (state == MHI_STATE_RESET) { mhi_write_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, - MHICTRL_RESET_MASK, MHICTRL_RESET_SHIFT, 1); + MHICTRL_RESET_MASK, 1); } else { mhi_write_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, - MHICTRL_MHISTATE_MASK, - MHICTRL_MHISTATE_SHIFT, state); + MHICTRL_MHISTATE_MASK, state); } } @@ -167,16 +166,14 @@ int mhi_ready_state_transition(struct mhi_controller *mhi_cntrl) /* Wait for RESET to be cleared and READY bit to be set by the device */ ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, - MHICTRL_RESET_MASK, MHICTRL_RESET_SHIFT, 0, - interval_us); + MHICTRL_RESET_MASK, 0, interval_us); if (ret) { dev_err(dev, "Device failed to clear MHI Reset\n"); return ret; } ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHISTATUS, - MHISTATUS_READY_MASK, MHISTATUS_READY_SHIFT, 1, - interval_us); + MHISTATUS_READY_MASK, 1, interval_us); if (ret) { dev_err(dev, "Device failed to enter MHI Ready\n"); return ret; @@ -470,8 +467,7 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl) /* Wait for the reset bit to be cleared by the device */ ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, - MHICTRL_RESET_MASK, MHICTRL_RESET_SHIFT, 0, - 25000); + MHICTRL_RESET_MASK, 0, 25000); if (ret) dev_err(dev, "Device failed to clear MHI Reset\n"); @@ -602,7 +598,6 @@ static void mhi_pm_sys_error_transition(struct mhi_controller *mhi_cntrl) mhi_cntrl->regs, MHICTRL, MHICTRL_RESET_MASK, - MHICTRL_RESET_SHIFT, &in_reset) || !in_reset, timeout); if (!ret || in_reset) { @@ -1093,8 +1088,7 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl) if (state == MHI_STATE_SYS_ERR) { mhi_set_mhi_state(mhi_cntrl, MHI_STATE_RESET); ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, - MHICTRL_RESET_MASK, MHICTRL_RESET_SHIFT, 0, - interval_us); + MHICTRL_RESET_MASK, 0, interval_us); if (ret) { dev_info(dev, "Failed to reset MHI due to syserr state\n"); goto error_exit; From patchwork Sat Feb 12 18:21:00 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 542592 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1E507C433F5 for ; Sat, 12 Feb 2022 18:22:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229622AbiBLSWg (ORCPT ); Sat, 12 Feb 2022 13:22:36 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:45774 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229766AbiBLSW2 (ORCPT ); Sat, 12 Feb 2022 13:22:28 -0500 Received: from mail-pf1-x42a.google.com (mail-pf1-x42a.google.com [IPv6:2607:f8b0:4864:20::42a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CBFCE5FF29 for ; Sat, 12 Feb 2022 10:22:22 -0800 (PST) Received: by mail-pf1-x42a.google.com with SMTP id f6so955194pfj.11 for ; Sat, 12 Feb 2022 10:22:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=yo3rzZXemv8KWlw17BIoBTt1lNvqc8MJS5UcJWM9INQ=; b=jLwHtttdCC57MT1T8+2a+I/fZ9Duz8vE6PgwYsIxEMD/8Tigs4jsj5h0faxRo4TzNX /cjIElbgZExWPKAxqQHaDVTeG/8KSnhYydonu7lTa2hjkTxWf1UKQpWrj0iJNRDwDqiS W+Jkpp5RDso8cPqm4xOcjXLtMCdhrMsBrnv4Vgj5JI2DWMCsGYk2MVVBDuXKxBNgFCul c9BupRkEPO3rWjgNDZWHbrVdoS3xuHPM8UuU0UCh7utfM56G44Qp208vBTZbtw/SVwlR MNGrQoTrTAvFFKVirK2z/D6MUAB0jz9hyQA4Q69nH7tKT9kUjVahNYEN59Kk8HNcYQ5v t8IQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=yo3rzZXemv8KWlw17BIoBTt1lNvqc8MJS5UcJWM9INQ=; b=r2LJgGEUb+cFxWGuArONDKyjw2dznHDWrHffEeJYXDhBLhNUbc69aylWTbZZllL6tO vzLr0FYdc/neNPSZVzXEnZCItqO5g3aq69FpzaVk/vhSTQODPJiAlgbJT0t67CNJBVg0 RX4GlJ3vCOUq/a/awRjvvwy3IJ8u+n1ZgIKZnPlGYej3VRS5p4AkLbaZEPo4mkSeAom3 MDcUnFSR1JS0olYcB/QYOxvvay7IfuqQDpNcTGvC6faDOVuNjKF5Y3rP/eF1xbu/L/I7 XmrwucQbqrTfeH80hQIasSfy9tngaRqdlXkMhJz/4V0I7rkXeart5nODo7Wo2FystFmP Yy/A== X-Gm-Message-State: AOAM533OmzcwQVPuS5CA9+E+9st+RB+08o/ZECmTUyCNANE4qCwqRAdG Q+rcLPo/1SxeJKDn8floiDRT X-Google-Smtp-Source: ABdhPJxBEc3e1tEgXdKe1ffMjAuhbEZL0mTJjED+m6lF+sdKFM1qlMSXdpAsq8AckH/VRr+06k31ww== X-Received: by 2002:a05:6a00:170d:: with SMTP id h13mr7153162pfc.39.1644690142120; Sat, 12 Feb 2022 10:22:22 -0800 (PST) Received: from localhost.localdomain ([27.111.75.57]) by smtp.gmail.com with ESMTPSA id g12sm14961987pfj.148.2022.02.12.10.22.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Feb 2022 10:22:21 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v3 08/25] bus: mhi: ep: Add support for registering MHI endpoint controllers Date: Sat, 12 Feb 2022 23:51:00 +0530 Message-Id: <20220212182117.49438-9-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> References: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org This commit adds support for registering MHI endpoint controller drivers with the MHI endpoint stack. MHI endpoint controller drivers manages the interaction with the host machines such as x86. They are also the MHI endpoint bus master in charge of managing the physical link between the host and endpoint device. The endpoint controller driver encloses all information about the underlying physical bus like PCIe. The registration process involves parsing the channel configuration and allocating an MHI EP device. Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/Kconfig | 1 + drivers/bus/mhi/Makefile | 3 + drivers/bus/mhi/ep/Kconfig | 10 ++ drivers/bus/mhi/ep/Makefile | 2 + drivers/bus/mhi/ep/internal.h | 160 +++++++++++++++++++++++ drivers/bus/mhi/ep/main.c | 234 ++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 143 +++++++++++++++++++++ 7 files changed, 553 insertions(+) create mode 100644 drivers/bus/mhi/ep/Kconfig create mode 100644 drivers/bus/mhi/ep/Makefile create mode 100644 drivers/bus/mhi/ep/internal.h create mode 100644 drivers/bus/mhi/ep/main.c create mode 100644 include/linux/mhi_ep.h diff --git a/drivers/bus/mhi/Kconfig b/drivers/bus/mhi/Kconfig index 4748df7f9cd5..b39a11e6c624 100644 --- a/drivers/bus/mhi/Kconfig +++ b/drivers/bus/mhi/Kconfig @@ -6,3 +6,4 @@ # source "drivers/bus/mhi/host/Kconfig" +source "drivers/bus/mhi/ep/Kconfig" diff --git a/drivers/bus/mhi/Makefile b/drivers/bus/mhi/Makefile index 5f5708a249f5..46981331b38f 100644 --- a/drivers/bus/mhi/Makefile +++ b/drivers/bus/mhi/Makefile @@ -1,2 +1,5 @@ # Host MHI stack obj-y += host/ + +# Endpoint MHI stack +obj-y += ep/ diff --git a/drivers/bus/mhi/ep/Kconfig b/drivers/bus/mhi/ep/Kconfig new file mode 100644 index 000000000000..229c71397b30 --- /dev/null +++ b/drivers/bus/mhi/ep/Kconfig @@ -0,0 +1,10 @@ +config MHI_BUS_EP + tristate "Modem Host Interface (MHI) bus Endpoint implementation" + help + Bus driver for MHI protocol. Modem Host Interface (MHI) is a + communication protocol used by the host processors to control + and communicate with modem devices over a high speed peripheral + bus or shared memory. + + MHI_BUS_EP implements the MHI protocol for the endpoint devices + like SDX55 modem connected to the host machine over PCIe. diff --git a/drivers/bus/mhi/ep/Makefile b/drivers/bus/mhi/ep/Makefile new file mode 100644 index 000000000000..64e29252b608 --- /dev/null +++ b/drivers/bus/mhi/ep/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_MHI_BUS_EP) += mhi_ep.o +mhi_ep-y := main.o diff --git a/drivers/bus/mhi/ep/internal.h b/drivers/bus/mhi/ep/internal.h new file mode 100644 index 000000000000..e313a2546664 --- /dev/null +++ b/drivers/bus/mhi/ep/internal.h @@ -0,0 +1,160 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2021, Linaro Ltd. + * + */ + +#ifndef _MHI_EP_INTERNAL_ +#define _MHI_EP_INTERNAL_ + +#include + +#include "../common.h" + +extern struct bus_type mhi_ep_bus_type; + +#define MHI_REG_OFFSET 0x100 +#define BHI_REG_OFFSET 0x200 + +/* MHI registers */ +#define MHIREGLEN (MHI_REG_OFFSET + REG_MHIREGLEN) +#define MHIVER (MHI_REG_OFFSET + REG_MHIVER) +#define MHICFG (MHI_REG_OFFSET + REG_MHICFG) +#define CHDBOFF (MHI_REG_OFFSET + REG_CHDBOFF) +#define ERDBOFF (MHI_REG_OFFSET + REG_ERDBOFF) +#define BHIOFF (MHI_REG_OFFSET + REG_BHIOFF) +#define BHIEOFF (MHI_REG_OFFSET + REG_BHIEOFF) +#define DEBUGOFF (MHI_REG_OFFSET + REG_DEBUGOFF) +#define MHICTRL (MHI_REG_OFFSET + REG_MHICTRL) +#define MHISTATUS (MHI_REG_OFFSET + REG_MHISTATUS) +#define CCABAP_LOWER (MHI_REG_OFFSET + REG_CCABAP_LOWER) +#define CCABAP_HIGHER (MHI_REG_OFFSET + REG_CCABAP_HIGHER) +#define ECABAP_LOWER (MHI_REG_OFFSET + REG_ECABAP_LOWER) +#define ECABAP_HIGHER (MHI_REG_OFFSET + REG_ECABAP_HIGHER) +#define CRCBAP_LOWER (MHI_REG_OFFSET + REG_CRCBAP_LOWER) +#define CRCBAP_HIGHER (MHI_REG_OFFSET + REG_CRCBAP_HIGHER) +#define CRDB_LOWER (MHI_REG_OFFSET + REG_CRDB_LOWER) +#define CRDB_HIGHER (MHI_REG_OFFSET + REG_CRDB_HIGHER) +#define MHICTRLBASE_LOWER (MHI_REG_OFFSET + REG_MHICTRLBASE_LOWER) +#define MHICTRLBASE_HIGHER (MHI_REG_OFFSET + REG_MHICTRLBASE_HIGHER) +#define MHICTRLLIMIT_LOWER (MHI_REG_OFFSET + REG_MHICTRLLIMIT_LOWER) +#define MHICTRLLIMIT_HIGHER (MHI_REG_OFFSET + REG_MHICTRLLIMIT_HIGHER) +#define MHIDATABASE_LOWER (MHI_REG_OFFSET + REG_MHIDATABASE_LOWER) +#define MHIDATABASE_HIGHER (MHI_REG_OFFSET + REG_MHIDATABASE_HIGHER) +#define MHIDATALIMIT_LOWER (MHI_REG_OFFSET + REG_MHIDATALIMIT_LOWER) +#define MHIDATALIMIT_HIGHER (MHI_REG_OFFSET + REG_MHIDATALIMIT_HIGHER) + +/* MHI BHI registers */ +#define BHI_IMGTXDB (BHI_REG_OFFSET + REG_BHI_IMGTXDB) +#define BHI_EXECENV (BHI_REG_OFFSET + REG_BHI_EXECENV) +#define BHI_INTVEC (BHI_REG_OFFSET + REG_BHI_INTVEC) + +/* MHI Doorbell registers */ +#define CHDB_LOWER_n(n) (0x400 + 0x8 * (n)) +#define CHDB_HIGHER_n(n) (0x404 + 0x8 * (n)) +#define ERDB_LOWER_n(n) (0x800 + 0x8 * (n)) +#define ERDB_HIGHER_n(n) (0x804 + 0x8 * (n)) + +#define MHI_CTRL_INT_STATUS_A7 0x4 +#define MHI_CTRL_INT_STATUS_A7_MSK BIT(0) +#define MHI_CTRL_INT_STATUS_CRDB_MSK BIT(1) +#define MHI_CHDB_INT_STATUS_A7_n(n) (0x28 + 0x4 * (n)) +#define MHI_ERDB_INT_STATUS_A7_n(n) (0x38 + 0x4 * (n)) + +#define MHI_CTRL_INT_CLEAR_A7 0x4c +#define MHI_CTRL_INT_MMIO_WR_CLEAR BIT(2) +#define MHI_CTRL_INT_CRDB_CLEAR BIT(1) +#define MHI_CTRL_INT_CRDB_MHICTRL_CLEAR BIT(0) + +#define MHI_CHDB_INT_CLEAR_A7_n(n) (0x70 + 0x4 * (n)) +#define MHI_CHDB_INT_CLEAR_A7_n_CLEAR_ALL GENMASK(31, 0) +#define MHI_ERDB_INT_CLEAR_A7_n(n) (0x80 + 0x4 * (n)) +#define MHI_ERDB_INT_CLEAR_A7_n_CLEAR_ALL GENMASK(31, 0) + +/* + * Unlike the usual "masking" convention, writing "1" to a bit in this register + * enables the interrupt and writing "0" will disable it.. + */ +#define MHI_CTRL_INT_MASK_A7 0x94 +#define MHI_CTRL_INT_MASK_A7_MASK GENMASK(1, 0) +#define MHI_CTRL_MHICTRL_MASK BIT(0) +#define MHI_CTRL_CRDB_MASK BIT(1) + +#define MHI_CHDB_INT_MASK_A7_n(n) (0xb8 + 0x4 * (n)) +#define MHI_CHDB_INT_MASK_A7_n_EN_ALL GENMASK(31, 0) +#define MHI_ERDB_INT_MASK_A7_n(n) (0xc8 + 0x4 * (n)) +#define MHI_ERDB_INT_MASK_A7_n_EN_ALL GENMASK(31, 0) + +#define NR_OF_CMD_RINGS 1 +#define MHI_MASK_ROWS_CH_EV_DB 4 +#define MHI_MASK_CH_EV_LEN 32 + +/* Generic context */ +struct mhi_generic_ctx { + __u32 reserved0; + __u32 reserved1; + __u32 reserved2; + + __u64 rbase __packed __aligned(4); + __u64 rlen __packed __aligned(4); + __u64 rp __packed __aligned(4); + __u64 wp __packed __aligned(4); +}; + +enum mhi_ep_ring_type { + RING_TYPE_CMD = 0, + RING_TYPE_ER, + RING_TYPE_CH, +}; + +struct mhi_ep_ring_element { + u64 ptr; + u32 dword[2]; +}; + +/* Ring element */ +union mhi_ep_ring_ctx { + struct mhi_cmd_ctxt cmd; + struct mhi_event_ctxt ev; + struct mhi_chan_ctxt ch; + struct mhi_generic_ctx generic; +}; + +struct mhi_ep_ring { + struct mhi_ep_cntrl *mhi_cntrl; + int (*ring_cb)(struct mhi_ep_ring *ring, struct mhi_ep_ring_element *el); + union mhi_ep_ring_ctx *ring_ctx; + struct mhi_ep_ring_element *ring_cache; + enum mhi_ep_ring_type type; + size_t rd_offset; + size_t wr_offset; + size_t ring_size; + u32 db_offset_h; + u32 db_offset_l; + u32 ch_id; +}; + +struct mhi_ep_cmd { + struct mhi_ep_ring ring; +}; + +struct mhi_ep_event { + struct mhi_ep_ring ring; +}; + +struct mhi_ep_chan { + char *name; + struct mhi_ep_device *mhi_dev; + struct mhi_ep_ring ring; + struct mutex lock; + void (*xfer_cb)(struct mhi_ep_device *mhi_dev, struct mhi_result *result); + enum mhi_ch_state state; + enum dma_data_direction dir; + u64 tre_loc; + u32 tre_size; + u32 tre_bytes_left; + u32 chan; + bool skip_td; +}; + +#endif diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c new file mode 100644 index 000000000000..b006011d025d --- /dev/null +++ b/drivers/bus/mhi/ep/main.c @@ -0,0 +1,234 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MHI Bus Endpoint stack + * + * Copyright (C) 2021 Linaro Ltd. + * Author: Manivannan Sadhasivam + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "internal.h" + +static DEFINE_IDA(mhi_ep_cntrl_ida); + +static void mhi_ep_release_device(struct device *dev) +{ + struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev); + + if (mhi_dev->dev_type == MHI_DEVICE_CONTROLLER) + mhi_dev->mhi_cntrl->mhi_dev = NULL; + + /* + * We need to set the mhi_chan->mhi_dev to NULL here since the MHI + * devices for the channels will only get created during start + * channel if the mhi_dev associated with it is NULL. + */ + if (mhi_dev->ul_chan) + mhi_dev->ul_chan->mhi_dev = NULL; + + if (mhi_dev->dl_chan) + mhi_dev->dl_chan->mhi_dev = NULL; + + kfree(mhi_dev); +} + +static struct mhi_ep_device *mhi_ep_alloc_device(struct mhi_ep_cntrl *mhi_cntrl, + enum mhi_device_type dev_type) +{ + struct mhi_ep_device *mhi_dev; + struct device *dev; + + mhi_dev = kzalloc(sizeof(*mhi_dev), GFP_KERNEL); + if (!mhi_dev) + return ERR_PTR(-ENOMEM); + + dev = &mhi_dev->dev; + device_initialize(dev); + dev->bus = &mhi_ep_bus_type; + dev->release = mhi_ep_release_device; + + if (dev_type == MHI_DEVICE_CONTROLLER) + /* for MHI controller device, parent is the bus device (e.g. PCI EPF) */ + dev->parent = mhi_cntrl->cntrl_dev; + else + /* for MHI client devices, parent is the MHI controller device */ + dev->parent = &mhi_cntrl->mhi_dev->dev; + + mhi_dev->mhi_cntrl = mhi_cntrl; + mhi_dev->dev_type = dev_type; + + return mhi_dev; +} + +static int parse_ch_cfg(struct mhi_ep_cntrl *mhi_cntrl, + const struct mhi_ep_cntrl_config *config) +{ + const struct mhi_ep_channel_config *ch_cfg; + struct device *dev = mhi_cntrl->cntrl_dev; + u32 chan, i; + int ret = -EINVAL; + + mhi_cntrl->max_chan = config->max_channels; + + /* + * Allocate max_channels supported by the MHI endpoint and populate + * only the defined channels + */ + mhi_cntrl->mhi_chan = kcalloc(mhi_cntrl->max_chan, sizeof(*mhi_cntrl->mhi_chan), + GFP_KERNEL); + if (!mhi_cntrl->mhi_chan) + return -ENOMEM; + + for (i = 0; i < config->num_channels; i++) { + struct mhi_ep_chan *mhi_chan; + + ch_cfg = &config->ch_cfg[i]; + + chan = ch_cfg->num; + if (chan >= mhi_cntrl->max_chan) { + dev_err(dev, "Channel %d not available\n", chan); + goto error_chan_cfg; + } + + /* Bi-directional and direction less channels are not supported */ + if (ch_cfg->dir == DMA_BIDIRECTIONAL || ch_cfg->dir == DMA_NONE) { + dev_err(dev, "Invalid channel configuration\n"); + goto error_chan_cfg; + } + + mhi_chan = &mhi_cntrl->mhi_chan[chan]; + mhi_chan->name = ch_cfg->name; + mhi_chan->chan = chan; + mhi_chan->dir = ch_cfg->dir; + mutex_init(&mhi_chan->lock); + } + + return 0; + +error_chan_cfg: + kfree(mhi_cntrl->mhi_chan); + + return ret; +} + +/* + * Allocate channel and command rings here. Event rings will be allocated + * in mhi_ep_power_up() as the config comes from the host. + */ +int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, + const struct mhi_ep_cntrl_config *config) +{ + struct mhi_ep_device *mhi_dev; + int ret; + + if (!mhi_cntrl || !mhi_cntrl->cntrl_dev) + return -EINVAL; + + ret = parse_ch_cfg(mhi_cntrl, config); + if (ret) + return ret; + + mhi_cntrl->mhi_cmd = kcalloc(NR_OF_CMD_RINGS, sizeof(*mhi_cntrl->mhi_cmd), GFP_KERNEL); + if (!mhi_cntrl->mhi_cmd) { + ret = -ENOMEM; + goto err_free_ch; + } + + /* Set controller index */ + mhi_cntrl->index = ida_alloc(&mhi_ep_cntrl_ida, GFP_KERNEL); + if (mhi_cntrl->index < 0) { + ret = mhi_cntrl->index; + goto err_free_cmd; + } + + /* Allocate the controller device */ + mhi_dev = mhi_ep_alloc_device(mhi_cntrl, MHI_DEVICE_CONTROLLER); + if (IS_ERR(mhi_dev)) { + dev_err(mhi_cntrl->cntrl_dev, "Failed to allocate controller device\n"); + ret = PTR_ERR(mhi_dev); + goto err_ida_free; + } + + dev_set_name(&mhi_dev->dev, "mhi_ep%d", mhi_cntrl->index); + mhi_dev->name = dev_name(&mhi_dev->dev); + + ret = device_add(&mhi_dev->dev); + if (ret) + goto err_put_dev; + + mhi_cntrl->mhi_dev = mhi_dev; + + dev_dbg(&mhi_dev->dev, "MHI EP Controller registered\n"); + + return 0; + +err_put_dev: + put_device(&mhi_dev->dev); +err_ida_free: + ida_free(&mhi_ep_cntrl_ida, mhi_cntrl->index); +err_free_cmd: + kfree(mhi_cntrl->mhi_cmd); +err_free_ch: + kfree(mhi_cntrl->mhi_chan); + + return ret; +} +EXPORT_SYMBOL_GPL(mhi_ep_register_controller); + +void mhi_ep_unregister_controller(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct mhi_ep_device *mhi_dev = mhi_cntrl->mhi_dev; + + kfree(mhi_cntrl->mhi_cmd); + kfree(mhi_cntrl->mhi_chan); + + device_del(&mhi_dev->dev); + put_device(&mhi_dev->dev); + + ida_free(&mhi_ep_cntrl_ida, mhi_cntrl->index); +} +EXPORT_SYMBOL_GPL(mhi_ep_unregister_controller); + +static int mhi_ep_match(struct device *dev, struct device_driver *drv) +{ + struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev); + + /* + * If the device is a controller type then there is no client driver + * associated with it + */ + if (mhi_dev->dev_type == MHI_DEVICE_CONTROLLER) + return 0; + + return 0; +}; + +struct bus_type mhi_ep_bus_type = { + .name = "mhi_ep", + .dev_name = "mhi_ep", + .match = mhi_ep_match, +}; + +static int __init mhi_ep_init(void) +{ + return bus_register(&mhi_ep_bus_type); +} + +static void __exit mhi_ep_exit(void) +{ + bus_unregister(&mhi_ep_bus_type); +} + +postcore_initcall(mhi_ep_init); +module_exit(mhi_ep_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("MHI Bus Endpoint stack"); +MODULE_AUTHOR("Manivannan Sadhasivam "); diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h new file mode 100644 index 000000000000..20238e9df1b3 --- /dev/null +++ b/include/linux/mhi_ep.h @@ -0,0 +1,143 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2021, Linaro Ltd. + * + */ +#ifndef _MHI_EP_H_ +#define _MHI_EP_H_ + +#include +#include + +#define MHI_EP_DEFAULT_MTU 0x8000 + +/** + * struct mhi_ep_channel_config - Channel configuration structure for controller + * @name: The name of this channel + * @num: The number assigned to this channel + * @num_elements: The number of elements that can be queued to this channel + * @dir: Direction that data may flow on this channel + */ +struct mhi_ep_channel_config { + char *name; + u32 num; + u32 num_elements; + enum dma_data_direction dir; +}; + +/** + * struct mhi_ep_cntrl_config - MHI Endpoint controller configuration + * @max_channels: Maximum number of channels supported + * @num_channels: Number of channels defined in @ch_cfg + * @ch_cfg: Array of defined channels + * @mhi_version: MHI spec version supported by the controller + */ +struct mhi_ep_cntrl_config { + u32 max_channels; + u32 num_channels; + const struct mhi_ep_channel_config *ch_cfg; + u32 mhi_version; +}; + +/** + * struct mhi_ep_db_info - MHI Endpoint doorbell info + * @mask: Mask of the doorbell interrupt + * @status: Status of the doorbell interrupt + */ +struct mhi_ep_db_info { + u32 mask; + u32 status; +}; + +/** + * struct mhi_ep_cntrl - MHI Endpoint controller structure + * @cntrl_dev: Pointer to the struct device of physical bus acting as the MHI + * Endpoint controller + * @mhi_dev: MHI Endpoint device instance for the controller + * @mmio: MMIO region containing the MHI registers + * @mhi_chan: Points to the channel configuration table + * @mhi_event: Points to the event ring configurations table + * @mhi_cmd: Points to the command ring configurations table + * @sm: MHI Endpoint state machine + * @raise_irq: CB function for raising IRQ to the host + * @alloc_addr: CB function for allocating memory in endpoint for storing host context + * @map_addr: CB function for mapping host context to endpoint + * @free_addr: CB function to free the allocated memory in endpoint for storing host context + * @unmap_addr: CB function to unmap the host context in endpoint + * @read_from_host: CB function for reading from host memory from endpoint + * @write_to_host: CB function for writing to host memory from endpoint + * @mhi_state: MHI Endpoint state + * @max_chan: Maximum channels supported by the endpoint controller + * @mru: MRU (Maximum Receive Unit) value of the endpoint controller + * @index: MHI Endpoint controller index + */ +struct mhi_ep_cntrl { + struct device *cntrl_dev; + struct mhi_ep_device *mhi_dev; + void __iomem *mmio; + + struct mhi_ep_chan *mhi_chan; + struct mhi_ep_event *mhi_event; + struct mhi_ep_cmd *mhi_cmd; + struct mhi_ep_sm *sm; + + void (*raise_irq)(struct mhi_ep_cntrl *mhi_cntrl, u32 vector); + void __iomem *(*alloc_addr)(struct mhi_ep_cntrl *mhi_cntrl, phys_addr_t *phys_addr, + size_t size); + int (*map_addr)(struct mhi_ep_cntrl *mhi_cntrl, phys_addr_t phys_addr, u64 pci_addr, + size_t size); + void (*free_addr)(struct mhi_ep_cntrl *mhi_cntrl, phys_addr_t phys_addr, + void __iomem *virt_addr, size_t size); + void (*unmap_addr)(struct mhi_ep_cntrl *mhi_cntrl, phys_addr_t phys_addr); + int (*read_from_host)(struct mhi_ep_cntrl *mhi_cntrl, u64 from, void __iomem *to, + size_t size); + int (*write_to_host)(struct mhi_ep_cntrl *mhi_cntrl, void __iomem *from, u64 to, + size_t size); + + enum mhi_state mhi_state; + + u32 max_chan; + u32 mru; + int index; +}; + +/** + * struct mhi_ep_device - Structure representing an MHI Endpoint device that binds + * to channels or is associated with controllers + * @dev: Driver model device node for the MHI Endpoint device + * @mhi_cntrl: Controller the device belongs to + * @id: Pointer to MHI Endpoint device ID struct + * @name: Name of the associated MHI Endpoint device + * @ul_chan: UL channel for the device + * @dl_chan: DL channel for the device + * @dev_type: MHI device type + */ +struct mhi_ep_device { + struct device dev; + struct mhi_ep_cntrl *mhi_cntrl; + const struct mhi_device_id *id; + const char *name; + struct mhi_ep_chan *ul_chan; + struct mhi_ep_chan *dl_chan; + enum mhi_device_type dev_type; +}; + +#define to_mhi_ep_device(dev) container_of(dev, struct mhi_ep_device, dev) + +/** + * mhi_ep_register_controller - Register MHI Endpoint controller + * @mhi_cntrl: MHI Endpoint controller to register + * @config: Configuration to use for the controller + * + * Return: 0 if controller registrations succeeds, a negative error code otherwise. + */ +int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, + const struct mhi_ep_cntrl_config *config); + +/** + * mhi_ep_unregister_controller - Unregister MHI Endpoint controller + * @mhi_cntrl: MHI Endpoint controller to unregister + */ +void mhi_ep_unregister_controller(struct mhi_ep_cntrl *mhi_cntrl); + +#endif From patchwork Sat Feb 12 18:21:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 542591 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7374FC4332F for ; Sat, 12 Feb 2022 18:22:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229708AbiBLSWj (ORCPT ); Sat, 12 Feb 2022 13:22:39 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:45774 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229800AbiBLSWg (ORCPT ); Sat, 12 Feb 2022 13:22:36 -0500 Received: from mail-pl1-x631.google.com (mail-pl1-x631.google.com [IPv6:2607:f8b0:4864:20::631]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 498A0606C8 for ; Sat, 12 Feb 2022 10:22:28 -0800 (PST) Received: by mail-pl1-x631.google.com with SMTP id u12so7230245plf.13 for ; Sat, 12 Feb 2022 10:22:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=g49+wFi0+L2EFX9slEZO36BXMBmO9BAHKtkIF7AjIc4=; b=Qaj0Oks+qpWWnbjrfPIrbHozo3YeLmLdIG/TvZbU5V6dTbOje+t2Np1msaSIll/jGZ fRn3bd46oK30vNMMF+3mmzFg9Mi6CgjKNyQIyKYruUjJXJdl/qLwxHdxZli4GArgp/O/ eYLnTc4kBSIGs6PxY6IMH5VXSV+6AAXKTnzF/pid6ZTfk+lVeYCgv77UFucBnnLgoXrb 8e1hGrMPM81vZ5MBQGXLPn3ql+ub/Y9HZiUN4Um7iWlpphmp4yjmGEu4kuGj1VT1WhPq AjnRbF1rJgyhuN+n7ibTQZ3AGqW62jAQ988nKYUuMpm2yHII2SkntIPjZ4S23eazPB+0 HoJA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=g49+wFi0+L2EFX9slEZO36BXMBmO9BAHKtkIF7AjIc4=; b=WqX2uBqOl6ZX2aLQ4pK0U3n6rohzkVizemxkqC2l5Mrh561NeikkJ0Pqq678H+mQB+ mHKjsqVdsyiUQ8Jj36NqI41OC+EESjDBYJwWnBgtOi9mrwmtthIUp582awIU8YiNoCwk OW1h4i0oOyP4hWl5CTQK5etp5qJhUiwoLWrc0PI3MvMbEri0Rz7GCSASdHAWN0Bu7tYy ymqlo/xoUHUpJiu1mPx0WU/15hwpVlqGqISIgrqv5c+aBYHnkdPSxMkg3ndB/oacnk7o U3BLOJV97wruXDxPRb9mQ8UO+uYJarHX/5z6/F7A2bKuHtGnUc1IQJSOuB07eztoTLfr 76VQ== X-Gm-Message-State: AOAM530EO3JuARq/NGrT5LcYpzgzLy0RZctaLwV9pyox0GcIiz/EuppR cjwyOrkIRamWDZk87NxZKQcd X-Google-Smtp-Source: ABdhPJwcmUlXO8ifxo1TZGZofZ1qRsSxT5ttiDr7LbbIKnn76r/wYRjgD2Q7FbM7DaU+VwrkvIGPWg== X-Received: by 2002:a17:902:d486:: with SMTP id c6mr6965799plg.141.1644690147753; Sat, 12 Feb 2022 10:22:27 -0800 (PST) Received: from localhost.localdomain ([27.111.75.57]) by smtp.gmail.com with ESMTPSA id g12sm14961987pfj.148.2022.02.12.10.22.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Feb 2022 10:22:27 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v3 09/25] bus: mhi: ep: Add support for registering MHI endpoint client drivers Date: Sat, 12 Feb 2022 23:51:01 +0530 Message-Id: <20220212182117.49438-10-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> References: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org This commit adds support for registering MHI endpoint client drivers with the MHI endpoint stack. MHI endpoint client drivers binds to one or more MHI endpoint devices inorder to send and receive the upper-layer protocol packets like IP packets, modem control messages, and diagnostics messages over MHI bus. Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/ep/main.c | 86 +++++++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 53 ++++++++++++++++++++++++ 2 files changed, 139 insertions(+) diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index b006011d025d..f66404181972 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -196,9 +196,89 @@ void mhi_ep_unregister_controller(struct mhi_ep_cntrl *mhi_cntrl) } EXPORT_SYMBOL_GPL(mhi_ep_unregister_controller); +static int mhi_ep_driver_probe(struct device *dev) +{ + struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev); + struct mhi_ep_driver *mhi_drv = to_mhi_ep_driver(dev->driver); + struct mhi_ep_chan *ul_chan = mhi_dev->ul_chan; + struct mhi_ep_chan *dl_chan = mhi_dev->dl_chan; + + /* Client drivers should have callbacks for both channels */ + if (!mhi_drv->ul_xfer_cb || !mhi_drv->dl_xfer_cb) + return -EINVAL; + + ul_chan->xfer_cb = mhi_drv->ul_xfer_cb; + dl_chan->xfer_cb = mhi_drv->dl_xfer_cb; + + return mhi_drv->probe(mhi_dev, mhi_dev->id); +} + +static int mhi_ep_driver_remove(struct device *dev) +{ + struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev); + struct mhi_ep_driver *mhi_drv = to_mhi_ep_driver(dev->driver); + struct mhi_result result = {}; + struct mhi_ep_chan *mhi_chan; + int dir; + + /* Skip if it is a controller device */ + if (mhi_dev->dev_type == MHI_DEVICE_CONTROLLER) + return 0; + + /* Disconnect the channels associated with the driver */ + for (dir = 0; dir < 2; dir++) { + mhi_chan = dir ? mhi_dev->ul_chan : mhi_dev->dl_chan; + + if (!mhi_chan) + continue; + + mutex_lock(&mhi_chan->lock); + /* Send channel disconnect status to the client driver */ + if (mhi_chan->xfer_cb) { + result.transaction_status = -ENOTCONN; + result.bytes_xferd = 0; + mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); + } + + /* Set channel state to DISABLED */ + mhi_chan->state = MHI_CH_STATE_DISABLED; + mhi_chan->xfer_cb = NULL; + mutex_unlock(&mhi_chan->lock); + } + + /* Remove the client driver now */ + mhi_drv->remove(mhi_dev); + + return 0; +} + +int __mhi_ep_driver_register(struct mhi_ep_driver *mhi_drv, struct module *owner) +{ + struct device_driver *driver = &mhi_drv->driver; + + if (!mhi_drv->probe || !mhi_drv->remove) + return -EINVAL; + + driver->bus = &mhi_ep_bus_type; + driver->owner = owner; + driver->probe = mhi_ep_driver_probe; + driver->remove = mhi_ep_driver_remove; + + return driver_register(driver); +} +EXPORT_SYMBOL_GPL(__mhi_ep_driver_register); + +void mhi_ep_driver_unregister(struct mhi_ep_driver *mhi_drv) +{ + driver_unregister(&mhi_drv->driver); +} +EXPORT_SYMBOL_GPL(mhi_ep_driver_unregister); + static int mhi_ep_match(struct device *dev, struct device_driver *drv) { struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev); + struct mhi_ep_driver *mhi_drv = to_mhi_ep_driver(drv); + const struct mhi_device_id *id; /* * If the device is a controller type then there is no client driver @@ -207,6 +287,12 @@ static int mhi_ep_match(struct device *dev, struct device_driver *drv) if (mhi_dev->dev_type == MHI_DEVICE_CONTROLLER) return 0; + for (id = mhi_drv->id_table; id->chan[0]; id++) + if (!strcmp(mhi_dev->name, id->chan)) { + mhi_dev->id = id; + return 1; + } + return 0; }; diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 20238e9df1b3..da865f9d3646 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -122,7 +122,60 @@ struct mhi_ep_device { enum mhi_device_type dev_type; }; +/** + * struct mhi_ep_driver - Structure representing a MHI Endpoint client driver + * @id_table: Pointer to MHI Endpoint device ID table + * @driver: Device driver model driver + * @probe: CB function for client driver probe function + * @remove: CB function for client driver remove function + * @ul_xfer_cb: CB function for UL data transfer + * @dl_xfer_cb: CB function for DL data transfer + */ +struct mhi_ep_driver { + const struct mhi_device_id *id_table; + struct device_driver driver; + int (*probe)(struct mhi_ep_device *mhi_ep, + const struct mhi_device_id *id); + void (*remove)(struct mhi_ep_device *mhi_ep); + void (*ul_xfer_cb)(struct mhi_ep_device *mhi_dev, + struct mhi_result *result); + void (*dl_xfer_cb)(struct mhi_ep_device *mhi_dev, + struct mhi_result *result); +}; + #define to_mhi_ep_device(dev) container_of(dev, struct mhi_ep_device, dev) +#define to_mhi_ep_driver(drv) container_of(drv, struct mhi_ep_driver, driver) + +/* + * module_mhi_ep_driver() - Helper macro for drivers that don't do + * anything special other than using default mhi_ep_driver_register() and + * mhi_ep_driver_unregister(). This eliminates a lot of boilerplate. + * Each module may only use this macro once. + */ +#define module_mhi_ep_driver(mhi_drv) \ + module_driver(mhi_drv, mhi_ep_driver_register, \ + mhi_ep_driver_unregister) + +/* + * Macro to avoid include chaining to get THIS_MODULE + */ +#define mhi_ep_driver_register(mhi_drv) \ + __mhi_ep_driver_register(mhi_drv, THIS_MODULE) + +/** + * __mhi_ep_driver_register - Register a driver with MHI Endpoint bus + * @mhi_drv: Driver to be associated with the device + * @owner: The module owner + * + * Return: 0 if driver registrations succeeds, a negative error code otherwise. + */ +int __mhi_ep_driver_register(struct mhi_ep_driver *mhi_drv, struct module *owner); + +/** + * mhi_ep_driver_unregister - Unregister a driver from MHI Endpoint bus + * @mhi_drv: Driver associated with the device + */ +void mhi_ep_driver_unregister(struct mhi_ep_driver *mhi_drv); /** * mhi_ep_register_controller - Register MHI Endpoint controller From patchwork Sat Feb 12 18:21:02 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 542174 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C0661C433EF for ; Sat, 12 Feb 2022 18:22:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229699AbiBLSWj (ORCPT ); Sat, 12 Feb 2022 13:22:39 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:46168 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229765AbiBLSWi (ORCPT ); Sat, 12 Feb 2022 13:22:38 -0500 Received: from mail-pf1-x435.google.com (mail-pf1-x435.google.com [IPv6:2607:f8b0:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 600275FF0D for ; Sat, 12 Feb 2022 10:22:33 -0800 (PST) Received: by mail-pf1-x435.google.com with SMTP id e17so2445244pfv.5 for ; Sat, 12 Feb 2022 10:22:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=dRyVbSQXppN/OUuF4/pZFzmZtZ5UsMfwyjfSr89DRIw=; b=y0/VsjANcaLH2vRblATIxK3xx4jk4uiGpLeyo6hO672fh0QEeXI08eUWqVw232OvCW xOIyO4AhXpI3LL6nxCd8BmoFThKPLWU4skh9MF1zHMKRAUJSs9ujn/ZNQ4Z3wfpdrNZb kIs37yfnIntz2BU9NfUYtFbsxLiPAUNvchXn37NFg1nF3qINiukzPz/Vk8rMXlxSl67Q 38m6theu77LbsBfaQovsETvlxyoUKsel4WgVZHO7gwNCQw83BM0yrIRYZ5tfNUkG5idf Ebt3KbC/QO4xrpBKPtyprXbH1amIboXJfuVKDbolURzZxT9rR+0vXzouPOHIfFmexzP2 bHkA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=dRyVbSQXppN/OUuF4/pZFzmZtZ5UsMfwyjfSr89DRIw=; b=JkVqVxZH9aTBXunUo+rEJgA3LzE1SrZ7dY40KxdYH5vLjxWQNofbHlW1zAPtqX3PfE Igbh5x4dP+U9pYGoy3K8uq8Nb80uIgj7s7N778Cgyksho8BoqGr/g6BLFFxuyun3i6Sw EMMLHdvF71dggsgrTCMR+tPdH8ooNIvOm8km1IHLrOZfzNozem1l0bSh6993qGOWoIS3 u2GJZQVDQpJrh05eLN4P02zi7m07OXlkSEQgTymUwIofkEgyj53hSOypcJlgAOv7/IzS ctZqIVEkBD32cy9X52XhhiGFECRb7dunr0esG5uE3tJrreZe3ZIss46SUMyVf510VUUs zurw== X-Gm-Message-State: AOAM53191IpecLnP2N8wNp9vDkciKHdjZIlh7kPwRmxqSWy7HzUN2VUh BuYoQHLffFwElOA7TrS9mXyl X-Google-Smtp-Source: ABdhPJxubjawu1rUQHWDhi1P1ZgIgZ89wp/2lwaVUSDQqFAkJ4M4AnqMt65H7xfVqgts9O46SjG95w== X-Received: by 2002:a63:555b:: with SMTP id f27mr5780074pgm.468.1644690152896; Sat, 12 Feb 2022 10:22:32 -0800 (PST) Received: from localhost.localdomain ([27.111.75.57]) by smtp.gmail.com with ESMTPSA id g12sm14961987pfj.148.2022.02.12.10.22.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Feb 2022 10:22:32 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v3 10/25] bus: mhi: ep: Add support for creating and destroying MHI EP devices Date: Sat, 12 Feb 2022 23:51:02 +0530 Message-Id: <20220212182117.49438-11-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> References: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org This commit adds support for creating and destroying MHI endpoint devices. The MHI endpoint devices binds to the MHI endpoint channels and are used to transfer data between MHI host and endpoint device. There is a single MHI EP device for each channel pair. The devices will be created when the corresponding channels has been started by the host and will be destroyed during MHI EP power down and reset. Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/ep/main.c | 77 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index f66404181972..fcaacf9ddbd1 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -67,6 +67,83 @@ static struct mhi_ep_device *mhi_ep_alloc_device(struct mhi_ep_cntrl *mhi_cntrl, return mhi_dev; } +/* + * MHI channels are always defined in pairs with UL as the even numbered + * channel and DL as odd numbered one. + */ +static int mhi_ep_create_device(struct mhi_ep_cntrl *mhi_cntrl, u32 ch_id) +{ + struct mhi_ep_chan *mhi_chan = &mhi_cntrl->mhi_chan[ch_id]; + struct mhi_ep_device *mhi_dev; + int ret; + + /* Check if the channel name is same for both UL and DL */ + if (strcmp(mhi_chan->name, mhi_chan[1].name)) + return -EINVAL; + + mhi_dev = mhi_ep_alloc_device(mhi_cntrl, MHI_DEVICE_XFER); + if (IS_ERR(mhi_dev)) + return PTR_ERR(mhi_dev); + + /* Configure primary channel */ + mhi_dev->ul_chan = mhi_chan; + get_device(&mhi_dev->dev); + mhi_chan->mhi_dev = mhi_dev; + + /* Configure secondary channel as well */ + mhi_chan++; + mhi_dev->dl_chan = mhi_chan; + get_device(&mhi_dev->dev); + mhi_chan->mhi_dev = mhi_dev; + + /* Channel name is same for both UL and DL */ + mhi_dev->name = mhi_chan->name; + dev_set_name(&mhi_dev->dev, "%s_%s", + dev_name(&mhi_cntrl->mhi_dev->dev), + mhi_dev->name); + + ret = device_add(&mhi_dev->dev); + if (ret) + put_device(&mhi_dev->dev); + + return ret; +} + +static int mhi_ep_destroy_device(struct device *dev, void *data) +{ + struct mhi_ep_device *mhi_dev; + struct mhi_ep_cntrl *mhi_cntrl; + struct mhi_ep_chan *ul_chan, *dl_chan; + + if (dev->bus != &mhi_ep_bus_type) + return 0; + + mhi_dev = to_mhi_ep_device(dev); + mhi_cntrl = mhi_dev->mhi_cntrl; + + /* Only destroy devices created for channels */ + if (mhi_dev->dev_type == MHI_DEVICE_CONTROLLER) + return 0; + + ul_chan = mhi_dev->ul_chan; + dl_chan = mhi_dev->dl_chan; + + if (ul_chan) + put_device(&ul_chan->mhi_dev->dev); + + if (dl_chan) + put_device(&dl_chan->mhi_dev->dev); + + dev_dbg(&mhi_cntrl->mhi_dev->dev, "Destroying device for chan:%s\n", + mhi_dev->name); + + /* Notify the client and remove the device from MHI bus */ + device_del(dev); + put_device(dev); + + return 0; +} + static int parse_ch_cfg(struct mhi_ep_cntrl *mhi_cntrl, const struct mhi_ep_cntrl_config *config) { From patchwork Sat Feb 12 18:21:03 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 542173 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2DF82C433F5 for ; Sat, 12 Feb 2022 18:22:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229735AbiBLSWr (ORCPT ); Sat, 12 Feb 2022 13:22:47 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:46438 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229817AbiBLSWp (ORCPT ); Sat, 12 Feb 2022 13:22:45 -0500 Received: from mail-pj1-x1034.google.com (mail-pj1-x1034.google.com [IPv6:2607:f8b0:4864:20::1034]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 373925FF35 for ; Sat, 12 Feb 2022 10:22:37 -0800 (PST) Received: by mail-pj1-x1034.google.com with SMTP id t14-20020a17090a3e4e00b001b8f6032d96so11845256pjm.2 for ; Sat, 12 Feb 2022 10:22:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=nX8pUBwKky2LdiFf9TxlzbYf+tv5DdGbcpHlM/nAQUg=; b=it0CBKz3c7dJqQf2nVMGHjZH5xYvHc4sqnB+4rLvJLH5/u/ltaTjqV2XFDXLAyuh7S SWd7C8909p8YcgnYpTU+HpPJLMEbIJabinW5b3Z7MbOuj4k6rFRSe4QaO0FYUyKC1Rx2 QEnTeikKU1uDWlKS8phuZK4Bf722w5mUp7BJpAGbx5PPFH66EesmpPHxGWyjnoVnNTb3 RnJcyR4dRyspsjsglTXSuxje190DUfBL3ZfHEed5LNQhpritTIP9I7bcavvgNNb4TTp0 vEL6ujNIN05+hP8rkJJTzaamWnV0YqGIP5CN3iV8SB8lnP2VmKPHm2NnV7aaNjUct+t1 QX+w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=nX8pUBwKky2LdiFf9TxlzbYf+tv5DdGbcpHlM/nAQUg=; b=K5+aS+52wwUc5DQ/+CnIVOQrd+03YOZsAL2cL59luIc+omQ31dCqFtBy4KzObT6Y9w 3qUKI8SigDpX4jqkCZLVm3Zv/oYmnO11Nr4ZNxnb9aPkQQd73hofkvcx/3eaRPEyiPBw zNc+UOEAmiU1/nsKaGC4ljlQiJaai4dadgioXzXT9DB6dnnqtY0AVmtyi/pLUS87NeJC z+mARBBRfV7NHOiPBSxD/uy3Q7ovg7HfDTJpli3+yIl0YPQrq/vwxdHuJGU3RMdb1aEl wMvVKok6sGQ+Ny0095E7fWxIC3noZSWtqvVszC3/9saY5wCzfnzH6xLVgq29ZzfYtWAz ej0g== X-Gm-Message-State: AOAM530UE9SaWSkiYvYS9LRaRGuapfExWftum910r39AgtSxVIYCKJtc UJ1kpww/dahCJNKXRVNjxGY/ X-Google-Smtp-Source: ABdhPJyR0fVwxQfwWTuBT4QJjgZVgtj9CxeGwWUq5Tw1ivSsdSY1Fo/pOyo8iQrD4pi/3VEHFbx+MA== X-Received: by 2002:a17:902:c3d5:: with SMTP id j21mr6886426plj.59.1644690157332; Sat, 12 Feb 2022 10:22:37 -0800 (PST) Received: from localhost.localdomain ([27.111.75.57]) by smtp.gmail.com with ESMTPSA id g12sm14961987pfj.148.2022.02.12.10.22.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Feb 2022 10:22:36 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v3 11/25] bus: mhi: ep: Add support for managing MMIO registers Date: Sat, 12 Feb 2022 23:51:03 +0530 Message-Id: <20220212182117.49438-12-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> References: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Add support for managing the Memory Mapped Input Output (MMIO) registers of the MHI bus. All MHI operations are carried out using the MMIO registers by both host and the endpoint device. The MMIO registers reside inside the endpoint device memory (fixed location based on the platform) and the address is passed by the MHI EP controller driver during its registration. Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/ep/Makefile | 2 +- drivers/bus/mhi/ep/internal.h | 37 +++++ drivers/bus/mhi/ep/main.c | 6 +- drivers/bus/mhi/ep/mmio.c | 274 ++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 18 +++ 5 files changed, 335 insertions(+), 2 deletions(-) create mode 100644 drivers/bus/mhi/ep/mmio.c diff --git a/drivers/bus/mhi/ep/Makefile b/drivers/bus/mhi/ep/Makefile index 64e29252b608..a1555ae287ad 100644 --- a/drivers/bus/mhi/ep/Makefile +++ b/drivers/bus/mhi/ep/Makefile @@ -1,2 +1,2 @@ obj-$(CONFIG_MHI_BUS_EP) += mhi_ep.o -mhi_ep-y := main.o +mhi_ep-y := main.o mmio.o diff --git a/drivers/bus/mhi/ep/internal.h b/drivers/bus/mhi/ep/internal.h index e313a2546664..2c756a90774c 100644 --- a/drivers/bus/mhi/ep/internal.h +++ b/drivers/bus/mhi/ep/internal.h @@ -101,6 +101,17 @@ struct mhi_generic_ctx { __u64 wp __packed __aligned(4); }; +/** + * enum mhi_ep_execenv - MHI Endpoint Execution Environment + * @MHI_EP_SBL_EE: Secondary Bootloader + * @MHI_EP_AMSS_EE: Advanced Mode Subscriber Software + */ +enum mhi_ep_execenv { + MHI_EP_SBL_EE = 1, + MHI_EP_AMSS_EE = 2, + MHI_EP_UNRESERVED +}; + enum mhi_ep_ring_type { RING_TYPE_CMD = 0, RING_TYPE_ER, @@ -157,4 +168,30 @@ struct mhi_ep_chan { bool skip_td; }; +/* MMIO related functions */ +u32 mhi_ep_mmio_read(struct mhi_ep_cntrl *mhi_cntrl, u32 offset); +void mhi_ep_mmio_write(struct mhi_ep_cntrl *mhi_cntrl, u32 offset, u32 val); +void mhi_ep_mmio_masked_write(struct mhi_ep_cntrl *mhi_cntrl, u32 offset, u32 mask, u32 val); +u32 mhi_ep_mmio_masked_read(struct mhi_ep_cntrl *dev, u32 offset, u32 mask); +void mhi_ep_mmio_enable_ctrl_interrupt(struct mhi_ep_cntrl *mhi_cntrl); +void mhi_ep_mmio_disable_ctrl_interrupt(struct mhi_ep_cntrl *mhi_cntrl); +void mhi_ep_mmio_enable_cmdb_interrupt(struct mhi_ep_cntrl *mhi_cntrl); +void mhi_ep_mmio_disable_cmdb_interrupt(struct mhi_ep_cntrl *mhi_cntrl); +void mhi_ep_mmio_enable_chdb_a7(struct mhi_ep_cntrl *mhi_cntrl, u32 chdb_id); +void mhi_ep_mmio_disable_chdb_a7(struct mhi_ep_cntrl *mhi_cntrl, u32 chdb_id); +void mhi_ep_mmio_enable_chdb_interrupts(struct mhi_ep_cntrl *mhi_cntrl); +void mhi_ep_mmio_read_chdb_status_interrupts(struct mhi_ep_cntrl *mhi_cntrl); +void mhi_ep_mmio_mask_interrupts(struct mhi_ep_cntrl *mhi_cntrl); +void mhi_ep_mmio_get_chc_base(struct mhi_ep_cntrl *mhi_cntrl); +void mhi_ep_mmio_get_erc_base(struct mhi_ep_cntrl *mhi_cntrl); +void mhi_ep_mmio_get_crc_base(struct mhi_ep_cntrl *mhi_cntrl); +u64 mhi_ep_mmio_get_db(struct mhi_ep_ring *ring); +void mhi_ep_mmio_set_env(struct mhi_ep_cntrl *mhi_cntrl, u32 value); +void mhi_ep_mmio_clear_reset(struct mhi_ep_cntrl *mhi_cntrl); +void mhi_ep_mmio_reset(struct mhi_ep_cntrl *mhi_cntrl); +void mhi_ep_mmio_get_mhi_state(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state *state, + bool *mhi_reset); +void mhi_ep_mmio_init(struct mhi_ep_cntrl *mhi_cntrl); +void mhi_ep_mmio_update_ner(struct mhi_ep_cntrl *mhi_cntrl); + #endif diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index fcaacf9ddbd1..950b5bcabe18 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -205,7 +205,7 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_device *mhi_dev; int ret; - if (!mhi_cntrl || !mhi_cntrl->cntrl_dev) + if (!mhi_cntrl || !mhi_cntrl->cntrl_dev || !mhi_cntrl->mmio) return -EINVAL; ret = parse_ch_cfg(mhi_cntrl, config); @@ -218,6 +218,10 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, goto err_free_ch; } + /* Set MHI version and AMSS EE before enumeration */ + mhi_ep_mmio_write(mhi_cntrl, MHIVER, config->mhi_version); + mhi_ep_mmio_set_env(mhi_cntrl, MHI_EP_AMSS_EE); + /* Set controller index */ mhi_cntrl->index = ida_alloc(&mhi_ep_cntrl_ida, GFP_KERNEL); if (mhi_cntrl->index < 0) { diff --git a/drivers/bus/mhi/ep/mmio.c b/drivers/bus/mhi/ep/mmio.c new file mode 100644 index 000000000000..58e887beb050 --- /dev/null +++ b/drivers/bus/mhi/ep/mmio.c @@ -0,0 +1,274 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2021 Linaro Ltd. + * Author: Manivannan Sadhasivam + */ + +#include +#include +#include + +#include "internal.h" + +u32 mhi_ep_mmio_read(struct mhi_ep_cntrl *mhi_cntrl, u32 offset) +{ + return readl(mhi_cntrl->mmio + offset); +} + +void mhi_ep_mmio_write(struct mhi_ep_cntrl *mhi_cntrl, u32 offset, u32 val) +{ + writel(val, mhi_cntrl->mmio + offset); +} + +void mhi_ep_mmio_masked_write(struct mhi_ep_cntrl *mhi_cntrl, u32 offset, u32 mask, u32 val) +{ + u32 regval; + + regval = mhi_ep_mmio_read(mhi_cntrl, offset); + regval &= ~mask; + regval |= ((val << __ffs(mask)) & mask); + mhi_ep_mmio_write(mhi_cntrl, offset, regval); +} + +u32 mhi_ep_mmio_masked_read(struct mhi_ep_cntrl *dev, u32 offset, u32 mask) +{ + u32 regval; + + regval = mhi_ep_mmio_read(dev, offset); + regval &= mask; + regval >>= __ffs(mask); + + return regval; +} + +void mhi_ep_mmio_get_mhi_state(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state *state, + bool *mhi_reset) +{ + u32 regval; + + regval = mhi_ep_mmio_read(mhi_cntrl, MHICTRL); + *state = FIELD_GET(MHICTRL_MHISTATE_MASK, regval); + *mhi_reset = !!FIELD_GET(MHICTRL_RESET_MASK, regval); +} + +static void mhi_ep_mmio_mask_set_chdb_int_a7(struct mhi_ep_cntrl *mhi_cntrl, + u32 chdb_id, bool enable) +{ + u32 chid_mask, chid_idx, chid_shift, val = 0; + + chid_shift = chdb_id % 32; + chid_mask = BIT(chid_shift); + chid_idx = chdb_id / 32; + + WARN_ON(chid_idx >= MHI_MASK_ROWS_CH_EV_DB); + + if (enable) + val = 1; + + mhi_ep_mmio_masked_write(mhi_cntrl, MHI_CHDB_INT_MASK_A7_n(chid_idx), + chid_mask, val); + + /* Update the local copy of the channel mask */ + mhi_cntrl->chdb[chid_idx].mask &= ~chid_mask; + mhi_cntrl->chdb[chid_idx].mask |= val << chid_shift; +} + +void mhi_ep_mmio_enable_chdb_a7(struct mhi_ep_cntrl *mhi_cntrl, u32 chdb_id) +{ + mhi_ep_mmio_mask_set_chdb_int_a7(mhi_cntrl, chdb_id, true); +} + +void mhi_ep_mmio_disable_chdb_a7(struct mhi_ep_cntrl *mhi_cntrl, u32 chdb_id) +{ + mhi_ep_mmio_mask_set_chdb_int_a7(mhi_cntrl, chdb_id, false); +} + +static void mhi_ep_mmio_set_chdb_interrupts(struct mhi_ep_cntrl *mhi_cntrl, bool enable) +{ + u32 val = 0, i; + + if (enable) + val = MHI_CHDB_INT_MASK_A7_n_EN_ALL; + + for (i = 0; i < MHI_MASK_ROWS_CH_EV_DB; i++) { + mhi_ep_mmio_write(mhi_cntrl, MHI_CHDB_INT_MASK_A7_n(i), val); + mhi_cntrl->chdb[i].mask = val; + } +} + +void mhi_ep_mmio_enable_chdb_interrupts(struct mhi_ep_cntrl *mhi_cntrl) +{ + mhi_ep_mmio_set_chdb_interrupts(mhi_cntrl, true); +} + +static void mhi_ep_mmio_mask_chdb_interrupts(struct mhi_ep_cntrl *mhi_cntrl) +{ + mhi_ep_mmio_set_chdb_interrupts(mhi_cntrl, false); +} + +void mhi_ep_mmio_read_chdb_status_interrupts(struct mhi_ep_cntrl *mhi_cntrl) +{ + u32 i; + + for (i = 0; i < MHI_MASK_ROWS_CH_EV_DB; i++) + mhi_cntrl->chdb[i].status = mhi_ep_mmio_read(mhi_cntrl, + MHI_CHDB_INT_STATUS_A7_n(i)); +} + +static void mhi_ep_mmio_set_erdb_interrupts(struct mhi_ep_cntrl *mhi_cntrl, bool enable) +{ + u32 val = 0, i; + + if (enable) + val = MHI_ERDB_INT_MASK_A7_n_EN_ALL; + + for (i = 0; i < MHI_MASK_ROWS_CH_EV_DB; i++) + mhi_ep_mmio_write(mhi_cntrl, MHI_ERDB_INT_MASK_A7_n(i), val); +} + +static void mhi_ep_mmio_mask_erdb_interrupts(struct mhi_ep_cntrl *mhi_cntrl) +{ + mhi_ep_mmio_set_erdb_interrupts(mhi_cntrl, false); +} + +void mhi_ep_mmio_enable_ctrl_interrupt(struct mhi_ep_cntrl *mhi_cntrl) +{ + mhi_ep_mmio_masked_write(mhi_cntrl, MHI_CTRL_INT_MASK_A7, + MHI_CTRL_MHICTRL_MASK, 1); +} + +void mhi_ep_mmio_disable_ctrl_interrupt(struct mhi_ep_cntrl *mhi_cntrl) +{ + mhi_ep_mmio_masked_write(mhi_cntrl, MHI_CTRL_INT_MASK_A7, + MHI_CTRL_MHICTRL_MASK, 0); +} + +void mhi_ep_mmio_enable_cmdb_interrupt(struct mhi_ep_cntrl *mhi_cntrl) +{ + mhi_ep_mmio_masked_write(mhi_cntrl, MHI_CTRL_INT_MASK_A7, + MHI_CTRL_CRDB_MASK, 1); +} + +void mhi_ep_mmio_disable_cmdb_interrupt(struct mhi_ep_cntrl *mhi_cntrl) +{ + mhi_ep_mmio_masked_write(mhi_cntrl, MHI_CTRL_INT_MASK_A7, + MHI_CTRL_CRDB_MASK, 0); +} + +void mhi_ep_mmio_mask_interrupts(struct mhi_ep_cntrl *mhi_cntrl) +{ + mhi_ep_mmio_disable_ctrl_interrupt(mhi_cntrl); + mhi_ep_mmio_disable_cmdb_interrupt(mhi_cntrl); + mhi_ep_mmio_mask_chdb_interrupts(mhi_cntrl); + mhi_ep_mmio_mask_erdb_interrupts(mhi_cntrl); +} + +static void mhi_ep_mmio_clear_interrupts(struct mhi_ep_cntrl *mhi_cntrl) +{ + u32 i = 0; + + for (i = 0; i < MHI_MASK_ROWS_CH_EV_DB; i++) + mhi_ep_mmio_write(mhi_cntrl, MHI_CHDB_INT_CLEAR_A7_n(i), + MHI_CHDB_INT_CLEAR_A7_n_CLEAR_ALL); + + for (i = 0; i < MHI_MASK_ROWS_CH_EV_DB; i++) + mhi_ep_mmio_write(mhi_cntrl, MHI_ERDB_INT_CLEAR_A7_n(i), + MHI_ERDB_INT_CLEAR_A7_n_CLEAR_ALL); + + mhi_ep_mmio_write(mhi_cntrl, MHI_CTRL_INT_CLEAR_A7, + MHI_CTRL_INT_MMIO_WR_CLEAR | + MHI_CTRL_INT_CRDB_CLEAR | + MHI_CTRL_INT_CRDB_MHICTRL_CLEAR); +} + +void mhi_ep_mmio_get_chc_base(struct mhi_ep_cntrl *mhi_cntrl) +{ + u32 ccabap_value; + + ccabap_value = mhi_ep_mmio_read(mhi_cntrl, CCABAP_HIGHER); + mhi_cntrl->ch_ctx_host_pa = ccabap_value; + mhi_cntrl->ch_ctx_host_pa <<= 32; + + ccabap_value = mhi_ep_mmio_read(mhi_cntrl, CCABAP_LOWER); + mhi_cntrl->ch_ctx_host_pa |= ccabap_value; +} + +void mhi_ep_mmio_get_erc_base(struct mhi_ep_cntrl *mhi_cntrl) +{ + u32 ecabap_value; + + ecabap_value = mhi_ep_mmio_read(mhi_cntrl, ECABAP_HIGHER); + mhi_cntrl->ev_ctx_host_pa = ecabap_value; + mhi_cntrl->ev_ctx_host_pa <<= 32; + + ecabap_value = mhi_ep_mmio_read(mhi_cntrl, ECABAP_LOWER); + mhi_cntrl->ev_ctx_host_pa |= ecabap_value; +} + +void mhi_ep_mmio_get_crc_base(struct mhi_ep_cntrl *mhi_cntrl) +{ + u32 crcbap_value; + + crcbap_value = mhi_ep_mmio_read(mhi_cntrl, CRCBAP_HIGHER); + mhi_cntrl->cmd_ctx_host_pa = crcbap_value; + mhi_cntrl->cmd_ctx_host_pa <<= 32; + + crcbap_value = mhi_ep_mmio_read(mhi_cntrl, CRCBAP_LOWER); + mhi_cntrl->cmd_ctx_host_pa |= crcbap_value; +} + +u64 mhi_ep_mmio_get_db(struct mhi_ep_ring *ring) +{ + struct mhi_ep_cntrl *mhi_cntrl = ring->mhi_cntrl; + u64 db_offset; + u32 regval; + + regval = mhi_ep_mmio_read(mhi_cntrl, ring->db_offset_h); + db_offset = regval; + db_offset <<= 32; + + regval = mhi_ep_mmio_read(mhi_cntrl, ring->db_offset_l); + db_offset |= regval; + + return db_offset; +} + +void mhi_ep_mmio_set_env(struct mhi_ep_cntrl *mhi_cntrl, u32 value) +{ + mhi_ep_mmio_write(mhi_cntrl, BHI_EXECENV, value); +} + +void mhi_ep_mmio_clear_reset(struct mhi_ep_cntrl *mhi_cntrl) +{ + mhi_ep_mmio_masked_write(mhi_cntrl, MHICTRL, MHICTRL_RESET_MASK, 0); +} + +void mhi_ep_mmio_reset(struct mhi_ep_cntrl *mhi_cntrl) +{ + mhi_ep_mmio_write(mhi_cntrl, MHICTRL, 0); + mhi_ep_mmio_write(mhi_cntrl, MHISTATUS, 0); + mhi_ep_mmio_clear_interrupts(mhi_cntrl); +} + +void mhi_ep_mmio_init(struct mhi_ep_cntrl *mhi_cntrl) +{ + int mhi_cfg; + + mhi_cntrl->chdb_offset = mhi_ep_mmio_read(mhi_cntrl, CHDBOFF); + mhi_cntrl->erdb_offset = mhi_ep_mmio_read(mhi_cntrl, ERDBOFF); + + mhi_cfg = mhi_ep_mmio_read(mhi_cntrl, MHICFG); + mhi_cntrl->event_rings = FIELD_GET(MHICFG_NER_MASK, mhi_cfg); + mhi_cntrl->hw_event_rings = FIELD_GET(MHICFG_NHWER_MASK, mhi_cfg); + + mhi_ep_mmio_reset(mhi_cntrl); +} + +void mhi_ep_mmio_update_ner(struct mhi_ep_cntrl *mhi_cntrl) +{ + int mhi_cfg; + + mhi_cfg = mhi_ep_mmio_read(mhi_cntrl, MHICFG); + mhi_cntrl->event_rings = FIELD_GET(MHICFG_NER_MASK, mhi_cfg); + mhi_cntrl->hw_event_rings = FIELD_GET(MHICFG_NHWER_MASK, mhi_cfg); +} diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index da865f9d3646..3d2ab7a5ccd7 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -59,6 +59,10 @@ struct mhi_ep_db_info { * @mhi_event: Points to the event ring configurations table * @mhi_cmd: Points to the command ring configurations table * @sm: MHI Endpoint state machine + * @ch_ctx_host_pa: Physical address of host channel context data structure + * @ev_ctx_host_pa: Physical address of host event context data structure + * @cmd_ctx_host_pa: Physical address of host command context data structure + * @chdb: Array of channel doorbell interrupt info * @raise_irq: CB function for raising IRQ to the host * @alloc_addr: CB function for allocating memory in endpoint for storing host context * @map_addr: CB function for mapping host context to endpoint @@ -69,6 +73,10 @@ struct mhi_ep_db_info { * @mhi_state: MHI Endpoint state * @max_chan: Maximum channels supported by the endpoint controller * @mru: MRU (Maximum Receive Unit) value of the endpoint controller + * @event_rings: Number of event rings supported by the endpoint controller + * @hw_event_rings: Number of hardware event rings supported by the endpoint controller + * @chdb_offset: Channel doorbell offset set by the host + * @erdb_offset: Event ring doorbell offset set by the host * @index: MHI Endpoint controller index */ struct mhi_ep_cntrl { @@ -81,6 +89,12 @@ struct mhi_ep_cntrl { struct mhi_ep_cmd *mhi_cmd; struct mhi_ep_sm *sm; + u64 ch_ctx_host_pa; + u64 ev_ctx_host_pa; + u64 cmd_ctx_host_pa; + + struct mhi_ep_db_info chdb[4]; + void (*raise_irq)(struct mhi_ep_cntrl *mhi_cntrl, u32 vector); void __iomem *(*alloc_addr)(struct mhi_ep_cntrl *mhi_cntrl, phys_addr_t *phys_addr, size_t size); @@ -98,6 +112,10 @@ struct mhi_ep_cntrl { u32 max_chan; u32 mru; + u32 event_rings; + u32 hw_event_rings; + u32 chdb_offset; + u32 erdb_offset; int index; }; From patchwork Sat Feb 12 18:21:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 542590 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 71C9CC433F5 for ; Sat, 12 Feb 2022 18:22:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229802AbiBLSWz (ORCPT ); Sat, 12 Feb 2022 13:22:55 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:46622 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229812AbiBLSWy (ORCPT ); Sat, 12 Feb 2022 13:22:54 -0500 Received: from mail-pf1-x436.google.com (mail-pf1-x436.google.com [IPv6:2607:f8b0:4864:20::436]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C55105FF07 for ; Sat, 12 Feb 2022 10:22:43 -0800 (PST) Received: by mail-pf1-x436.google.com with SMTP id z16so61100pfh.3 for ; Sat, 12 Feb 2022 10:22:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=4kd2+LJhJ/YC6gbGrKXixFZ3JiEsy8O4oW6NXNFZZXE=; b=PhdzjUmVW5X4QF8pmN1NFMhwcrwDsV4qIaj9AvQ9di2vHo7ZHpsyu9x/8orB8gtuUS 54FV+7wClOx0vFG3D/WFOFPmP5ToB0mRiz3BXKV2CYGABNysxJJ3fN6zg/GqPrhxhGU6 mQW0EgrsaQfk/NdFPTNp1K9rkxug8MuJJcTpwO8dOODOIBgRRwA5WykJZb2kwwjw5Ept m80NwhtCkzaR8mEaysl53Rl64+ioitSkkungf9+22eCPZedeAxlnmywL738G0eFCUcIr w5ucfoBCQ1Wu6azJQ32bi2XEwdQCxAsDLQbLe5T97c9/gQdSKki/FGXhPAGnD/GBFpcV q+KA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=4kd2+LJhJ/YC6gbGrKXixFZ3JiEsy8O4oW6NXNFZZXE=; b=1aSfjmdeDhH4daxzyRK+iSlX45VvOs7slEJQl+1P2q9G0/aHx1wM58QWPpK2EUJdc9 0OmQ9c52CXmi0rE49acWj5woJoQ26Wl2w1xYAZOQsq1SnrLyB/Qce+G9QwpJ7cA2e5Te +tHjretCmtU/gHCRKLBnqgz77ZRYJ31I0ShHqQ9iW0Fxha24kO0xbwSqpLSjTSlLJTyM HLiwkOBwRP0HEKuSwQpbiMDmiMVzbXUpbg8lha2dZYXzYuaZL6Rqp+T4nKSX30o71wSV WG/2lHKs0y0VmekWYNHJdBXoEThT8o2dvURNSESFsrciPZJZgOwPDOTyeVdxn7PIRCPu fdYQ== X-Gm-Message-State: AOAM5334CNKeCmEV6keoUC4DYWKM2hde6LmJcvEtJg7dSVUShwQMZwMY ZvVFhYYIoX9FknK+Lx9NVKjW X-Google-Smtp-Source: ABdhPJxxyTi1WZ+BIevwlQqA1/psQc9A5GYa2uS0caQ5IOtn1nupq2w6o9zdLsjwBMJ4qCNkjRMeVg== X-Received: by 2002:a63:6a49:: with SMTP id f70mr5632981pgc.55.1644690162642; Sat, 12 Feb 2022 10:22:42 -0800 (PST) Received: from localhost.localdomain ([27.111.75.57]) by smtp.gmail.com with ESMTPSA id g12sm14961987pfj.148.2022.02.12.10.22.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Feb 2022 10:22:42 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v3 12/25] bus: mhi: ep: Add support for ring management Date: Sat, 12 Feb 2022 23:51:04 +0530 Message-Id: <20220212182117.49438-13-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> References: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Add support for managing the MHI ring. The MHI ring is a circular queue of data structures used to pass the information between host and the endpoint. MHI support 3 types of rings: 1. Transfer ring 2. Event ring 3. Command ring All rings reside inside the host memory and the MHI EP device maps it to the device memory using blocks like PCIe iATU. The mapping is handled in the MHI EP controller driver itself. Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/ep/Makefile | 2 +- drivers/bus/mhi/ep/internal.h | 33 +++++ drivers/bus/mhi/ep/main.c | 59 +++++++- drivers/bus/mhi/ep/ring.c | 267 ++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 11 ++ 5 files changed, 370 insertions(+), 2 deletions(-) create mode 100644 drivers/bus/mhi/ep/ring.c diff --git a/drivers/bus/mhi/ep/Makefile b/drivers/bus/mhi/ep/Makefile index a1555ae287ad..7ba0e04801eb 100644 --- a/drivers/bus/mhi/ep/Makefile +++ b/drivers/bus/mhi/ep/Makefile @@ -1,2 +1,2 @@ obj-$(CONFIG_MHI_BUS_EP) += mhi_ep.o -mhi_ep-y := main.o mmio.o +mhi_ep-y := main.o mmio.o ring.o diff --git a/drivers/bus/mhi/ep/internal.h b/drivers/bus/mhi/ep/internal.h index 2c756a90774c..48d6e9667d55 100644 --- a/drivers/bus/mhi/ep/internal.h +++ b/drivers/bus/mhi/ep/internal.h @@ -112,6 +112,18 @@ enum mhi_ep_execenv { MHI_EP_UNRESERVED }; +/* Transfer Ring Element macros */ +#define MHI_EP_TRE_PTR(ptr) (ptr) +#define MHI_EP_TRE_DWORD0(len) (len & MHI_MAX_MTU) +#define MHI_EP_TRE_DWORD1(bei, ieot, ieob, chain) ((2 << 16) | (bei << 10) \ + | (ieot << 9) | (ieob << 8) | chain) +#define MHI_EP_TRE_GET_PTR(tre) ((tre)->ptr) +#define MHI_EP_TRE_GET_LEN(tre) ((tre)->dword[0] & 0xffff) +#define MHI_EP_TRE_GET_CHAIN(tre) FIELD_GET(BIT(0), (tre)->dword[1]) +#define MHI_EP_TRE_GET_IEOB(tre) FIELD_GET(BIT(8), (tre)->dword[1]) +#define MHI_EP_TRE_GET_IEOT(tre) FIELD_GET(BIT(9), (tre)->dword[1]) +#define MHI_EP_TRE_GET_BEI(tre) FIELD_GET(BIT(10), (tre)->dword[1]) + enum mhi_ep_ring_type { RING_TYPE_CMD = 0, RING_TYPE_ER, @@ -131,6 +143,11 @@ union mhi_ep_ring_ctx { struct mhi_generic_ctx generic; }; +struct mhi_ep_ring_item { + struct list_head node; + struct mhi_ep_ring *ring; +}; + struct mhi_ep_ring { struct mhi_ep_cntrl *mhi_cntrl; int (*ring_cb)(struct mhi_ep_ring *ring, struct mhi_ep_ring_element *el); @@ -143,6 +160,9 @@ struct mhi_ep_ring { u32 db_offset_h; u32 db_offset_l; u32 ch_id; + u32 er_index; + u32 irq_vector; + bool started; }; struct mhi_ep_cmd { @@ -168,6 +188,19 @@ struct mhi_ep_chan { bool skip_td; }; +/* MHI Ring related functions */ +void mhi_ep_ring_init(struct mhi_ep_ring *ring, enum mhi_ep_ring_type type, u32 id); +void mhi_ep_ring_reset(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_ring *ring); +int mhi_ep_ring_start(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_ring *ring, + union mhi_ep_ring_ctx *ctx); +size_t mhi_ep_ring_addr2offset(struct mhi_ep_ring *ring, u64 ptr); +int mhi_ep_process_ring(struct mhi_ep_ring *ring); +int mhi_ep_ring_add_element(struct mhi_ep_ring *ring, struct mhi_ep_ring_element *element); +void mhi_ep_ring_inc_index(struct mhi_ep_ring *ring); +int mhi_ep_process_cmd_ring(struct mhi_ep_ring *ring, struct mhi_ep_ring_element *el); +int mhi_ep_process_tre_ring(struct mhi_ep_ring *ring, struct mhi_ep_ring_element *el); +int mhi_ep_update_wr_offset(struct mhi_ep_ring *ring); + /* MMIO related functions */ u32 mhi_ep_mmio_read(struct mhi_ep_cntrl *mhi_cntrl, u32 offset); void mhi_ep_mmio_write(struct mhi_ep_cntrl *mhi_cntrl, u32 offset, u32 val); diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 950b5bcabe18..2c8045766292 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -18,6 +18,48 @@ static DEFINE_IDA(mhi_ep_cntrl_ida); +static void mhi_ep_ring_worker(struct work_struct *work) +{ + struct mhi_ep_cntrl *mhi_cntrl = container_of(work, + struct mhi_ep_cntrl, ring_work); + struct device *dev = &mhi_cntrl->mhi_dev->dev; + struct mhi_ep_ring_item *itr, *tmp; + struct mhi_ep_ring *ring; + struct mhi_ep_chan *chan; + unsigned long flags; + LIST_HEAD(head); + int ret; + + /* Process the command ring first */ + ret = mhi_ep_process_ring(&mhi_cntrl->mhi_cmd->ring); + if (ret) { + dev_err(dev, "Error processing command ring: %d\n", ret); + return; + } + + spin_lock_irqsave(&mhi_cntrl->list_lock, flags); + list_splice_tail_init(&mhi_cntrl->ch_db_list, &head); + spin_unlock_irqrestore(&mhi_cntrl->list_lock, flags); + + /* Process the channel rings now */ + list_for_each_entry_safe(itr, tmp, &head, node) { + list_del(&itr->node); + ring = itr->ring; + chan = &mhi_cntrl->mhi_chan[ring->ch_id]; + mutex_lock(&chan->lock); + dev_dbg(dev, "Processing the ring for channel (%d)\n", ring->ch_id); + ret = mhi_ep_process_ring(ring); + if (ret) { + dev_err(dev, "Error processing ring for channel (%d): %d\n", + ring->ch_id, ret); + mutex_unlock(&chan->lock); + return; + } + mutex_unlock(&chan->lock); + kfree(itr); + } +} + static void mhi_ep_release_device(struct device *dev) { struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev); @@ -218,6 +260,17 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, goto err_free_ch; } + INIT_WORK(&mhi_cntrl->ring_work, mhi_ep_ring_worker); + + mhi_cntrl->ring_wq = alloc_workqueue("mhi_ep_ring_wq", 0, 0); + if (!mhi_cntrl->ring_wq) { + ret = -ENOMEM; + goto err_free_cmd; + } + + INIT_LIST_HEAD(&mhi_cntrl->ch_db_list); + spin_lock_init(&mhi_cntrl->list_lock); + /* Set MHI version and AMSS EE before enumeration */ mhi_ep_mmio_write(mhi_cntrl, MHIVER, config->mhi_version); mhi_ep_mmio_set_env(mhi_cntrl, MHI_EP_AMSS_EE); @@ -226,7 +279,7 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, mhi_cntrl->index = ida_alloc(&mhi_ep_cntrl_ida, GFP_KERNEL); if (mhi_cntrl->index < 0) { ret = mhi_cntrl->index; - goto err_free_cmd; + goto err_destroy_ring_wq; } /* Allocate the controller device */ @@ -254,6 +307,8 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, put_device(&mhi_dev->dev); err_ida_free: ida_free(&mhi_ep_cntrl_ida, mhi_cntrl->index); +err_destroy_ring_wq: + destroy_workqueue(mhi_cntrl->ring_wq); err_free_cmd: kfree(mhi_cntrl->mhi_cmd); err_free_ch: @@ -267,6 +322,8 @@ void mhi_ep_unregister_controller(struct mhi_ep_cntrl *mhi_cntrl) { struct mhi_ep_device *mhi_dev = mhi_cntrl->mhi_dev; + destroy_workqueue(mhi_cntrl->ring_wq); + kfree(mhi_cntrl->mhi_cmd); kfree(mhi_cntrl->mhi_chan); diff --git a/drivers/bus/mhi/ep/ring.c b/drivers/bus/mhi/ep/ring.c new file mode 100644 index 000000000000..3eb02c9be5eb --- /dev/null +++ b/drivers/bus/mhi/ep/ring.c @@ -0,0 +1,267 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2021 Linaro Ltd. + * Author: Manivannan Sadhasivam + */ + +#include +#include "internal.h" + +size_t mhi_ep_ring_addr2offset(struct mhi_ep_ring *ring, u64 ptr) +{ + u64 rbase; + + rbase = le64_to_cpu(ring->ring_ctx->generic.rbase); + + return (ptr - rbase) / sizeof(struct mhi_ep_ring_element); +} + +static u32 mhi_ep_ring_num_elems(struct mhi_ep_ring *ring) +{ + return le64_to_cpu(ring->ring_ctx->generic.rlen) / sizeof(struct mhi_ep_ring_element); +} + +void mhi_ep_ring_inc_index(struct mhi_ep_ring *ring) +{ + ring->rd_offset++; + if (ring->rd_offset == ring->ring_size) + ring->rd_offset = 0; +} + +static int __mhi_ep_cache_ring(struct mhi_ep_ring *ring, size_t end) +{ + struct mhi_ep_cntrl *mhi_cntrl = ring->mhi_cntrl; + struct device *dev = &mhi_cntrl->mhi_dev->dev; + size_t start, copy_size; + int ret; + + /* No need to cache event rings */ + if (ring->type == RING_TYPE_ER) + return 0; + + /* No need to cache the ring if write pointer is unmodified */ + if (ring->wr_offset == end) + return 0; + + start = ring->wr_offset; + if (start < end) { + copy_size = (end - start) * sizeof(struct mhi_ep_ring_element); + ret = mhi_cntrl->read_from_host(mhi_cntrl, + (le64_to_cpu(ring->ring_ctx->generic.rbase) + + (start * sizeof(struct mhi_ep_ring_element))), + &ring->ring_cache[start], copy_size); + if (ret < 0) + return ret; + } else { + copy_size = (ring->ring_size - start) * sizeof(struct mhi_ep_ring_element); + ret = mhi_cntrl->read_from_host(mhi_cntrl, + (le64_to_cpu(ring->ring_ctx->generic.rbase) + + (start * sizeof(struct mhi_ep_ring_element))), + &ring->ring_cache[start], copy_size); + if (ret < 0) + return ret; + + if (end) { + ret = mhi_cntrl->read_from_host(mhi_cntrl, + le64_to_cpu(ring->ring_ctx->generic.rbase), + &ring->ring_cache[0], + end * sizeof(struct mhi_ep_ring_element)); + if (ret < 0) + return ret; + } + } + + dev_dbg(dev, "Cached ring: start %zu end %zu size %zu\n", start, end, copy_size); + + return 0; +} + +static int mhi_ep_cache_ring(struct mhi_ep_ring *ring, u64 wr_ptr) +{ + size_t wr_offset; + int ret; + + wr_offset = mhi_ep_ring_addr2offset(ring, wr_ptr); + + /* Cache the host ring till write offset */ + ret = __mhi_ep_cache_ring(ring, wr_offset); + if (ret) + return ret; + + ring->wr_offset = wr_offset; + + return 0; +} + +int mhi_ep_update_wr_offset(struct mhi_ep_ring *ring) +{ + u64 wr_ptr; + + wr_ptr = mhi_ep_mmio_get_db(ring); + + return mhi_ep_cache_ring(ring, wr_ptr); +} + +static int mhi_ep_process_ring_element(struct mhi_ep_ring *ring, size_t offset) +{ + struct mhi_ep_ring_element *el; + + /* Get the element and invoke the respective callback */ + el = &ring->ring_cache[offset]; + + return ring->ring_cb(ring, el); +} + +int mhi_ep_process_ring(struct mhi_ep_ring *ring) +{ + struct mhi_ep_cntrl *mhi_cntrl = ring->mhi_cntrl; + struct device *dev = &mhi_cntrl->mhi_dev->dev; + int ret = 0; + + /* Event rings should not be processed */ + if (ring->type == RING_TYPE_ER) + return -EINVAL; + + dev_dbg(dev, "Processing ring of type: %d\n", ring->type); + + /* Update the write offset for the ring */ + ret = mhi_ep_update_wr_offset(ring); + if (ret) { + dev_err(dev, "Error updating write offset for ring\n"); + return ret; + } + + /* Sanity check to make sure there are elements in the ring */ + if (ring->rd_offset == ring->wr_offset) + return 0; + + /* Process channel ring first */ + if (ring->type == RING_TYPE_CH) { + ret = mhi_ep_process_ring_element(ring, ring->rd_offset); + if (ret) + dev_err(dev, "Error processing ch ring element: %zu\n", ring->rd_offset); + + return ret; + } + + /* Process command ring now */ + while (ring->rd_offset != ring->wr_offset) { + ret = mhi_ep_process_ring_element(ring, ring->rd_offset); + if (ret) { + dev_err(dev, "Error processing cmd ring element: %zu\n", ring->rd_offset); + return ret; + } + + mhi_ep_ring_inc_index(ring); + } + + return 0; +} + +/* TODO: Support for adding multiple ring elements to the ring */ +int mhi_ep_ring_add_element(struct mhi_ep_ring *ring, struct mhi_ep_ring_element *el) +{ + struct mhi_ep_cntrl *mhi_cntrl = ring->mhi_cntrl; + struct device *dev = &mhi_cntrl->mhi_dev->dev; + __le64 rbase = ring->ring_ctx->generic.rbase; + size_t old_offset = 0; + u32 num_free_elem; + int ret; + + ret = mhi_ep_update_wr_offset(ring); + if (ret) { + dev_err(dev, "Error updating write pointer\n"); + return ret; + } + + if (ring->rd_offset < ring->wr_offset) + num_free_elem = (ring->wr_offset - ring->rd_offset) - 1; + else + num_free_elem = ((ring->ring_size - ring->rd_offset) + ring->wr_offset) - 1; + + /* Check if there is space in ring for adding at least an element */ + if (!num_free_elem) { + dev_err(dev, "No space left in the ring\n"); + return -ENOSPC; + } + + old_offset = ring->rd_offset; + mhi_ep_ring_inc_index(ring); + + dev_dbg(dev, "Adding an element to ring at offset (%zu)\n", ring->rd_offset); + + /* Update rp in ring context */ + ring->ring_ctx->generic.rp = cpu_to_le64((ring->rd_offset * sizeof(*el))) + rbase; + + /* Ensure that the ring pointer gets updated before writing the element to ring */ + smp_wmb(); + + ret = mhi_cntrl->write_to_host(mhi_cntrl, el, (le64_to_cpu(rbase) + + (old_offset * sizeof(*el))), sizeof(*el)); + if (ret < 0) + return ret; + + return 0; +} + +void mhi_ep_ring_init(struct mhi_ep_ring *ring, enum mhi_ep_ring_type type, u32 id) +{ + ring->type = type; + if (ring->type == RING_TYPE_CMD) { + ring->ring_cb = mhi_ep_process_cmd_ring; + ring->db_offset_h = CRDB_HIGHER; + ring->db_offset_l = CRDB_LOWER; + } else if (ring->type == RING_TYPE_CH) { + ring->ring_cb = mhi_ep_process_tre_ring; + ring->db_offset_h = CHDB_HIGHER_n(id); + ring->db_offset_l = CHDB_LOWER_n(id); + ring->ch_id = id; + } else { + ring->db_offset_h = ERDB_HIGHER_n(id); + ring->db_offset_l = ERDB_LOWER_n(id); + } +} + +int mhi_ep_ring_start(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_ring *ring, + union mhi_ep_ring_ctx *ctx) +{ + struct device *dev = &mhi_cntrl->mhi_dev->dev; + int ret; + + ring->mhi_cntrl = mhi_cntrl; + ring->ring_ctx = ctx; + ring->ring_size = mhi_ep_ring_num_elems(ring); + + if (ring->type == RING_TYPE_CH) + ring->er_index = le32_to_cpu(ring->ring_ctx->ch.erindex); + + if (ring->type == RING_TYPE_ER) + ring->irq_vector = le32_to_cpu(ring->ring_ctx->ev.msivec); + + /* During ring init, both rp and wp are equal */ + ring->rd_offset = mhi_ep_ring_addr2offset(ring, le64_to_cpu(ring->ring_ctx->generic.rp)); + ring->wr_offset = mhi_ep_ring_addr2offset(ring, le64_to_cpu(ring->ring_ctx->generic.rp)); + + /* Allocate ring cache memory for holding the copy of host ring */ + ring->ring_cache = kcalloc(ring->ring_size, sizeof(struct mhi_ep_ring_element), + GFP_KERNEL); + if (!ring->ring_cache) + return -ENOMEM; + + ret = mhi_ep_cache_ring(ring, le64_to_cpu(ring->ring_ctx->generic.wp)); + if (ret) { + dev_err(dev, "Failed to cache ring\n"); + kfree(ring->ring_cache); + return ret; + } + + ring->started = true; + + return 0; +} + +void mhi_ep_ring_reset(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_ring *ring) +{ + ring->started = false; + kfree(ring->ring_cache); +} diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 3d2ab7a5ccd7..33828a6c4e63 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -62,6 +62,11 @@ struct mhi_ep_db_info { * @ch_ctx_host_pa: Physical address of host channel context data structure * @ev_ctx_host_pa: Physical address of host event context data structure * @cmd_ctx_host_pa: Physical address of host command context data structure + * @ring_wq: Dedicated workqueue for processing MHI rings + * @ring_work: Ring worker + * @ch_db_list: List of queued channel doorbells + * @st_transition_list: List of state transitions + * @list_lock: Lock for protecting state transition and channel doorbell lists * @chdb: Array of channel doorbell interrupt info * @raise_irq: CB function for raising IRQ to the host * @alloc_addr: CB function for allocating memory in endpoint for storing host context @@ -93,6 +98,12 @@ struct mhi_ep_cntrl { u64 ev_ctx_host_pa; u64 cmd_ctx_host_pa; + struct workqueue_struct *ring_wq; + struct work_struct ring_work; + + struct list_head ch_db_list; + struct list_head st_transition_list; + spinlock_t list_lock; struct mhi_ep_db_info chdb[4]; void (*raise_irq)(struct mhi_ep_cntrl *mhi_cntrl, u32 vector); From patchwork Sat Feb 12 18:21:05 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 542172 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 00268C433F5 for ; Sat, 12 Feb 2022 18:23:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229819AbiBLSXD (ORCPT ); Sat, 12 Feb 2022 13:23:03 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:46974 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229812AbiBLSXC (ORCPT ); Sat, 12 Feb 2022 13:23:02 -0500 Received: from mail-pj1-x1030.google.com (mail-pj1-x1030.google.com [IPv6:2607:f8b0:4864:20::1030]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 02104606E6 for ; Sat, 12 Feb 2022 10:22:48 -0800 (PST) Received: by mail-pj1-x1030.google.com with SMTP id v13-20020a17090ac90d00b001b87bc106bdso14970153pjt.4 for ; Sat, 12 Feb 2022 10:22:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=LH8VJ+pSm68sFc1cYY3RYcOsle29FQzPNq8mbSVmnMo=; b=jaN2QYAFCXw39e/R/Y87XTjdpCjQfdQm5AkN0M2GWj9XN5QWiA7D4ae9ptNAZFQ64A majLcE8twb/XcOnWpgRC+E4cmnqstL4ovGZG8ygCyFbHFknvU8hXB0tfsoum6I/9ADSa kBdnXpQ2wGWlDOCWXnkXFhjK+aGekmkYmwoCmS6TvLBMo+ZLMWpRWGJJP8ZJKffNgQTV ftKIVNLXchWUinSdnyDIuyYO6gCNe/0BphNzXi9DpcFeV8jE95pSRLFSBAKPqgKVGu36 bbFc+4iQSpCU5X6ZwC57+Mel4Foj2H5J6VP26cSLt1PkkhL5BwjXm09Nal6Wuks8IXwQ t7/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=LH8VJ+pSm68sFc1cYY3RYcOsle29FQzPNq8mbSVmnMo=; b=6OpK9Rs4YmOFCw93C5+wx4ifuwgCHa5dnEt+Lw/Bdfxo4D8fSyXmJzmfibtc4ILUZz /YoZk3JvGjuJ8SpS7CjEzlJ8G8oDvtHk6E1hbXd8jTHUqAX8Wkrig40xTvNwWVV5F6zS OyK7+FzrW/6tC9TJllCi7P0DmHrEgtw20rjLPsmEITUS7Fijk8VNKi2aXQQZ0r2J/wN2 tzfD+uuuAClpVdNg5ZTgu/bNZ/NFXj4AJwGTwj7gqy49yDvDhQ9TTS+U1JuSZqUkmuWX dSXi1CCRHHc1QWPub9w7u9/CPTJPcGuEVmtaF7msZUEeyh5i5tGlqO3Djunf825Wvvnv zX/Q== X-Gm-Message-State: AOAM532RT/9Y7K93Ez1xjsFlcPSC1VN7e+pFfDFVzELp4M0z3gnPa44Z XlFN5LDfKNRvWd2OTQWFa8gH X-Google-Smtp-Source: ABdhPJxOsTY0/lquS0mrUFozAuMj3XneF+aIrwN2gNp9QE5NCBQj1+TLoGqvUrbfa5LP4JGac8Nvnw== X-Received: by 2002:a17:90a:ac0f:: with SMTP id o15mr6299586pjq.140.1644690167340; Sat, 12 Feb 2022 10:22:47 -0800 (PST) Received: from localhost.localdomain ([27.111.75.57]) by smtp.gmail.com with ESMTPSA id g12sm14961987pfj.148.2022.02.12.10.22.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Feb 2022 10:22:46 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v3 13/25] bus: mhi: ep: Add support for sending events to the host Date: Sat, 12 Feb 2022 23:51:05 +0530 Message-Id: <20220212182117.49438-14-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> References: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Add support for sending the events to the host over MHI bus from the endpoint. Following events are supported: 1. Transfer completion event 2. Command completion event 3. State change event 4. Execution Environment (EE) change event An event is sent whenever an operation has been completed in the MHI EP device. Event is sent using the MHI event ring and additionally the host is notified using an IRQ if required. Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/common.h | 15 ++++ drivers/bus/mhi/ep/internal.h | 8 ++- drivers/bus/mhi/ep/main.c | 126 ++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 8 +++ 4 files changed, 155 insertions(+), 2 deletions(-) diff --git a/drivers/bus/mhi/common.h b/drivers/bus/mhi/common.h index 728c82928d8d..26d94ed52b34 100644 --- a/drivers/bus/mhi/common.h +++ b/drivers/bus/mhi/common.h @@ -176,6 +176,21 @@ #define MHI_TRE_GET_EV_LINKSPEED(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 24) & 0xFF) #define MHI_TRE_GET_EV_LINKWIDTH(tre) (MHI_TRE_GET_DWORD(tre, 0) & 0xFF) +/* State change event */ +#define MHI_SC_EV_PTR 0 +#define MHI_SC_EV_DWORD0(state) cpu_to_le32(state << 24) +#define MHI_SC_EV_DWORD1(type) cpu_to_le32(type << 16) + +/* EE event */ +#define MHI_EE_EV_PTR 0 +#define MHI_EE_EV_DWORD0(ee) cpu_to_le32(ee << 24) +#define MHI_EE_EV_DWORD1(type) cpu_to_le32(type << 16) + +/* Command Completion event */ +#define MHI_CC_EV_PTR(ptr) cpu_to_le64(ptr) +#define MHI_CC_EV_DWORD0(code) cpu_to_le32(code << 24) +#define MHI_CC_EV_DWORD1(type) cpu_to_le32(type << 16) + /* Transfer descriptor macros */ #define MHI_TRE_DATA_PTR(ptr) cpu_to_le64(ptr) #define MHI_TRE_DATA_DWORD0(len) cpu_to_le32(len & MHI_MAX_MTU) diff --git a/drivers/bus/mhi/ep/internal.h b/drivers/bus/mhi/ep/internal.h index 48d6e9667d55..fd63f79c6aec 100644 --- a/drivers/bus/mhi/ep/internal.h +++ b/drivers/bus/mhi/ep/internal.h @@ -131,8 +131,8 @@ enum mhi_ep_ring_type { }; struct mhi_ep_ring_element { - u64 ptr; - u32 dword[2]; + __le64 ptr; + __le32 dword[2]; }; /* Ring element */ @@ -227,4 +227,8 @@ void mhi_ep_mmio_get_mhi_state(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state *s void mhi_ep_mmio_init(struct mhi_ep_cntrl *mhi_cntrl); void mhi_ep_mmio_update_ner(struct mhi_ep_cntrl *mhi_cntrl); +/* MHI EP core functions */ +int mhi_ep_send_state_change_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state state); +int mhi_ep_send_ee_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_ep_execenv exec_env); + #endif diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 2c8045766292..61f066c6286b 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -18,6 +18,131 @@ static DEFINE_IDA(mhi_ep_cntrl_ida); +static int mhi_ep_send_event(struct mhi_ep_cntrl *mhi_cntrl, u32 ring_idx, + struct mhi_ep_ring_element *el) +{ + struct device *dev = &mhi_cntrl->mhi_dev->dev; + union mhi_ep_ring_ctx *ctx; + struct mhi_ep_ring *ring; + int ret; + + mutex_lock(&mhi_cntrl->event_lock); + ring = &mhi_cntrl->mhi_event[ring_idx].ring; + ctx = (union mhi_ep_ring_ctx *)&mhi_cntrl->ev_ctx_cache[ring_idx]; + if (!ring->started) { + ret = mhi_ep_ring_start(mhi_cntrl, ring, ctx); + if (ret) { + dev_err(dev, "Error starting event ring (%d)\n", ring_idx); + goto err_unlock; + } + } + + /* Add element to the event ring */ + ret = mhi_ep_ring_add_element(ring, el); + if (ret) { + dev_err(dev, "Error adding element to event ring (%d)\n", ring_idx); + goto err_unlock; + } + + /* Ensure that the ring pointer gets updated in host memory before triggering IRQ */ + smp_wmb(); + + mutex_unlock(&mhi_cntrl->event_lock); + + /* + * Raise IRQ to host only if the BEI flag is not set in TRE. Host might + * set this flag for interrupt moderation as per MHI protocol. + */ + if (!MHI_EP_TRE_GET_BEI(el)) + mhi_cntrl->raise_irq(mhi_cntrl, ring->irq_vector); + + return 0; + +err_unlock: + mutex_unlock(&mhi_cntrl->event_lock); + + return ret; +} + +static int mhi_ep_send_completion_event(struct mhi_ep_cntrl *mhi_cntrl, + struct mhi_ep_ring *ring, u32 len, + enum mhi_ev_ccs code) +{ + struct mhi_ep_ring_element event = {}; + __le32 tmp; + + event.ptr = le64_to_cpu(ring->ring_ctx->generic.rbase) + + ring->rd_offset * sizeof(struct mhi_ep_ring_element); + + tmp = event.dword[0]; + tmp |= MHI_TRE_EV_DWORD0(code, len); + event.dword[0] = tmp; + + tmp = event.dword[1]; + tmp |= MHI_TRE_EV_DWORD1(ring->ch_id, MHI_PKT_TYPE_TX_EVENT); + event.dword[1] = tmp; + + return mhi_ep_send_event(mhi_cntrl, ring->er_index, &event); +} + +int mhi_ep_send_state_change_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state state) +{ + struct mhi_ep_ring_element event = {}; + __le32 tmp; + + tmp = event.dword[0]; + tmp |= MHI_SC_EV_DWORD0(state); + event.dword[0] = tmp; + + tmp = event.dword[1]; + tmp |= MHI_SC_EV_DWORD1(MHI_PKT_TYPE_STATE_CHANGE_EVENT); + event.dword[1] = tmp; + + return mhi_ep_send_event(mhi_cntrl, 0, &event); +} + +int mhi_ep_send_ee_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_ep_execenv exec_env) +{ + struct mhi_ep_ring_element event = {}; + __le32 tmp; + + tmp = event.dword[0]; + tmp |= MHI_EE_EV_DWORD0(exec_env); + event.dword[0] = tmp; + + tmp = event.dword[1]; + tmp |= MHI_SC_EV_DWORD1(MHI_PKT_TYPE_EE_EVENT); + event.dword[1] = tmp; + + return mhi_ep_send_event(mhi_cntrl, 0, &event); +} + +static int mhi_ep_send_cmd_comp_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_ev_ccs code) +{ + struct device *dev = &mhi_cntrl->mhi_dev->dev; + struct mhi_ep_ring_element event = {}; + __le32 tmp; + + if (code > MHI_EV_CC_BAD_TRE) { + dev_err(dev, "Invalid command completion code (%d)\n", code); + return -EINVAL; + } + + event.ptr = le64_to_cpu(mhi_cntrl->cmd_ctx_cache->rbase) + + (mhi_cntrl->mhi_cmd->ring.rd_offset * + (sizeof(struct mhi_ep_ring_element))); + + tmp = event.dword[0]; + tmp |= MHI_CC_EV_DWORD0(code); + event.dword[0] = tmp; + + tmp = event.dword[1]; + tmp |= MHI_CC_EV_DWORD1(MHI_PKT_TYPE_CMD_COMPLETION_EVENT); + event.dword[1] = tmp; + + return mhi_ep_send_event(mhi_cntrl, 0, &event); +} + static void mhi_ep_ring_worker(struct work_struct *work) { struct mhi_ep_cntrl *mhi_cntrl = container_of(work, @@ -270,6 +395,7 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, INIT_LIST_HEAD(&mhi_cntrl->ch_db_list); spin_lock_init(&mhi_cntrl->list_lock); + mutex_init(&mhi_cntrl->event_lock); /* Set MHI version and AMSS EE before enumeration */ mhi_ep_mmio_write(mhi_cntrl, MHIVER, config->mhi_version); diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 33828a6c4e63..062133a68118 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -59,6 +59,9 @@ struct mhi_ep_db_info { * @mhi_event: Points to the event ring configurations table * @mhi_cmd: Points to the command ring configurations table * @sm: MHI Endpoint state machine + * @ch_ctx_cache: Cache of host channel context data structure + * @ev_ctx_cache: Cache of host event context data structure + * @cmd_ctx_cache: Cache of host command context data structure * @ch_ctx_host_pa: Physical address of host channel context data structure * @ev_ctx_host_pa: Physical address of host event context data structure * @cmd_ctx_host_pa: Physical address of host command context data structure @@ -67,6 +70,7 @@ struct mhi_ep_db_info { * @ch_db_list: List of queued channel doorbells * @st_transition_list: List of state transitions * @list_lock: Lock for protecting state transition and channel doorbell lists + * @event_lock: Lock for protecting event rings * @chdb: Array of channel doorbell interrupt info * @raise_irq: CB function for raising IRQ to the host * @alloc_addr: CB function for allocating memory in endpoint for storing host context @@ -94,6 +98,9 @@ struct mhi_ep_cntrl { struct mhi_ep_cmd *mhi_cmd; struct mhi_ep_sm *sm; + struct mhi_chan_ctxt *ch_ctx_cache; + struct mhi_event_ctxt *ev_ctx_cache; + struct mhi_cmd_ctxt *cmd_ctx_cache; u64 ch_ctx_host_pa; u64 ev_ctx_host_pa; u64 cmd_ctx_host_pa; @@ -104,6 +111,7 @@ struct mhi_ep_cntrl { struct list_head ch_db_list; struct list_head st_transition_list; spinlock_t list_lock; + struct mutex event_lock; struct mhi_ep_db_info chdb[4]; void (*raise_irq)(struct mhi_ep_cntrl *mhi_cntrl, u32 vector); From patchwork Sat Feb 12 18:21:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 542589 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 43A87C433F5 for ; Sat, 12 Feb 2022 18:23:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229844AbiBLSXG (ORCPT ); Sat, 12 Feb 2022 13:23:06 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:47034 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229817AbiBLSXF (ORCPT ); Sat, 12 Feb 2022 13:23:05 -0500 Received: from mail-pj1-x1032.google.com (mail-pj1-x1032.google.com [IPv6:2607:f8b0:4864:20::1032]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2BBE55F8FB for ; Sat, 12 Feb 2022 10:22:52 -0800 (PST) Received: by mail-pj1-x1032.google.com with SMTP id c5-20020a17090a1d0500b001b904a7046dso13459453pjd.1 for ; Sat, 12 Feb 2022 10:22:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=BZz+ApV6CMo3XRxcwNl+ACxxmN8UYIbiSWGLdU9rvYA=; b=MjgyEMBe4nkJ5OAJjjxVxaRYCseAnT9PRzMEusZwmP0H1NhKTKyQVXoQRHWxyNEMqa PbFaAVs/4szlEnGZsIyVBAoEy1ToJT2jDt6bzifFUL0dwOwzKrt7hnnwX2UclgjmgCOZ ajrtDT5NrHsAwchbqhHMAN5Mh+GeDqAM/l0XD5KGFLVVM3oNn7TdT1FIojeu8OJCvHy3 JgvniyVJ8FmRNmbcvYvlFm3ek0n+reCJjVuDZouXLUW69xr4DVk3wPbQxm8w5WHP238G orgk5bCxwx8wvYWEcaH99xpe7pgtEG8WKI+2AARMnkoWTHwIdomuI04hAlCpX7BmuKff oj5Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=BZz+ApV6CMo3XRxcwNl+ACxxmN8UYIbiSWGLdU9rvYA=; b=SZZYmdpb9g4TPVjLVGO+mSCSxCq2qfx1UegQGM3rgAkJJ3Bejj+wsCRFnZDKNra7D9 WjXc46QUWgRWWzL7NtTIGdrKwydUJHhKWkzdGbjl1+T73/Wmg4O3d95x+gncp0OaUOUj tQIx2Ls65STus0cCxR6Zp0C8k75RQugn8lpr1ZDH5UTf2Hkr2c9FEdX1vpm/eKE3RQqU lw8PHMq7ZaxMWbnFGJbusITiVcNA9rtV+nYTNzVDOg6FbTpzjI7WHqk4e2sp1VhR+Gnc PPgWoJvrs0+g/WfAYA65R9B53/NerjbAlNjzDZDT33T/3FUALl99jZMVyn5hMsITjOoa Nf4A== X-Gm-Message-State: AOAM5317mQypfmXjCK6AVxtRbNotb/Oqqmeb9nJsHg9dqlHPww5ViBJM 7+okvsvuOQbczwC16eo+7IJ+ X-Google-Smtp-Source: ABdhPJwqItcP585vZFYcZUNZiw+vKowLswqj/TA3tCJzrfNUR18KbRDaDPIkPFohs+hgGWOCqCkp2Q== X-Received: by 2002:a17:902:bcca:: with SMTP id o10mr6897818pls.147.1644690171632; Sat, 12 Feb 2022 10:22:51 -0800 (PST) Received: from localhost.localdomain ([27.111.75.57]) by smtp.gmail.com with ESMTPSA id g12sm14961987pfj.148.2022.02.12.10.22.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Feb 2022 10:22:51 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v3 14/25] bus: mhi: ep: Add support for managing MHI state machine Date: Sat, 12 Feb 2022 23:51:06 +0530 Message-Id: <20220212182117.49438-15-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> References: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Add support for managing the MHI state machine by controlling the state transitions. Only the following MHI state transitions are supported: 1. Ready state 2. M0 state 3. M3 state 4. SYS_ERR state Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/ep/Makefile | 2 +- drivers/bus/mhi/ep/internal.h | 11 +++ drivers/bus/mhi/ep/main.c | 51 ++++++++++- drivers/bus/mhi/ep/sm.c | 168 ++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 6 ++ 5 files changed, 236 insertions(+), 2 deletions(-) create mode 100644 drivers/bus/mhi/ep/sm.c diff --git a/drivers/bus/mhi/ep/Makefile b/drivers/bus/mhi/ep/Makefile index 7ba0e04801eb..aad85f180b70 100644 --- a/drivers/bus/mhi/ep/Makefile +++ b/drivers/bus/mhi/ep/Makefile @@ -1,2 +1,2 @@ obj-$(CONFIG_MHI_BUS_EP) += mhi_ep.o -mhi_ep-y := main.o mmio.o ring.o +mhi_ep-y := main.o mmio.o ring.o sm.o diff --git a/drivers/bus/mhi/ep/internal.h b/drivers/bus/mhi/ep/internal.h index fd63f79c6aec..e4e8f06c2898 100644 --- a/drivers/bus/mhi/ep/internal.h +++ b/drivers/bus/mhi/ep/internal.h @@ -173,6 +173,11 @@ struct mhi_ep_event { struct mhi_ep_ring ring; }; +struct mhi_ep_state_transition { + struct list_head node; + enum mhi_state state; +}; + struct mhi_ep_chan { char *name; struct mhi_ep_device *mhi_dev; @@ -230,5 +235,11 @@ void mhi_ep_mmio_update_ner(struct mhi_ep_cntrl *mhi_cntrl); /* MHI EP core functions */ int mhi_ep_send_state_change_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state state); int mhi_ep_send_ee_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_ep_execenv exec_env); +bool mhi_ep_check_mhi_state(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state cur_mhi_state, + enum mhi_state mhi_state); +int mhi_ep_set_mhi_state(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state mhi_state); +int mhi_ep_set_m0_state(struct mhi_ep_cntrl *mhi_cntrl); +int mhi_ep_set_m3_state(struct mhi_ep_cntrl *mhi_cntrl); +int mhi_ep_set_ready_state(struct mhi_ep_cntrl *mhi_cntrl); #endif diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 61f066c6286b..ccb3c2795041 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -185,6 +185,43 @@ static void mhi_ep_ring_worker(struct work_struct *work) } } +static void mhi_ep_state_worker(struct work_struct *work) +{ + struct mhi_ep_cntrl *mhi_cntrl = container_of(work, struct mhi_ep_cntrl, state_work); + struct device *dev = &mhi_cntrl->mhi_dev->dev; + struct mhi_ep_state_transition *itr, *tmp; + unsigned long flags; + LIST_HEAD(head); + int ret; + + spin_lock_irqsave(&mhi_cntrl->list_lock, flags); + list_splice_tail_init(&mhi_cntrl->st_transition_list, &head); + spin_unlock_irqrestore(&mhi_cntrl->list_lock, flags); + + list_for_each_entry_safe(itr, tmp, &head, node) { + list_del(&itr->node); + dev_dbg(dev, "Handling MHI state transition to %s\n", + mhi_state_str(itr->state)); + + switch (itr->state) { + case MHI_STATE_M0: + ret = mhi_ep_set_m0_state(mhi_cntrl); + if (ret) + dev_err(dev, "Failed to transition to M0 state\n"); + break; + case MHI_STATE_M3: + ret = mhi_ep_set_m3_state(mhi_cntrl); + if (ret) + dev_err(dev, "Failed to transition to M3 state\n"); + break; + default: + dev_err(dev, "Invalid MHI state transition: %d\n", itr->state); + break; + } + kfree(itr); + } +} + static void mhi_ep_release_device(struct device *dev) { struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev); @@ -386,6 +423,7 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, } INIT_WORK(&mhi_cntrl->ring_work, mhi_ep_ring_worker); + INIT_WORK(&mhi_cntrl->state_work, mhi_ep_state_worker); mhi_cntrl->ring_wq = alloc_workqueue("mhi_ep_ring_wq", 0, 0); if (!mhi_cntrl->ring_wq) { @@ -393,8 +431,16 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, goto err_free_cmd; } + mhi_cntrl->state_wq = alloc_workqueue("mhi_ep_state_wq", 0, 0); + if (!mhi_cntrl->state_wq) { + ret = -ENOMEM; + goto err_destroy_ring_wq; + } + INIT_LIST_HEAD(&mhi_cntrl->ch_db_list); + INIT_LIST_HEAD(&mhi_cntrl->st_transition_list); spin_lock_init(&mhi_cntrl->list_lock); + spin_lock_init(&mhi_cntrl->state_lock); mutex_init(&mhi_cntrl->event_lock); /* Set MHI version and AMSS EE before enumeration */ @@ -405,7 +451,7 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, mhi_cntrl->index = ida_alloc(&mhi_ep_cntrl_ida, GFP_KERNEL); if (mhi_cntrl->index < 0) { ret = mhi_cntrl->index; - goto err_destroy_ring_wq; + goto err_destroy_state_wq; } /* Allocate the controller device */ @@ -433,6 +479,8 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, put_device(&mhi_dev->dev); err_ida_free: ida_free(&mhi_ep_cntrl_ida, mhi_cntrl->index); +err_destroy_state_wq: + destroy_workqueue(mhi_cntrl->state_wq); err_destroy_ring_wq: destroy_workqueue(mhi_cntrl->ring_wq); err_free_cmd: @@ -448,6 +496,7 @@ void mhi_ep_unregister_controller(struct mhi_ep_cntrl *mhi_cntrl) { struct mhi_ep_device *mhi_dev = mhi_cntrl->mhi_dev; + destroy_workqueue(mhi_cntrl->state_wq); destroy_workqueue(mhi_cntrl->ring_wq); kfree(mhi_cntrl->mhi_cmd); diff --git a/drivers/bus/mhi/ep/sm.c b/drivers/bus/mhi/ep/sm.c new file mode 100644 index 000000000000..68e7f99b9137 --- /dev/null +++ b/drivers/bus/mhi/ep/sm.c @@ -0,0 +1,168 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2021 Linaro Ltd. + * Author: Manivannan Sadhasivam + */ + +#include +#include +#include +#include "internal.h" + +bool __must_check mhi_ep_check_mhi_state(struct mhi_ep_cntrl *mhi_cntrl, + enum mhi_state cur_mhi_state, + enum mhi_state mhi_state) +{ + bool valid = false; + + switch (mhi_state) { + case MHI_STATE_READY: + valid = (cur_mhi_state == MHI_STATE_RESET); + break; + case MHI_STATE_M0: + valid = (cur_mhi_state == MHI_STATE_READY || + cur_mhi_state == MHI_STATE_M3); + break; + case MHI_STATE_M3: + valid = (cur_mhi_state == MHI_STATE_M0); + break; + case MHI_STATE_SYS_ERR: + /* Transition to SYS_ERR state is allowed all the time */ + valid = true; + break; + default: + break; + } + + return valid; +} + +int mhi_ep_set_mhi_state(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state mhi_state) +{ + struct device *dev = &mhi_cntrl->mhi_dev->dev; + + if (!mhi_ep_check_mhi_state(mhi_cntrl, mhi_cntrl->mhi_state, mhi_state)) { + dev_err(dev, "MHI state change to %s from %s is not allowed!\n", + mhi_state_str(mhi_state), + mhi_state_str(mhi_cntrl->mhi_state)); + return -EACCES; + } + + switch (mhi_state) { + case MHI_STATE_READY: + mhi_ep_mmio_masked_write(mhi_cntrl, MHISTATUS, + MHISTATUS_READY_MASK, 1); + + mhi_ep_mmio_masked_write(mhi_cntrl, MHISTATUS, + MHISTATUS_MHISTATE_MASK, mhi_state); + break; + case MHI_STATE_SYS_ERR: + mhi_ep_mmio_masked_write(mhi_cntrl, MHISTATUS, + MHISTATUS_SYSERR_MASK, 1); + + mhi_ep_mmio_masked_write(mhi_cntrl, MHISTATUS, + MHISTATUS_MHISTATE_MASK, mhi_state); + break; + case MHI_STATE_M1: + case MHI_STATE_M2: + dev_err(dev, "MHI state (%s) not supported\n", mhi_state_str(mhi_state)); + return -EOPNOTSUPP; + case MHI_STATE_M0: + case MHI_STATE_M3: + mhi_ep_mmio_masked_write(mhi_cntrl, MHISTATUS, + MHISTATUS_MHISTATE_MASK, mhi_state); + break; + default: + dev_err(dev, "Invalid MHI state (%d)\n", mhi_state); + return -EINVAL; + } + + mhi_cntrl->mhi_state = mhi_state; + + return 0; +} + +int mhi_ep_set_m0_state(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct device *dev = &mhi_cntrl->mhi_dev->dev; + enum mhi_state old_state; + int ret; + + spin_lock_bh(&mhi_cntrl->state_lock); + old_state = mhi_cntrl->mhi_state; + + ret = mhi_ep_set_mhi_state(mhi_cntrl, MHI_STATE_M0); + if (ret) { + spin_unlock_bh(&mhi_cntrl->state_lock); + return ret; + } + + spin_unlock_bh(&mhi_cntrl->state_lock); + /* Signal host that the device moved to M0 */ + ret = mhi_ep_send_state_change_event(mhi_cntrl, MHI_STATE_M0); + if (ret) { + dev_err(dev, "Failed sending M0 state change event\n"); + return ret; + } + + if (old_state == MHI_STATE_READY) { + /* Allow the host to process state change event */ + mdelay(1); + + /* Send AMSS EE event to host */ + ret = mhi_ep_send_ee_event(mhi_cntrl, MHI_EP_AMSS_EE); + if (ret) { + dev_err(dev, "Failed sending AMSS EE event\n"); + return ret; + } + } + + return 0; +} + +int mhi_ep_set_m3_state(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct device *dev = &mhi_cntrl->mhi_dev->dev; + int ret; + + spin_lock_bh(&mhi_cntrl->state_lock); + ret = mhi_ep_set_mhi_state(mhi_cntrl, MHI_STATE_M3); + if (ret) { + spin_unlock_bh(&mhi_cntrl->state_lock); + return ret; + } + + spin_unlock_bh(&mhi_cntrl->state_lock); + + /* Signal host that the device moved to M3 */ + ret = mhi_ep_send_state_change_event(mhi_cntrl, MHI_STATE_M3); + if (ret) { + dev_err(dev, "Failed sending M3 state change event\n"); + return ret; + } + + return 0; +} + +int mhi_ep_set_ready_state(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct device *dev = &mhi_cntrl->mhi_dev->dev; + enum mhi_state mhi_state; + int ret, is_ready; + + spin_lock_bh(&mhi_cntrl->state_lock); + /* Ensure that the MHISTATUS is set to RESET by host */ + mhi_state = mhi_ep_mmio_masked_read(mhi_cntrl, MHISTATUS, MHISTATUS_MHISTATE_MASK); + is_ready = mhi_ep_mmio_masked_read(mhi_cntrl, MHISTATUS, MHISTATUS_READY_MASK); + + if (mhi_state != MHI_STATE_RESET || is_ready) { + dev_err(dev, "READY state transition failed. MHI host not in RESET state\n"); + spin_unlock_bh(&mhi_cntrl->state_lock); + return -EFAULT; + } + + ret = mhi_ep_set_mhi_state(mhi_cntrl, MHI_STATE_READY); + spin_unlock_bh(&mhi_cntrl->state_lock); + + return ret; +} diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 062133a68118..72ce30cbe87e 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -65,11 +65,14 @@ struct mhi_ep_db_info { * @ch_ctx_host_pa: Physical address of host channel context data structure * @ev_ctx_host_pa: Physical address of host event context data structure * @cmd_ctx_host_pa: Physical address of host command context data structure + * @state_wq: Dedicated workqueue for handling MHI state transitions * @ring_wq: Dedicated workqueue for processing MHI rings + * @state_work: State transition worker * @ring_work: Ring worker * @ch_db_list: List of queued channel doorbells * @st_transition_list: List of state transitions * @list_lock: Lock for protecting state transition and channel doorbell lists + * @state_lock: Lock for protecting state transitions * @event_lock: Lock for protecting event rings * @chdb: Array of channel doorbell interrupt info * @raise_irq: CB function for raising IRQ to the host @@ -105,12 +108,15 @@ struct mhi_ep_cntrl { u64 ev_ctx_host_pa; u64 cmd_ctx_host_pa; + struct workqueue_struct *state_wq; struct workqueue_struct *ring_wq; + struct work_struct state_work; struct work_struct ring_work; struct list_head ch_db_list; struct list_head st_transition_list; spinlock_t list_lock; + spinlock_t state_lock; struct mutex event_lock; struct mhi_ep_db_info chdb[4]; From patchwork Sat Feb 12 18:21:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 542171 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9BFF2C433F5 for ; Sat, 12 Feb 2022 18:23:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229854AbiBLSXP (ORCPT ); Sat, 12 Feb 2022 13:23:15 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:47330 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229842AbiBLSXO (ORCPT ); Sat, 12 Feb 2022 13:23:14 -0500 Received: from mail-pl1-x632.google.com (mail-pl1-x632.google.com [IPv6:2607:f8b0:4864:20::632]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6F6E95FF2B for ; Sat, 12 Feb 2022 10:22:58 -0800 (PST) Received: by mail-pl1-x632.google.com with SMTP id c3so7265232pls.5 for ; Sat, 12 Feb 2022 10:22:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=TXpSxFmkH++353D/y17KqaRLPut9rLTNrGcXF32Trzc=; b=aRb0qiKjLol0cgbSQjwI6F5aTfUs0oPPGzfMTA1pVM9h3FVngqTn4OYY+vGBv467zt ca2yxr/C6MynXZS6K1SBjDtOuLLAiE+F1UNb8Hh+GupKORAyie1iV344e6AwiLfs2MYP qRzmCe+VEAeAzhbHeyUzd4IaHn31KPLUVh+Ul0mSfqIXHHhNcU0/eT076SllrcPi2RGj yIJ5JK/2vYbpDVNtdHwttS3dBzB/umWeHrjsDfrdSmTgvhxe3wfO9ZIEH5QjTZbtAGyg bPKRwRw590vWUfvScxiwdcELzx+90CF7HiFSUqe96ROuSTYfYzIJk5lgUDAkkPUUGlRz ogzA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=TXpSxFmkH++353D/y17KqaRLPut9rLTNrGcXF32Trzc=; b=Iryf+zjdhekIJqUvgMvva/kVc8dEqqm+P8yuTbpquZagJNENskyFgNN2y4MJVIRG9+ QJOHIEBKI0APyWzO70threivvK4ib+KPBUUJCoPjqa7KI4oeGq+G+J75VvTdzmlBfD/s P6YxJukYCqfm+zJ3Tc28N3XUI9dOeI5rfxyM1X3N9rxriNjBwcY5mZTMhJm9v05pFgpI epoZvLUilpaojQIaXvwY7U0WgOlIJRwyitWGXFcm3UEhz2vJD8Z0daVuiuS2memtHRf3 6yVeUc6H/9JfFnD00XrKjnhnVt7QI9ZeS9KbTMysNB/gT99YMVbeJyjUoGCx51ItMtVK 4Ndw== X-Gm-Message-State: AOAM530IDgpDwVxVlqYVnyXMuLd0/2aA2lXbDyBZjeZ7lErTOjcDNCdW ZgBi9dNJwiIMAenBlvx3EVY1 X-Google-Smtp-Source: ABdhPJyhXLccNlgPfvYFLXpxrQrPm1ffN3TfV+KsExAFC7fraqn+4U76adIJtahyNO1VLsC/3tBUmA== X-Received: by 2002:a17:903:32cb:: with SMTP id i11mr6797100plr.118.1644690177841; Sat, 12 Feb 2022 10:22:57 -0800 (PST) Received: from localhost.localdomain ([27.111.75.57]) by smtp.gmail.com with ESMTPSA id g12sm14961987pfj.148.2022.02.12.10.22.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Feb 2022 10:22:57 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v3 15/25] bus: mhi: ep: Add support for processing MHI endpoint interrupts Date: Sat, 12 Feb 2022 23:51:07 +0530 Message-Id: <20220212182117.49438-16-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> References: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Add support for processing MHI endpoint interrupts such as control interrupt, command interrupt and channel interrupt from the host. The interrupts will be generated in the endpoint device whenever host writes to the corresponding doorbell registers. The doorbell logic is handled inside the hardware internally. Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/ep/main.c | 113 +++++++++++++++++++++++++++++++++++++- include/linux/mhi_ep.h | 2 + 2 files changed, 113 insertions(+), 2 deletions(-) diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index ccb3c2795041..072b872e735b 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -185,6 +185,56 @@ static void mhi_ep_ring_worker(struct work_struct *work) } } +static void mhi_ep_queue_channel_db(struct mhi_ep_cntrl *mhi_cntrl, + unsigned long ch_int, u32 ch_idx) +{ + struct device *dev = &mhi_cntrl->mhi_dev->dev; + struct mhi_ep_ring_item *item; + struct mhi_ep_ring *ring; + unsigned int i; + + for_each_set_bit(i, &ch_int, 32) { + /* Channel index varies for each register: 0, 32, 64, 96 */ + i += ch_idx; + ring = &mhi_cntrl->mhi_chan[i].ring; + + item = kmalloc(sizeof(*item), GFP_ATOMIC); + item->ring = ring; + + dev_dbg(dev, "Queuing doorbell interrupt for channel (%d)\n", i); + spin_lock(&mhi_cntrl->list_lock); + list_add_tail(&item->node, &mhi_cntrl->ch_db_list); + spin_unlock(&mhi_cntrl->list_lock); + + queue_work(mhi_cntrl->ring_wq, &mhi_cntrl->ring_work); + } +} + +/* + * Channel interrupt statuses are contained in 4 registers each of 32bit length. + * For checking all interrupts, we need to loop through each registers and then + * check for bits set. + */ +static void mhi_ep_check_channel_interrupt(struct mhi_ep_cntrl *mhi_cntrl) +{ + u32 ch_int, ch_idx; + int i; + + mhi_ep_mmio_read_chdb_status_interrupts(mhi_cntrl); + + for (i = 0; i < MHI_MASK_ROWS_CH_EV_DB; i++) { + ch_idx = i * MHI_MASK_CH_EV_LEN; + + /* Only process channel interrupt if the mask is enabled */ + ch_int = (mhi_cntrl->chdb[i].status & mhi_cntrl->chdb[i].mask); + if (ch_int) { + mhi_ep_queue_channel_db(mhi_cntrl, ch_int, ch_idx); + mhi_ep_mmio_write(mhi_cntrl, MHI_CHDB_INT_CLEAR_A7_n(i), + mhi_cntrl->chdb[i].status); + } + } +} + static void mhi_ep_state_worker(struct work_struct *work) { struct mhi_ep_cntrl *mhi_cntrl = container_of(work, struct mhi_ep_cntrl, state_work); @@ -222,6 +272,53 @@ static void mhi_ep_state_worker(struct work_struct *work) } } +static void mhi_ep_process_ctrl_interrupt(struct mhi_ep_cntrl *mhi_cntrl, + enum mhi_state state) +{ + struct mhi_ep_state_transition *item = kmalloc(sizeof(*item), GFP_ATOMIC); + + item->state = state; + spin_lock(&mhi_cntrl->list_lock); + list_add_tail(&item->node, &mhi_cntrl->st_transition_list); + spin_unlock(&mhi_cntrl->list_lock); + + queue_work(mhi_cntrl->state_wq, &mhi_cntrl->state_work); +} + +/* + * Interrupt handler that services interrupts raised by the host writing to + * MHICTRL and Command ring doorbell (CRDB) registers for state change and + * channel interrupts. + */ +static irqreturn_t mhi_ep_irq(int irq, void *data) +{ + struct mhi_ep_cntrl *mhi_cntrl = data; + struct device *dev = &mhi_cntrl->mhi_dev->dev; + enum mhi_state state; + u32 int_value; + + /* Acknowledge the interrupts */ + int_value = mhi_ep_mmio_read(mhi_cntrl, MHI_CTRL_INT_STATUS_A7); + mhi_ep_mmio_write(mhi_cntrl, MHI_CTRL_INT_CLEAR_A7, int_value); + + /* Check for ctrl interrupt */ + if (FIELD_GET(MHI_CTRL_INT_STATUS_A7_MSK, int_value)) { + dev_dbg(dev, "Processing ctrl interrupt\n"); + mhi_ep_process_ctrl_interrupt(mhi_cntrl, state); + } + + /* Check for command doorbell interrupt */ + if (FIELD_GET(MHI_CTRL_INT_STATUS_CRDB_MSK, int_value)) { + dev_dbg(dev, "Processing command doorbell interrupt\n"); + queue_work(mhi_cntrl->ring_wq, &mhi_cntrl->ring_work); + } + + /* Check for channel interrupts */ + mhi_ep_check_channel_interrupt(mhi_cntrl); + + return IRQ_HANDLED; +} + static void mhi_ep_release_device(struct device *dev) { struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev); @@ -409,7 +506,7 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_device *mhi_dev; int ret; - if (!mhi_cntrl || !mhi_cntrl->cntrl_dev || !mhi_cntrl->mmio) + if (!mhi_cntrl || !mhi_cntrl->cntrl_dev || !mhi_cntrl->mmio || !mhi_cntrl->irq) return -EINVAL; ret = parse_ch_cfg(mhi_cntrl, config); @@ -454,12 +551,20 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, goto err_destroy_state_wq; } + irq_set_status_flags(mhi_cntrl->irq, IRQ_NOAUTOEN); + ret = request_irq(mhi_cntrl->irq, mhi_ep_irq, IRQF_TRIGGER_HIGH, + "doorbell_irq", mhi_cntrl); + if (ret) { + dev_err(mhi_cntrl->cntrl_dev, "Failed to request Doorbell IRQ\n"); + goto err_ida_free; + } + /* Allocate the controller device */ mhi_dev = mhi_ep_alloc_device(mhi_cntrl, MHI_DEVICE_CONTROLLER); if (IS_ERR(mhi_dev)) { dev_err(mhi_cntrl->cntrl_dev, "Failed to allocate controller device\n"); ret = PTR_ERR(mhi_dev); - goto err_ida_free; + goto err_free_irq; } dev_set_name(&mhi_dev->dev, "mhi_ep%d", mhi_cntrl->index); @@ -477,6 +582,8 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, err_put_dev: put_device(&mhi_dev->dev); +err_free_irq: + free_irq(mhi_cntrl->irq, mhi_cntrl); err_ida_free: ida_free(&mhi_ep_cntrl_ida, mhi_cntrl->index); err_destroy_state_wq: @@ -499,6 +606,8 @@ void mhi_ep_unregister_controller(struct mhi_ep_cntrl *mhi_cntrl) destroy_workqueue(mhi_cntrl->state_wq); destroy_workqueue(mhi_cntrl->ring_wq); + free_irq(mhi_cntrl->irq, mhi_cntrl); + kfree(mhi_cntrl->mhi_cmd); kfree(mhi_cntrl->mhi_chan); diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 72ce30cbe87e..a207058a4991 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -90,6 +90,7 @@ struct mhi_ep_db_info { * @chdb_offset: Channel doorbell offset set by the host * @erdb_offset: Event ring doorbell offset set by the host * @index: MHI Endpoint controller index + * @irq: IRQ used by the endpoint controller */ struct mhi_ep_cntrl { struct device *cntrl_dev; @@ -142,6 +143,7 @@ struct mhi_ep_cntrl { u32 chdb_offset; u32 erdb_offset; int index; + int irq; }; /** From patchwork Sat Feb 12 18:21:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 542588 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 00BD2C433F5 for ; Sat, 12 Feb 2022 18:23:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229862AbiBLSXS (ORCPT ); Sat, 12 Feb 2022 13:23:18 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:47432 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229903AbiBLSXR (ORCPT ); Sat, 12 Feb 2022 13:23:17 -0500 Received: from mail-pl1-x62c.google.com (mail-pl1-x62c.google.com [IPv6:2607:f8b0:4864:20::62c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C61BC5BD24 for ; Sat, 12 Feb 2022 10:23:02 -0800 (PST) Received: by mail-pl1-x62c.google.com with SMTP id x3so7260614pll.3 for ; Sat, 12 Feb 2022 10:23:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=vOmmbrSNxmau9lTsvUDcXn9EkQVZP0/Kf324XUTxwjo=; b=b0hLTyy1T/GJJOR3l9jTU3BAdQ+WHYEYZMIcsQWath5P69/OrSFu+9h37CwQROXYwu +69Yf1w+ReEtSVv2kfQm6d9+8lMs0867DRO3JXCmHsV1+cB1yszEuuki5aCDm301GJVE DW2q+PkxFbWK1V/cr8XzMkl03AOMtXPC2jcClxYiUit3dgdpQKXaWkqroRq2CUL1jQyC ALlDVTYJ8Oej55W33W8rt9ltupBIj0fY0KeIZl6g3fzjk0o0f/3cmnzsSwP+vOBNbhS5 uIITh4ZoVcLZ78iQzgunYhVq7ffbgvBxaErJkhtsDBpT0EYik4B7hFN7HYaLrPcOcGP4 mt6A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=vOmmbrSNxmau9lTsvUDcXn9EkQVZP0/Kf324XUTxwjo=; b=StdxSesBASxsTIV2w59OG88ImsXYVs6HqPmjmYCRZ2m7XtEbSjSKGMib0X6m3+D9Un BKju1GUN5sqcTTelPy87FBoXZ+EKrA/j5Dc8YGYb14EOBHo4J7loqgslSa6xKGH8Dmtj M1bpLwA3Ivnxohrj90tGz28Xb91tJn1/Qm+Z7fdiQXIFpgTTkTeWw7i0jtKKqYZx3wCO wQOkxG1x1ll1iakUnyxi5IGnF/wIJ6AjxrdJRj7afJG/m72cDC5s5d/Yph0/AAjkqb6W VIwC2ULH4G2U1sJgrGByfrWUpv1YYp/4u8pBFYvXmY0YgwN4LmEesYLTTPMxgo1TLzYB D+Xg== X-Gm-Message-State: AOAM532/WBXP2p9oy+Be+DBFFMmydJ10X3J5cK7bhqGXM9sBSj3W3nnB pG3nD2ygarpfyBPHk2gwt99YaGo/E9Xk1pU= X-Google-Smtp-Source: ABdhPJwLCuFD0qvOnqY75rNyJESD1apojCf0REVf1J3Dm9B9G9D7zKTHeKFsw5jLCIt8QCfD9/NJ8Q== X-Received: by 2002:a17:902:7c84:: with SMTP id y4mr6805187pll.149.1644690182219; Sat, 12 Feb 2022 10:23:02 -0800 (PST) Received: from localhost.localdomain ([27.111.75.57]) by smtp.gmail.com with ESMTPSA id g12sm14961987pfj.148.2022.02.12.10.22.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Feb 2022 10:23:01 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v3 16/25] bus: mhi: ep: Add support for powering up the MHI endpoint stack Date: Sat, 12 Feb 2022 23:51:08 +0530 Message-Id: <20220212182117.49438-17-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> References: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Add support for MHI endpoint power_up that includes initializing the MMIO and rings, caching the host MHI registers, and setting the MHI state to M0. After registering the MHI EP controller, the stack has to be powered up for usage. Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/ep/internal.h | 6 + drivers/bus/mhi/ep/main.c | 229 ++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 22 ++++ 3 files changed, 257 insertions(+) diff --git a/drivers/bus/mhi/ep/internal.h b/drivers/bus/mhi/ep/internal.h index e4e8f06c2898..ee8c5974f0c0 100644 --- a/drivers/bus/mhi/ep/internal.h +++ b/drivers/bus/mhi/ep/internal.h @@ -242,4 +242,10 @@ int mhi_ep_set_m0_state(struct mhi_ep_cntrl *mhi_cntrl); int mhi_ep_set_m3_state(struct mhi_ep_cntrl *mhi_cntrl); int mhi_ep_set_ready_state(struct mhi_ep_cntrl *mhi_cntrl); +/* MHI EP memory management functions */ +int mhi_ep_alloc_map(struct mhi_ep_cntrl *mhi_cntrl, u64 pci_addr, size_t size, + phys_addr_t *phys_ptr, void __iomem **virt); +void mhi_ep_unmap_free(struct mhi_ep_cntrl *mhi_cntrl, u64 pci_addr, phys_addr_t phys, + void __iomem *virt, size_t size); + #endif diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 072b872e735b..016e819f640a 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -16,6 +16,9 @@ #include #include "internal.h" +#define MHI_SUSPEND_MIN 100 +#define MHI_SUSPEND_TIMEOUT 600 + static DEFINE_IDA(mhi_ep_cntrl_ida); static int mhi_ep_send_event(struct mhi_ep_cntrl *mhi_cntrl, u32 ring_idx, @@ -143,6 +146,176 @@ static int mhi_ep_send_cmd_comp_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_e return mhi_ep_send_event(mhi_cntrl, 0, &event); } +int mhi_ep_alloc_map(struct mhi_ep_cntrl *mhi_cntrl, u64 pci_addr, size_t size, + phys_addr_t *phys_ptr, void __iomem **virt) +{ + size_t offset = pci_addr % 0x1000; + void __iomem *buf; + phys_addr_t phys; + int ret; + + size += offset; + + buf = mhi_cntrl->alloc_addr(mhi_cntrl, &phys, size); + if (!buf) + return -ENOMEM; + + ret = mhi_cntrl->map_addr(mhi_cntrl, phys, pci_addr - offset, size); + if (ret) { + mhi_cntrl->free_addr(mhi_cntrl, phys, buf, size); + return ret; + } + + *phys_ptr = phys + offset; + *virt = buf + offset; + + return 0; +} + +void mhi_ep_unmap_free(struct mhi_ep_cntrl *mhi_cntrl, u64 pci_addr, phys_addr_t phys, + void __iomem *virt, size_t size) +{ + size_t offset = pci_addr % 0x1000; + + size += offset; + + mhi_cntrl->unmap_addr(mhi_cntrl, phys - offset); + mhi_cntrl->free_addr(mhi_cntrl, phys - offset, virt - offset, size); +} + +static int mhi_ep_cache_host_cfg(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct device *dev = &mhi_cntrl->mhi_dev->dev; + int ret; + + /* Update the number of event rings (NER) programmed by the host */ + mhi_ep_mmio_update_ner(mhi_cntrl); + + dev_dbg(dev, "Number of Event rings: %d, HW Event rings: %d\n", + mhi_cntrl->event_rings, mhi_cntrl->hw_event_rings); + + mhi_cntrl->ch_ctx_host_size = sizeof(struct mhi_chan_ctxt) * + mhi_cntrl->max_chan; + mhi_cntrl->ev_ctx_host_size = sizeof(struct mhi_event_ctxt) * + mhi_cntrl->event_rings; + mhi_cntrl->cmd_ctx_host_size = sizeof(struct mhi_cmd_ctxt); + + /* Get the channel context base pointer from host */ + mhi_ep_mmio_get_chc_base(mhi_cntrl); + + /* Allocate and map memory for caching host channel context */ + ret = mhi_ep_alloc_map(mhi_cntrl, mhi_cntrl->ch_ctx_host_pa, mhi_cntrl->ch_ctx_host_size, + &mhi_cntrl->ch_ctx_cache_phys, + (void __iomem **)&mhi_cntrl->ch_ctx_cache); + if (ret) { + dev_err(dev, "Failed to allocate and map ch_ctx_cache\n"); + return ret; + } + + /* Get the event context base pointer from host */ + mhi_ep_mmio_get_erc_base(mhi_cntrl); + + /* Allocate and map memory for caching host event context */ + ret = mhi_ep_alloc_map(mhi_cntrl, mhi_cntrl->ev_ctx_host_pa, mhi_cntrl->ev_ctx_host_size, + &mhi_cntrl->ev_ctx_cache_phys, + (void __iomem **)&mhi_cntrl->ev_ctx_cache); + if (ret) { + dev_err(dev, "Failed to allocate and map ev_ctx_cache\n"); + goto err_ch_ctx; + } + + /* Get the command context base pointer from host */ + mhi_ep_mmio_get_crc_base(mhi_cntrl); + + /* Allocate and map memory for caching host command context */ + ret = mhi_ep_alloc_map(mhi_cntrl, mhi_cntrl->cmd_ctx_host_pa, mhi_cntrl->cmd_ctx_host_size, + &mhi_cntrl->cmd_ctx_cache_phys, + (void __iomem **)&mhi_cntrl->cmd_ctx_cache); + if (ret) { + dev_err(dev, "Failed to allocate and map cmd_ctx_cache\n"); + goto err_ev_ctx; + } + + /* Initialize command ring */ + ret = mhi_ep_ring_start(mhi_cntrl, &mhi_cntrl->mhi_cmd->ring, + (union mhi_ep_ring_ctx *)mhi_cntrl->cmd_ctx_cache); + if (ret) { + dev_err(dev, "Failed to start the command ring\n"); + goto err_cmd_ctx; + } + + return ret; + +err_cmd_ctx: + mhi_ep_unmap_free(mhi_cntrl, mhi_cntrl->cmd_ctx_host_pa, mhi_cntrl->cmd_ctx_cache_phys, + mhi_cntrl->cmd_ctx_cache, mhi_cntrl->cmd_ctx_host_size); + +err_ev_ctx: + mhi_ep_unmap_free(mhi_cntrl, mhi_cntrl->ev_ctx_host_pa, mhi_cntrl->ev_ctx_cache_phys, + mhi_cntrl->ev_ctx_cache, mhi_cntrl->ev_ctx_host_size); + +err_ch_ctx: + mhi_ep_unmap_free(mhi_cntrl, mhi_cntrl->ch_ctx_host_pa, mhi_cntrl->ch_ctx_cache_phys, + mhi_cntrl->ch_ctx_cache, mhi_cntrl->ch_ctx_host_size); + + return ret; +} + +static void mhi_ep_free_host_cfg(struct mhi_ep_cntrl *mhi_cntrl) +{ + mhi_ep_unmap_free(mhi_cntrl, mhi_cntrl->cmd_ctx_host_pa, mhi_cntrl->cmd_ctx_cache_phys, + mhi_cntrl->cmd_ctx_cache, mhi_cntrl->cmd_ctx_host_size); + mhi_ep_unmap_free(mhi_cntrl, mhi_cntrl->ev_ctx_host_pa, mhi_cntrl->ev_ctx_cache_phys, + mhi_cntrl->ev_ctx_cache, mhi_cntrl->ev_ctx_host_size); + mhi_ep_unmap_free(mhi_cntrl, mhi_cntrl->ch_ctx_host_pa, mhi_cntrl->ch_ctx_cache_phys, + mhi_cntrl->ch_ctx_cache, mhi_cntrl->ch_ctx_host_size); +} + +static void mhi_ep_enable_int(struct mhi_ep_cntrl *mhi_cntrl) +{ + mhi_ep_mmio_enable_ctrl_interrupt(mhi_cntrl); + mhi_ep_mmio_enable_cmdb_interrupt(mhi_cntrl); +} + +static int mhi_ep_enable(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct device *dev = &mhi_cntrl->mhi_dev->dev; + enum mhi_state state; + u32 max_cnt = 0; + bool mhi_reset; + int ret; + + /* Wait for Host to set the M0 state */ + do { + msleep(MHI_SUSPEND_MIN); + mhi_ep_mmio_get_mhi_state(mhi_cntrl, &state, &mhi_reset); + if (mhi_reset) { + /* Clear the MHI reset if host is in reset state */ + mhi_ep_mmio_clear_reset(mhi_cntrl); + dev_dbg(dev, "Host initiated reset while waiting for M0\n"); + } + max_cnt++; + } while (state != MHI_STATE_M0 && max_cnt < MHI_SUSPEND_TIMEOUT); + + if (state == MHI_STATE_M0) { + ret = mhi_ep_cache_host_cfg(mhi_cntrl); + if (ret) { + dev_err(dev, "Failed to cache host config\n"); + return ret; + } + + mhi_ep_mmio_set_env(mhi_cntrl, MHI_EP_AMSS_EE); + } else { + dev_err(dev, "Host failed to enter M0\n"); + return -ETIMEDOUT; + } + + /* Enable all interrupts now */ + mhi_ep_enable_int(mhi_cntrl); + + return 0; +} + static void mhi_ep_ring_worker(struct work_struct *work) { struct mhi_ep_cntrl *mhi_cntrl = container_of(work, @@ -319,6 +492,62 @@ static irqreturn_t mhi_ep_irq(int irq, void *data) return IRQ_HANDLED; } +int mhi_ep_power_up(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct device *dev = &mhi_cntrl->mhi_dev->dev; + int ret, i; + + /* + * Mask all interrupts until the state machine is ready. Interrupts will + * be enabled later with mhi_ep_enable(). + */ + mhi_ep_mmio_mask_interrupts(mhi_cntrl); + mhi_ep_mmio_init(mhi_cntrl); + + mhi_cntrl->mhi_event = kzalloc(mhi_cntrl->event_rings * (sizeof(*mhi_cntrl->mhi_event)), + GFP_KERNEL); + if (!mhi_cntrl->mhi_event) + return -ENOMEM; + + /* Initialize command, channel and event rings */ + mhi_ep_ring_init(&mhi_cntrl->mhi_cmd->ring, RING_TYPE_CMD, 0); + for (i = 0; i < mhi_cntrl->max_chan; i++) + mhi_ep_ring_init(&mhi_cntrl->mhi_chan[i].ring, RING_TYPE_CH, i); + for (i = 0; i < mhi_cntrl->event_rings; i++) + mhi_ep_ring_init(&mhi_cntrl->mhi_event[i].ring, RING_TYPE_ER, i); + + spin_lock_bh(&mhi_cntrl->state_lock); + mhi_cntrl->mhi_state = MHI_STATE_RESET; + spin_unlock_bh(&mhi_cntrl->state_lock); + + /* Set AMSS EE before signaling ready state */ + mhi_ep_mmio_set_env(mhi_cntrl, MHI_EP_AMSS_EE); + + /* All set, notify the host that we are ready */ + ret = mhi_ep_set_ready_state(mhi_cntrl); + if (ret) + goto err_free_event; + + dev_dbg(dev, "READY state notification sent to the host\n"); + + ret = mhi_ep_enable(mhi_cntrl); + if (ret) { + dev_err(dev, "Failed to enable MHI endpoint\n"); + goto err_free_event; + } + + enable_irq(mhi_cntrl->irq); + mhi_cntrl->is_enabled = true; + + return 0; + +err_free_event: + kfree(mhi_cntrl->mhi_event); + + return ret; +} +EXPORT_SYMBOL_GPL(mhi_ep_power_up); + static void mhi_ep_release_device(struct device *dev) { struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev); diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index a207058a4991..53895f1c68e1 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -65,6 +65,12 @@ struct mhi_ep_db_info { * @ch_ctx_host_pa: Physical address of host channel context data structure * @ev_ctx_host_pa: Physical address of host event context data structure * @cmd_ctx_host_pa: Physical address of host command context data structure + * @ch_ctx_cache_phys: Physical address of the host channel context cache + * @ev_ctx_cache_phys: Physical address of the host event context cache + * @cmd_ctx_cache_phys: Physical address of the host command context cache + * @ch_ctx_host_size: Size of the host channel context data structure + * @ev_ctx_host_size: Size of the host event context data structure + * @cmd_ctx_host_size: Size of the host command context data structure * @state_wq: Dedicated workqueue for handling MHI state transitions * @ring_wq: Dedicated workqueue for processing MHI rings * @state_work: State transition worker @@ -91,6 +97,7 @@ struct mhi_ep_db_info { * @erdb_offset: Event ring doorbell offset set by the host * @index: MHI Endpoint controller index * @irq: IRQ used by the endpoint controller + * @is_enabled: Check if the endpoint controller is enabled or not */ struct mhi_ep_cntrl { struct device *cntrl_dev; @@ -108,6 +115,12 @@ struct mhi_ep_cntrl { u64 ch_ctx_host_pa; u64 ev_ctx_host_pa; u64 cmd_ctx_host_pa; + phys_addr_t ch_ctx_cache_phys; + phys_addr_t ev_ctx_cache_phys; + phys_addr_t cmd_ctx_cache_phys; + size_t ch_ctx_host_size; + size_t ev_ctx_host_size; + size_t cmd_ctx_host_size; struct workqueue_struct *state_wq; struct workqueue_struct *ring_wq; @@ -144,6 +157,7 @@ struct mhi_ep_cntrl { u32 erdb_offset; int index; int irq; + bool is_enabled; }; /** @@ -238,4 +252,12 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, */ void mhi_ep_unregister_controller(struct mhi_ep_cntrl *mhi_cntrl); +/** + * mhi_ep_power_up - Power up the MHI endpoint stack + * @mhi_cntrl: MHI Endpoint controller + * + * Return: 0 if power up succeeds, a negative error code otherwise. + */ +int mhi_ep_power_up(struct mhi_ep_cntrl *mhi_cntrl); + #endif From patchwork Sat Feb 12 18:21:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 542170 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 481BFC433EF for ; Sat, 12 Feb 2022 18:23:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229980AbiBLSX2 (ORCPT ); Sat, 12 Feb 2022 13:23:28 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:47774 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229902AbiBLSX1 (ORCPT ); Sat, 12 Feb 2022 13:23:27 -0500 Received: from mail-pl1-x62a.google.com (mail-pl1-x62a.google.com [IPv6:2607:f8b0:4864:20::62a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D86145FF07 for ; Sat, 12 Feb 2022 10:23:06 -0800 (PST) Received: by mail-pl1-x62a.google.com with SMTP id x4so7260019plb.4 for ; Sat, 12 Feb 2022 10:23:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Et3UmaSI3XUp/0zr/hwPTmUKeNrGOKIPlwFzxB6LurA=; b=yRV6USNNPuO9dPgcA7Eqbhg70sy1oivDCCGDWfwlqmRvdqMjgxfZEHX1lJ5Y83Ozcs nZoZuJEybjxCdeznbPzv4ZKsgYdXo4/5NRJRNVpHvktBPSyuqwXtXAFd2DHUAUBayKnE UpMjQD6A/6jX0hVLJm7gsy0CRnTAaiUS09pARMci3wMLrotL5RcMV9WeenWE+cqm6v1k NVdxpn5yNwrGHck0l3zTtuBV997zLK/n33YXLlWA8e0JFrbRlktXFly13Wk6YfEQOy3g +X0A3WiZ1jaDjPpfkFGQmjw8AhGTSwX2xjwFbQ0w2XNJEPR1krphHO3lFPqrNPBUY858 YtZw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Et3UmaSI3XUp/0zr/hwPTmUKeNrGOKIPlwFzxB6LurA=; b=u3X2OTmGS/21ubLP5MpJZUBYvagJfL9p56clm12+eo7Bu/3KBkDaDrU8U4UeDHGbZp R97oDp/Dm9fFWU42ZPJiIused9DWDK5iY44G2L3e4gdNhBKyTyJOTR1Ql0mt9SyTu70+ QAS9Z/OkAAy+hS5IdNXZfB3pcy8500e0Q1TN66pKKII4V03blEnQYTnGKvJwc/NeCVD7 rpq4EeCWPsb9vKeLraD0zARBsAAMGfjXjyjUPUN6KdczZf08coXImccjdjfK0PsG1w5Z 2XbeFZ89tIEcylYfGQb1qrX8cMKVratDKDsR8Niq3pSt0KSncDst7aOLCrL8Ygnwyyf/ XLgw== X-Gm-Message-State: AOAM531gTYe4LhWSdTcfCkFDBvdvFQmqVgJkdRY0+fiyr6Q6Q0Vqf+bN Dj8C/2ZGizB74s/x9EUgkeDh X-Google-Smtp-Source: ABdhPJyQe1bE8FxZ3ysWp54sVedcAx8a2TfWGKEOu2E0KFFqiBOTHdvoq4m43njxHo8YG4UMFJfKVg== X-Received: by 2002:a17:90a:741:: with SMTP id s1mr6400954pje.161.1644690186313; Sat, 12 Feb 2022 10:23:06 -0800 (PST) Received: from localhost.localdomain ([27.111.75.57]) by smtp.gmail.com with ESMTPSA id g12sm14961987pfj.148.2022.02.12.10.23.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Feb 2022 10:23:05 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v3 17/25] bus: mhi: ep: Add support for powering down the MHI endpoint stack Date: Sat, 12 Feb 2022 23:51:09 +0530 Message-Id: <20220212182117.49438-18-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> References: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Add support for MHI endpoint power_down that includes stopping all available channels, destroying the channels, resetting the event and transfer rings and freeing the host cache. The stack will be powered down whenever the physical bus link goes down. Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/ep/main.c | 81 +++++++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 6 +++ 2 files changed, 87 insertions(+) diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 016e819f640a..14cb08de4263 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -21,6 +21,8 @@ static DEFINE_IDA(mhi_ep_cntrl_ida); +static int mhi_ep_destroy_device(struct device *dev, void *data); + static int mhi_ep_send_event(struct mhi_ep_cntrl *mhi_cntrl, u32 ring_idx, struct mhi_ep_ring_element *el) { @@ -492,6 +494,71 @@ static irqreturn_t mhi_ep_irq(int irq, void *data) return IRQ_HANDLED; } +static void mhi_ep_abort_transfer(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct mhi_ep_ring *ch_ring, *ev_ring; + struct mhi_result result = {}; + struct mhi_ep_chan *mhi_chan; + int i; + + /* Stop all the channels */ + for (i = 0; i < mhi_cntrl->max_chan; i++) { + ch_ring = &mhi_cntrl->mhi_chan[i].ring; + if (!ch_ring->started) + continue; + + mhi_chan = &mhi_cntrl->mhi_chan[i]; + mutex_lock(&mhi_chan->lock); + /* Send channel disconnect status to client drivers */ + if (mhi_chan->xfer_cb) { + result.transaction_status = -ENOTCONN; + result.bytes_xferd = 0; + mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); + } + + /* Set channel state to DISABLED */ + mhi_chan->state = MHI_CH_STATE_DISABLED; + mutex_unlock(&mhi_chan->lock); + } + + flush_workqueue(mhi_cntrl->ring_wq); + flush_workqueue(mhi_cntrl->state_wq); + + /* Destroy devices associated with all channels */ + device_for_each_child(&mhi_cntrl->mhi_dev->dev, NULL, mhi_ep_destroy_device); + + /* Stop and reset the transfer rings */ + for (i = 0; i < mhi_cntrl->max_chan; i++) { + ch_ring = &mhi_cntrl->mhi_chan[i].ring; + if (!ch_ring->started) + continue; + + mhi_chan = &mhi_cntrl->mhi_chan[i]; + mutex_lock(&mhi_chan->lock); + mhi_ep_ring_reset(mhi_cntrl, ch_ring); + mutex_unlock(&mhi_chan->lock); + } + + /* Stop and reset the event rings */ + for (i = 0; i < mhi_cntrl->event_rings; i++) { + ev_ring = &mhi_cntrl->mhi_event[i].ring; + if (!ev_ring->started) + continue; + + mutex_lock(&mhi_cntrl->event_lock); + mhi_ep_ring_reset(mhi_cntrl, ev_ring); + mutex_unlock(&mhi_cntrl->event_lock); + } + + /* Stop and reset the command ring */ + mhi_ep_ring_reset(mhi_cntrl, &mhi_cntrl->mhi_cmd->ring); + + mhi_ep_free_host_cfg(mhi_cntrl); + mhi_ep_mmio_mask_interrupts(mhi_cntrl); + + mhi_cntrl->is_enabled = false; +} + int mhi_ep_power_up(struct mhi_ep_cntrl *mhi_cntrl) { struct device *dev = &mhi_cntrl->mhi_dev->dev; @@ -548,6 +615,16 @@ int mhi_ep_power_up(struct mhi_ep_cntrl *mhi_cntrl) } EXPORT_SYMBOL_GPL(mhi_ep_power_up); +void mhi_ep_power_down(struct mhi_ep_cntrl *mhi_cntrl) +{ + if (mhi_cntrl->is_enabled) + mhi_ep_abort_transfer(mhi_cntrl); + + kfree(mhi_cntrl->mhi_event); + disable_irq(mhi_cntrl->irq); +} +EXPORT_SYMBOL_GPL(mhi_ep_power_down); + static void mhi_ep_release_device(struct device *dev) { struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev); @@ -828,6 +905,10 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, } EXPORT_SYMBOL_GPL(mhi_ep_register_controller); +/* + * It is expected that the controller drivers will power down the MHI EP stack + * using "mhi_ep_power_down()" before calling this function to unregister themselves. + */ void mhi_ep_unregister_controller(struct mhi_ep_cntrl *mhi_cntrl) { struct mhi_ep_device *mhi_dev = mhi_cntrl->mhi_dev; diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 53895f1c68e1..4f86e7986c93 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -260,4 +260,10 @@ void mhi_ep_unregister_controller(struct mhi_ep_cntrl *mhi_cntrl); */ int mhi_ep_power_up(struct mhi_ep_cntrl *mhi_cntrl); +/** + * mhi_ep_power_down - Power down the MHI endpoint stack + * @mhi_cntrl: MHI controller + */ +void mhi_ep_power_down(struct mhi_ep_cntrl *mhi_cntrl); + #endif From patchwork Sat Feb 12 18:21:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 542587 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E3DC5C433FE for ; Sat, 12 Feb 2022 18:23:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229985AbiBLSXb (ORCPT ); Sat, 12 Feb 2022 13:23:31 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:47848 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229902AbiBLSX3 (ORCPT ); Sat, 12 Feb 2022 13:23:29 -0500 Received: from mail-pf1-x436.google.com (mail-pf1-x436.google.com [IPv6:2607:f8b0:4864:20::436]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A6C9E6004A for ; Sat, 12 Feb 2022 10:23:11 -0800 (PST) Received: by mail-pf1-x436.google.com with SMTP id d187so21920636pfa.10 for ; Sat, 12 Feb 2022 10:23:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Ng+FJmRFoQc89QlNXGEu6Nz+DsWMowqD6JzTm0cBnHI=; b=VPJI5RfGfxcBSf0QCISXQcbfstewq+3Xs+C4gL6WufagubJPmyHN1LYFaXIqL+YlHz uIAzpSjT5zk7jpumLD3QfrKQhj3xn5kGYFV5jNqIDx/rtokTPd8Ha7wvaJKeUwAM8bum HP2OhF0laEajy6uQVBDTxSssHFmyF1ZI1JEXWoszjyLyJD0nJWiKT8Hw8ObO/FNuJ1Qq R4bTaty9M3qIo/tQ9N0Z4g5Ei9uEFtTn4eyArgXPkIHKAz+fIn6CXjS3+JoQplEsxgbA Bbo5M/ycAM8KLD+TR7m17FbqyfP53rA/ojJd8EcCnmU9nsnO3RnU5NoqBskCILFHmIXL T+HQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Ng+FJmRFoQc89QlNXGEu6Nz+DsWMowqD6JzTm0cBnHI=; b=jAunTRGkYPE9k2tcYADXqX+T8PwvIpliHGZUwSqAOQZ/Cb37axqMOaSu/R20mpK1jr KBM/CKpMQhsbJy2I4BJJcp9d5e44U+qmewOMhXPvLaG5MGTOx3GX03xQnhL5RrJ3ZhmX Pj+Pr0UuDdT4mM7Z8rMnq1CAaCdTYwF/Lz9kP6MkY/zYkKB2nKQ+UUrddaWp+0frm28+ zh2FCfLeKngal5Dtt3Uo8VMFGMNRyZr0aQS3AgQYAG7Zc4vu6uPdZcOKun2gHesSMUbd 6riFlSTLddNKlz1E2MYLz+J9+2sgO8xrfM+PyiZ9aUNiz5b+ii9vdeEXaWMpmAHfjg4b IvQw== X-Gm-Message-State: AOAM5314ccRWoHvmjiUE4weJ8Edq3DrZiPcdsfzPFJYHrstEYsBgzCDp EcCQS/dshQopGIHSBfvkDy5K X-Google-Smtp-Source: ABdhPJxzQw7S9tasrOjpKXFp+CMbejZJTVo1V7X6T1PPGnxNyTmSRhp1q/FXC/uKEFOs432QgWAE4A== X-Received: by 2002:a65:458f:: with SMTP id o15mr4100193pgq.92.1644690191159; Sat, 12 Feb 2022 10:23:11 -0800 (PST) Received: from localhost.localdomain ([27.111.75.57]) by smtp.gmail.com with ESMTPSA id g12sm14961987pfj.148.2022.02.12.10.23.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Feb 2022 10:23:10 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v3 18/25] bus: mhi: ep: Add support for handling MHI_RESET Date: Sat, 12 Feb 2022 23:51:10 +0530 Message-Id: <20220212182117.49438-19-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> References: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Add support for handling MHI_RESET in MHI endpoint stack. MHI_RESET will be issued by the host during shutdown and during error scenario so that it can recover the endpoint device without restarting the whole device. MHI_RESET handling involves resetting the internal MHI registers, data structures, state machines, resetting all channels/rings and setting MHICTRL.RESET bit to 0. Additionally the device will also move to READY state if the reset was due to SYS_ERR. Signed-off-by: Manivannan Sadhasivam Reviewed-by: Alex Elder --- drivers/bus/mhi/ep/main.c | 53 +++++++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 2 ++ 2 files changed, 55 insertions(+) diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 14cb08de4263..ddedd0fb19aa 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -471,6 +471,7 @@ static irqreturn_t mhi_ep_irq(int irq, void *data) struct device *dev = &mhi_cntrl->mhi_dev->dev; enum mhi_state state; u32 int_value; + bool mhi_reset; /* Acknowledge the interrupts */ int_value = mhi_ep_mmio_read(mhi_cntrl, MHI_CTRL_INT_STATUS_A7); @@ -479,6 +480,14 @@ static irqreturn_t mhi_ep_irq(int irq, void *data) /* Check for ctrl interrupt */ if (FIELD_GET(MHI_CTRL_INT_STATUS_A7_MSK, int_value)) { dev_dbg(dev, "Processing ctrl interrupt\n"); + mhi_ep_mmio_get_mhi_state(mhi_cntrl, &state, &mhi_reset); + if (mhi_reset) { + dev_info(dev, "Host triggered MHI reset!\n"); + disable_irq_nosync(mhi_cntrl->irq); + schedule_work(&mhi_cntrl->reset_work); + return IRQ_HANDLED; + } + mhi_ep_process_ctrl_interrupt(mhi_cntrl, state); } @@ -559,6 +568,49 @@ static void mhi_ep_abort_transfer(struct mhi_ep_cntrl *mhi_cntrl) mhi_cntrl->is_enabled = false; } +static void mhi_ep_reset_worker(struct work_struct *work) +{ + struct mhi_ep_cntrl *mhi_cntrl = container_of(work, struct mhi_ep_cntrl, reset_work); + struct device *dev = &mhi_cntrl->mhi_dev->dev; + enum mhi_state cur_state; + int ret; + + mhi_ep_abort_transfer(mhi_cntrl); + + spin_lock_bh(&mhi_cntrl->state_lock); + /* Reset MMIO to signal host that the MHI_RESET is completed in endpoint */ + mhi_ep_mmio_reset(mhi_cntrl); + cur_state = mhi_cntrl->mhi_state; + spin_unlock_bh(&mhi_cntrl->state_lock); + + /* + * Only proceed further if the reset is due to SYS_ERR. The host will + * issue reset during shutdown also and we don't need to do re-init in + * that case. + */ + if (cur_state == MHI_STATE_SYS_ERR) { + mhi_ep_mmio_init(mhi_cntrl); + + /* Set AMSS EE before signaling ready state */ + mhi_ep_mmio_set_env(mhi_cntrl, MHI_EP_AMSS_EE); + + /* All set, notify the host that we are ready */ + ret = mhi_ep_set_ready_state(mhi_cntrl); + if (ret) + return; + + dev_dbg(dev, "READY state notification sent to the host\n"); + + ret = mhi_ep_enable(mhi_cntrl); + if (ret) { + dev_err(dev, "Failed to enable MHI endpoint: %d\n", ret); + return; + } + + enable_irq(mhi_cntrl->irq); + } +} + int mhi_ep_power_up(struct mhi_ep_cntrl *mhi_cntrl) { struct device *dev = &mhi_cntrl->mhi_dev->dev; @@ -827,6 +879,7 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, INIT_WORK(&mhi_cntrl->ring_work, mhi_ep_ring_worker); INIT_WORK(&mhi_cntrl->state_work, mhi_ep_state_worker); + INIT_WORK(&mhi_cntrl->reset_work, mhi_ep_reset_worker); mhi_cntrl->ring_wq = alloc_workqueue("mhi_ep_ring_wq", 0, 0); if (!mhi_cntrl->ring_wq) { diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 4f86e7986c93..276d29fef465 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -75,6 +75,7 @@ struct mhi_ep_db_info { * @ring_wq: Dedicated workqueue for processing MHI rings * @state_work: State transition worker * @ring_work: Ring worker + * @reset_work: Worker for MHI Endpoint reset * @ch_db_list: List of queued channel doorbells * @st_transition_list: List of state transitions * @list_lock: Lock for protecting state transition and channel doorbell lists @@ -126,6 +127,7 @@ struct mhi_ep_cntrl { struct workqueue_struct *ring_wq; struct work_struct state_work; struct work_struct ring_work; + struct work_struct reset_work; struct list_head ch_db_list; struct list_head st_transition_list; From patchwork Sat Feb 12 18:21:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 542169 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A35FEC433F5 for ; Sat, 12 Feb 2022 18:23:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229903AbiBLSXd (ORCPT ); Sat, 12 Feb 2022 13:23:33 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:47850 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229920AbiBLSXb (ORCPT ); Sat, 12 Feb 2022 13:23:31 -0500 Received: from mail-pl1-x62b.google.com (mail-pl1-x62b.google.com [IPv6:2607:f8b0:4864:20::62b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ED36B60062 for ; Sat, 12 Feb 2022 10:23:15 -0800 (PST) Received: by mail-pl1-x62b.google.com with SMTP id c3so7265670pls.5 for ; Sat, 12 Feb 2022 10:23:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=nOeAtH9KqQy90Wc3/INZFeCi473Iwk1s2/Fhz+I9C3k=; b=QVyTtzeYWyHPclKxH4SZFHtF3XCzqOxoFhFxXy2EYmqZBAs4qu7xculGq8C+XBIAQ6 mnNoxhoezaVExurBfqUDBoG3+QukjV1xsSgsJlIjJlO4sV87QeTciq+pweb+NPWSneBR C44eWQfK50ltPyKIiD3qTuO3qum1GxmwW1cyNx2oPma5DknsnycP2tuaKg0k5GAqKJth cGarVlOqQcCCVWh1BuSIgqN4LpBclde/55vIUNGLj4jA9IZafiqXmx+yLG7dL9UbQ1ov AgAP9+h1euN1dD2TQP2QT2et4qNLNxru/nSDrpDxYGV0ko9UG+GcGfi9BiKBR3fFxRIc JqlQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=nOeAtH9KqQy90Wc3/INZFeCi473Iwk1s2/Fhz+I9C3k=; b=AmqCR5qvi2yME9t6EflWlF+LPCgcVGkl12mXE1dG6vKVI28tFSoh1rzfo/1T0hWZ// v9ASH6r9ZicUeGTZNTz4OJsiFpON9ehaMnKgr1b3g8j59gRbhWzanNgGnrB6KofDOVDO fIYzJSp+02g7XXXwDejlofHg6dWUbwG7FGwSloOdwD6lExMBBPOrtLLGu/AP95y5CUPj J0PFLFSQ07meq085F5u+JZ93dTt6kAu0mPehw4Z2SfKVg52wwa55VWaCWFqU9BNsicIT NppRuRSUergUkldiOKiQkXMAWbqZOeu7qXSBMB45ywHaBxLr2cdar0TgZkWx/0TZubh+ Tjww== X-Gm-Message-State: AOAM5315FqcUDZkQvO3UsGY2lk7IN0N+nOPKjvPvWgslieNjqU43m4Fs tabll37ZYsn3aiH/m9241dlj X-Google-Smtp-Source: ABdhPJx6sakHNoUbIv6WLbXVv5/bnUcjzl4CHpRshFMWafwsldLiP14yjSqXEdQQorWGmy1gsOxkKA== X-Received: by 2002:a17:90b:4c0d:: with SMTP id na13mr6274373pjb.96.1644690195423; Sat, 12 Feb 2022 10:23:15 -0800 (PST) Received: from localhost.localdomain ([27.111.75.57]) by smtp.gmail.com with ESMTPSA id g12sm14961987pfj.148.2022.02.12.10.23.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Feb 2022 10:23:15 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v3 19/25] bus: mhi: ep: Add support for handling SYS_ERR condition Date: Sat, 12 Feb 2022 23:51:11 +0530 Message-Id: <20220212182117.49438-20-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> References: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Add support for handling SYS_ERR (System Error) condition in the MHI endpoint stack. The SYS_ERR flag will be asserted by the endpoint device when it detects an internal error. The host will then issue reset and reinitializes MHI to recover from the error state. Signed-off-by: Manivannan Sadhasivam Reviewed-by: Alex Elder --- drivers/bus/mhi/ep/internal.h | 1 + drivers/bus/mhi/ep/main.c | 24 ++++++++++++++++++++++++ drivers/bus/mhi/ep/sm.c | 2 ++ 3 files changed, 27 insertions(+) diff --git a/drivers/bus/mhi/ep/internal.h b/drivers/bus/mhi/ep/internal.h index ee8c5974f0c0..8654af7caf40 100644 --- a/drivers/bus/mhi/ep/internal.h +++ b/drivers/bus/mhi/ep/internal.h @@ -241,6 +241,7 @@ int mhi_ep_set_mhi_state(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state mhi_stat int mhi_ep_set_m0_state(struct mhi_ep_cntrl *mhi_cntrl); int mhi_ep_set_m3_state(struct mhi_ep_cntrl *mhi_cntrl); int mhi_ep_set_ready_state(struct mhi_ep_cntrl *mhi_cntrl); +void mhi_ep_handle_syserr(struct mhi_ep_cntrl *mhi_cntrl); /* MHI EP memory management functions */ int mhi_ep_alloc_map(struct mhi_ep_cntrl *mhi_cntrl, u64 pci_addr, size_t size, diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index ddedd0fb19aa..6378ac5c7e37 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -611,6 +611,30 @@ static void mhi_ep_reset_worker(struct work_struct *work) } } +/* + * We don't need to do anything special other than setting the MHI SYS_ERR + * state. The host issue will reset all contexts and issue MHI RESET so that we + * could also recover from error state. + */ +void mhi_ep_handle_syserr(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct device *dev = &mhi_cntrl->mhi_dev->dev; + int ret; + + /* If MHI EP is not enabled, nothing to do */ + if (!mhi_cntrl->is_enabled) + return; + + ret = mhi_ep_set_mhi_state(mhi_cntrl, MHI_STATE_SYS_ERR); + if (ret) + return; + + /* Signal host that the device went to SYS_ERR state */ + ret = mhi_ep_send_state_change_event(mhi_cntrl, MHI_STATE_SYS_ERR); + if (ret) + dev_err(dev, "Failed sending SYS_ERR state change event: %d\n", ret); +} + int mhi_ep_power_up(struct mhi_ep_cntrl *mhi_cntrl) { struct device *dev = &mhi_cntrl->mhi_dev->dev; diff --git a/drivers/bus/mhi/ep/sm.c b/drivers/bus/mhi/ep/sm.c index 68e7f99b9137..9a75ecfe1adf 100644 --- a/drivers/bus/mhi/ep/sm.c +++ b/drivers/bus/mhi/ep/sm.c @@ -93,6 +93,7 @@ int mhi_ep_set_m0_state(struct mhi_ep_cntrl *mhi_cntrl) ret = mhi_ep_set_mhi_state(mhi_cntrl, MHI_STATE_M0); if (ret) { + mhi_ep_handle_syserr(mhi_cntrl); spin_unlock_bh(&mhi_cntrl->state_lock); return ret; } @@ -128,6 +129,7 @@ int mhi_ep_set_m3_state(struct mhi_ep_cntrl *mhi_cntrl) spin_lock_bh(&mhi_cntrl->state_lock); ret = mhi_ep_set_mhi_state(mhi_cntrl, MHI_STATE_M3); if (ret) { + mhi_ep_handle_syserr(mhi_cntrl); spin_unlock_bh(&mhi_cntrl->state_lock); return ret; } From patchwork Sat Feb 12 18:21:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 542586 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7DB34C433EF for ; Sat, 12 Feb 2022 18:23:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230061AbiBLSXo (ORCPT ); Sat, 12 Feb 2022 13:23:44 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:48274 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230090AbiBLSXm (ORCPT ); Sat, 12 Feb 2022 13:23:42 -0500 Received: from mail-pl1-x629.google.com (mail-pl1-x629.google.com [IPv6:2607:f8b0:4864:20::629]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 89832606C4 for ; Sat, 12 Feb 2022 10:23:20 -0800 (PST) Received: by mail-pl1-x629.google.com with SMTP id 10so7268574plj.1 for ; Sat, 12 Feb 2022 10:23:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=m/hPWm0+5LcdOB8NWzzaMRU3PadY6NbOKvxGtL82+j4=; b=MAYIMl8lfe4WoVIa2YvE97sC8uSrnnZiWqPEW1iuYn1xqCViy5MGkLuyrr4oy3Yqgb 3Fb/y0+eVDYDTesbT61m0ivf/4VJ20M5qr98GpUTO0nDl3YdW6gm7W2D7zkFhx9waMBy GwfctOKxATTTcPAwC8z52r/TCI2xZELn9C1PJrElhW1YLlPJA43lcJx4r0TDWFUQVIXT woNBDUGgPObzMsWbJ4vvorjGixuKglumXzccBAehLGuZDnJASuAwYYkpqAjxDKy6cuPe 8lAE9IbqF6ODOwZCZSM2dLD31/ORj7MRAoJA6Tx6mvBiC76XV5fdr3B033CU2svNeZd+ dB6Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=m/hPWm0+5LcdOB8NWzzaMRU3PadY6NbOKvxGtL82+j4=; b=evYtw1r9g+DN5nzYPmXbYFDGxtOCxQ2dPneN3sklO7YOEnt8QK7GID8n3uFnjX64Fj hKD/fJ/wi/soJCHR2261qiWE5CqJIW+Tb8tj7ufpQ8iIEiL40t0tr6aq3OGTl5dte/yW s6oNRR2bkKYdCZtJN8SLjYgf0jKmPQ/9c+0eBKHui8kneH/smRO3bRL6bWi9zEFjU7oN +l2zp+PfnvD++d7bma/93eR5FOWUnRlqCazHFv1UzYbBgqWWQ6vd4m/WjM8VevB+ZriV nu/Q4JQGLrf2a6o79VD/bf9htWfkhmplILSkb+e3BgJ9C2+dnO2zXdOgHUb7609QNhLq NBjA== X-Gm-Message-State: AOAM530b/z/nDYYEkqRT9hdgoCeY30vLRmVIqLtguCQ02ON3fIg8cr/v nmnqRxLAsyIM3wNdIQvP1vzq X-Google-Smtp-Source: ABdhPJwRrc/SxpGGHBJIIaKyU1LDqCDZZdi4badsonGW1XzxaGDljBrPXmLf3jIz6WrVI9Sh1b7dtA== X-Received: by 2002:a17:90b:398:: with SMTP id ga24mr6372706pjb.108.1644690199968; Sat, 12 Feb 2022 10:23:19 -0800 (PST) Received: from localhost.localdomain ([27.111.75.57]) by smtp.gmail.com with ESMTPSA id g12sm14961987pfj.148.2022.02.12.10.23.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Feb 2022 10:23:19 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v3 20/25] bus: mhi: ep: Add support for processing command ring Date: Sat, 12 Feb 2022 23:51:12 +0530 Message-Id: <20220212182117.49438-21-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> References: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Add support for processing the command ring. Command ring is used by the host to issue channel specific commands to the ep device. Following commands are supported: 1. Start channel 2. Stop channel 3. Reset channel Once the device receives the command doorbell interrupt from host, it executes the command and generates a command completion event to the host in the primary event ring. Signed-off-by: Manivannan Sadhasivam Reviewed-by: Alex Elder --- drivers/bus/mhi/ep/main.c | 151 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 6378ac5c7e37..4c2ee517832c 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -21,6 +21,7 @@ static DEFINE_IDA(mhi_ep_cntrl_ida); +static int mhi_ep_create_device(struct mhi_ep_cntrl *mhi_cntrl, u32 ch_id); static int mhi_ep_destroy_device(struct device *dev, void *data); static int mhi_ep_send_event(struct mhi_ep_cntrl *mhi_cntrl, u32 ring_idx, @@ -185,6 +186,156 @@ void mhi_ep_unmap_free(struct mhi_ep_cntrl *mhi_cntrl, u64 pci_addr, phys_addr_t mhi_cntrl->free_addr(mhi_cntrl, phys - offset, virt - offset, size); } +int mhi_ep_process_cmd_ring(struct mhi_ep_ring *ring, struct mhi_ep_ring_element *el) +{ + struct mhi_ep_cntrl *mhi_cntrl = ring->mhi_cntrl; + struct device *dev = &mhi_cntrl->mhi_dev->dev; + struct mhi_result result = {}; + struct mhi_ep_chan *mhi_chan; + struct mhi_ep_ring *ch_ring; + u32 tmp, ch_id; + int ret; + + ch_id = MHI_TRE_GET_CMD_CHID(el); + mhi_chan = &mhi_cntrl->mhi_chan[ch_id]; + ch_ring = &mhi_cntrl->mhi_chan[ch_id].ring; + + switch (MHI_TRE_GET_CMD_TYPE(el)) { + case MHI_PKT_TYPE_START_CHAN_CMD: + dev_dbg(dev, "Received START command for channel (%d)\n", ch_id); + + mutex_lock(&mhi_chan->lock); + /* Initialize and configure the corresponding channel ring */ + if (!ch_ring->started) { + ret = mhi_ep_ring_start(mhi_cntrl, ch_ring, + (union mhi_ep_ring_ctx *)&mhi_cntrl->ch_ctx_cache[ch_id]); + if (ret) { + dev_err(dev, "Failed to start ring for channel (%d)\n", ch_id); + ret = mhi_ep_send_cmd_comp_event(mhi_cntrl, + MHI_EV_CC_UNDEFINED_ERR); + if (ret) + dev_err(dev, "Error sending completion event (%d)\n", + MHI_EV_CC_UNDEFINED_ERR); + + goto err_unlock; + } + } + + /* Enable DB for the channel */ + mhi_ep_mmio_enable_chdb_a7(mhi_cntrl, ch_id); + + /* Set channel state to RUNNING */ + mhi_chan->state = MHI_CH_STATE_RUNNING; + tmp = le32_to_cpu(mhi_cntrl->ch_ctx_cache[ch_id].chcfg); + tmp &= ~CHAN_CTX_CHSTATE_MASK; + tmp |= FIELD_PREP(CHAN_CTX_CHSTATE_MASK, MHI_CH_STATE_RUNNING); + mhi_cntrl->ch_ctx_cache[ch_id].chcfg = cpu_to_le32(tmp); + + ret = mhi_ep_send_cmd_comp_event(mhi_cntrl, MHI_EV_CC_SUCCESS); + if (ret) { + dev_err(dev, "Error sending command completion event (%d)\n", + MHI_EV_CC_SUCCESS); + goto err_unlock; + } + + mutex_unlock(&mhi_chan->lock); + + /* + * Create MHI device only during UL channel start. Since the MHI + * channels operate in a pair, we'll associate both UL and DL + * channels to the same device. + * + * We also need to check for mhi_dev != NULL because, the host + * will issue START_CHAN command during resume and we don't + * destroy the device during suspend. + */ + if (!(ch_id % 2) && !mhi_chan->mhi_dev) { + ret = mhi_ep_create_device(mhi_cntrl, ch_id); + if (ret) { + dev_err(dev, "Error creating device for channel (%d)\n", ch_id); + return ret; + } + } + + break; + case MHI_PKT_TYPE_STOP_CHAN_CMD: + dev_dbg(dev, "Received STOP command for channel (%d)\n", ch_id); + if (!ch_ring->started) { + dev_err(dev, "Channel (%d) not opened\n", ch_id); + return -ENODEV; + } + + mutex_lock(&mhi_chan->lock); + /* Disable DB for the channel */ + mhi_ep_mmio_disable_chdb_a7(mhi_cntrl, ch_id); + + /* Send channel disconnect status to client drivers */ + result.transaction_status = -ENOTCONN; + result.bytes_xferd = 0; + mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); + + /* Set channel state to STOP */ + mhi_chan->state = MHI_CH_STATE_STOP; + tmp = le32_to_cpu(mhi_cntrl->ch_ctx_cache[ch_id].chcfg); + tmp &= ~CHAN_CTX_CHSTATE_MASK; + tmp |= FIELD_PREP(CHAN_CTX_CHSTATE_MASK, MHI_CH_STATE_STOP); + mhi_cntrl->ch_ctx_cache[ch_id].chcfg = cpu_to_le32(tmp); + + ret = mhi_ep_send_cmd_comp_event(mhi_cntrl, MHI_EV_CC_SUCCESS); + if (ret) { + dev_err(dev, "Error sending command completion event (%d)\n", + MHI_EV_CC_SUCCESS); + goto err_unlock; + } + + mutex_unlock(&mhi_chan->lock); + break; + case MHI_PKT_TYPE_RESET_CHAN_CMD: + dev_dbg(dev, "Received STOP command for channel (%d)\n", ch_id); + if (!ch_ring->started) { + dev_err(dev, "Channel (%d) not opened\n", ch_id); + return -ENODEV; + } + + mutex_lock(&mhi_chan->lock); + /* Stop and reset the transfer ring */ + mhi_ep_ring_reset(mhi_cntrl, ch_ring); + + /* Send channel disconnect status to client driver */ + result.transaction_status = -ENOTCONN; + result.bytes_xferd = 0; + mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); + + /* Set channel state to DISABLED */ + mhi_chan->state = MHI_CH_STATE_DISABLED; + tmp = le32_to_cpu(mhi_cntrl->ch_ctx_cache[ch_id].chcfg); + tmp &= ~CHAN_CTX_CHSTATE_MASK; + tmp |= FIELD_PREP(CHAN_CTX_CHSTATE_MASK, MHI_CH_STATE_DISABLED); + mhi_cntrl->ch_ctx_cache[ch_id].chcfg = cpu_to_le32(tmp); + + ret = mhi_ep_send_cmd_comp_event(mhi_cntrl, MHI_EV_CC_SUCCESS); + if (ret) { + dev_err(dev, "Error sending command completion event (%d)\n", + MHI_EV_CC_SUCCESS); + goto err_unlock; + } + + mutex_unlock(&mhi_chan->lock); + break; + default: + dev_err(dev, "Invalid command received: %d for channel (%d)\n", + MHI_TRE_GET_CMD_TYPE(el), ch_id); + return -EINVAL; + } + + return 0; + +err_unlock: + mutex_unlock(&mhi_chan->lock); + + return ret; +} + static int mhi_ep_cache_host_cfg(struct mhi_ep_cntrl *mhi_cntrl) { struct device *dev = &mhi_cntrl->mhi_dev->dev; From patchwork Sat Feb 12 18:21:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 542585 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3BA64C433FE for ; Sat, 12 Feb 2022 18:23:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230216AbiBLSXu (ORCPT ); Sat, 12 Feb 2022 13:23:50 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:48078 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230046AbiBLSXo (ORCPT ); Sat, 12 Feb 2022 13:23:44 -0500 Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1F62B5FF2A for ; Sat, 12 Feb 2022 10:23:26 -0800 (PST) Received: by mail-pj1-x102c.google.com with SMTP id a11-20020a17090a740b00b001b8b506c42fso15098059pjg.0 for ; Sat, 12 Feb 2022 10:23:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=2XD6GLOy1WeMbVJM+mE9l+D4GurGc+LL2vthiVaNWmY=; b=ZQ8ws5jacEDY80ooN3Y1PtbbBoqTJx2pmlj5MsuJAXCvaiM79s35ZAmULMIe0fx4Rm pf3bgdmHLGxiscLlFkNTIi7l9U1dqxHMJtPohpxrgIpVdTpOgRu8d4BlclDpGEVfTgjG yjcZZ+wZy4hWcmqm7EBh3G0OWitkP038EK+sFkrcbiN8cSZsvFSRDh+Y3+tWTUWypZpO m4LEie7uvPtV601HIIOdGisINSq1GqL9Im5R6pNpBBlkFshu5MfPoeKsj28ubiA73S5Z 0rb/b6Qw2Cz/VSPiYZG7nqa7RSs5CgzaFbkfeTmZlDTmy4Xo/+WxO6j+DYKFlBcScnNp chaw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=2XD6GLOy1WeMbVJM+mE9l+D4GurGc+LL2vthiVaNWmY=; b=UFvzNVPmhVcwe+6PKtFgxJGizQy6aXQmt3ttdAhCeQw8NHRGhYIDTNRcu9Skv6ujqq cc0Z8UlAnoBOHT/WLfq/4V3ID8Jwf9aDutjhmXBqwEHvLILRBjGZxh8IgJhB5t/ed4pY We/Yk3Jth+dnwLfLun1ASm7+zYbJuFNVWJ8LK9GVUfpNtSd1keLTJVWDOkJVzIZFbRLR EiJghSqrHE5hWHBXkr3VcrC5EmtCpCxcpNosuq2PNdwv1iP0ID6ULjoLPWAsQt+4zTtf duqfA+eVeiXqKA9TCeDBEFAEtG0DUqMZAtwdgDZCtWtmSoz8uHlQV7D0/Km64oQNFY4z 4nSg== X-Gm-Message-State: AOAM531bgGaK1wFB6RmpciTwC19DtMqQd9TTYPM3jecwCHfhYclo+UVO nJJuasmof3vUypXDMmxh8J1x X-Google-Smtp-Source: ABdhPJyWqwE3MwA3UG5zv2W75d93RjLa8xtdZ1MDEYli+5Z+jvcztVTBVQCs5WEid0A193wDhVC6rw== X-Received: by 2002:a17:90b:3810:: with SMTP id mq16mr6452775pjb.26.1644690205278; Sat, 12 Feb 2022 10:23:25 -0800 (PST) Received: from localhost.localdomain ([27.111.75.57]) by smtp.gmail.com with ESMTPSA id g12sm14961987pfj.148.2022.02.12.10.23.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Feb 2022 10:23:24 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v3 21/25] bus: mhi: ep: Add support for reading from the host Date: Sat, 12 Feb 2022 23:51:13 +0530 Message-Id: <20220212182117.49438-22-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> References: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Data transfer between host and the ep device happens over the transfer ring associated with each bi-directional channel pair. Host defines the transfer ring by allocating memory for it. The read and write pointer addresses of the transfer ring are stored in the channel context. Once host places the elements in the transfer ring, it increments the write pointer and rings the channel doorbell. Device will receive the doorbell interrupt and will process the transfer ring elements. This commit adds support for reading the transfer ring elements from the transfer ring till write pointer, incrementing the read pointer and finally sending the completion event to the host through corresponding event ring. Signed-off-by: Manivannan Sadhasivam Reviewed-by: Alex Elder --- drivers/bus/mhi/ep/main.c | 103 ++++++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 9 ++++ 2 files changed, 112 insertions(+) diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 4c2ee517832c..b937c6cda9ba 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -336,6 +336,109 @@ int mhi_ep_process_cmd_ring(struct mhi_ep_ring *ring, struct mhi_ep_ring_element return ret; } +bool mhi_ep_queue_is_empty(struct mhi_ep_device *mhi_dev, enum dma_data_direction dir) +{ + struct mhi_ep_chan *mhi_chan = (dir == DMA_FROM_DEVICE) ? mhi_dev->dl_chan : + mhi_dev->ul_chan; + struct mhi_ep_cntrl *mhi_cntrl = mhi_dev->mhi_cntrl; + struct mhi_ep_ring *ring = &mhi_cntrl->mhi_chan[mhi_chan->chan].ring; + + return !!(ring->rd_offset == ring->wr_offset); +} +EXPORT_SYMBOL_GPL(mhi_ep_queue_is_empty); + +static int mhi_ep_read_channel(struct mhi_ep_cntrl *mhi_cntrl, + struct mhi_ep_ring *ring, + struct mhi_result *result, + u32 len) +{ + struct mhi_ep_chan *mhi_chan = &mhi_cntrl->mhi_chan[ring->ch_id]; + size_t bytes_to_read, read_offset, write_offset; + struct device *dev = &mhi_cntrl->mhi_dev->dev; + struct mhi_ep_ring_element *el; + bool td_done = false; + void *write_to_loc; + u64 read_from_loc; + u32 buf_remaining; + int ret; + + buf_remaining = len; + + do { + /* Don't process the transfer ring if the channel is not in RUNNING state */ + if (mhi_chan->state != MHI_CH_STATE_RUNNING) + return -ENODEV; + + el = &ring->ring_cache[ring->rd_offset]; + + /* Check if there is data pending to be read from previous read operation */ + if (mhi_chan->tre_bytes_left) { + dev_dbg(dev, "TRE bytes remaining: %d\n", mhi_chan->tre_bytes_left); + bytes_to_read = min(buf_remaining, mhi_chan->tre_bytes_left); + } else { + mhi_chan->tre_loc = MHI_EP_TRE_GET_PTR(el); + mhi_chan->tre_size = MHI_EP_TRE_GET_LEN(el); + mhi_chan->tre_bytes_left = mhi_chan->tre_size; + + bytes_to_read = min(buf_remaining, mhi_chan->tre_size); + } + + read_offset = mhi_chan->tre_size - mhi_chan->tre_bytes_left; + write_offset = len - buf_remaining; + read_from_loc = mhi_chan->tre_loc + read_offset; + write_to_loc = result->buf_addr + write_offset; + + dev_dbg(dev, "Reading %zd bytes from channel (%d)\n", bytes_to_read, ring->ch_id); + ret = mhi_cntrl->read_from_host(mhi_cntrl, read_from_loc, write_to_loc, + bytes_to_read); + if (ret < 0) + return ret; + + buf_remaining -= bytes_to_read; + mhi_chan->tre_bytes_left -= bytes_to_read; + + /* + * Once the TRE (Transfer Ring Element) of a TD (Transfer Descriptor) has been + * read completely: + * + * 1. Send completion event to the host based on the flags set in TRE. + * 2. Increment the local read offset of the transfer ring. + */ + if (!mhi_chan->tre_bytes_left) { + /* + * The host will split the data packet into multiple TREs if it can't fit + * the packet in a single TRE. In that case, CHAIN flag will be set by the + * host for all TREs except the last one. + */ + if (MHI_EP_TRE_GET_CHAIN(el)) { + /* + * IEOB (Interrupt on End of Block) flag will be set by the host if + * it expects the completion event for all TREs of a TD. + */ + if (MHI_EP_TRE_GET_IEOB(el)) + mhi_ep_send_completion_event(mhi_cntrl, + ring, MHI_EP_TRE_GET_LEN(el), MHI_EV_CC_EOB); + } else { + /* + * IEOT (Interrupt on End of Transfer) flag will be set by the host + * for the last TRE of the TD and expects the completion event for + * the same. + */ + if (MHI_EP_TRE_GET_IEOT(el)) + mhi_ep_send_completion_event(mhi_cntrl, + ring, MHI_EP_TRE_GET_LEN(el), MHI_EV_CC_EOT); + td_done = true; + } + + mhi_ep_ring_inc_index(ring); + } + + result->bytes_xferd += bytes_to_read; + } while (buf_remaining && !td_done); + + return 0; +} + static int mhi_ep_cache_host_cfg(struct mhi_ep_cntrl *mhi_cntrl) { struct device *dev = &mhi_cntrl->mhi_dev->dev; diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 276d29fef465..aaf4b6942037 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -268,4 +268,13 @@ int mhi_ep_power_up(struct mhi_ep_cntrl *mhi_cntrl); */ void mhi_ep_power_down(struct mhi_ep_cntrl *mhi_cntrl); +/** + * mhi_ep_queue_is_empty - Determine whether the transfer queue is empty + * @mhi_dev: Device associated with the channels + * @dir: DMA direction for the channel + * + * Return: true if the queue is empty, false otherwise. + */ +bool mhi_ep_queue_is_empty(struct mhi_ep_device *mhi_dev, enum dma_data_direction dir); + #endif From patchwork Sat Feb 12 18:21:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 542168 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A6411C433EF for ; Sat, 12 Feb 2022 18:23:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230172AbiBLSXs (ORCPT ); Sat, 12 Feb 2022 13:23:48 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:47788 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230192AbiBLSXq (ORCPT ); Sat, 12 Feb 2022 13:23:46 -0500 Received: from mail-pf1-x434.google.com (mail-pf1-x434.google.com [IPv6:2607:f8b0:4864:20::434]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3313760042 for ; Sat, 12 Feb 2022 10:23:30 -0800 (PST) Received: by mail-pf1-x434.google.com with SMTP id c4so619617pfl.7 for ; Sat, 12 Feb 2022 10:23:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Ysuje3nEy8KvAdAcfcWxVoVzsgbCmUXoBnVe5XL9ZLI=; b=wPHLfGKLHFKi9xnbSoXzfIWPBKlHLJGYnt7UAa0QUROMkK6gLeTd3BcGYde9yoYHyv Sc83DVfbwgvKvQ2wZbPnqJMCFY0tHaV+FOgwuQ+kZkK8rStPD+5oibLMQd+pl1l3IG3r nhTNeaIhPWKuNvwUvEzHF6yPiWOoRvwTf3MvzDDjqcO3m94cIdD/ykI7i7zh6rrTzBVa UbyQHnI96fpSKQZ2fwlakFoZUouYXSHuto5U+fkoFWa1EYWVAiPcWyVq1T5zTRpAxsf0 XK1OlRStUcpb9ZfjYXLzU4YFECQBOUyngMWv81FRosViehYyrUebh3WzBEl1zBW21bZ/ mKpw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Ysuje3nEy8KvAdAcfcWxVoVzsgbCmUXoBnVe5XL9ZLI=; b=pDbq0LL6wcBj48Yh1zvRXacITgBERbxNjsiz6dY19TGXpPA4tZI4l9/n/mIYXu0RxC mQ69lYYuPw4w1ZEYAJEQZhEFovYmNTdJNTnePDV3gf6gEZBH/kV95u5RQNS9hTAwW96Q Wf5pC1apwlAlKuJ0vuhDJxgtfgWWB/2rMg+5JPuMlJHEet8rq4ClfnlNjEfDSB6nrfSd 3w/8qa+UVPThz39GPTrzvs53ZEY10nsB3CZpKcFDbjsB1d9eWk2WuogDLJGtEuC7S2Bb EcAq1EO5bmDWx1NYrq7Lj70rzqbA4RDOhqn3gEPiY538FTK7ZLl1q0CGL5j9TjIUV3B5 RvxA== X-Gm-Message-State: AOAM5338eftf6idGJCw1v6f+Z5s8viKk1eNHDWYYbpyBwr/NtCAsw3Xj J8eKgGrLlSjR8pi7GxMoWbqk X-Google-Smtp-Source: ABdhPJyZVCadrz2t/5hSZ935KMcv1E7SSSKtfPFkJ6xTWe0nbGfrM39zANDUveiLFxgDoKAFavC7yA== X-Received: by 2002:a05:6a00:2490:: with SMTP id c16mr7060175pfv.67.1644690209534; Sat, 12 Feb 2022 10:23:29 -0800 (PST) Received: from localhost.localdomain ([27.111.75.57]) by smtp.gmail.com with ESMTPSA id g12sm14961987pfj.148.2022.02.12.10.23.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Feb 2022 10:23:29 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v3 22/25] bus: mhi: ep: Add support for processing transfer ring Date: Sat, 12 Feb 2022 23:51:14 +0530 Message-Id: <20220212182117.49438-23-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> References: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Add support for processing the transfer ring from host. For the transfer ring associated with DL channel, the xfer callback will simply invoked. For the case of UL channel, the ring elements will be read in a buffer till the write pointer and later passed to the client driver using the xfer callback. The client drivers should provide the callbacks for both UL and DL channels during registration. Signed-off-by: Manivannan Sadhasivam Reviewed-by: Alex Elder --- drivers/bus/mhi/ep/main.c | 49 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index b937c6cda9ba..baf383a4857b 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -439,6 +439,55 @@ static int mhi_ep_read_channel(struct mhi_ep_cntrl *mhi_cntrl, return 0; } +int mhi_ep_process_tre_ring(struct mhi_ep_ring *ring, struct mhi_ep_ring_element *el) +{ + struct mhi_ep_cntrl *mhi_cntrl = ring->mhi_cntrl; + struct mhi_result result = {}; + u32 len = MHI_EP_DEFAULT_MTU; + struct mhi_ep_chan *mhi_chan; + int ret; + + mhi_chan = &mhi_cntrl->mhi_chan[ring->ch_id]; + + /* + * Bail out if transfer callback is not registered for the channel. + * This is most likely due to the client driver not loaded at this point. + */ + if (!mhi_chan->xfer_cb) { + dev_err(&mhi_chan->mhi_dev->dev, "Client driver not available\n"); + return -ENODEV; + } + + if (ring->ch_id % 2) { + /* DL channel */ + result.dir = mhi_chan->dir; + mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); + } else { + /* UL channel */ + do { + result.buf_addr = kzalloc(len, GFP_KERNEL); + if (!result.buf_addr) + return -ENOMEM; + + ret = mhi_ep_read_channel(mhi_cntrl, ring, &result, len); + if (ret < 0) { + dev_err(&mhi_chan->mhi_dev->dev, "Failed to read channel\n"); + kfree(result.buf_addr); + return ret; + } + + result.dir = mhi_chan->dir; + mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); + kfree(result.buf_addr); + result.bytes_xferd = 0; + + /* Read until the ring becomes empty */ + } while (!mhi_ep_queue_is_empty(mhi_chan->mhi_dev, DMA_TO_DEVICE)); + } + + return 0; +} + static int mhi_ep_cache_host_cfg(struct mhi_ep_cntrl *mhi_cntrl) { struct device *dev = &mhi_cntrl->mhi_dev->dev; From patchwork Sat Feb 12 18:21:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 542167 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3EDDAC433F5 for ; Sat, 12 Feb 2022 18:24:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230292AbiBLSYP (ORCPT ); Sat, 12 Feb 2022 13:24:15 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:48700 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230286AbiBLSXx (ORCPT ); Sat, 12 Feb 2022 13:23:53 -0500 Received: from mail-pj1-x102d.google.com (mail-pj1-x102d.google.com [IPv6:2607:f8b0:4864:20::102d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D272360067 for ; Sat, 12 Feb 2022 10:23:39 -0800 (PST) Received: by mail-pj1-x102d.google.com with SMTP id t14-20020a17090a3e4e00b001b8f6032d96so11846617pjm.2 for ; Sat, 12 Feb 2022 10:23:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=DR39PJTsN+CNaJsE354sTId/TsA16GNncXIpBGtTVUk=; b=faMhg0PFlLM1YusH1b7hIXOxUUfqurJoJ5tMvwyIN4gtLmqcOwBsoIA63fj85zO2Xe J5Yd8jRPD+wiNt8wYLEodvbcvZPJhm3cy57ZLj3gsPKhPJ6p+/HHqDc2LXZWSCzkuoon G1jzwOOwgQGtPulEbH8yo/XaCd3G8cCMbY1BfWp/2D5YAi0y4hHj58uQWnYTAhx3aEUl o7JFyXbZYJQmecTF4pHivyayCPCWA+Hfr1naI9rHBIRhZLOaRNy2lF/B4GGOZMFm9Kvq SvCUmmYO5lZFvPnneasnAb2gBNDkzPuJJXgMvC83YnXLV1g6b73+62NvoUpyhbiPzGOZ 7FcQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=DR39PJTsN+CNaJsE354sTId/TsA16GNncXIpBGtTVUk=; b=w887yNC0c3xVea5vZWH+GZAcRduOGFSD7Rn8sN5+Q0x5QF+FEqjSeb/EB+q63h0brR rLWxVpLCB7pHBnbaPc40m/C2gQQGHEwXGPGhiH0n084B1cmKplXslS7us10Xk7Kde6Ra Apo9V5bOfGYDdJ4stcaB021lT4awi4Y8mYERTsNyIsfIHl8M+oDDWVMcNrvxGOvx1N/2 3m2BoLcVCAkLyc2WZuD5TQ/GVcDeM8hHJgTyC7Hr+bhgoVupcNKiHwJtlz1hSWzMlrBM 5bfIuzok3sfXEfMzZ4BaCWaL9hfElRJFVawJbENRYiUV2PGsjbTObhhAO4yI/k1AhY7m VT+A== X-Gm-Message-State: AOAM533FYF1bouQxPSJkhCZByD1F6UD2ebI8U1BiTyePrHzqf6gXOM6p sAqcTqrskVJEDCNGcMht6Yd2 X-Google-Smtp-Source: ABdhPJxr+CZietQDfAClfTK8cHhPac34/F4IF4g6p0VHydivyrubP6Vzkh/g4lVOAjxyMsIpB3gpWg== X-Received: by 2002:a17:90a:6881:: with SMTP id a1mr6372208pjd.123.1644690213665; Sat, 12 Feb 2022 10:23:33 -0800 (PST) Received: from localhost.localdomain ([27.111.75.57]) by smtp.gmail.com with ESMTPSA id g12sm14961987pfj.148.2022.02.12.10.23.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Feb 2022 10:23:33 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v3 23/25] bus: mhi: ep: Add support for queueing SKBs to the host Date: Sat, 12 Feb 2022 23:51:15 +0530 Message-Id: <20220212182117.49438-24-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> References: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Add support for queueing SKBs to the host over the transfer ring of the relevant channel. The mhi_ep_queue_skb() API will be used by the client networking drivers to queue the SKBs to the host over MHI bus. The host will add ring elements to the transfer ring periodically for the device and the device will write SKBs to the ring elements. If a single SKB doesn't fit in a ring element (TRE), it will be placed in multiple ring elements and the overflow event will be sent for all ring elements except the last one. For the last ring element, the EOT event will be sent indicating the packet boundary. Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/ep/main.c | 102 ++++++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 13 +++++ 2 files changed, 115 insertions(+) diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index baf383a4857b..e4186b012257 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -488,6 +488,108 @@ int mhi_ep_process_tre_ring(struct mhi_ep_ring *ring, struct mhi_ep_ring_element return 0; } +int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, enum dma_data_direction dir, + struct sk_buff *skb, size_t len, enum mhi_flags mflags) +{ + struct mhi_ep_chan *mhi_chan = (dir == DMA_FROM_DEVICE) ? mhi_dev->dl_chan : + mhi_dev->ul_chan; + struct mhi_ep_cntrl *mhi_cntrl = mhi_dev->mhi_cntrl; + struct device *dev = &mhi_chan->mhi_dev->dev; + struct mhi_ep_ring_element *el; + struct mhi_ep_ring *ring; + size_t bytes_to_write; + enum mhi_ev_ccs code; + void *read_from_loc; + u32 buf_remaining; + u64 write_to_loc; + u32 tre_len; + int ret = 0; + + if (dir == DMA_TO_DEVICE) + return -EINVAL; + + buf_remaining = len; + ring = &mhi_cntrl->mhi_chan[mhi_chan->chan].ring; + + mutex_lock(&mhi_chan->lock); + + do { + /* Don't process the transfer ring if the channel is not in RUNNING state */ + if (mhi_chan->state != MHI_CH_STATE_RUNNING) { + dev_err(dev, "Channel not available\n"); + ret = -ENODEV; + goto err_exit; + } + + if (mhi_ep_queue_is_empty(mhi_dev, dir)) { + dev_err(dev, "TRE not available!\n"); + ret = -EINVAL; + goto err_exit; + } + + el = &ring->ring_cache[ring->rd_offset]; + tre_len = MHI_EP_TRE_GET_LEN(el); + if (skb->len > tre_len) { + dev_err(dev, "Buffer size (%d) is too large for TRE (%d)!\n", + skb->len, tre_len); + ret = -ENOMEM; + goto err_exit; + } + + bytes_to_write = min(buf_remaining, tre_len); + read_from_loc = skb->data; + write_to_loc = MHI_EP_TRE_GET_PTR(el); + + ret = mhi_cntrl->write_to_host(mhi_cntrl, read_from_loc, write_to_loc, + bytes_to_write); + if (ret < 0) + goto err_exit; + + buf_remaining -= bytes_to_write; + /* + * For all TREs queued by the host for DL channel, only the EOT flag will be set. + * If the packet doesn't fit into a single TRE, send the OVERFLOW event to + * the host so that the host can adjust the packet boundary to next TREs. Else send + * the EOT event to the host indicating the packet boundary. + */ + if (buf_remaining) + code = MHI_EV_CC_OVERFLOW; + else + code = MHI_EV_CC_EOT; + + ret = mhi_ep_send_completion_event(mhi_cntrl, ring, bytes_to_write, code); + if (ret) { + dev_err(dev, "Error sending completion event\n"); + goto err_exit; + } + + mhi_ep_ring_inc_index(ring); + } while (buf_remaining); + + /* + * During high network traffic, sometimes the DL doorbell interrupt from the host is missed + * by the endpoint. So manually check for the write pointer update here so that we don't run + * out of buffer due to missing interrupts. + */ + if (ring->rd_offset + 1 == ring->wr_offset) { + ret = mhi_ep_update_wr_offset(ring); + if (ret) { + dev_err(dev, "Error updating write pointer\n"); + goto err_exit; + } + } + + mutex_unlock(&mhi_chan->lock); + + return 0; + +err_exit: + mutex_unlock(&mhi_chan->lock); + + return ret; +} +EXPORT_SYMBOL_GPL(mhi_ep_queue_skb); + static int mhi_ep_cache_host_cfg(struct mhi_ep_cntrl *mhi_cntrl) { struct device *dev = &mhi_cntrl->mhi_dev->dev; diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index aaf4b6942037..75cfbf0c6fb0 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -277,4 +277,17 @@ void mhi_ep_power_down(struct mhi_ep_cntrl *mhi_cntrl); */ bool mhi_ep_queue_is_empty(struct mhi_ep_device *mhi_dev, enum dma_data_direction dir); +/** + * mhi_ep_queue_skb - Send SKBs to host over MHI Endpoint + * @mhi_dev: Device associated with the channels + * @dir: DMA direction for the channel + * @skb: Buffer for holding SKBs + * @len: Buffer length + * @mflags: MHI Endpoint transfer flags used for the transfer + * + * Return: 0 if the SKBs has been sent successfully, a negative error code otherwise. + */ +int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, enum dma_data_direction dir, + struct sk_buff *skb, size_t len, enum mhi_flags mflags); + #endif From patchwork Sat Feb 12 18:21:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 542584 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DED52C433FE for ; Sat, 12 Feb 2022 18:24:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229701AbiBLSYP (ORCPT ); Sat, 12 Feb 2022 13:24:15 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:48796 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230129AbiBLSX4 (ORCPT ); Sat, 12 Feb 2022 13:23:56 -0500 Received: from mail-pj1-x1036.google.com (mail-pj1-x1036.google.com [IPv6:2607:f8b0:4864:20::1036]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B35BE6006E for ; Sat, 12 Feb 2022 10:23:42 -0800 (PST) Received: by mail-pj1-x1036.google.com with SMTP id v13-20020a17090ac90d00b001b87bc106bdso14971368pjt.4 for ; Sat, 12 Feb 2022 10:23:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ghLLgeFSuBhLBbaF2D3N7y/Ag1lbiZHSv5o6U722W+E=; b=tahHHV1myQ3F3+Wgz9DF+8m8aUh8rKmNw7/K9YIpt3LzMNmadOQeOgEkkDcaYAZABz osaiwszIy/oRiTbE9jtLj4915dThnRSBBA03IY/5G8rIdXsR776HP1p68iYZSvNGT58V 9iZxZMB9U7S98bqctQFE1NqAk4tQO9UJLSZdQHxoEwFpcUryWaAGUN8amVZdn8vDYb7l /axuHuNsDFYRrB6ow7NgAkGXNyYtIXDbEHZnZEHoxFE8DUX0rB90vm978DcjrrRPKk5i 1ra0o1jMj6eF/8SKRj0m9SRn/DBF0ULPLsPxDAj5ROxiSQDPLoE7De+xsnMWdLYBVYSY 5dHQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ghLLgeFSuBhLBbaF2D3N7y/Ag1lbiZHSv5o6U722W+E=; b=VSh9zD5D/gQJ4C7DqemM0hSJB+fxzbBZLA11VyaAJIXLuOTTS0kDx//J9PhUxjK7t5 wUfY5iajZSSkvWzGFQYu4hByMbo7WjtPdrj1/Iiqp2oUvaUITk3aLTMt2mqjiGh00YK0 Up3OZMyTXpMJ5rqDOqlTq2e19bYwZfZFM7DSNoEMJHgiKzpahPZLSYWyZLFk3PGTj3SI OGiNRwekl58vg4oDCZR86qARnYtoZ8zbgX8rx6wjpw5Ea/Ayzmgx7un4aIOzPbL3Px0W w3OTn4BXpMPusI6Y4pinVUMhhAghldK7OxnnuSSg6BSVsnfczCv6dC3lvHHAS+lu5kgV a7jQ== X-Gm-Message-State: AOAM532tDgrWv6NGDhqADZEVdJLbIn5au+N/btn2Tgv0L7PY2Ob5k7B0 9EK5BbwsViBfu7r0Vuwk8df7O0GO3Avjrls= X-Google-Smtp-Source: ABdhPJwL8gTpbO4sB21qrNwsTxI/qy0bKJJ5PyPHhXLqGc00N+XZNqAutm1T8cig2zQj4ObL1yunmw== X-Received: by 2002:a17:90b:4b84:: with SMTP id lr4mr6224735pjb.231.1644690217960; Sat, 12 Feb 2022 10:23:37 -0800 (PST) Received: from localhost.localdomain ([27.111.75.57]) by smtp.gmail.com with ESMTPSA id g12sm14961987pfj.148.2022.02.12.10.23.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Feb 2022 10:23:37 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v3 24/25] bus: mhi: ep: Add support for suspending and resuming channels Date: Sat, 12 Feb 2022 23:51:16 +0530 Message-Id: <20220212182117.49438-25-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> References: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Add support for suspending and resuming the channels in MHI endpoint stack. The channels will be moved to the suspended state during M3 state transition and will be resumed during M0 transition. Signed-off-by: Manivannan Sadhasivam Reviewed-by: Alex Elder --- drivers/bus/mhi/ep/internal.h | 2 ++ drivers/bus/mhi/ep/main.c | 58 +++++++++++++++++++++++++++++++++++ drivers/bus/mhi/ep/sm.c | 4 +++ 3 files changed, 64 insertions(+) diff --git a/drivers/bus/mhi/ep/internal.h b/drivers/bus/mhi/ep/internal.h index 8654af7caf40..e23d2fd04282 100644 --- a/drivers/bus/mhi/ep/internal.h +++ b/drivers/bus/mhi/ep/internal.h @@ -242,6 +242,8 @@ int mhi_ep_set_m0_state(struct mhi_ep_cntrl *mhi_cntrl); int mhi_ep_set_m3_state(struct mhi_ep_cntrl *mhi_cntrl); int mhi_ep_set_ready_state(struct mhi_ep_cntrl *mhi_cntrl); void mhi_ep_handle_syserr(struct mhi_ep_cntrl *mhi_cntrl); +void mhi_ep_resume_channels(struct mhi_ep_cntrl *mhi_cntrl); +void mhi_ep_suspend_channels(struct mhi_ep_cntrl *mhi_cntrl); /* MHI EP memory management functions */ int mhi_ep_alloc_map(struct mhi_ep_cntrl *mhi_cntrl, u64 pci_addr, size_t size, diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index e4186b012257..315409705b91 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -1106,6 +1106,64 @@ void mhi_ep_power_down(struct mhi_ep_cntrl *mhi_cntrl) } EXPORT_SYMBOL_GPL(mhi_ep_power_down); +void mhi_ep_suspend_channels(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct mhi_ep_chan *mhi_chan; + u32 tmp; + int i; + + for (i = 0; i < mhi_cntrl->max_chan; i++) { + mhi_chan = &mhi_cntrl->mhi_chan[i]; + + if (!mhi_chan->mhi_dev) + continue; + + mutex_lock(&mhi_chan->lock); + /* Skip if the channel is not currently running */ + tmp = le32_to_cpu(mhi_cntrl->ch_ctx_cache[i].chcfg); + if (FIELD_GET(CHAN_CTX_CHSTATE_MASK, tmp) != MHI_CH_STATE_RUNNING) { + mutex_unlock(&mhi_chan->lock); + continue; + } + + dev_dbg(&mhi_chan->mhi_dev->dev, "Suspending channel\n"); + /* Set channel state to SUSPENDED */ + tmp &= ~CHAN_CTX_CHSTATE_MASK; + tmp |= FIELD_PREP(CHAN_CTX_CHSTATE_MASK, MHI_CH_STATE_SUSPENDED); + mhi_cntrl->ch_ctx_cache[i].chcfg = cpu_to_le32(tmp); + mutex_unlock(&mhi_chan->lock); + } +} + +void mhi_ep_resume_channels(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct mhi_ep_chan *mhi_chan; + u32 tmp; + int i; + + for (i = 0; i < mhi_cntrl->max_chan; i++) { + mhi_chan = &mhi_cntrl->mhi_chan[i]; + + if (!mhi_chan->mhi_dev) + continue; + + mutex_lock(&mhi_chan->lock); + /* Skip if the channel is not currently suspended */ + tmp = le32_to_cpu(mhi_cntrl->ch_ctx_cache[i].chcfg); + if (FIELD_GET(CHAN_CTX_CHSTATE_MASK, tmp) != MHI_CH_STATE_SUSPENDED) { + mutex_unlock(&mhi_chan->lock); + continue; + } + + dev_dbg(&mhi_chan->mhi_dev->dev, "Resuming channel\n"); + /* Set channel state to RUNNING */ + tmp &= ~CHAN_CTX_CHSTATE_MASK; + tmp |= FIELD_PREP(CHAN_CTX_CHSTATE_MASK, MHI_CH_STATE_RUNNING); + mhi_cntrl->ch_ctx_cache[i].chcfg = cpu_to_le32(tmp); + mutex_unlock(&mhi_chan->lock); + } +} + static void mhi_ep_release_device(struct device *dev) { struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev); diff --git a/drivers/bus/mhi/ep/sm.c b/drivers/bus/mhi/ep/sm.c index 9a75ecfe1adf..e24ba2d85e13 100644 --- a/drivers/bus/mhi/ep/sm.c +++ b/drivers/bus/mhi/ep/sm.c @@ -88,8 +88,11 @@ int mhi_ep_set_m0_state(struct mhi_ep_cntrl *mhi_cntrl) enum mhi_state old_state; int ret; + /* If MHI is in M3, resume suspended channels */ spin_lock_bh(&mhi_cntrl->state_lock); old_state = mhi_cntrl->mhi_state; + if (old_state == MHI_STATE_M3) + mhi_ep_resume_channels(mhi_cntrl); ret = mhi_ep_set_mhi_state(mhi_cntrl, MHI_STATE_M0); if (ret) { @@ -135,6 +138,7 @@ int mhi_ep_set_m3_state(struct mhi_ep_cntrl *mhi_cntrl) } spin_unlock_bh(&mhi_cntrl->state_lock); + mhi_ep_suspend_channels(mhi_cntrl); /* Signal host that the device moved to M3 */ ret = mhi_ep_send_state_change_event(mhi_cntrl, MHI_STATE_M3); From patchwork Sat Feb 12 18:21:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 542166 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4605DC433EF for ; Sat, 12 Feb 2022 18:24:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230338AbiBLSYQ (ORCPT ); Sat, 12 Feb 2022 13:24:16 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:48286 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230334AbiBLSYA (ORCPT ); Sat, 12 Feb 2022 13:24:00 -0500 Received: from mail-pf1-x42f.google.com (mail-pf1-x42f.google.com [IPv6:2607:f8b0:4864:20::42f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AF9685B3C1 for ; Sat, 12 Feb 2022 10:23:43 -0800 (PST) Received: by mail-pf1-x42f.google.com with SMTP id i30so21935181pfk.8 for ; Sat, 12 Feb 2022 10:23:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Au/mBqZaaQyBAGIOH8RzJibxV3VU/TZF+4arCyxvGTY=; b=KaOcepOdTQrhOR4AS8lQLqlzl7Q6jPb8Sp1fugWR2kck0NPwQOzIORI/gBTLGakR4r mta45Y/42w3HqwzwIkj6/ojghtSL2zLxZSBpfu9ehwvYwIpoTvRW9Tvpz3in4vnCEXkX etExvaeN8yYqmfniJum7ZrW+ExsK/EbPbwQaV/CTek6eZeKRGbPQVtdK+mYLrQBwiAet eXOKCOjgl+MtnfuOPNBYlWkoge4EMEZS7GG+887shkuPAZHEf9UZq+4UwPSAkY4WSZPo J4DJGVCOkVws3RtTh4QeGywhQzxrF7Fkm1qC38o8B6Zd71tcdeNXSX1v2y/8iE4QYkwF u0mA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Au/mBqZaaQyBAGIOH8RzJibxV3VU/TZF+4arCyxvGTY=; b=xtJjc1vIWWbP9p7nMaooXiWJ+WjW8mr/JlhIgFiK2XnOxFEbRGPALIUIS33+Yah/cB bdx19PTB5XguzGKRxPkuOGuGUoekJElRYm8gix70jenT5tXGZ9w1L/JVoSI4GYfc0tIs 8ASMatC1XkNNw9A+qdg4iTEE0UvTOCZiPSaoKz0qVAP+8yZviUvM0je0GI6GW5h2gWBP 40vpX3FquTYPE/DqSOG7jBmzQiFMXRqVz/uNqNqhlpJ3wt88rA+FvfbOR57spoMH0zrx IQaMq9bP1z4GfxMacvMVNpbuYDl9HvxIwPj/U6O/54YTrOicywmvB3+VgbOFjzs44l5p DHMA== X-Gm-Message-State: AOAM530fLAIi4JCraQUGIWXgsVyitCZ1F8Iobvb19y3t9dhi1k9P1efG ixgALaaZKbSkZyCIOl2Z6tpt X-Google-Smtp-Source: ABdhPJw7rtn/EqYS4Ti9SeALK9sOS/Hq/eKqV26Px0lGVYCc+iEb1T9YnhTUhEymkPvN7SoJF+YBNQ== X-Received: by 2002:a63:4903:: with SMTP id w3mr5749982pga.5.1644690222170; Sat, 12 Feb 2022 10:23:42 -0800 (PST) Received: from localhost.localdomain ([27.111.75.57]) by smtp.gmail.com with ESMTPSA id g12sm14961987pfj.148.2022.02.12.10.23.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Feb 2022 10:23:41 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v3 25/25] bus: mhi: ep: Add uevent support for module autoloading Date: Sat, 12 Feb 2022 23:51:17 +0530 Message-Id: <20220212182117.49438-26-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> References: <20220212182117.49438-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Add uevent support to MHI endpoint bus so that the client drivers can be autoloaded by udev when the MHI endpoint devices gets created. The client drivers are expected to provide MODULE_DEVICE_TABLE with the MHI id_table struct so that the alias can be exported. The MHI endpoint reused the mhi_device_id structure of the MHI bus. Signed-off-by: Manivannan Sadhasivam Reviewed-by: Alex Elder --- drivers/bus/mhi/ep/main.c | 9 +++++++++ include/linux/mod_devicetable.h | 2 ++ scripts/mod/file2alias.c | 10 ++++++++++ 3 files changed, 21 insertions(+) diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 315409705b91..8889382ee8d0 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -1546,6 +1546,14 @@ void mhi_ep_driver_unregister(struct mhi_ep_driver *mhi_drv) } EXPORT_SYMBOL_GPL(mhi_ep_driver_unregister); +static int mhi_ep_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev); + + return add_uevent_var(env, "MODALIAS=" MHI_EP_DEVICE_MODALIAS_FMT, + mhi_dev->name); +} + static int mhi_ep_match(struct device *dev, struct device_driver *drv) { struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev); @@ -1572,6 +1580,7 @@ struct bus_type mhi_ep_bus_type = { .name = "mhi_ep", .dev_name = "mhi_ep", .match = mhi_ep_match, + .uevent = mhi_ep_uevent, }; static int __init mhi_ep_init(void) diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 4bb71979a8fd..0cff19bd72bf 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -835,6 +835,8 @@ struct wmi_device_id { #define MHI_DEVICE_MODALIAS_FMT "mhi:%s" #define MHI_NAME_SIZE 32 +#define MHI_EP_DEVICE_MODALIAS_FMT "mhi_ep:%s" + /** * struct mhi_device_id - MHI device identification * @chan: MHI channel name diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 5258247d78ac..d9d6a31446ea 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -1391,6 +1391,15 @@ static int do_mhi_entry(const char *filename, void *symval, char *alias) return 1; } +/* Looks like: mhi_ep:S */ +static int do_mhi_ep_entry(const char *filename, void *symval, char *alias) +{ + DEF_FIELD_ADDR(symval, mhi_device_id, chan); + sprintf(alias, MHI_EP_DEVICE_MODALIAS_FMT, *chan); + + return 1; +} + /* Looks like: ishtp:{guid} */ static int do_ishtp_entry(const char *filename, void *symval, char *alias) { @@ -1519,6 +1528,7 @@ static const struct devtable devtable[] = { {"tee", SIZE_tee_client_device_id, do_tee_entry}, {"wmi", SIZE_wmi_device_id, do_wmi_entry}, {"mhi", SIZE_mhi_device_id, do_mhi_entry}, + {"mhi_ep", SIZE_mhi_device_id, do_mhi_ep_entry}, {"auxiliary", SIZE_auxiliary_device_id, do_auxiliary_entry}, {"ssam", SIZE_ssam_device_id, do_ssam_entry}, {"dfl", SIZE_dfl_device_id, do_dfl_entry},