{"id":2232036,"url":"http://patchwork.ozlabs.org/api/1.1/patches/2232036/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-pci/patch/20260502101319.2364052-6-inochiama@gmail.com/","project":{"id":28,"url":"http://patchwork.ozlabs.org/api/1.1/projects/28/?format=json","name":"Linux PCI development","link_name":"linux-pci","list_id":"linux-pci.vger.kernel.org","list_email":"linux-pci@vger.kernel.org","web_url":null,"scm_url":null,"webscm_url":null},"msgid":"<20260502101319.2364052-6-inochiama@gmail.com>","date":"2026-05-02T10:13:18","name":"[5/5] PCI: spacemit-k1: Add Spacemit K3 PCIe host controller support","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"a0b8c8b4c1b9890c893c1a222e172005e6c26563","submitter":{"id":89342,"url":"http://patchwork.ozlabs.org/api/1.1/people/89342/?format=json","name":"Inochi Amaoto","email":"inochiama@gmail.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/linux-pci/patch/20260502101319.2364052-6-inochiama@gmail.com/mbox/","series":[{"id":502524,"url":"http://patchwork.ozlabs.org/api/1.1/series/502524/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-pci/list/?series=502524","date":"2026-05-02T10:13:13","name":"riscv: spacemit: Add PCIe RC controller support for K3","version":1,"mbox":"http://patchwork.ozlabs.org/series/502524/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2232036/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2232036/checks/","tags":{},"headers":{"Return-Path":"\n <linux-pci+bounces-53623-incoming=patchwork.ozlabs.org@vger.kernel.org>","X-Original-To":["incoming@patchwork.ozlabs.org","linux-pci@vger.kernel.org"],"Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=TwOL8+DZ;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=104.64.211.4; helo=sin.lore.kernel.org;\n envelope-from=linux-pci+bounces-53623-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)","smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com\n header.b=\"TwOL8+DZ\"","smtp.subspace.kernel.org;\n arc=none smtp.client-ip=209.85.215.170","smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=gmail.com","smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=gmail.com"],"Received":["from sin.lore.kernel.org (sin.lore.kernel.org [104.64.211.4])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g73fv2dMvz1yJw\n\tfor <incoming@patchwork.ozlabs.org>; Sat, 02 May 2026 20:14:31 +1000 (AEST)","from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sin.lore.kernel.org (Postfix) with ESMTP id 69FC63004D9E\n\tfor <incoming@patchwork.ozlabs.org>; Sat,  2 May 2026 10:14:17 +0000 (UTC)","from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 335B8332918;\n\tSat,  2 May 2026 10:14:00 +0000 (UTC)","from mail-pg1-f170.google.com (mail-pg1-f170.google.com\n [209.85.215.170])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id 6E40D330B11\n\tfor <linux-pci@vger.kernel.org>; Sat,  2 May 2026 10:13:55 +0000 (UTC)","by mail-pg1-f170.google.com with SMTP id\n 41be03b00d2f7-c70fb6aa323so897995a12.3\n        for <linux-pci@vger.kernel.org>; Sat, 02 May 2026 03:13:55 -0700 (PDT)","from localhost ([2001:19f0:8001:1b2d:5400:5ff:fefa:a95d])\n        by smtp.gmail.com with ESMTPSA id\n d2e1a72fcca58-83515ad0049sm5842519b3a.33.2026.05.02.03.13.53\n        (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n        Sat, 02 May 2026 03:13:53 -0700 (PDT)"],"ARC-Seal":"i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1777716839; cv=none;\n b=sw7GhaPcumLL1WV29TFFk3SpTHE2uMDUUdraJehAsdc50wZE2x6yOFPpkfYjHCZ/vf/T15kxBVGES1uVQ3CVBqB7FH38dccSrSrA19k+8QIactwmZgSmqcc9aO2D2Afl8B01yIXMtdklW0RhHY1YsehF1iReDouK7d4qT6K1vPA=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1777716839; c=relaxed/simple;\n\tbh=IIn0BqYi016AJzSVBnUNDk9SvN+vM/Po4/FcjBlMWf8=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version;\n b=kr3RgiN4KzJkqzLAj7pGC5zhJVPJPJq75sadw090Lq3jhV1/7/xOawMgrjOMztCDNzXIYAOG2fKSLWotzZVL2mQfeLqLY1NUPGdeVtQ7XbgnDD2Q7SFmwmZIZ3Ro7GGqTlUDlwfDrmZBTw1kWLj2FCTs41rwW7NyMIffw6aaSNY=","ARC-Authentication-Results":"i=1; smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=gmail.com;\n spf=pass smtp.mailfrom=gmail.com;\n dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com\n header.b=TwOL8+DZ; arc=none smtp.client-ip=209.85.215.170","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n        d=gmail.com; s=20251104; t=1777716834; x=1778321634;\n darn=vger.kernel.org;\n        h=content-transfer-encoding:mime-version:references:in-reply-to\n         :message-id:date:subject:cc:to:from:from:to:cc:subject:date\n         :message-id:reply-to;\n        bh=gr6D/Xzdn4v9rbHKlmP/r4GXGKbaNof+CbkZ0R6qh7Y=;\n        b=TwOL8+DZNv1xF6v7995T1SodJ99yLez5hgKGe/hgR4lAMv74R296qrdDDynr/fG+G9\n         fdD/uHwDin3G5QXbmOgI1fhl4eI1GQJNFy+G65XmtHfmxyodSktZlD/cCgry02N+IM/d\n         xzO8Ka8kGM42CoHb00CxStfiSQTm4Vbj6Wbz8HxqqAdGJUIzl95nmgomOxmGBtF/Az8n\n         I+MvC8fpe5zweYkHFOQpNLHnCwKTN+PwBIPIYBxqRhA0HH4UDGMXmXXf+tb5PyrhAAj9\n         IC5hscrRA7INgV8EBK80AMSo5HTJ1wH8z6LFijSAkQBapU8gPXQK4UfzyFh8o7+3IOKK\n         awZQ==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n        d=1e100.net; s=20251104; t=1777716834; x=1778321634;\n        h=content-transfer-encoding:mime-version:references:in-reply-to\n         :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from\n         :to:cc:subject:date:message-id:reply-to;\n        bh=gr6D/Xzdn4v9rbHKlmP/r4GXGKbaNof+CbkZ0R6qh7Y=;\n        b=OXED4K3ZMAhbNjwL8IPiDfhCLOvIkTQ0pgvVqNlAUth1iM9ThQ+eq/jAWllxJVUBub\n         vVi8Gt9yZ2O8eh6+H0lJGyd8qzlPs6FMiDhrXzH0O6d4HeIY/kPqduwV7TPZVUz3hfFg\n         +yo7+jg8FZtJLlC4XFKMOzTeTCVjGT3GDkc1wA4WBxoARG/zWiF/enkTP8oYKS0JWgme\n         e2MQZT5PzhYN2xHu5fuJ8xtoNrciPLmH7k4AhJqY3vOe5O5oxjOjq1NIeUa5ed9j37mM\n         l8rfcUe9VgyLbV4C7eKTXMhjWOAQPMAK8aEoYaybDFdfU7C842S8L3zLiUPqihsw+160\n         kQBQ==","X-Gm-Message-State":"AOJu0YwRlpFSThEtQ0H9rPPOPiKIm+qEx9iL2W2i9y823/9gqDrIK+6K\n\th5ZVGkX0n2jUyJQBo8c6kHaUDQIIzdouCzkcV+P0zigrO1nmILgrAOBH","X-Gm-Gg":"AeBDiesOSfna4og/RSXRVUqmk/9/RbWe9jmbqBgqbNDn5n0wp8LdIcoXdZaiExhjj6w\n\tZQAN6crBcp4UuJgXqY8Bi8gl6bUmvJET/4AcXkSPS9H/J6albcbJyEriER3fBgf7zO6vqyRgOcl\n\tjIhzZx8cSlmd2rx2Eh9k0hnl1nNC2pbNs2zGmYwfWfDHrsrvbsZlYIcnFakC6wNeJz/pX1icAZH\n\ttu28ENlqTGRL1Q0w+SkqiQ+RShRfqsBukV/J3S7Ihhpwlp9dWPLc2REzzS7LPraPm4GdaiCuqmJ\n\t8jQiUUYprAYM5XIe6Q7q+bIlF3mui+PQMjjCrM2tWfPlubVAFC3gGo9/+waGfqHUzhB9qU6cYgh\n\tGpHEZmWAq/by53MAah3gOa7MHJJH6IAFkDTg2vvo++oEUymDKWUGBCfpZYaJc10MgajNH4OVX/U\n\tdNeZ/KaoyOgAw/5/LexarqwYeHkoHygk3JAXKz679InI3M","X-Received":"by 2002:a05:6a20:72a7:b0:39c:235:c5ec with SMTP id\n adf61e73a8af0-3a7f1d18314mr2674945637.34.1777716834197;\n        Sat, 02 May 2026 03:13:54 -0700 (PDT)","From":"Inochi Amaoto <inochiama@gmail.com>","To":"Jingoo Han <jingoohan1@gmail.com>,\n Manivannan Sadhasivam <mani@kernel.org>, Bjorn Helgaas <bhelgaas@google.com>,\n Lorenzo Pieralisi <lpieralisi@kernel.org>, =?utf-8?q?Krzysztof_Wilczy=C5=84?=\n\t=?utf-8?q?ski?= <kwilczynski@kernel.org>, Rob Herring <robh@kernel.org>,\n Krzysztof Kozlowski <krzk+dt@kernel.org>, Conor Dooley <conor+dt@kernel.org>,\n Yixun Lan <dlan@kernel.org>, Paul Walmsley <pjw@kernel.org>,\n Palmer Dabbelt <palmer@dabbelt.com>, Albert Ou <aou@eecs.berkeley.edu>,\n Alexandre Ghiti <alex@ghiti.fr>, Inochi Amaoto <inochiama@gmail.com>,\n Alex Elder <elder@riscstar.com>,\n Gustavo Pimentel <gustavo.pimentel@synopsys.com>","Cc":"linux-pci@vger.kernel.org,\n\tdevicetree@vger.kernel.org,\n\tlinux-kernel@vger.kernel.org,\n\tlinux-riscv@lists.infradead.org,\n\tspacemit@lists.linux.dev,\n\tYixun Lan <dlan@gentoo.org>,\n\tLongbin Li <looong.bin@gmail.com>","Subject":"[PATCH 5/5] PCI: spacemit-k1: Add Spacemit K3 PCIe host controller\n support","Date":"Sat,  2 May 2026 18:13:18 +0800","Message-ID":"<20260502101319.2364052-6-inochiama@gmail.com>","X-Mailer":"git-send-email 2.54.0","In-Reply-To":"<20260502101319.2364052-1-inochiama@gmail.com>","References":"<20260502101319.2364052-1-inochiama@gmail.com>","Precedence":"bulk","X-Mailing-List":"linux-pci@vger.kernel.org","List-Id":"<linux-pci.vger.kernel.org>","List-Subscribe":"<mailto:linux-pci+subscribe@vger.kernel.org>","List-Unsubscribe":"<mailto:linux-pci+unsubscribe@vger.kernel.org>","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit"},"content":"The PCIe controller on Spacemit K3 is almost a standard Synopsys\nDesignware PCIe IP with extra link and reset control. Unlike\nthe PCIe controller on K1, this controller supports external MSI\ninterrupt controller and can use multiple phy at the same time.\n\nAdd driver to support PCIe controller on Spacemit K3 PCIe.\n\nSigned-off-by: Inochi Amaoto <inochiama@gmail.com>\n---\n drivers/pci/controller/dwc/pcie-spacemit-k1.c | 238 ++++++++++++++++++\n 1 file changed, 238 insertions(+)","diff":"diff --git a/drivers/pci/controller/dwc/pcie-spacemit-k1.c b/drivers/pci/controller/dwc/pcie-spacemit-k1.c\nindex f2a722e5edb5..fa529ac18f2d 100644\n--- a/drivers/pci/controller/dwc/pcie-spacemit-k1.c\n+++ b/drivers/pci/controller/dwc/pcie-spacemit-k1.c\n@@ -23,6 +23,7 @@\n \n #define PCI_VENDOR_ID_SPACEMIT\t\t0x201f\n #define PCI_DEVICE_ID_SPACEMIT_K1\t0x0001\n+#define PCI_DEVICE_ID_SPACEMIT_K3\t0x0002\n \n /* Offsets and field definitions for link management registers */\n #define K1_PHY_AHB_IRQ_EN\t\t\t0x0000\n@@ -32,8 +33,27 @@\n #define SMLH_LINK_UP\t\t\tBIT(1)\n #define RDLH_LINK_UP\t\t\tBIT(12)\n \n+#define INTR_STATUS\t\t\t\t0x0010\n+\n #define INTR_ENABLE\t\t\t\t0x0014\n #define MSI_CTRL_INT\t\t\tBIT(11)\n+#define RDLH_LINK_UP_INT\t\tBIT(20)\n+\n+#define K3_PHY_AHB_IRQSTATUS_INTX\t\t0x0008\n+\n+#define K3_PHY_AHB_IRQENABLE_SET_INTX\t\t0x000c\n+#define LEG_EP_INTERRUPTS\t\t(BIT(6) | BIT(7) | BIT(8) | BIT(9))\n+\n+#define K3_PHY_AHB_IRQENABLE_SET_MSI\t\t0x0014\n+/* MSI defined as BIT(11) in existing INTR_ENABLE, reusing */\n+\n+#define K3_ADDR_INTR_STATUS1\t\t\t0x0018\n+\n+#define K3_ADDR_INTR_ENABLE1\t\t\t0x001C\n+#define MSI_INT\t\t\t\tBIT(0)\n+#define MSIX_INT\t\t\tGENMASK(8, 1)\n+\n+#define K3_MAX_PHY_NUMBER\t\t6\n \n /* Some controls require APMU regmap access */\n #define SYSCON_APMU\t\t\t\"spacemit,apmu\"\n@@ -48,6 +68,9 @@\n \n #define PCIE_CONTROL_LOGIC\t\t\t0x0004\n #define PCIE_SOFT_RESET\t\t\tBIT(0)\n+#define PCIE_PERSTN_OE\t\t\tBIT(24)\n+#define PCIE_PERSTN_OUT\t\t\tBIT(25)\n+#define PCIE_IGNORE_PERSTN\t\tBIT(31)\n \n struct k1_pcie {\n \tstruct dw_pcie pci;\n@@ -263,6 +286,213 @@ static const struct dw_pcie_ops k1_pcie_ops = {\n \t.stop_link\t= k1_pcie_stop_link,\n };\n \n+static int k3_pcie_enable_phy(struct k1_pcie *pcie)\n+{\n+\tint i, ret;\n+\n+\tfor (i = 0; i < pcie->phy_count; i++) {\n+\t\tret = phy_init(pcie->phy[i]);\n+\t\tif (ret)\n+\t\t\tgoto err_phy;\n+\t}\n+\n+\treturn 0;\n+\n+err_phy:\n+\twhile (--i >= 0)\n+\t\tphy_exit(pcie->phy[i]);\n+\n+\treturn ret;\n+}\n+\n+static int k3_pcie_init(struct dw_pcie_rp *pp)\n+{\n+\tstruct dw_pcie *pci = to_dw_pcie_from_pp(pp);\n+\tstruct k1_pcie *k1 = to_k1_pcie(pci);\n+\tu32 reset_ctrl = k1->pmu_off + PCIE_CLK_RESET_CONTROL;\n+\tu32 val;\n+\tint ret;\n+\n+\tregmap_clear_bits(k1->pmu, reset_ctrl, LTSSM_EN);\n+\n+\tk1_pcie_toggle_soft_reset(k1);\n+\n+\tret = k1_pcie_enable_resources(k1);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tregmap_set_bits(k1->pmu, reset_ctrl, PCIE_AUX_PWR_DET);\n+\tregmap_clear_bits(k1->pmu, reset_ctrl, APP_HOLD_PHY_RST);\n+\n+\tret = k3_pcie_enable_phy(k1);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\t/* K3: Set IGNORE_PERSTN and drive PERSTN_OE high (assert reset) */\n+\tregmap_set_bits(k1->pmu, k1->pmu_off + PCIE_CONTROL_LOGIC,\n+\t\t\tPCIE_IGNORE_PERSTN | PCIE_PERSTN_OE | PCIE_PERSTN_OUT);\n+\tusleep_range(1000, 2000);\n+\tregmap_clear_bits(k1->pmu, k1->pmu_off + PCIE_CONTROL_LOGIC, PCIE_PERSTN_OUT);\n+\n+\tmdelay(PCIE_T_PVPERL_MS);\n+\n+\t/*\n+\t * Put the controller in root complex mode, and indicate that\n+\t * Vaux (3.3v) is present.\n+\t */\n+\tregmap_set_bits(k1->pmu, k1->pmu_off + PCIE_CONTROL_LOGIC,\n+\t\t\tPCIE_PERSTN_OUT | PCIE_PERSTN_OE);\n+\n+\tval = dw_pcie_readl_dbi(pci, GEN3_EQ_CONTROL_OFF);\n+\tval &= ~(0xffff << 8);\n+\tval |= ((0x1 << 4) << 8);\n+\tdw_pcie_writel_dbi(pci, GEN3_EQ_CONTROL_OFF, val);\n+\n+\t/* Set the PCI vendor and device ID */\n+\tdw_pcie_dbi_ro_wr_en(pci);\n+\tdw_pcie_writew_dbi(pci, PCI_VENDOR_ID, PCI_VENDOR_ID_SPACEMIT);\n+\tdw_pcie_writew_dbi(pci, PCI_DEVICE_ID, PCI_DEVICE_ID_SPACEMIT_K3);\n+\tdw_pcie_dbi_ro_wr_dis(pci);\n+\n+\t/* Finally, as a workaround, disable ASPM L1 */\n+\tk1_pcie_disable_aspm_l1(k1);\n+\n+\treturn 0;\n+}\n+\n+static int k3_pcie_msi_host_init(struct dw_pcie_rp *pp)\n+{\n+\tstruct dw_pcie *pci = to_dw_pcie_from_pp(pp);\n+\tu32 val;\n+\n+\tdw_pcie_dbi_ro_wr_en(pci);\n+\n+\tval = dw_pcie_readl_dbi(pci, COHERENCY_CONTROL_3_OFF);\n+\tval |= (0xf << 11);\n+\tdw_pcie_writel_dbi(pci, COHERENCY_CONTROL_3_OFF, val);\n+\n+\tdw_pcie_dbi_ro_wr_dis(pci);\n+\n+\treturn 0;\n+}\n+\n+static const struct dw_pcie_host_ops k3_pcie_host_ops = {\n+\t.init\t\t= k3_pcie_init,\n+\t.deinit\t\t= k1_pcie_deinit,\n+\t.msi_init\t= k3_pcie_msi_host_init,\n+};\n+\n+static int k3_pcie_start_link(struct dw_pcie *pci)\n+{\n+\tstruct k1_pcie *k1 = to_k1_pcie(pci);\n+\tu32 val;\n+\n+\tk1_pcie_start_link(pci);\n+\n+\t/* Enable INTx */\n+\tval = readl_relaxed(k1->link + K3_PHY_AHB_IRQENABLE_SET_INTX);\n+\tval |= LEG_EP_INTERRUPTS;\n+\twritel_relaxed(val, k1->link + K3_PHY_AHB_IRQENABLE_SET_INTX);\n+\n+\t/* Enable MSI/MSIX specific to K3 */\n+\tval = readl_relaxed(k1->link + K3_ADDR_INTR_ENABLE1);\n+\tval |= (MSI_INT | MSIX_INT);\n+\twritel_relaxed(val, k1->link + K3_ADDR_INTR_ENABLE1);\n+\n+\treturn 0;\n+}\n+\n+static const struct dw_pcie_ops k3_pcie_ops = {\n+\t.link_up\t= k1_pcie_link_up,\n+\t.start_link\t= k3_pcie_start_link,\n+\t.stop_link\t= k1_pcie_stop_link,\n+};\n+\n+static void k3_pcie_clear_irq_status(struct k1_pcie *k1,\n+\t\t\t\t     u32 *status0, u32 *status1, u32 *status2)\n+{\n+\t*status0 = readl_relaxed(k1->link + K3_PHY_AHB_IRQSTATUS_INTX);\n+\t*status1 = readl_relaxed(k1->link + INTR_STATUS);\n+\t*status2 = readl_relaxed(k1->link + K3_ADDR_INTR_STATUS1);\n+\n+\twritel_relaxed(*status0, k1->link + K3_PHY_AHB_IRQSTATUS_INTX);\n+\twritel_relaxed(*status1, k1->link + INTR_STATUS);\n+\twritel_relaxed(*status2, k1->link + K3_ADDR_INTR_STATUS1);\n+}\n+\n+static int k3_pcie_parse_port(struct k1_pcie *k1)\n+{\n+\tstruct device *dev = k1->pci.dev;\n+\tu32 status0, status1, status2;\n+\tint i;\n+\n+\tk1->phy = devm_kmalloc_array(dev, sizeof(*k1->phy),\n+\t\t\t\t     K3_MAX_PHY_NUMBER, GFP_KERNEL);\n+\tif (IS_ERR(k1->phy))\n+\t\treturn PTR_ERR(k1->phy);\n+\n+\tfor (i = 0; i < K3_MAX_PHY_NUMBER; i++) {\n+\t\tk1->phy[i] = devm_of_phy_get_by_index(dev, dev->of_node, i);\n+\t\tif (IS_ERR(k1->phy[i])) {\n+\t\t\tif (PTR_ERR(k1->phy[i]) == -ENODEV)\n+\t\t\t\tbreak;\n+\n+\t\t\treturn PTR_ERR(k1->phy[i]);\n+\t\t}\n+\t}\n+\n+\tk1->phy_count = i;\n+\tif (k1->phy_count == 0)\n+\t\treturn -EINVAL;\n+\n+\tk3_pcie_clear_irq_status(k1, &status0, &status1, &status2);\n+\n+\treturn 0;\n+}\n+\n+static irqreturn_t k3_pcie_irq_thread(int irq, void *data)\n+{\n+\tstruct k1_pcie *k1 = data;\n+\tstruct dw_pcie_rp *pp = &k1->pci.pp;\n+\tstruct device *dev = k1->pci.dev;\n+\tu32 status0, status1, status2;\n+\n+\tk3_pcie_clear_irq_status(k1, &status0, &status1, &status2);\n+\n+\twritel_relaxed(status0, k1->link + K3_PHY_AHB_IRQSTATUS_INTX);\n+\twritel_relaxed(status1, k1->link + INTR_STATUS);\n+\twritel_relaxed(status2, k1->link + K3_ADDR_INTR_STATUS1);\n+\n+\tif (FIELD_GET(RDLH_LINK_UP_INT, status1)) {\n+\t\tmsleep(PCIE_RESET_CONFIG_WAIT_MS);\n+\t\t/* Rescan the bus to enumerate endpoint devices */\n+\t\tpci_lock_rescan_remove();\n+\t\tpci_rescan_bus(pp->bridge->bus);\n+\t\tpci_unlock_rescan_remove();\n+\t} else if (!status0 && !status1 && !status2)\n+\t\tdev_WARN_ONCE(dev, true,\n+\t\t\t      \"Received unknown event. status0=0x%08x status1=0x%08x status2=0x%08x\\n\",\n+\t\t\t      status0, status1, status2);\n+\n+\treturn IRQ_HANDLED;\n+}\n+\n+static int k3_pcie_post_init(struct k1_pcie *k1)\n+{\n+\tstruct device *dev = k1->pci.dev;\n+\tstruct platform_device *pdev = to_platform_device(dev);\n+\tint irq;\n+\n+\tirq = platform_get_irq_byname_optional(pdev, \"app\");\n+\tif (irq > 0) {\n+\t\treturn devm_request_threaded_irq(dev, irq, NULL,\n+\t\t\t\t\t\t k3_pcie_irq_thread,\n+\t\t\t\t\t\t IRQF_ONESHOT, NULL, k1);\n+\t}\n+\n+\treturn 0;\n+}\n+\n static int k1_pcie_parse_port(struct k1_pcie *k1)\n {\n \tstruct device *dev = k1->pci.dev;\n@@ -373,8 +603,16 @@ static const struct k1_pcie_device_data k1_pcie_device_data = {\n \t.parse_port\t= k1_pcie_parse_port,\n };\n \n+static const struct k1_pcie_device_data k3_pcie_device_data = {\n+\t.host_ops\t= &k3_pcie_host_ops,\n+\t.ops\t\t= &k3_pcie_ops,\n+\t.parse_port\t= k3_pcie_parse_port,\n+\t.post_init\t= k3_pcie_post_init,\n+};\n+\n static const struct of_device_id k1_pcie_of_match_table[] = {\n \t{ .compatible = \"spacemit,k1-pcie\", .data = &k1_pcie_device_data},\n+\t{ .compatible = \"spacemit,k3-pcie\", .data = &k3_pcie_device_data},\n \t{ }\n };\n \n","prefixes":["5/5"]}