From patchwork Tue Sep 7 14:54:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sven Peter X-Patchwork-Id: 12478885 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 72B54C433FE for ; Tue, 7 Sep 2021 14:57:48 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 44DD5610C8 for ; Tue, 7 Sep 2021 14:57:48 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 44DD5610C8 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=svenpeter.dev Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=4WjYenXTgWZFLVepGqp/ytOmBQ9fm4fngpDpxeHGo1I=; b=NJrVrgAOQEmOoR qHz651eMpSE20YPjcDmZKFgFPtYFmgmkCTjtzo/RcR/iUSlp1FmkTNALrCCSOzw0S74BKBp1/BL3O LrRmMCjpUtSbZIuJ0Tpp12HB88BOs4UvQ4Q8D8CND3HqaP/Kyk6SB1ksFG6vwULzBZde4cESJbBq6 ak+QBbyE70FD2tZ0PnzQa9ZwMKB7BbGWxW67JXokGGIt08s+0V934Bq38c3fnbtdDVNlXYgTpY1I0 DXkyCanYuVttNIDKRweeV5Rdz4id+yRAcTGNtnYQ98LDjlrzw8iYV8Pa0Oo4RiAZE9BxUUD6aCRdh uEm22BybrxbOP1eWZVcw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mNcVX-003vmA-5N; Tue, 07 Sep 2021 14:55:31 +0000 Received: from new3-smtp.messagingengine.com ([66.111.4.229]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mNcVS-003vkM-Lf for linux-arm-kernel@lists.infradead.org; Tue, 07 Sep 2021 14:55:28 +0000 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailnew.nyi.internal (Postfix) with ESMTP id 20BF9580E87; Tue, 7 Sep 2021 10:55:23 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Tue, 07 Sep 2021 10:55:23 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=svenpeter.dev; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=fm2; bh=y8PXeVnFzrsl/ cXDsgWmWZzL6RQvNo+H9tfhruaVO+U=; b=CJVhLaHjIvv39oj5hmIgfFph0tsWf jzoffG1Gq9uLrd1mlg5qU08WTS43II6E+PedvrJP8dZfEDFX8MzUOjY5j5pYz0t3 X60XP7NEOK//kOB8W41tDMLd1swUwHCg2DMKS1HlD2XFDe9Ti2ELGFIGzyh0JU/y 1TvFzliUs+0Oi/yQPZ9IGrp+PUacdkPiIfQfMy7eIQY5KzZYS1aJVYHFxYYUOZrO 81r3BdukbIRrhaTJRYEWxkQgPnMqKA7/IsZp/s6K1Qs60b9z22mBZnJ6X4FNFeeY 4YOlDcZWNo+6Fqksvkk1CmbttBrbNMN7Fbbxesp8Hcg7us2ztz1TFLxZw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=y8PXeVnFzrsl/cXDsgWmWZzL6RQvNo+H9tfhruaVO+U=; b=IZI7grHk SQOCKYf7sDAum6+2HiDs+ZFdNt861sQYGOl1D+v/xPXRsamUxs5adghUTHqD/B1H m/yX+hlb1bLwtvEr7wKGJLkWbqetW1jmx2wniChnTD3YdF8QFcSVGjDavdIkWNdp T9cpd2WzBmEFIgDbzBEsOf5gQEnqL/wQdr58Wz3f8QWf12Ea9jeQZsX4+g+8syVZ ztYrL9lrZPdH9XXVLtpPtvRYJQNGDfDmZxC+BC67CfdLvoZbcFysY4+jpMmkOTph UbQ1aZka7BL2/WQNBBYmQK2l7cRIPJGwlyznCtS2DsSDxlvXWpWTe8uTY1gO53aj KSVLoONg6pzkag== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvtddrudefhedgkeegucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhephffvufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefuvhgvnhcu rfgvthgvrhcuoehsvhgvnhesshhvvghnphgvthgvrhdruggvvheqnecuggftrfgrthhtvg hrnheptedvkeetleeuffffhfekteetffeggffgveehieelueefvddtueffveevlefhfeej necuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomhepshhvvg hnsehsvhgvnhhpvghtvghrrdguvghv X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 7 Sep 2021 10:55:21 -0400 (EDT) From: Sven Peter To: Jassi Brar Cc: Sven Peter , Rob Herring , Mark Kettenis , Hector Martin , Alyssa Rosenzweig , Mohamed Mediouni , Stan Skowronek , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/3] mailbox: Add txdone_fifo Date: Tue, 7 Sep 2021 16:54:59 +0200 Message-Id: <20210907145501.69161-2-sven@svenpeter.dev> X-Mailer: git-send-email 2.30.1 (Apple Git-130) In-Reply-To: <20210907145501.69161-1-sven@svenpeter.dev> References: <20210907145501.69161-1-sven@svenpeter.dev> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210907_075526_896241_B5AB31B2 X-CRM114-Status: GOOD ( 31.65 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Some mailbox controllers are backed by a hardware FIFO and only provide a "FIFO not full" or "FIFO empty" interrupt. In the most common case it is however not neccesarry to wait for this interrupt since there is enough space in the FIFO and the message can be accepted directly. txdone_fifo adds supports for such controllers. Messages are assumed to have been transmitted as long as ops->send_data() returns success. Only if the FIFO is full and ops->send_data() returns -EBUSY the interrupt is enabled with ops->request_irq(). Signed-off-by: Sven Peter --- drivers/mailbox/mailbox.c | 66 ++++++++++++++++++++++++++---- drivers/mailbox/mailbox.h | 1 + include/linux/mailbox_controller.h | 15 +++++++ 3 files changed, 73 insertions(+), 9 deletions(-) diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c index 3e7d4b20ab34..cd628d98d211 100644 --- a/drivers/mailbox/mailbox.c +++ b/drivers/mailbox/mailbox.c @@ -50,6 +50,15 @@ static int add_to_rbuf(struct mbox_chan *chan, void *mssg) return idx; } +static void complete_msg(struct mbox_chan *chan, void *msg, int r) +{ + if (chan->cl->tx_done) + chan->cl->tx_done(chan->cl, msg, r); + + if (r != -ETIME && chan->cl->tx_block) + complete(&chan->tx_complete); +} + static void msg_submit(struct mbox_chan *chan) { unsigned count, idx; @@ -59,7 +68,7 @@ static void msg_submit(struct mbox_chan *chan) spin_lock_irqsave(&chan->lock, flags); - if (!chan->msg_count || chan->active_req) + if (!chan->msg_count || chan->active_req || chan->irq_pending) goto exit; count = chan->msg_count; @@ -75,15 +84,30 @@ static void msg_submit(struct mbox_chan *chan) chan->cl->tx_prepare(chan->cl, data); /* Try to submit a message to the MBOX controller */ err = chan->mbox->ops->send_data(chan, data); - if (!err) { - chan->active_req = data; + if (err) { + /* HW FIFO is full and we need to wait for an irq to continue */ + if (chan->txdone_method & TXDONE_BY_FIFO) { + chan->irq_pending = true; + chan->mbox->ops->request_irq(chan); + } + } else { + /* controllers with a FIFO have already accepted the message */ + if (!(chan->txdone_method & TXDONE_BY_FIFO)) + chan->active_req = data; chan->msg_count--; } exit: spin_unlock_irqrestore(&chan->lock, flags); + if (err) + return; + + /* controllers with a FIFO have already accepted the message */ + if (chan->txdone_method & TXDONE_BY_FIFO) + complete_msg(chan, data, 0); + /* kick start the timer immediately to avoid delays */ - if (!err && (chan->txdone_method & TXDONE_BY_POLL)) { + if (chan->txdone_method & TXDONE_BY_POLL) { /* but only if not already active */ if (!hrtimer_active(&chan->mbox->poll_hrt)) hrtimer_start(&chan->mbox->poll_hrt, 0, HRTIMER_MODE_REL); @@ -107,11 +131,7 @@ static void tx_tick(struct mbox_chan *chan, int r) return; /* Notify the client */ - if (chan->cl->tx_done) - chan->cl->tx_done(chan->cl, mssg, r); - - if (r != -ETIME && chan->cl->tx_block) - complete(&chan->tx_complete); + complete_msg(chan, mssg, r); } static enum hrtimer_restart txdone_hrtimer(struct hrtimer *hrtimer) @@ -179,6 +199,31 @@ void mbox_chan_txdone(struct mbox_chan *chan, int r) } EXPORT_SYMBOL_GPL(mbox_chan_txdone); +/** + * mbox_chan_txfifo_ready - A way for controller driver to notify the + * framework that there is space in the FIFO + * to accept messages again. + * @chan: Pointer to the mailbox chan on which there is FIFO space available + * + * The controller that has IRQ for TX ACK calls this atomic API + * to notify that there is space in the hardware FIFO again. + * It works only if txdone_fifo is set by the controller. + * This must be called from within the IRQ handler. + */ +void mbox_chan_txfifo_ready(struct mbox_chan *chan) +{ + if (unlikely(!(chan->txdone_method & TXDONE_BY_FIFO))) { + dev_err(chan->mbox->dev, + "Controller can't run the TX FIFO ticker\n"); + return; + } + + WRITE_ONCE(chan->irq_pending, false); + while (!READ_ONCE(chan->irq_pending) && READ_ONCE(chan->msg_count)) + msg_submit(chan); +} +EXPORT_SYMBOL_GPL(mbox_chan_txfifo_ready); + /** * mbox_client_txdone - The way for a client to run the TX state machine. * @chan: Mailbox channel assigned to this client. @@ -376,6 +421,7 @@ struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index) chan->msg_free = 0; chan->msg_count = 0; chan->active_req = NULL; + chan->irq_pending = false; chan->cl = cl; init_completion(&chan->tx_complete); @@ -485,6 +531,8 @@ int mbox_controller_register(struct mbox_controller *mbox) if (mbox->txdone_irq) txdone = TXDONE_BY_IRQ; + else if (mbox->txdone_fifo) + txdone = TXDONE_BY_FIFO; else if (mbox->txdone_poll) txdone = TXDONE_BY_POLL; else /* It has to be ACK then */ diff --git a/drivers/mailbox/mailbox.h b/drivers/mailbox/mailbox.h index 046d6d258b32..710525341df6 100644 --- a/drivers/mailbox/mailbox.h +++ b/drivers/mailbox/mailbox.h @@ -6,5 +6,6 @@ #define TXDONE_BY_IRQ BIT(0) /* controller has remote RTR irq */ #define TXDONE_BY_POLL BIT(1) /* controller can read status of last TX */ #define TXDONE_BY_ACK BIT(2) /* S/W ACK received by Client ticks the TX */ +#define TXDONE_BY_FIFO BIT(3) /* controller has HW FIFO with not-empty irq */ #endif /* __MAILBOX_H */ diff --git a/include/linux/mailbox_controller.h b/include/linux/mailbox_controller.h index 36d6ce673503..638cc20b9ebc 100644 --- a/include/linux/mailbox_controller.h +++ b/include/linux/mailbox_controller.h @@ -42,6 +42,11 @@ struct mbox_chan; * Used only if txdone_poll:=true && txdone_irq:=false * @peek_data: Atomic check for any received data. Return true if controller * has some data to push to the client. False otherwise. + * @request_irq: If the controller sets 'txdone_fifo', the API calls this + * to enable the 'ready to submit' interrupt whenever a previous + * call to send_data was not successful. This interrupt must fire + * only once and must call mbox_chan_txfifo_ready when new + * messages can be accepted into the hardware FIFO again. */ struct mbox_chan_ops { int (*send_data)(struct mbox_chan *chan, void *data); @@ -50,6 +55,7 @@ struct mbox_chan_ops { void (*shutdown)(struct mbox_chan *chan); bool (*last_tx_done)(struct mbox_chan *chan); bool (*peek_data)(struct mbox_chan *chan); + void (*request_irq)(struct mbox_chan *chan); }; /** @@ -61,6 +67,11 @@ struct mbox_chan_ops { * @txdone_irq: Indicates if the controller can report to API when * the last transmitted data was read by the remote. * Eg, if it has some TX ACK irq. + * @txdone_fifo: Indicates if the controller has a hardware FIFO which + * can directly accept multiple messages without delay. + * In case the FIFO cannot accept a message ops->send_data + * returns -EBUSY and ops->request_irq is used to request + * an interrupt once the FIFO has space for new messages. * @txdone_poll: If the controller can read but not report the TX * done. Ex, some register shows the TX status but * no interrupt rises. Ignored if 'txdone_irq' is set. @@ -77,6 +88,7 @@ struct mbox_controller { struct mbox_chan *chans; int num_chans; bool txdone_irq; + bool txdone_fifo; bool txdone_poll; unsigned txpoll_period; struct mbox_chan *(*of_xlate)(struct mbox_controller *mbox, @@ -108,6 +120,7 @@ struct mbox_controller { * @cl: Pointer to the current owner of this channel * @tx_complete: Transmission completion * @active_req: Currently active request hook + * @irq_pending: Set if the API is waiting for an interrupt to continue * @msg_count: No. of mssg currently queued * @msg_free: Index of next available mssg slot * @msg_data: Hook for data packet @@ -120,6 +133,7 @@ struct mbox_chan { struct mbox_client *cl; struct completion tx_complete; void *active_req; + bool irq_pending; unsigned msg_count, msg_free; void *msg_data[MBOX_TX_QUEUE_LEN]; spinlock_t lock; /* Serialise access to the channel */ @@ -130,6 +144,7 @@ int mbox_controller_register(struct mbox_controller *mbox); /* can sleep */ void mbox_controller_unregister(struct mbox_controller *mbox); /* can sleep */ void mbox_chan_received_data(struct mbox_chan *chan, void *data); /* atomic */ void mbox_chan_txdone(struct mbox_chan *chan, int r); /* atomic */ +void mbox_chan_txfifo_ready(struct mbox_chan *chan); /* atomic */ int devm_mbox_controller_register(struct device *dev, struct mbox_controller *mbox); From patchwork Tue Sep 7 14:55:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sven Peter X-Patchwork-Id: 12478889 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-22.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,MENTIONS_GIT_HOSTING,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id ADFB7C433F5 for ; Tue, 7 Sep 2021 14:58:03 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7FECB600CD for ; Tue, 7 Sep 2021 14:58:03 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 7FECB600CD Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=svenpeter.dev Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=0iLpQh1gpiRJu+zryeapamMvtK5THS8URIxyygXWEcE=; b=VXQ+JSB+xEfVFI Vj1vryWK18mSk1y5sfrzuL1wY8PLpNhmcW6MoFB/ZtCeeF6bVlL+czVO2wBMLtODIXK8U44VZZ9Da yXI/a8i01VFNk/8RYydMVU9wCqxu/wrt8Ube4EfcKzVUNczvfXlIML1Q5DwauQPm4uo6zhP1PEcxf hy+m7+ej5PosHPDykZfk+wMMNVKkAd7omaNPFTUnBfNn6GAjCchiVmbCZ9Dw9IlsfpX8l78gy84e8 fEg+QLEIqby4t/LkA7AbIK5p8intNJrdUFTmKykJcjkD6S58xZTyR18xbho0A52tv9TlR2qHSz/t8 ObTFB2x6m/8Mahie8WHQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mNcVu-003vpR-3s; Tue, 07 Sep 2021 14:55:54 +0000 Received: from new3-smtp.messagingengine.com ([66.111.4.229]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mNcVT-003vkU-L4 for linux-arm-kernel@lists.infradead.org; Tue, 07 Sep 2021 14:55:30 +0000 Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailnew.nyi.internal (Postfix) with ESMTP id 2994C580E94; Tue, 7 Sep 2021 10:55:25 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute5.internal (MEProxy); Tue, 07 Sep 2021 10:55:25 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=svenpeter.dev; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=fm2; bh=s5RoFGayuv7lj w9jyx+KFmGAlL1NLShQA4u/5VnW4IM=; b=kE1ijEYL4y7xBtiN7VabPEDRRxXmw OhkxadPT/wfGFmzhocdnJX4uMcyohN6Hhh1RlmelUdJErjqilkiGGIhYh57wOq4t Nh5FNgBFCEXbqoLywb2ME8Y+64K4RDKCDIl0ilSVfn0KdZQdFxwKN68flWemaZGF hhrDDzbwllD2Jnk9CjtaswMv/ZwYn5zjPrH5NIn2j0jBNSTI+2qTkNDgeI7QjRp2 ouAXl/deOVHYyMqqm7vBGlQw20GqFx385MztVo7lRZZKqUlBWx3yYDHRHcVcaahH IR4FRyPIIUaos8Rt4BAJeOKDPMHMmXhVrm2dUCrqcDfxg6DrKqG60PW4A== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=s5RoFGayuv7ljw9jyx+KFmGAlL1NLShQA4u/5VnW4IM=; b=XTCRXoqm BmEqIsYnZSvdt2NNR3+DQzWmU7IS7lOjgwkVlWPw+OwqMpeuc8HGrYMvuLPwsJJM ijYSHmKQKj5x6Cbz2WQHz2Z573pVqDyZruTU5p4GEw9JxDRgohevmPlvib1GcNby SDgERi3R4AidJ/kIt1f2HaX4ahxz3mAlVg51CPsrfN/veQR1OpjC+MmyjEKQirpq 3GHZzhkJZ4JV/1A7diABbSFtz1NQaR8tVcgZS79tAftZIJkSGwy+epr+q6yLEc3U 5ydzGalodAK+MKHZ6x5OGy/Z2ciZdpz+w28Vz4m7BQdhSZo52jWHapGOMvSMcBdv av8vxUvNOw7nRw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvtddrudefhedgkeefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhephffvufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefuvhgvnhcu rfgvthgvrhcuoehsvhgvnhesshhvvghnphgvthgvrhdruggvvheqnecuggftrfgrthhtvg hrnheptefgjedtjeejffelleejleehtdetvedujeelhffgieehgeduueehhfegueeuhfdv necuffhomhgrihhnpeguvghvihgtvghtrhgvvgdrohhrghdpohhfthgtrdhnvghtpdhgih hthhhusgdrtghomhenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhl fhhrohhmpehsvhgvnhesshhvvghnphgvthgvrhdruggvvh X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 7 Sep 2021 10:55:23 -0400 (EDT) From: Sven Peter To: Jassi Brar Cc: Sven Peter , Rob Herring , Mark Kettenis , Hector Martin , Alyssa Rosenzweig , Mohamed Mediouni , Stan Skowronek , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/3] dt-bindings: mailbox: Add Apple mailbox bindings Date: Tue, 7 Sep 2021 16:55:00 +0200 Message-Id: <20210907145501.69161-3-sven@svenpeter.dev> X-Mailer: git-send-email 2.30.1 (Apple Git-130) In-Reply-To: <20210907145501.69161-1-sven@svenpeter.dev> References: <20210907145501.69161-1-sven@svenpeter.dev> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210907_075527_807692_8D5C8C27 X-CRM114-Status: GOOD ( 18.52 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Apple mailbox controller are found on the M1 and are used for communication with various co-processors. Signed-off-by: Sven Peter Reviewed-by: Mark Kettenis --- .../bindings/mailbox/apple,mailbox.yaml | 81 +++++++++++++++++++ MAINTAINERS | 1 + 2 files changed, 82 insertions(+) create mode 100644 Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml diff --git a/Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml b/Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml new file mode 100644 index 000000000000..360d8a162cc5 --- /dev/null +++ b/Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml @@ -0,0 +1,81 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mailbox/apple,mailbox.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Apple Mailbox Controller + +maintainers: + - Hector Martin + - Sven Peter + +description: + The Apple mailbox consists of two FIFOs used to exchange 64+32 bit + messages between the main CPU and a co-processor. Multiple instances + of this mailbox can be found on Apple SoCs. + One of the two FIFOs is used to send data to a co-processor while the other + FIFO is used for the other direction. + Various clients implement different IPC protocols based on these simple + messages and shared memory buffers. + +properties: + compatible: + oneOf: + - description: + ASC mailboxes are the most common variant found on the M1. + items: + - const: apple,t8103-asc-mailbox + + - description: + M3 mailboxes are an older variant with a slightly different MMIO + interface still found on the M1. + items: + - const: apple,t8103-m3-mailbox + + reg: + maxItems: 1 + + interrupts: + minItems: 4 + items: + - description: send fifo is empty interrupt + - description: send fifo is not empty interrupt + - description: receive fifo is empty interrupt + - description: receive fifo is not empty interrupt + + interrupt-names: + minItems: 4 + items: + - const: send-empty + - const: send-not-empty + - const: recv-empty + - const: recv-not-empty + + clocks: + description: + Reference to the clock gate phandle(s) if required for this mailbox. + Optional since not all mailboxes are attached to a clock gate. + + "#mbox-cells": + const: 0 + +required: + - compatible + - reg + - interrupts + - interrupt-names + - "#mbox-cells" + +additionalProperties: false + +examples: + - | + mailbox@77408000 { + compatible = "apple,t8103-asc-mailbox"; + reg = <0x77408000 0x4000>; + interrupts = <1 583 4>, <1 584 4>, <1 585 4>, <1 586 4>; + interrupt-names = "send-empty", "send-not-empty", + "recv-empty", "recv-not-empty"; + #mbox-cells = <0>; + }; diff --git a/MAINTAINERS b/MAINTAINERS index cad1289793db..47de27282c98 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1720,6 +1720,7 @@ C: irc://irc.oftc.net/asahi-dev T: git https://github.com/AsahiLinux/linux.git F: Documentation/devicetree/bindings/arm/apple.yaml F: Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml +F: Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml F: Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml F: arch/arm64/boot/dts/apple/ F: drivers/irqchip/irq-apple-aic.c From patchwork Tue Sep 7 14:55:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sven Peter X-Patchwork-Id: 12478891 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 66A79C433EF for ; Tue, 7 Sep 2021 14:58:20 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3427F610C8 for ; Tue, 7 Sep 2021 14:58:20 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 3427F610C8 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=svenpeter.dev Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=/6OtAe7DclIyF7Sne+dPcRXzi75glC4+kjKJHhNWC3I=; b=P53g8mQ+00VJ8k OLWO+UG0o7jGZ+8pyFelCyznPQJm2FNB1/5LS4xkRgR6rWwKbz4PlBusmaOIlHzzKgJgevgI0UTkI lnPJlYz3OY+oo328FsaVryukBQgdrW26nreZexxwmEyImwz3SXVfIzcHlxchDNFFRjlNPlubn2Q26 Mm4mntTRq80bmqAhGVMQ3JVQer9/92F6+jJPnbml+mD7cvnMOgbYF/1HaDMG17pXGbrzlLTBFGu+K BLMP/Vz4rNOtZjqexJntnXYBJBRMPhqSxoGOS6qXTFJr9K0iCA18gVTT7u91BFaPoUz4AktzcgHop rr82eDcqWcBosroEc1CQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mNcW7-003vst-7I; Tue, 07 Sep 2021 14:56:07 +0000 Received: from new3-smtp.messagingengine.com ([66.111.4.229]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mNcVT-003vl3-Hv for linux-arm-kernel@lists.infradead.org; Tue, 07 Sep 2021 14:55:31 +0000 Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailnew.nyi.internal (Postfix) with ESMTP id EBB0A580E9A; Tue, 7 Sep 2021 10:55:26 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute1.internal (MEProxy); Tue, 07 Sep 2021 10:55:26 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=svenpeter.dev; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=fm2; bh=EyfTuGE0XugR+ IeHeZP4P0SsiQml/467dB/O4QGvyYM=; b=P8zBwco/bMGPtY6U9KkTLamMXXlLQ sM1xwrrJAdrtEqC3gs3JIK9ND8Ono/BNllCKmgp1JiBCd3Ej8YVrq8TmLp4Ovv04 4g6SDeE34sodE8Ym31wMmabF9BKJl49z51IQHKh26he3q2hJy5boTYVI1kYNMOZf b4RfJlSB9aRQSChcwRRd+BAAqy52iNSoDsFfOHnJ4WB18pvVL/O+JALrrfXhXhA+ 2F4qivzwkh6+QrRNFvLeOBM60e+P0qri5FwqcNw/9V13GuUez9G9O5xz+zJJWRUK OKmQaE5a9XUqITi2IMBb8+33nBgj0OHWv7w4pNnABWVZtaTSYOLhUKjtw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=EyfTuGE0XugR+IeHeZP4P0SsiQml/467dB/O4QGvyYM=; b=COGaex/7 CHndftvur9SVvLymVJ96et5aXvEgZWjN8465uOZRh/4l24tfgAmT/asUhRBNz2r/ iC5N/Xvz6xS5D+jeVBwxkoCLHGXHwll0rTkY0S1BlPqW6W0YxJXAqXVzt7dzzgXH IicTATMl2/MYrwbvLN6Z5f8yKM9xM7DGh+t1r3bOQB2sfuxvQfGYQ/QfXTNCOiY5 DXop1L1RbW0tCIH1uPcGoM8SaGrzJaxMM0VkkWLdItt7GvE7kCQZDjwo5vKLCyrd LQRHZmCQkp24NXNHNqL4ELklen3dZ6JtIpPFNcQ8wtM5fH/owL+eNAdnOY2KlZiU eH+3t0ZyjCZ3wg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvtddrudefhedgkeegucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhephffvufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefuvhgvnhcu rfgvthgvrhcuoehsvhgvnhesshhvvghnphgvthgvrhdruggvvheqnecuggftrfgrthhtvg hrnheptedvkeetleeuffffhfekteetffeggffgveehieelueefvddtueffveevlefhfeej necuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomhepshhvvg hnsehsvhgvnhhpvghtvghrrdguvghv X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 7 Sep 2021 10:55:25 -0400 (EDT) From: Sven Peter To: Jassi Brar Cc: Sven Peter , Rob Herring , Mark Kettenis , Hector Martin , Alyssa Rosenzweig , Mohamed Mediouni , Stan Skowronek , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH 3/3] mailbox: apple: Add driver for Apple mailboxes Date: Tue, 7 Sep 2021 16:55:01 +0200 Message-Id: <20210907145501.69161-4-sven@svenpeter.dev> X-Mailer: git-send-email 2.30.1 (Apple Git-130) In-Reply-To: <20210907145501.69161-1-sven@svenpeter.dev> References: <20210907145501.69161-1-sven@svenpeter.dev> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210907_075527_792268_11573E5B X-CRM114-Status: GOOD ( 31.61 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Apple SoCs such as the M1 come with various co-processors. Mailboxes are used to communicate with those. This driver adds support for two variants of those mailboxes. Signed-off-by: Sven Peter --- MAINTAINERS | 2 + drivers/mailbox/Kconfig | 12 + drivers/mailbox/Makefile | 2 + drivers/mailbox/apple-mailbox.c | 432 ++++++++++++++++++++++++++++++++ include/linux/apple-mailbox.h | 18 ++ 5 files changed, 466 insertions(+) create mode 100644 drivers/mailbox/apple-mailbox.c create mode 100644 include/linux/apple-mailbox.h diff --git a/MAINTAINERS b/MAINTAINERS index 47de27282c98..cf0500bbea5b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1724,8 +1724,10 @@ F: Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml F: Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml F: arch/arm64/boot/dts/apple/ F: drivers/irqchip/irq-apple-aic.c +F: drivers/mailbox/apple-mailbox.c F: include/dt-bindings/interrupt-controller/apple-aic.h F: include/dt-bindings/pinctrl/apple.h +F: include/linux/apple-mailbox.h ARM/ARTPEC MACHINE SUPPORT M: Jesper Nilsson diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig index c9fc06c7e685..a2caff75047f 100644 --- a/drivers/mailbox/Kconfig +++ b/drivers/mailbox/Kconfig @@ -8,6 +8,18 @@ menuconfig MAILBOX if MAILBOX +config APPLE_MBOX + tristate "Apple Mailbox driver" + depends on ARCH_APPLE || (ARM64 && COMPILE_TEST) + default ARCH_APPLE + help + Apple SoCs have various co-processors that need to be started and + initialized for certain peripherals to work (NVMe, display controller, + etc.). This driver adds support for the mailbox controller used to + communicate with those. + + Say Y here if you have a Apple SoC. + config ARM_MHU tristate "ARM MHU Mailbox" depends on ARM_AMBA diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile index c2089f04887e..896554c7c169 100644 --- a/drivers/mailbox/Makefile +++ b/drivers/mailbox/Makefile @@ -58,3 +58,5 @@ obj-$(CONFIG_SUN6I_MSGBOX) += sun6i-msgbox.o obj-$(CONFIG_SPRD_MBOX) += sprd-mailbox.o obj-$(CONFIG_QCOM_IPCC) += qcom-ipcc.o + +obj-$(CONFIG_APPLE_MBOX) += apple-mailbox.o diff --git a/drivers/mailbox/apple-mailbox.c b/drivers/mailbox/apple-mailbox.c new file mode 100644 index 000000000000..d59642d9216a --- /dev/null +++ b/drivers/mailbox/apple-mailbox.c @@ -0,0 +1,432 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Apple mailbox driver + * + * Copyright (C) 2021 The Asahi Linux Contributors + * + * This driver adds support for two mailbox variants (called ASC and M3 by + * Apple) found in Apple SoCs such as the M1. It consists of two FIFOs used to + * exchange 64+32 bit messages between the main CPU and a co-processor. + * Various clients implement different IPC protocols based on these simple + * messages and shared memory buffers. + * + * Both the main CPU and the co-processor see the same set of registers but + * the first FIFO (A2I) is always used to transfer messages from the application + * processor (us) to the I/O processor and the second one (I2A) for the + * other direction. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define APPLE_ASC_MBOX_CONTROL_FULL BIT(16) +#define APPLE_ASC_MBOX_CONTROL_EMPTY BIT(17) + +#define APPLE_ASC_MBOX_A2I_CONTROL 0x110 +#define APPLE_ASC_MBOX_A2I_SEND0 0x800 +#define APPLE_ASC_MBOX_A2I_SEND1 0x808 +#define APPLE_ASC_MBOX_A2I_RECV0 0x810 +#define APPLE_ASC_MBOX_A2I_RECV1 0x818 + +#define APPLE_ASC_MBOX_I2A_CONTROL 0x114 +#define APPLE_ASC_MBOX_I2A_SEND0 0x820 +#define APPLE_ASC_MBOX_I2A_SEND1 0x828 +#define APPLE_ASC_MBOX_I2A_RECV0 0x830 +#define APPLE_ASC_MBOX_I2A_RECV1 0x838 + +#define APPLE_M3_MBOX_A2I_CONTROL 0x50 +#define APPLE_M3_MBOX_A2I_SEND0 0x60 +#define APPLE_M3_MBOX_A2I_SEND1 0x68 +#define APPLE_M3_MBOX_A2I_RECV0 0x70 +#define APPLE_M3_MBOX_A2I_RECV1 0x78 + +#define APPLE_M3_MBOX_I2A_CONTROL 0x80 +#define APPLE_M3_MBOX_I2A_SEND0 0x90 +#define APPLE_M3_MBOX_I2A_SEND1 0x98 +#define APPLE_M3_MBOX_I2A_RECV0 0xa0 +#define APPLE_M3_MBOX_I2A_RECV1 0xa8 + +#define APPLE_M3_MBOX_CONTROL_FULL BIT(16) +#define APPLE_M3_MBOX_CONTROL_EMPTY BIT(17) + +#define APPLE_M3_MBOX_IRQ_ENABLE 0x48 +#define APPLE_M3_MBOX_IRQ_ACK 0x4c +#define APPLE_M3_MBOX_IRQ_A2I_EMPTY BIT(0) +#define APPLE_M3_MBOX_IRQ_A2I_NOT_EMPTY BIT(1) +#define APPLE_M3_MBOX_IRQ_I2A_EMPTY BIT(2) +#define APPLE_M3_MBOX_IRQ_I2A_NOT_EMPTY BIT(3) + +#define APPLE_MBOX_MSG1_OUTCNT GENMASK(56, 52) +#define APPLE_MBOX_MSG1_INCNT GENMASK(51, 48) +#define APPLE_MBOX_MSG1_OUTPTR GENMASK(47, 44) +#define APPLE_MBOX_MSG1_INPTR GENMASK(43, 40) +#define APPLE_MBOX_MSG1_MSG GENMASK(31, 0) + +struct apple_mbox_hw { + unsigned int control_full; + unsigned int control_empty; + + unsigned int a2i_control; + unsigned int a2i_send0; + unsigned int a2i_send1; + + unsigned int i2a_control; + unsigned int i2a_recv0; + unsigned int i2a_recv1; + + bool has_irq_controls; + unsigned int irq_enable; + unsigned int irq_ack; + unsigned int irq_bit_recv_not_empty; + unsigned int irq_bit_send_empty; +}; + +static const struct apple_mbox_hw apple_mbox_asc_hw = { + .control_full = APPLE_ASC_MBOX_CONTROL_FULL, + .control_empty = APPLE_ASC_MBOX_CONTROL_EMPTY, + + .a2i_control = APPLE_ASC_MBOX_A2I_CONTROL, + .a2i_send0 = APPLE_ASC_MBOX_A2I_SEND0, + .a2i_send1 = APPLE_ASC_MBOX_A2I_SEND1, + + .i2a_control = APPLE_ASC_MBOX_I2A_CONTROL, + .i2a_recv0 = APPLE_ASC_MBOX_I2A_RECV0, + .i2a_recv1 = APPLE_ASC_MBOX_I2A_RECV1, + + .has_irq_controls = false, +}; + +static const struct apple_mbox_hw apple_mbox_m3_hw = { + .control_full = APPLE_M3_MBOX_CONTROL_FULL, + .control_empty = APPLE_M3_MBOX_CONTROL_EMPTY, + + .a2i_control = APPLE_M3_MBOX_A2I_CONTROL, + .a2i_send0 = APPLE_M3_MBOX_A2I_SEND0, + .a2i_send1 = APPLE_M3_MBOX_A2I_SEND1, + + .i2a_control = APPLE_M3_MBOX_I2A_CONTROL, + .i2a_recv0 = APPLE_M3_MBOX_I2A_RECV0, + .i2a_recv1 = APPLE_M3_MBOX_I2A_RECV1, + + .has_irq_controls = true, + .irq_enable = APPLE_M3_MBOX_IRQ_ENABLE, + .irq_ack = APPLE_M3_MBOX_IRQ_ACK, + .irq_bit_recv_not_empty = APPLE_M3_MBOX_IRQ_I2A_NOT_EMPTY, + .irq_bit_send_empty = APPLE_M3_MBOX_IRQ_A2I_EMPTY, +}; + +static const struct of_device_id apple_mbox_of_match[] = { + { .compatible = "apple,t8103-asc-mailbox", .data = &apple_mbox_asc_hw }, + { .compatible = "apple,t8103-m3-mailbox", .data = &apple_mbox_m3_hw }, + {} +}; +MODULE_DEVICE_TABLE(of, apple_mbox_of_match); + +struct apple_mbox { + void __iomem *regs; + const struct apple_mbox_hw *hw; + + int irq_recv_not_empty; + int irq_send_empty; + + struct clk_bulk_data *clks; + int num_clks; + + struct mbox_chan chan; + + struct device *dev; + struct mbox_controller controller; +}; + +static bool apple_mbox_hw_can_send(struct apple_mbox *apple_mbox) +{ + u32 mbox_ctrl = + readl_relaxed(apple_mbox->regs + apple_mbox->hw->a2i_control); + + return !(mbox_ctrl & apple_mbox->hw->control_full); +} + +static void apple_mbox_hw_send(struct apple_mbox *apple_mbox, + struct apple_mbox_msg *msg) +{ + WARN_ON(!apple_mbox_hw_can_send(apple_mbox)); + + dev_dbg(apple_mbox->dev, "> TX %016llx %08x\n", msg->msg0, msg->msg1); + + /* + * This message may be related to a shared memory buffer and we must + * ensure all previous writes to normal memory are visible before + * submitting it. + */ + dma_wmb(); + + writeq_relaxed(msg->msg0, apple_mbox->regs + apple_mbox->hw->a2i_send0); + writeq_relaxed(FIELD_PREP(APPLE_MBOX_MSG1_MSG, msg->msg1), + apple_mbox->regs + apple_mbox->hw->a2i_send1); +} + +static bool apple_mbox_hw_can_recv(struct apple_mbox *apple_mbox) +{ + u32 mbox_ctrl = + readl_relaxed(apple_mbox->regs + apple_mbox->hw->i2a_control); + + return !(mbox_ctrl & apple_mbox->hw->control_empty); +} + +static void apple_mbox_hw_recv(struct apple_mbox *apple_mbox, + struct apple_mbox_msg *msg) +{ + WARN_ON(!apple_mbox_hw_can_recv(apple_mbox)); + + msg->msg0 = readq_relaxed(apple_mbox->regs + apple_mbox->hw->i2a_recv0); + msg->msg1 = FIELD_GET( + APPLE_MBOX_MSG1_MSG, + readq_relaxed(apple_mbox->regs + apple_mbox->hw->i2a_recv1)); + + dev_dbg(apple_mbox->dev, "< RX %016llx %08x\n", msg->msg0, msg->msg1); + + /* + * This message may be related to a shared memory buffer and we must + * ensure any following reads from normal memory only happen after + * having read this message. + */ + dma_rmb(); +} + +static int apple_mbox_chan_send_data(struct mbox_chan *chan, void *data) +{ + struct apple_mbox *apple_mbox = chan->con_priv; + struct apple_mbox_msg *msg = data; + + if (!apple_mbox_hw_can_send(apple_mbox)) { + dev_dbg(apple_mbox->dev, "FIFO full, waiting for IRQ\n"); + return -EBUSY; + } + + apple_mbox_hw_send(apple_mbox, msg); + return 0; +} + +static irqreturn_t apple_mbox_send_empty_irq(int irq, void *data) +{ + struct apple_mbox *apple_mbox = data; + + dev_dbg(apple_mbox->dev, "got FIFO empty IRQ\n"); + + /* + * We don't need to acknowledge the interrupt at the mailbox level + * here even if supported by the hardware. It will keep firing but that + * doesn't matter since it's disabled at the main interrupt controller. + * apple_mbox_chan_request_irq will acknowledge it before enabling + * it at the main controller again. + */ + disable_irq_nosync(apple_mbox->irq_send_empty); + mbox_chan_txfifo_ready(&apple_mbox->chan); + return IRQ_HANDLED; +} + +static irqreturn_t apple_mbox_recv_irq(int irq, void *data) +{ + struct apple_mbox *apple_mbox = data; + struct apple_mbox_msg msg; + + while (apple_mbox_hw_can_recv(apple_mbox)) { + apple_mbox_hw_recv(apple_mbox, &msg); + mbox_chan_received_data(&apple_mbox->chan, (void *)&msg); + } + + /* + * The interrupt will keep firing even if there are no more messages + * unless we also acknowledge it at the mailbox level here. + * There's no race if a message comes in between the check in the while + * loop above and the ack below: If a new messages arrives inbetween + * those two the interrupt will just fire again immediately after the + * ack since it's level sensitive. + */ + if (apple_mbox->hw->has_irq_controls) + writel_relaxed(apple_mbox->hw->irq_bit_recv_not_empty, + apple_mbox->regs + apple_mbox->hw->irq_ack); + + return IRQ_HANDLED; +} + +static struct mbox_chan *apple_mbox_of_xlate(struct mbox_controller *mbox, + const struct of_phandle_args *spec) +{ + struct apple_mbox *apple_mbox = dev_get_drvdata(mbox->dev); + + if (spec->args_count != 0) + return ERR_PTR(-EINVAL); + if (apple_mbox->chan.con_priv) + return ERR_PTR(-EBUSY); + + apple_mbox->chan.con_priv = apple_mbox; + return &apple_mbox->chan; +} + +static int apple_mbox_chan_startup(struct mbox_chan *chan) +{ + struct apple_mbox *apple_mbox = chan->con_priv; + + /* + * Only some variants of this mailbox HW provide interrupt control + * at the mailbox level. We therefore need to handle enabling/disabling + * interrupts at the main interrupt controller anyway for hardware that + * doesn't. Just always keep the interrupts we care about enabled at + * the mailbox level so that both hardware revisions behave almost + * the same. + */ + if (apple_mbox->hw->has_irq_controls) + writel_relaxed(apple_mbox->hw->irq_bit_recv_not_empty | + apple_mbox->hw->irq_bit_send_empty, + apple_mbox->regs + apple_mbox->hw->irq_enable); + + enable_irq(apple_mbox->irq_recv_not_empty); + return 0; +} + +static void apple_mbox_chan_shutdown(struct mbox_chan *chan) +{ + struct apple_mbox *apple_mbox = chan->con_priv; + + disable_irq(apple_mbox->irq_recv_not_empty); +} + +static void apple_mbox_chan_request_irq(struct mbox_chan *chan) +{ + struct apple_mbox *apple_mbox = chan->con_priv; + + /* + * The interrupt is level sensitive and will keep firing as long as the + * FIFO is empty. It will also keep firing if the FIFO was empty + * at any point in the past until it has been acknowledged at the + * mailbox level. By acknowledging it here we can ensure that we will + * only get the interrupt once the FIFO has been cleared again. + * If the FIFO is already empty before the ack it will fire again + * immediately after the ack. + */ + if (apple_mbox->hw->has_irq_controls) + writel_relaxed(apple_mbox->hw->irq_bit_send_empty, + apple_mbox->regs + apple_mbox->hw->irq_ack); + enable_irq(apple_mbox->irq_send_empty); +} + +static const struct mbox_chan_ops apple_mbox_ops = { + .send_data = apple_mbox_chan_send_data, + .request_irq = apple_mbox_chan_request_irq, + .startup = apple_mbox_chan_startup, + .shutdown = apple_mbox_chan_shutdown, +}; + +static int apple_mbox_probe(struct platform_device *pdev) +{ + int ret; + const struct of_device_id *match; + char *irqname; + struct apple_mbox *mbox; + struct device *dev = &pdev->dev; + + match = of_match_node(apple_mbox_of_match, pdev->dev.of_node); + if (!match) + return -EINVAL; + if (!match->data) + return -EINVAL; + + mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL); + if (!mbox) + return -ENOMEM; + platform_set_drvdata(pdev, mbox); + + mbox->dev = dev; + mbox->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(mbox->regs)) + return PTR_ERR(mbox->regs); + + mbox->hw = match->data; + mbox->irq_recv_not_empty = + platform_get_irq_byname(pdev, "recv-not-empty"); + if (mbox->irq_recv_not_empty < 0) + return -ENODEV; + + mbox->irq_send_empty = platform_get_irq_byname(pdev, "send-empty"); + if (mbox->irq_send_empty < 0) + return -ENODEV; + + ret = devm_clk_bulk_get_all(dev, &mbox->clks); + if (ret < 0) + return ret; + mbox->num_clks = ret; + + ret = clk_bulk_prepare_enable(mbox->num_clks, mbox->clks); + if (ret) + return ret; + + mbox->controller.dev = mbox->dev; + mbox->controller.num_chans = 1; + mbox->controller.chans = &mbox->chan; + mbox->controller.ops = &apple_mbox_ops; + mbox->controller.of_xlate = &apple_mbox_of_xlate; + mbox->controller.txdone_fifo = true; + + irqname = devm_kasprintf(dev, GFP_KERNEL, "%s-recv", dev_name(dev)); + if (!irqname) { + ret = -ENOMEM; + goto err_clk_disable; + } + ret = devm_request_irq(dev, mbox->irq_recv_not_empty, + apple_mbox_recv_irq, IRQF_NO_AUTOEN, irqname, + mbox); + if (ret) + goto err_clk_disable; + + irqname = devm_kasprintf(dev, GFP_KERNEL, "%s-send", dev_name(dev)); + if (!irqname) { + ret = -ENOMEM; + goto err_clk_disable; + } + ret = devm_request_irq(dev, mbox->irq_send_empty, + apple_mbox_send_empty_irq, IRQF_NO_AUTOEN, + irqname, mbox); + if (ret) + goto err_clk_disable; + + ret = devm_mbox_controller_register(dev, &mbox->controller); + if (ret) + goto err_clk_disable; + return ret; + +err_clk_disable: + clk_bulk_disable_unprepare(mbox->num_clks, mbox->clks); + return ret; +} + +static int apple_mbox_remove(struct platform_device *pdev) +{ + struct apple_mbox *apple_mbox = dev_get_drvdata(&pdev->dev); + + clk_bulk_disable_unprepare(apple_mbox->num_clks, apple_mbox->clks); + return 0; +} + +static struct platform_driver apple_mbox_driver = { + .driver = { + .name = "apple-mailbox", + .of_match_table = apple_mbox_of_match, + }, + .probe = apple_mbox_probe, + .remove = apple_mbox_remove, +}; +module_platform_driver(apple_mbox_driver); + +MODULE_LICENSE("Dual MIT/GPL"); +MODULE_AUTHOR("Sven Peter "); +MODULE_DESCRIPTION("Apple Mailbox driver"); diff --git a/include/linux/apple-mailbox.h b/include/linux/apple-mailbox.h new file mode 100644 index 000000000000..c455e0f9c73b --- /dev/null +++ b/include/linux/apple-mailbox.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ +/* + * Apple mailbox message format + * + * Copyright (C) 2021 The Asahi Linux Contributors + */ + +#ifndef _LINUX_APPLE_MAILBOX_H_ +#define _LINUX_APPLE_MAILBOX_H_ + +#include + +struct apple_mbox_msg { + u64 msg0; + u32 msg1; +}; + +#endif