From patchwork Fri Mar 29 18:54:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Abel Vesa X-Patchwork-Id: 13610955 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 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 467AECD1283 for ; Fri, 29 Mar 2024 18:56:17 +0000 (UTC) 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:Cc:To:In-Reply-To:References:Message-Id :MIME-Version:Subject:Date:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=NxufRQevrxcNuAnkcXB+Iq/SYodym9SAuRudhueYCVs=; b=4NN9WSsSVd5JiP FB9T8vLUpK/sESibAyI/VuwLSS3NaTZEEyEsXmwUOnvJJXzf155N0OyQUEm6xIhu9o8qPiKCL4VUZ j5zDOf2MkJN67g1mmY3geFJz44a4PdlybWoBY513L3PsDRxOW39fOy/0qKRe5lmGOjlRKfQi75vJg WROvEOruvcBlRflO0+xB8S7Y12lRAX/zrLw4Rkd/u1aOVTY23DjE+MbRo6L25jQOCGFok8noUtawR yRKNWbzryoX8ein2xbu0krKMW6iHQWfzHGX0ecpHLGXVABMtT7yOpU53PxwykIqpjV8C7EHuzXY9w Xk2h2mdBnE+45wjfi0tg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1rqHOR-00000001ffe-3TCK; Fri, 29 Mar 2024 18:56:00 +0000 Received: from mail-ed1-x532.google.com ([2a00:1450:4864:20::532]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1rqHNP-00000001f24-1aMV for linux-arm-kernel@lists.infradead.org; Fri, 29 Mar 2024 18:54:59 +0000 Received: by mail-ed1-x532.google.com with SMTP id 4fb4d7f45d1cf-56829f41f81so3326340a12.2 for ; Fri, 29 Mar 2024 11:54:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1711738492; x=1712343292; darn=lists.infradead.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=gDWmNiwFaDyG4eVDcOJIipMcHBjPEMX/8w3VIoSj37Y=; b=MWpSIJg3R21DgeihH+3pPHcOlG90pUGt4w5TuVtVjbeNdnZTNVwyWwWWMFibvCI/XL X+FVcM3SW8IL3s31+5L1yccip1yME2uI2pFkwD9yygcftaSRSKwl+yNEZZkFL1S/n2js ghhVsD4eNsNjGM8HT7PaMuiUUkR9rRRp/eiCygwf7LZecO+qXrGo3e6VGj7h+FDRQQcj eSRbjaZu5pvlU+6aURgfUKKMX6qT/1wYvck8H8GCdzmikzCAqbtMB083vwEF3/opqf8Q PuRQoHlfB2MK/ZSW+XrabVQLNh8VIC8d+PgKGvXgz89blwenIqljJrlE4HAZ+EwwFWgq w67Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711738492; x=1712343292; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=gDWmNiwFaDyG4eVDcOJIipMcHBjPEMX/8w3VIoSj37Y=; b=buFa9G7x71JvTH7BMB7oHm+QHATA4exEmcZzf7/rTXuw15fjjyl3gDRCLDDTmbNc31 V9vxfnzWfFslAtiFBM2WMN7QMfp9sg4MfDr285paPHHFUeJEEDbWkjPqKvyJoOfrMGSc zGs5aaPXLJEM03dW3cCgPGi/281lnpLQXw+lFGj196yUDmALrKOI0uIIkRRjXzeCQfz7 W3IU9N1qeucl0Sz+R06wYg13ra9X57hfkn5KRm52eCyjrl3nv3sytEIE2o2pzxH65Hv4 EEmEkOPuRFlo7qYDIMqsB3BPXPTGNyxHpR5JZp0T1PTaNQKBs25zwhCD7URHPjSBznor dh9g== X-Forwarded-Encrypted: i=1; AJvYcCXlwc56EFLs++28HzJPOyQwyCHRKDl5q0pb+u4UCNWRapJ+oi3odniaSYEfJ3shsnodJul9GYEnl27sVL15yihEUb2mRJGLByvkIkF/jom9da8nzIE= X-Gm-Message-State: AOJu0YwZob8GDQoKy+A1NeIpC3plFra54R7tm08qw67N6dCf7n7as2pM iCDPjyGfE+fvtZoyM8J0HMBzFBEAW4ZrwTeFFJVv3wp2YyKh+TQ5BH01yHTAP9A= X-Google-Smtp-Source: AGHT+IEtKEI1LK9lS1mHVw1CNmNQ33IUOsSWQyQtYl0YqK2TB+8vPQKsER18RfjFqRKtZmrSueU3Tw== X-Received: by 2002:a17:907:7248:b0:a4e:4350:3b3a with SMTP id ds8-20020a170907724800b00a4e43503b3amr604914ejc.60.1711738492180; Fri, 29 Mar 2024 11:54:52 -0700 (PDT) Received: from [127.0.1.1] ([79.114.172.194]) by smtp.gmail.com with ESMTPSA id gl20-20020a170906e0d400b00a46c39e6a47sm2235618ejb.148.2024.03.29.11.54.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 29 Mar 2024 11:54:51 -0700 (PDT) From: Abel Vesa Date: Fri, 29 Mar 2024 20:54:23 +0200 Subject: [PATCH v7 6/6] spmi: pmic-arb: Add multi bus support MIME-Version: 1.0 Message-Id: <20240329-spmi-multi-master-support-v7-6-7b902824246c@linaro.org> References: <20240329-spmi-multi-master-support-v7-0-7b902824246c@linaro.org> In-Reply-To: <20240329-spmi-multi-master-support-v7-0-7b902824246c@linaro.org> To: Stephen Boyd , Matthias Brugger , Bjorn Andersson , Konrad Dybcio , Dmitry Baryshkov , Neil Armstrong , AngeloGioacchino Del Regno , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Srini Kandagatla , Johan Hovold , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-arm-msm@vger.kernel.org, linux-mediatek@lists.infradead.org, devicetree@vger.kernel.org, Abel Vesa X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=9932; i=abel.vesa@linaro.org; h=from:subject:message-id; bh=kiFNbFrr2cHRGI8Y32geRObZcge4BmsO3+tXioPlQw4=; b=owEBbQKS/ZANAwAKARtfRMkAlRVWAcsmYgBmBw5wmKqlBnGcmeFRd+VPQ2FIeVnh7xAj2hE5P 1xfqvfLhuaJAjMEAAEKAB0WIQRO8+4RTnqPKsqn0bgbX0TJAJUVVgUCZgcOcAAKCRAbX0TJAJUV VgttD/4xWJelpoSyHqTyDbdFlLRkyQUAcHCnevhPtmBJNrAdG8olNyVCTHD8Zgmkwi2hTO/INbP 6aVYK9UMhvBAjLxEizLYZJOJj8h841CPzHCyQUFnPwDpgtHLfTSSqViD2UR9k3kNvqOEg2fdTt4 dF5bm4JgWn8Q6IvvqbHFFSjNWf84xwABYNuZeFhyMZKJx/Q9mQXKs57U92Q4H/Yz141LHavtbgb AQIEm7n3CcsVFuEt27D1wam5E8BIbR4kr3njpm+mLKR3yjD2o5lHwA0fCmzdqxonx71xF1hYp8D T4tuqf76OrXHGIISJUFvo4zmoadjRJ0iVb1Lxfm2X8u3hYnMA9uJKRPoIv3CD9SG3hyayc6507A pDsIvgQ6mMv5BGZvxQGPZAF5BN3G5gZrUTRnEnCzDZLghtgj34FCinwS3dkjb4IztalXTeE4+F7 pruaIcNfhkHMXvRBU0v0UuvgckIu66dpmmo1t/eDqet98NkVyQrNQ2wfmDc+BL5ngPYRP85SeV0 ey9Cs1RL1t8ysKAk1fHGyG7g6tSU9ZfDP3ZKpi5z5tioJ8fUgoj0G0nSwKblO7ZLcCVZt8zXRir eSzYb+Di00H1+UlltQl6SGuSsNlefLZ9KMy/JvFPPfOq5p7qnJrA9F/uVtZs+MQhG4XeLnQLg4K IZ9bCoWuAgLrZjw== X-Developer-Key: i=abel.vesa@linaro.org; a=openpgp; fpr=6AFF162D57F4223A8770EF5AF7BF214136F41FAE X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240329_115455_827954_BB70DE6B X-CRM114-Status: GOOD ( 25.60 ) 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 Starting with HW version 7, there are actually two separate buses (with two separate sets of wires). So add support for the second bus. The first platform that needs this support for the second bus is the Qualcomm X1 Elite, so add the compatible for it as well. Signed-off-by: Abel Vesa --- drivers/spmi/spmi-pmic-arb.c | 138 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 120 insertions(+), 18 deletions(-) diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c index 19ff8665f3d9..56f2b3190d82 100644 --- a/drivers/spmi/spmi-pmic-arb.c +++ b/drivers/spmi/spmi-pmic-arb.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -95,6 +96,8 @@ enum pmic_arb_channel { PMIC_ARB_CHANNEL_OBS, }; +#define PMIC_ARB_MAX_BUSES 2 + /* Maximum number of support PMIC peripherals */ #define PMIC_ARB_MAX_PERIPHS 512 #define PMIC_ARB_MAX_PERIPHS_V7 1024 @@ -148,6 +151,7 @@ struct spmi_pmic_arb; * @min_apid: minimum APID (used for bounding IRQ search) * @max_apid: maximum APID * @irq: PMIC ARB interrupt. + * @id: unique ID of the bus */ struct spmi_pmic_arb_bus { struct spmi_pmic_arb *pmic_arb; @@ -165,6 +169,7 @@ struct spmi_pmic_arb_bus { u16 min_apid; u16 max_apid; int irq; + u8 id; }; /** @@ -179,7 +184,8 @@ struct spmi_pmic_arb_bus { * @ee: the current Execution Environment * @ver_ops: version dependent operations. * @max_periphs: Number of elements in apid_data[] - * @bus: per arbiter bus instance + * @buses: per arbiter buses instances + * @buses_available: number of buses registered */ struct spmi_pmic_arb { void __iomem *rd_base; @@ -191,7 +197,8 @@ struct spmi_pmic_arb { u8 ee; const struct pmic_arb_ver_ops *ver_ops; int max_periphs; - struct spmi_pmic_arb_bus *bus; + struct spmi_pmic_arb_bus *buses[PMIC_ARB_MAX_BUSES]; + int buses_available; }; /** @@ -219,7 +226,7 @@ struct spmi_pmic_arb { struct pmic_arb_ver_ops { const char *ver_str; int (*get_core_resources)(struct platform_device *pdev, void __iomem *core); - int (*init_apid)(struct spmi_pmic_arb_bus *bus); + int (*init_apid)(struct spmi_pmic_arb_bus *bus, int index); int (*ppid_to_apid)(struct spmi_pmic_arb_bus *bus, u16 ppid); /* spmi commands (read_cmd, write_cmd, cmd) functionality */ int (*offset)(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr, @@ -308,8 +315,8 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl, } if (status & PMIC_ARB_STATUS_FAILURE) { - dev_err(&ctrl->dev, "%s: %#x %#x: transaction failed (%#x)\n", - __func__, sid, addr, status); + dev_err(&ctrl->dev, "%s: %#x %#x: transaction failed (%#x) reg: 0x%x\n", + __func__, sid, addr, status, offset); WARN_ON(1); return -EIO; } @@ -325,8 +332,8 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl, udelay(1); } - dev_err(&ctrl->dev, "%s: %#x %#x: timeout, status %#x\n", - __func__, sid, addr, status); + dev_err(&ctrl->dev, "%s: %#x %#x %#x: timeout, status %#x\n", + __func__, bus->id, sid, addr, status); return -ETIMEDOUT; } @@ -1005,11 +1012,17 @@ static int pmic_arb_get_core_resources_v1(struct platform_device *pdev, return 0; } -static int pmic_arb_init_apid_v1(struct spmi_pmic_arb_bus *bus) +static int pmic_arb_init_apid_v1(struct spmi_pmic_arb_bus *bus, int index) { struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; u32 *mapping_table; + if (index) { + dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n", + index); + return -EINVAL; + } + mapping_table = devm_kcalloc(&bus->spmic->dev, pmic_arb->max_periphs, sizeof(*mapping_table), GFP_KERNEL); if (!mapping_table) @@ -1252,11 +1265,17 @@ static int pmic_arb_offset_v2(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr, return 0x1000 * pmic_arb->ee + 0x8000 * apid; } -static int pmic_arb_init_apid_v5(struct spmi_pmic_arb_bus *bus) +static int pmic_arb_init_apid_v5(struct spmi_pmic_arb_bus *bus, int index) { struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; int ret; + if (index) { + dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n", + index); + return -EINVAL; + } + bus->base_apid = 0; bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) & PMIC_ARB_FEATURES_PERIPH_MASK; @@ -1328,6 +1347,50 @@ static int pmic_arb_get_core_resources_v7(struct platform_device *pdev, return pmic_arb_get_obsrvr_chnls_v2(pdev); } +/* + * Only v7 supports 2 buses. Each bus will get a different apid count, read + * from different registers. + */ +static int pmic_arb_init_apid_v7(struct spmi_pmic_arb_bus *bus, int index) +{ + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; + int ret; + + if (index == 0) { + bus->base_apid = 0; + bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) & + PMIC_ARB_FEATURES_PERIPH_MASK; + } else if (index == 1) { + bus->base_apid = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) & + PMIC_ARB_FEATURES_PERIPH_MASK; + bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES1) & + PMIC_ARB_FEATURES_PERIPH_MASK; + } else { + dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n", + bus->id); + return -EINVAL; + } + + if (bus->base_apid + bus->apid_count > pmic_arb->max_periphs) { + dev_err(&bus->spmic->dev, "Unsupported APID count %d detected\n", + bus->base_apid + bus->apid_count); + return -EINVAL; + } + + ret = pmic_arb_init_apid_min_max(bus); + if (ret) + return ret; + + ret = pmic_arb_read_apid_map_v5(bus); + if (ret) { + dev_err(&bus->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n", + ret); + return ret; + } + + return 0; +} + /* * v7 offset per ee and per apid for observer channels and per apid for * read/write channels. @@ -1580,7 +1643,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v5 = { static const struct pmic_arb_ver_ops pmic_arb_v7 = { .ver_str = "v7", .get_core_resources = pmic_arb_get_core_resources_v7, - .init_apid = pmic_arb_init_apid_v5, + .init_apid = pmic_arb_init_apid_v7, .ppid_to_apid = pmic_arb_ppid_to_apid_v5, .non_data_cmd = pmic_arb_non_data_cmd_v2, .offset = pmic_arb_offset_v7, @@ -1604,6 +1667,7 @@ static int spmi_pmic_arb_bus_init(struct platform_device *pdev, struct device_node *node, struct spmi_pmic_arb *pmic_arb) { + int bus_index = pmic_arb->buses_available; struct spmi_pmic_arb_bus *bus; struct device *dev = &pdev->dev; struct spmi_controller *ctrl; @@ -1622,7 +1686,7 @@ static int spmi_pmic_arb_bus_init(struct platform_device *pdev, bus = spmi_controller_get_drvdata(ctrl); - pmic_arb->bus = bus; + pmic_arb->buses[bus_index] = bus; bus->ppid_to_apid = devm_kcalloc(dev, PMIC_ARB_MAX_PPID, sizeof(*bus->ppid_to_apid), @@ -1665,12 +1729,13 @@ static int spmi_pmic_arb_bus_init(struct platform_device *pdev, bus->cnfg = cnfg; bus->irq = irq; bus->spmic = ctrl; + bus->id = bus_index; - ret = pmic_arb->ver_ops->init_apid(bus); + ret = pmic_arb->ver_ops->init_apid(bus, bus_index); if (ret) return ret; - dev_dbg(&pdev->dev, "adding irq domain\n"); + dev_dbg(&pdev->dev, "adding irq domain for bus %d\n", bus_index); bus->domain = irq_domain_add_tree(dev->of_node, &pmic_arb_irq_domain_ops, bus); @@ -1683,14 +1748,53 @@ static int spmi_pmic_arb_bus_init(struct platform_device *pdev, pmic_arb_chained_irq, bus); ctrl->dev.of_node = node; + dev_set_name(&ctrl->dev, "spmi-%d", bus_index); ret = devm_spmi_controller_add(dev, ctrl); if (ret) return ret; + pmic_arb->buses_available++; + return 0; } +static int spmi_pmic_arb_register_buses(struct spmi_pmic_arb *pmic_arb, + struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node; + struct device_node *child; + int ret; + + /* legacy mode doesn't provide child node for the bus */ + if (of_device_is_compatible(node, "qcom,spmi-pmic-arb")) + return spmi_pmic_arb_bus_init(pdev, node, pmic_arb); + + for_each_available_child_of_node(node, child) { + if (of_node_name_eq(child, "spmi")) { + ret = spmi_pmic_arb_bus_init(pdev, child, pmic_arb); + if (ret) + return ret; + } + } + + return ret; +} + +static void spmi_pmic_arb_deregister_buses(struct spmi_pmic_arb *pmic_arb) +{ + int i; + + for (i = 0; i < PMIC_ARB_MAX_BUSES; i++) { + struct spmi_pmic_arb_bus *bus = pmic_arb->buses[i]; + + irq_set_chained_handler_and_data(bus->irq, + NULL, NULL); + irq_domain_remove(bus->domain); + } +} + static int spmi_pmic_arb_probe(struct platform_device *pdev) { struct spmi_pmic_arb *pmic_arb; @@ -1761,21 +1865,19 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) pmic_arb->ee = ee; - return spmi_pmic_arb_bus_init(pdev, dev->of_node, pmic_arb); + return spmi_pmic_arb_register_buses(pmic_arb, pdev); } static void spmi_pmic_arb_remove(struct platform_device *pdev) { struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev); - struct spmi_pmic_arb_bus *bus = pmic_arb->bus; - irq_set_chained_handler_and_data(bus->irq, - NULL, NULL); - irq_domain_remove(bus->domain); + spmi_pmic_arb_deregister_buses(pmic_arb); } static const struct of_device_id spmi_pmic_arb_match_table[] = { { .compatible = "qcom,spmi-pmic-arb", }, + { .compatible = "qcom,x1e80100-spmi-pmic-arb", }, {}, }; MODULE_DEVICE_TABLE(of, spmi_pmic_arb_match_table);