From patchwork Tue May 7 18:45:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frank Li X-Patchwork-Id: 13657600 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 8D01FC25B4F for ; Tue, 7 May 2024 18:47:45 +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:MIME-Version:Cc:To:In-Reply-To: References:Message-Id: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=+z/q+YQomwgG2ewXSehVLVV1a34gfxEPlOxhsvSgcns=; b=hKz7ozN3BQZHStpnTjE566qxYl +DUmPL3VVrzur6vpdGYtK16tt8/DuvXoDCL7rlUEi6hULfa7MDe8T9T7caHzuedggjqowM4h/JfYL lyHKbmxGkmGhtiPmBLUNbYIN1IYpv5FOepbFg/cU2E0+qtNpcljAF9pQyyVWJC2LxpgyC1Ays/dxY PqZBLnu3I+Yev3EHJCwHQOfUSMhw3ebbK8wLX0nE8zxvnyenLC0QTvZJ5zKZYBuBRwb80Zmz27dY7 tFyIlulnYQoITL+bf9uwN+5CZ+5yV7ix/BFUvp3Ri6JMUY9oicD5qzkQ5Ipd5UVRJ5peQ/M4+wiPg OUX5ti8w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1s4Pqa-0000000CQ4h-19g6; Tue, 07 May 2024 18:47:28 +0000 Received: from mail-he1eur01on0626.outbound.protection.outlook.com ([2a01:111:f400:fe1e::626] helo=EUR01-HE1-obe.outbound.protection.outlook.com) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1s4PqG-0000000CPkC-1FeL for linux-arm-kernel@lists.infradead.org; Tue, 07 May 2024 18:47:17 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=kJ8U1BefEGpUcX5CyF4c9aSZsIIyBv2UQRH3otAPHwW9I2EnhnV2NxjLZcuu17Mfm6x6nwBe+YON2Tx+yvbe6hvejMneJgRLqtS09UMrficfrYv8fCmcbPSduzt+jpCyTRWA1ucAnuMdrt0bYMzjIWm+XizeoXj99avesqkLSYi9OfX+B/ju/YdXuxoNDOmXWde/q75sLTzP6mw8JmDpVCMDoUsH3R31PUrn7A4JjLe0J8RxGV75pjsbDXDLcHxRp1A6hnjbbAo7FHnwnXR8aCk45FkGmOjOLNqOllAFKQ3xia6IjVzdIHpd0RZG/ubqarHT+CTneWgdzvvU/urAIw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=zY5T/oWna/5HjL2EqSYd7JGvKX/go1wp1bRk/SJgUGg=; b=JtfZTlk2UYyouGrhs3HIVd2hEosJcABnsIMocSgEa8I1oRWL4qbMUKEWpSmyvk0xnYTRH0MaQpzaRd+xZHb1G7FgLYCtxTJ0MCNQg7JDggN22idVOyU4fenBV7dUQ58Ffn7b+FNRTJooHm5/r7Td2xvaeRcpSoQ6Zt1rFqf+20goEL9Vw3U7E1mxbDhvjzCFbYcZiefvkG9sSI/YQwLb+T+yQzuCTRPmLXtIhGD8J+TDdpU1hwY+s7YdEQEoCtM0JLTb4OvSWyQOYq8F41ICxnO4DJ/IMHKN7nYNbCOdiPnfCg9Ck/msLcYmSeKCkIzmwou7/03uBKCRYpHPfkkgSg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nxp.com; dmarc=pass action=none header.from=nxp.com; dkim=pass header.d=nxp.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=zY5T/oWna/5HjL2EqSYd7JGvKX/go1wp1bRk/SJgUGg=; b=HjRlmyDi/IybXyF8p+z/Mq939YA0IbWS0jWSxGam931AO83Hrub2YgKl+NL2LSzaGYUdQjUptjDS1X25f5IP8OjGTC5tGx2OZxGHF0nfjSvEp0jb4zNclUGA5e6dphMW/M8Mbm6H7Dn2cXEVK3orgtWmN5LWJnN7xA9L9+4fT6c= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nxp.com; Received: from PAXPR04MB9642.eurprd04.prod.outlook.com (2603:10a6:102:240::14) by DU0PR04MB9636.eurprd04.prod.outlook.com (2603:10a6:10:320::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7544.41; Tue, 7 May 2024 18:47:05 +0000 Received: from PAXPR04MB9642.eurprd04.prod.outlook.com ([fe80::1e67:dfc9:d0c1:fe58]) by PAXPR04MB9642.eurprd04.prod.outlook.com ([fe80::1e67:dfc9:d0c1:fe58%7]) with mapi id 15.20.7544.041; Tue, 7 May 2024 18:47:05 +0000 From: Frank Li Date: Tue, 07 May 2024 14:45:46 -0400 Subject: [PATCH v4 08/12] PCI: imx6: Config look up table(LUT) to support MSI ITS and IOMMU for i.MX95 Message-Id: <20240507-pci2_upstream-v4-8-e8c80d874057@nxp.com> References: <20240507-pci2_upstream-v4-0-e8c80d874057@nxp.com> In-Reply-To: <20240507-pci2_upstream-v4-0-e8c80d874057@nxp.com> To: Richard Zhu , Lucas Stach , Lorenzo Pieralisi , =?utf-8?q?Krzysztof_Wilczy?= =?utf-8?q?=C5=84ski?= , Rob Herring , Bjorn Helgaas , Shawn Guo , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam , NXP Linux Team , Philipp Zabel , Liam Girdwood , Mark Brown , Manivannan Sadhasivam , Krzysztof Kozlowski , Conor Dooley Cc: linux-pci@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org, devicetree@vger.kernel.org, Frank Li X-Mailer: b4 0.13-dev-e586c X-Developer-Signature: v=1; a=ed25519-sha256; t=1715107574; l=7874; i=Frank.Li@nxp.com; s=20240130; h=from:subject:message-id; bh=yIrgxNwnmNXUu+Xre51WI5K2xwHWcW1tzJ/Z0ZY1NwA=; b=gEDVVe7ncxBPhBycpIKpSQb9a0bq1Vgfh5CoJiS3J91K6frQlbIQ6Cty4KOj4STrOJOPjwDR0 oENOuE/5rDmBn2LHdI1G6NoQ7W5Y5RN+7qWj0lWHsAwzsgc7Ioy8l96 X-Developer-Key: i=Frank.Li@nxp.com; a=ed25519; pk=I0L1sDUfPxpAkRvPKy7MdauTuSENRq+DnA+G4qcS94Q= X-ClientProxiedBy: BY5PR17CA0026.namprd17.prod.outlook.com (2603:10b6:a03:1b8::39) To PAXPR04MB9642.eurprd04.prod.outlook.com (2603:10a6:102:240::14) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PAXPR04MB9642:EE_|DU0PR04MB9636:EE_ X-MS-Office365-Filtering-Correlation-Id: 499d5d02-1ad8-4dbc-fc78-08dc6ec6172b X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230031|1800799015|376005|7416005|52116005|366007|921011|38350700005; X-Microsoft-Antispam-Message-Info: =?utf-8?q?3t9b2THP0MjfWtUunAaIawyfXkpqsGL?= =?utf-8?q?TwcK8W9fL9YbPaBZXyrq1TEvv1dg4YQVjHeofmMx2DEdtBceuAVGC0KXUlvvxpZCM?= =?utf-8?q?0u1eqpjRmZAM4LdeYRGz9sf51BQInldvcuZQp6rk+s/+K04X5JS0qmadU/wuOQ8Bm?= =?utf-8?q?z8ZAryOfK4t/YoXsaMqGOiY5+V8HmjOzs3GeW4BedJ38BHnbINRMLghZo59NL2WNq?= =?utf-8?q?agjKdIYgnQVCTeqaY0KReCvN//EIm4sjgS1uRsL/S2geuPvtvYbeIxPI8P0h/NB0g?= =?utf-8?q?NPuYP0I5k/U4QAxW0nDvbZ7TzHhF5p0kCeY3vzZOtQUL1kviDC6Lmszf9cVL3Y7Fr?= =?utf-8?q?8p9A8S7CQtmbbkk2CRd0az430pNyX2EdzCblpef3qHGAs3qfNFGQ8MSWKa7xzsWEN?= =?utf-8?q?gTM00uCOwun6Pbzw3AGDXP9pu/nE/J5spct2cKJodKi1CBy0ozV85pD5V3BwSM2z7?= =?utf-8?q?xU7aINTlNoHx8sz+Ay4myfRj+7ZJjetsmiF0UMmp5Aj2Se5z8O+73j1mTZoR7x1FL?= =?utf-8?q?QrSlnYnXL50HAe0LArXEhHJZHyhjEfaW2Ej9HFDzFE8d+LSzCjaj03y90ygcXumu8?= =?utf-8?q?aSMd/5hhG1zIuevL5qvkK2PY8sRtW83ZNEyG1aKo2odEtLCvTXr+aPUQCFwua3M3m?= =?utf-8?q?YMFVI+iI3jHO/Xs6Ok6/wq0ey2fXQLiqFf4XnQcM2RouHIaDGCm5rcN994uPMwj6n?= =?utf-8?q?WpJR2H7VI1b5ryV6xWBmnjrDpn2xUHgdqfAyxWq1A8NOZGnr5XAilACKCqV719Xt/?= =?utf-8?q?F/fKnPPKBQiJ9EDiWBxuq/H93Qv6CIm35TPQ2a7FCDmSAqRJ25UkloJz15KtdPzzT?= =?utf-8?q?+HWB16AEF4cASFVkCd2GDwXlf9uTzVETgLsIvEPtlpST2lks4LBQpwXwKICIQ1DUm?= =?utf-8?q?aWP5209K4XwIjy8Du/eTyDbO6hS1bu5rHXYl0hCxrSmriAqS9673xcmcISo404CGt?= =?utf-8?q?CDRUSxoCCk8WX2TH0uQqZ362eecmIG70nJBeTaTtYjCXbQQ+NPd+/3ISbuJ2LiRkF?= =?utf-8?q?xg/3InkJ7Ch4PnQ4g/oOCiAcmOuXIbcteiSNlnPs7zFqJEBp3OIprBjdhaob0Sr/t?= =?utf-8?q?SHbwOPuzQPPplv+pONxVLDSkj5M/+FW5JgmVy4wOAlfmcA2nDbma4UJEHQg3pyAZ9?= =?utf-8?q?ONwMeobddnWBuh6PQHZTbpG/4mOxWIMvnEOdva5fNvTF5OTBwJWHpjam1XjrJdRN3?= =?utf-8?q?0kifMEiHyJJdKt4I+PW5JHM70p+OrIc3Jd5jWnM9yrDhWIkXAyJWLeUVo91+Q3+tI?= =?utf-8?q?hWEdZq/XPYRM7IS+l4KihOsZ7u1mP9ve52FJGyPO/UkSoAG/Ep5t1R+s=3D?= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PAXPR04MB9642.eurprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230031)(1800799015)(376005)(7416005)(52116005)(366007)(921011)(38350700005);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?ES/HVHxjJ/m8CIQY3z2XsPMuh7Fd?= =?utf-8?q?wOjPM8VeW/kkugkOlfScwDPlUVszKbdE7K9YWDcGXmeRBxZU4NEjjURVaqjYx3Mb9?= =?utf-8?q?+TNtWwFhfn9BtGCZvdtnTgnwcF6AWoNqtIehcq5J16m9JXw28tgKlXD9PrYYmaNwN?= =?utf-8?q?QW9KpBmIuAzkatVooBUuOzzsk+0BESSe4NF2dZxZOdwa78zQSkTPvdigBJyFV4QI4?= =?utf-8?q?kH+qMEdMDxNrdmvswWHQP6tfCjJ7aq0EULhDuDJNStsiBYDTH1Tde6IxM5oehCZWv?= =?utf-8?q?xyZqNUUH/ohK4m3iANmG0kg6sWlBr3yMmHX3k0dwORxhQa2kt8qa/tf6pY0GK2v0A?= =?utf-8?q?LeTwZBUCF2itpu9U418c9/pCSs63PBhos1wpHH98moZLOJBvSuaFmhe351CNAva4y?= =?utf-8?q?VtuCOyuV7+8iKD0eSocovvyKMHiaPL4L/K7nrwBOuEYMYJttBU+evuboIkMxZc7Mx?= =?utf-8?q?1Ef8DSxFzG4ptvC5jZExYzgCwKqUx3x8IPaoXrKJQvpwYV4Q5n8jqkdiuTA9zjIGu?= =?utf-8?q?nyTmF6l4CRLjhzWrC/exJljV4SYu1aGYKILFbsGZTgQY050ZD4ohu5QBQnrfzysGL?= =?utf-8?q?M749zF1ouguZb1Qoj3S91k/d/B3Xv8TIZrYRjss31N/TmOzgkYYSoX4oZ4MsIFyH4?= =?utf-8?q?Ck/JQgiJTVt6su1SnZEUuifYaMDVbQjDDRQrg75XItkh8XriUULFvBO+54LhwAi9m?= =?utf-8?q?X4GMAmQsyFOuj5t9OC4Ido8fn8Hr8b1A2SXhmFr3pFqgExpm+klCqdlp5ZG7u6ZSd?= =?utf-8?q?t495tlzIsyPjvSiceJ4iACyHcrVQUkWQ6CxcD+BaCdYJX6EF1XlTJQCps6vmaulsk?= =?utf-8?q?gTAS4516ww0qnPqd+NnJQRCCV2GJI2cC8e1ahdMBSFPYE0U2GWd4xuXxO5V5CdHI2?= =?utf-8?q?Il/l1R7ZfMkC1d7GLPKQsQbgqYP8sYbO/qFvDu569MzHm9Hs+2gzmL/rCFjW+dHgA?= =?utf-8?q?XoawLXY76JN1WSIJszTh40c+UcS0P4F9U/zXgswFRmnstAfLcgEyC+hqwBh0yCc9h?= =?utf-8?q?lvrYGxwDhimztkJQ95XAtZpOBGSoSB4qLbPfeJ7J/OzmJd3MNKQ7+yQsWQakTkIOM?= =?utf-8?q?R35XzuwPy5yvWh2UfU/k/ItZAJ6vffqb+5zz21oQ56PFWf2BijOLqoJksdOXAYYVW?= =?utf-8?q?5OBQChVDdicGRMfabROCLoBfGkzKmpnKCBrSjMOf+fwdYpragT5IlFzGT+vT/R+PM?= =?utf-8?q?sWRsUoEuavVeT9Xww1FCzrl0ffMSsTV/M8AGDeljeyxKRiq+haYWZCxyGq35xsMs7?= =?utf-8?q?5m2gHr6vzR7D0e5YpKr5FSE+W+IJJxtApfaDdpYkuGo7MNRoQB4dX3+YYcU3MBVcl?= =?utf-8?q?E+3uKShSYH1mhLY5MPDW1siB1vvVYDT8dY8ER2nPHuPsJgmeiMJhucb43YwoZWezy?= =?utf-8?q?QSJB2sZyTzLQ/yQPcmsSVV5rEVpwklT2DnPhi93s7ZsqVSSPwiWiS3d6nJYdLcoh/?= =?utf-8?q?Ljx4PJgjddv6OeE5Bcbc0uGC+2mO6Ht1nH8aEffEnmCzJx9sr0G4sA+AABH/QsnRE?= =?utf-8?q?NB3pbSTKaABo?= X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 499d5d02-1ad8-4dbc-fc78-08dc6ec6172b X-MS-Exchange-CrossTenant-AuthSource: PAXPR04MB9642.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 May 2024 18:47:05.2505 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: zBKcmKWX2uVYzHemRLGFKWz7C15GajKSPTm0nnKbdIGGtlhRIuq82uGDvJ6i//MXOp1Sq9wLOdE1jM9JW7vyHg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0PR04MB9636 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240507_114709_142608_DB072AEB X-CRM114-Status: GOOD ( 22.87 ) 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 For the i.MX95, configuration of a LUT is necessary to convert Bus Device Function (BDF) to stream IDs, which are utilized by both IOMMU and ITS. This involves examining the msi-map and smmu-map to ensure consistent mapping of PCI BDF to the same stream IDs. Subsequently, LUT-related registers are configured. In the absence of an msi-map, the built-in MSI controller is utilized as a fallback. Additionally, register a PCI bus notifier to trigger imx_pcie_add_device() upon the appearance of a new PCI device and when the bus is an iMX6 PCI controller. This function configures the correct LUT based on Device Tree Settings (DTS). Signed-off-by: Frank Li --- drivers/pci/controller/dwc/pci-imx6.c | 175 +++++++++++++++++++++++++++++++++- 1 file changed, 174 insertions(+), 1 deletion(-) diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index b33d8790a93af..66573ef7a002b 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -55,6 +55,22 @@ #define IMX95_PE0_GEN_CTRL_3 0x1058 #define IMX95_PCIE_LTSSM_EN BIT(0) +#define IMX95_PE0_LUT_ACSCTRL 0x1008 +#define IMX95_PEO_LUT_RWA BIT(16) +#define IMX95_PE0_LUT_ENLOC GENMASK(4, 0) + +#define IMX95_PE0_LUT_DATA1 0x100c +#define IMX95_PE0_LUT_VLD BIT(31) +#define IMX95_PE0_LUT_DAC_ID GENMASK(10, 8) +#define IMX95_PE0_LUT_STREAM_ID GENMASK(5, 0) + +#define IMX95_PE0_LUT_DATA2 0x1010 +#define IMX95_PE0_LUT_REQID GENMASK(31, 16) +#define IMX95_PE0_LUT_MASK GENMASK(15, 0) + +#define IMX95_SID_MASK GENMASK(5, 0) +#define IMX95_MAX_LUT 32 + #define to_imx_pcie(x) dev_get_drvdata((x)->dev) enum imx_pcie_variants { @@ -80,6 +96,7 @@ enum imx_pcie_variants { #define IMX_PCIE_FLAG_HAS_PHY_RESET BIT(5) #define IMX_PCIE_FLAG_HAS_SERDES BIT(6) #define IMX_PCIE_FLAG_SUPPORT_64BIT BIT(7) +#define IMX_PCIE_FLAG_MONITOR_DEV BIT(8) #define imx_check_flag(pci, val) (pci->drvdata->flags & val) @@ -134,6 +151,8 @@ struct imx_pcie { struct device *pd_pcie_phy; struct phy *phy; const struct imx_pcie_drvdata *drvdata; + + struct mutex lock; }; /* Parameters for the waiting for PCIe PHY PLL to lock on i.MX7 */ @@ -217,6 +236,66 @@ static int imx95_pcie_init_phy(struct imx_pcie *imx_pcie) return 0; } +static int imx_pcie_config_lut(struct imx_pcie *imx_pcie, u16 reqid, u8 sid) +{ + struct dw_pcie *pci = imx_pcie->pci; + struct device *dev = pci->dev; + u32 data1, data2; + int i; + + if (sid >= 64) { + dev_err(dev, "Invalid SID for index %d\n", sid); + return -EINVAL; + } + + guard(mutex)(&imx_pcie->lock); + + for (i = 0; i < IMX95_MAX_LUT; i++) { + regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL, IMX95_PEO_LUT_RWA | i); + + regmap_read(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA1, &data1); + if (data1 & IMX95_PE0_LUT_VLD) + continue; + + data1 = FIELD_PREP(IMX95_PE0_LUT_DAC_ID, 0); + data1 |= FIELD_PREP(IMX95_PE0_LUT_STREAM_ID, sid); + data1 |= IMX95_PE0_LUT_VLD; + + regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA1, data1); + + data2 = 0xffff; + data2 |= FIELD_PREP(IMX95_PE0_LUT_REQID, reqid); + + regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2, data2); + + regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL, i); + + return 0; + } + + dev_err(dev, "All lut already used\n"); + return -EINVAL; +} + +static void imx_pcie_remove_lut(struct imx_pcie *imx_pcie, u16 reqid) +{ + u32 data2 = 0; + int i; + + guard(mutex)(&imx_pcie->lock); + + for (i = 0; i < IMX95_MAX_LUT; i++) { + regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL, IMX95_PEO_LUT_RWA | i); + + regmap_read(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2, &data2); + if (FIELD_GET(IMX95_PE0_LUT_REQID, data2) == reqid) { + regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA1, 0); + regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2, 0); + regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_ACSCTRL, i); + } + } +} + static void imx_pcie_configure_type(struct imx_pcie *imx_pcie) { const struct imx_pcie_drvdata *drvdata = imx_pcie->drvdata; @@ -1227,6 +1306,85 @@ static int imx_pcie_resume_noirq(struct device *dev) return 0; } +static bool imx_pcie_match_device(struct pci_bus *bus); + +static int imx_pcie_add_device(struct imx_pcie *imx_pcie, struct pci_dev *pdev) +{ + u32 sid_i = 0, sid_m = 0, rid = pci_dev_id(pdev); + struct device *dev = imx_pcie->pci->dev; + int err; + + err = of_map_id(dev->of_node, rid, "iommu-map", "iommu-map-mask", NULL, &sid_i); + if (err) + return err; + + err = of_map_id(dev->of_node, rid, "msi-map", "msi-map-mask", NULL, &sid_m); + if (err) + return err; + + if (sid_i != rid && sid_m != rid) + if ((sid_i & IMX95_SID_MASK) != (sid_m & IMX95_SID_MASK)) { + dev_err(dev, "its and iommu stream id miss match, please check dts file\n"); + return -EINVAL; + } + + /* if iommu-map is not existed then use msi-map's stream id*/ + if (sid_i == rid) + sid_i = sid_m; + + sid_i &= IMX95_SID_MASK; + + if (sid_i != rid) + return imx_pcie_config_lut(imx_pcie, rid, sid_i); + + /* Use dwc built-in MSI controller */ + return 0; +} + +static void imx_pcie_del_device(struct imx_pcie *imx_pcie, struct pci_dev *pdev) +{ + imx_pcie_remove_lut(imx_pcie, pci_dev_id(pdev)); +} + + +static int imx_pcie_bus_notifier(struct notifier_block *nb, unsigned long action, void *data) +{ + struct pci_host_bridge *host; + struct imx_pcie *imx_pcie; + struct pci_dev *pdev; + int err; + + pdev = to_pci_dev(data); + host = pci_find_host_bridge(pdev->bus); + + if (!imx_pcie_match_device(host->bus)) + return NOTIFY_OK; + + imx_pcie = to_imx_pcie(to_dw_pcie_from_pp(host->sysdata)); + + if (!imx_check_flag(imx_pcie, IMX_PCIE_FLAG_MONITOR_DEV)) + return NOTIFY_OK; + + switch (action) { + case BUS_NOTIFY_ADD_DEVICE: + err = imx_pcie_add_device(imx_pcie, pdev); + if (err) + return notifier_from_errno(err); + break; + case BUS_NOTIFY_DEL_DEVICE: + imx_pcie_del_device(imx_pcie, pdev); + break; + default: + return NOTIFY_DONE; + } + + return NOTIFY_OK; +} + +static struct notifier_block imx_pcie_nb = { + .notifier_call = imx_pcie_bus_notifier, +}; + static const struct dev_pm_ops imx_pcie_pm_ops = { NOIRQ_SYSTEM_SLEEP_PM_OPS(imx_pcie_suspend_noirq, imx_pcie_resume_noirq) @@ -1259,6 +1417,8 @@ static int imx_pcie_probe(struct platform_device *pdev) imx_pcie->pci = pci; imx_pcie->drvdata = of_device_get_match_data(dev); + mutex_init(&imx_pcie->lock); + /* Find the PHY if one is defined, only imx7d uses it */ np = of_parse_phandle(node, "fsl,imx7d-pcie-phy", 0); if (np) { @@ -1557,7 +1717,8 @@ static const struct imx_pcie_drvdata drvdata[] = { }, [IMX95] = { .variant = IMX95, - .flags = IMX_PCIE_FLAG_HAS_SERDES, + .flags = IMX_PCIE_FLAG_HAS_SERDES | + IMX_PCIE_FLAG_MONITOR_DEV, .clk_names = imx8mq_clks, .clks_cnt = ARRAY_SIZE(imx8mq_clks), .ltssm_off = IMX95_PE0_GEN_CTRL_3, @@ -1693,6 +1854,8 @@ DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_SYNOPSYS, 0xabcd, static int __init imx_pcie_init(void) { + int ret; + #ifdef CONFIG_ARM struct device_node *np; @@ -1711,7 +1874,17 @@ static int __init imx_pcie_init(void) hook_fault_code(8, imx6q_pcie_abort_handler, SIGBUS, 0, "external abort on non-linefetch"); #endif + ret = bus_register_notifier(&pci_bus_type, &imx_pcie_nb); + if (ret) + return ret; return platform_driver_register(&imx_pcie_driver); } + +static void __exit imx_pcie_exit(void) +{ + bus_unregister_notifier(&pci_bus_type, &imx_pcie_nb); +} + device_initcall(imx_pcie_init); +__exitcall(imx_pcie_exit);