From nobody Wed Apr 1 11:14:35 2026 Received: from MW6PR02CU001.outbound.protection.outlook.com (mail-westus2azon11012013.outbound.protection.outlook.com [52.101.48.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A7366387362 for ; Mon, 30 Mar 2026 16:37:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.48.13 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774888648; cv=fail; b=IlvQO4fAVq3Bs9F3FabojBvTvgocsa36IGitULFzJNNsq0vBt3lyk4Y1ZMCRm+c59aO1roKBLrnBL8fPWx9rhYeiEQ2MBqVwvdA2v9HpyGC75OuyvQXGn7vmjvVZJqcE6jaIFESmRiYvKbZl9XHr6xQ93efSYY85cOthCXN425s= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774888648; c=relaxed/simple; bh=v/L/MBxal0LSR5mJ5LHOgdSYfSHLaTrlEBPJfTCKGsg=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=OkCmdPSQS9IIpFvs96pKRbwJ2V6v6OcT6Tr5knAGCGhZSmrw0Sdduyybaflzz2QR2x9z2S6/4eMmOAg75rU4gacYrao/boRlMIltdH4QKWoRlyao01jrPXo93/Z/3OXP8uSb5ftFy4WfHT7Wj9SjexSRZnvw9t7Er72A42H4lDM= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=NRGAs+i2; arc=fail smtp.client-ip=52.101.48.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="NRGAs+i2" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=LPKwyu2RVqP/Ipgjjl8lgS7ShNXfsLBtYpHx1bJ85+Fi+MzKRdljbHVAu1LV5no7VdAh3xm5YQbrAhaIq5a65EQsqN9AttQE3tyTIngzD100fpZE1NCAykcfc8Z1x0q3zyK7nOVrrJemV9o9jQWWhFM509+O2Ei2RhEFqXEtwMT4mGx17D1mvPFyCW0XTKCmfsWX0YIQgDPEVqzXEO9EvHuTxzKb2fnfad4XvdjFdP/JzztW2NP532QwbDpYnzlrBcuvowMkOSwJQ+bttT/UT0zUblstXgFR95t7Ri2vVA1XYrLhNLUxoYyPTKxUbn+OK/nPVTQt9sDoKLkoc1Ag6w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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=8o0P9fRF8q6RdF7bn4NICLGsxL25a6TXCaRrEuyiZ+4=; b=DQ+ptOpYLEpfiQHDzOvnfMEe05mAwz5QXTVZEyHoodxQ58n9mtofkVSA2rRMngVfynu7kkLz2fFH6l71j1SpZpcmwPvHsJjE2JgrNvbL0ps0vaThdDIlpeLlqN55UWRC9W1Gw0jMg4ggDafFg4UQFxdqJuNMr0XDlGOPNxnOQ9usHPffCNAWRER0BvIzDMuR+BE7CR5SIFCIwyjN8aMlhgfdFYzxam22pybxBLn3utiM3CbF3/NRiDae1xgxAqV09ucSSgriVYrx8ODiLC/jU4IdJG9wWePq/5VkdK4JG4bhqudhrJ5Drffpxj6eJGUIVl9u4HKVg0LBSRClFsFQ2g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=8o0P9fRF8q6RdF7bn4NICLGsxL25a6TXCaRrEuyiZ+4=; b=NRGAs+i2/WmqYKY2RGm4l4CopbvNKOYrvRC/cluYDH07qCV5fjfFPOxkXiaeziO/Tsz7M6gUMwiNRz9AazWEBWb3qhFsFzzCniXXxBR6Ipx4CM9hSJHV1oy8PMi+l+Po/Z5QKNqa1STUEK494Jt8C/85Y4Z9h+DK43d4g0Otnmo= Received: from SA0PR11CA0048.namprd11.prod.outlook.com (2603:10b6:806:d0::23) by PH7PR12MB6468.namprd12.prod.outlook.com (2603:10b6:510:1f4::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9769.15; Mon, 30 Mar 2026 16:37:19 +0000 Received: from SA2PEPF00003AE6.namprd02.prod.outlook.com (2603:10b6:806:d0:cafe::15) by SA0PR11CA0048.outlook.office365.com (2603:10b6:806:d0::23) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9745.28 via Frontend Transport; Mon, 30 Mar 2026 16:37:05 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb08.amd.com; pr=C Received: from satlexmb08.amd.com (165.204.84.17) by SA2PEPF00003AE6.mail.protection.outlook.com (10.167.248.6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9745.21 via Frontend Transport; Mon, 30 Mar 2026 16:37:18 +0000 Received: from Satlexmb09.amd.com (10.181.42.218) by satlexmb08.amd.com (10.181.42.217) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 30 Mar 2026 11:37:18 -0500 Received: from satlexmb07.amd.com (10.181.42.216) by satlexmb09.amd.com (10.181.42.218) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 30 Mar 2026 09:37:18 -0700 Received: from xsjlizhih51.xilinx.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server id 15.2.2562.17 via Frontend Transport; Mon, 30 Mar 2026 11:37:17 -0500 From: Lizhi Hou To: , , , , CC: David Zhang , , , , Hayden Laccabue , Lizhi Hou Subject: [PATCH V1 4/6] accel/amdxdna: Add AIE4 firmware loading Date: Mon, 30 Mar 2026 09:37:03 -0700 Message-ID: <20260330163705.3153647-5-lizhi.hou@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260330163705.3153647-1-lizhi.hou@amd.com> References: <20260330163705.3153647-1-lizhi.hou@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SA2PEPF00003AE6:EE_|PH7PR12MB6468:EE_ X-MS-Office365-Filtering-Correlation-Id: 83056c46-4c7f-4f44-2054-08de8e7a9c16 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|36860700016|1800799024|376014|82310400026|56012099003|18002099003|22082099003; X-Microsoft-Antispam-Message-Info: 0WxHDreE/WzKimcGXm+lSprzXB5ObUjwAlf0Zc2XGQ40k3SDv8LHjLaho+FKGz7zM6KpRSg077SqLKi55bWHPuwNOZjBFr4BLVzBeRZ5TaaX65ZxmE8ZIwK/kk4b4Ow6KBh9ii/OkJh+AKl10yA75P1jQoyaQKIALeuN9HkRPKxXBjrTRSk4U1nYtS3xEqjbLXC1oATL3EbT88AiH9P4SQttx9cpnlovQieKq1v5ZxXOZ0JSd4lCbPUgCCS9hmRArAjUQEmQyJtQGc5OA64C8dQg4Bvj2Vf9lKP7LzJCU/0FWvh3Rr1bc9uL6I22Opqe2HcMd6OsmCiLtTMkuH0uHQr5zfNfxaxbt7GMb/zVSZX8A3O5nX0+BVX3xrZTEJZYWrdvYdteBIYpe5L+duSXs/1v1kJ+zMcGUpkJyWvdR3g28YYnCGsMyHDbrcgbcgC3n+EP1EslLHfcrQv9/cWvgAlxFUZCcH+VTwVAuYnwvsY/QdSjMHqcMef/InCQGnAm2lggzrp7WhpsbLu3AGl8s52CS2ukLuOH2es9QGvCTtmzxE6Pk0qwrq7J/JYbmj8AOpBpX13fCk5mHzE86yCAs9+aTW3xRUDCmYHCfX/OeoX3qW6KIkBvrZpP1g1uJnbrPdNMNgDgjYIeNwvUmyw63Uk2a0gpovVRD93nD5/+JFwQ1X/o3ntPR2h8kJ65Bx/g9r5HZLhJhlskmp1Rsy75PD820D/YFn1/YadvQIsVOLDIwgeeK0yuewiuCALp+UtHki3gh40eYfyrQNwuC8fa7A== X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb08.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(36860700016)(1800799024)(376014)(82310400026)(56012099003)(18002099003)(22082099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: ul1/FicWhX0aVqZ74fX8A5WuTIs5ZZehrjiHeqEOxMitl6fztbF3vsCZPd6qw7tze1YgBib0yrIZSeoeQCBQ39e924g4brOU3Z92IwmeGPnK20adDSrIia5irMZQEq7Vv7FcuvWeYpI06aZbw/XD/xmv4IUmtQ5qmudAJJuAl7ubmkORzaF2WfuMK+anpCKI2x3QP8ThvlxPe5S6En1SLCNG8x6b4W2fSvKlE7jOhLPVF0fwCFtRaoS2Awze3PTAOGMuCnO6lyYHkcJTKGAm5xEX1xDVmazWHo3x2LKeIpFtyWp4GBP7+Janz0d9NKcv6E9IReSloD26ideN5/AVmpwkLBiJFy8wNXn7NIt6d3s6DcqZT8Zkl1+WEiT77muuI6+qc+/T/umhEMOhfDbxjXAk9niaB0OrZTO1Enhr8D90H2blhiw11xq8Wlam+Fcg X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Mar 2026 16:37:18.8574 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 83056c46-4c7f-4f44-2054-08de8e7a9c16 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb08.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SA2PEPF00003AE6.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH7PR12MB6468 Content-Type: text/plain; charset="utf-8" From: David Zhang Add support for loading AIE4 firmware through the common PSP interfaces. Compared to AIE2, AIE4 introduces an additional CERT firmware image. aiem_psp_create() performs CERT setup when the CERT image size is non-zero. Co-developed-by: Hayden Laccabue Signed-off-by: Hayden Laccabue Signed-off-by: David Zhang Signed-off-by: Lizhi Hou Reviewed-by: Mario Limonciello (AMD) --- drivers/accel/amdxdna/aie.h | 4 + drivers/accel/amdxdna/aie2_pci.c | 2 + drivers/accel/amdxdna/aie4_pci.c | 109 ++++++++++++++++++++++- drivers/accel/amdxdna/aie4_pci.h | 4 + drivers/accel/amdxdna/aie_psp.c | 141 +++++++++++++++++++++++------- drivers/accel/amdxdna/npu3_regs.c | 23 +++++ 6 files changed, 247 insertions(+), 36 deletions(-) diff --git a/drivers/accel/amdxdna/aie.h b/drivers/accel/amdxdna/aie.h index 124c0f7e9ca0..423ed34af9ee 100644 --- a/drivers/accel/amdxdna/aie.h +++ b/drivers/accel/amdxdna/aie.h @@ -57,7 +57,11 @@ struct aie_bar_off_pair { struct psp_config { const void *fw_buf; u32 fw_size; + const void *certfw_buf; + u32 certfw_size; void __iomem *psp_regs[PSP_MAX_REGS]; + u32 arg2_mask; + u32 notify_val; }; =20 /* aie.c */ diff --git a/drivers/accel/amdxdna/aie2_pci.c b/drivers/accel/amdxdna/aie2_= pci.c index e4b7893bd429..0489e668cd73 100644 --- a/drivers/accel/amdxdna/aie2_pci.c +++ b/drivers/accel/amdxdna/aie2_pci.c @@ -549,6 +549,8 @@ static int aie2_init(struct amdxdna_dev *xdna) =20 psp_conf.fw_size =3D fw->size; psp_conf.fw_buf =3D fw->data; + psp_conf.arg2_mask =3D GENMASK(23, 0); + psp_conf.notify_val =3D 1; for (i =3D 0; i < PSP_MAX_REGS; i++) psp_conf.psp_regs[i] =3D tbl[PSP_REG_BAR(ndev, i)] + PSP_REG_OFF(ndev, i= ); ndev->aie.psp_hdl =3D aiem_psp_create(&xdna->ddev, &psp_conf); diff --git a/drivers/accel/amdxdna/aie4_pci.c b/drivers/accel/amdxdna/aie4_= pci.c index 0f360c1ccebd..e7993b315996 100644 --- a/drivers/accel/amdxdna/aie4_pci.c +++ b/drivers/accel/amdxdna/aie4_pci.c @@ -6,11 +6,15 @@ #include #include #include +#include +#include =20 #include "aie4_pci.h" #include "amdxdna_pci_drv.h" =20 -#define NO_IOHUB 0 +#define NO_IOHUB 0 +#define CERTFW_MAX_SIZE (SZ_32K + SZ_256) +#define PSP_NOTIFY_INTR 0xD007BE11 =20 /* * The management mailbox channel is allocated by firmware. @@ -207,13 +211,12 @@ static int aie4_mailbox_init(struct amdxdna_dev *xdna) =20 static void aie4_fw_unload(struct amdxdna_dev_hdl *ndev) { - /* TODO */ + aie_psp_stop(ndev->aie.psp_hdl); } =20 static int aie4_fw_load(struct amdxdna_dev_hdl *ndev) { - /* TODO */ - return 0; + return aie_psp_start(ndev->aie.psp_hdl); } =20 static int aie4_hw_start(struct amdxdna_dev *xdna) @@ -261,11 +264,98 @@ static void aie4_hw_stop(struct amdxdna_dev *xdna) aie4_fw_unload(ndev); } =20 +static int aie4_request_firmware(struct amdxdna_dev_hdl *ndev, + const struct firmware **npufw, + const struct firmware **certfw) +{ + struct amdxdna_dev *xdna =3D ndev->aie.xdna; + struct pci_dev *pdev =3D to_pci_dev(xdna->ddev.dev); + char fw_name[128]; + int ret; + + ret =3D snprintf(fw_name, sizeof(fw_name), "amdnpu/%04x_%02x/%s", + pdev->device, pdev->revision, ndev->priv->npufw_path); + if (ret >=3D sizeof(fw_name)) { + XDNA_ERR(xdna, "npu firmware path is truncated"); + return -EINVAL; + } + + ret =3D request_firmware(npufw, fw_name, &pdev->dev); + if (ret) { + XDNA_ERR(xdna, "failed to request_firmware %s, ret %d", fw_name, ret); + return ret; + } + + ret =3D snprintf(fw_name, sizeof(fw_name), "amdnpu/%04x_%02x/%s", + pdev->device, pdev->revision, ndev->priv->certfw_path); + if (ret >=3D sizeof(fw_name)) { + XDNA_ERR(xdna, "cert firmware path is truncated"); + ret =3D -EINVAL; + goto release_npufw; + } + + ret =3D request_firmware(certfw, fw_name, &pdev->dev); + if (ret) { + XDNA_ERR(xdna, "failed to request_firmware %s, ret %d", fw_name, ret); + goto release_npufw; + } + + if ((*certfw)->size > CERTFW_MAX_SIZE) { + XDNA_ERR(xdna, "CERTFW over maximum size of 32 KB + 256 B"); + ret =3D -EINVAL; + goto release_certfw; + } + + return 0; + +release_certfw: + release_firmware(*certfw); +release_npufw: + release_firmware(*npufw); + + return ret; +} + +static void aie4_release_firmware(struct amdxdna_dev_hdl *ndev, + const struct firmware *npufw, + const struct firmware *certfw) +{ + release_firmware(certfw); + release_firmware(npufw); +} + +static int aie4_prepare_firmware(struct amdxdna_dev_hdl *ndev, + const struct firmware *npufw, + const struct firmware *certfw, + void __iomem *tbl[PCI_NUM_RESOURCES]) +{ + struct amdxdna_dev *xdna =3D ndev->aie.xdna; + struct psp_config psp_conf; + int i; + + psp_conf.fw_size =3D npufw->size; + psp_conf.fw_buf =3D npufw->data; + psp_conf.certfw_size =3D certfw->size; + psp_conf.certfw_buf =3D certfw->data; + psp_conf.arg2_mask =3D ~0; + psp_conf.notify_val =3D PSP_NOTIFY_INTR; + for (i =3D 0; i < PSP_MAX_REGS; i++) + psp_conf.psp_regs[i] =3D tbl[PSP_REG_BAR(ndev, i)] + PSP_REG_OFF(ndev, i= ); + ndev->aie.psp_hdl =3D aiem_psp_create(&xdna->ddev, &psp_conf); + if (!ndev->aie.psp_hdl) { + XDNA_ERR(xdna, "failed to create psp"); + return -ENOMEM; + } + + return 0; +} + static int aie4_pcidev_init(struct amdxdna_dev_hdl *ndev) { struct amdxdna_dev *xdna =3D ndev->aie.xdna; struct pci_dev *pdev =3D to_pci_dev(xdna->ddev.dev); void __iomem *tbl[PCI_NUM_RESOURCES] =3D {0}; + const struct firmware *npufw, *certfw; unsigned long bars =3D 0; int ret, i; =20 @@ -282,6 +372,8 @@ static int aie4_pcidev_init(struct amdxdna_dev_hdl *nde= v) return ret; } =20 + for (i =3D 0; i < PSP_MAX_REGS; i++) + set_bit(PSP_REG_BAR(ndev, i), &bars); set_bit(xdna->dev_info->mbox_bar, &bars); set_bit(xdna->dev_info->sram_bar, &bars); =20 @@ -300,6 +392,15 @@ static int aie4_pcidev_init(struct amdxdna_dev_hdl *nd= ev) =20 pci_set_master(pdev); =20 + ret =3D aie4_request_firmware(ndev, &npufw, &certfw); + if (ret) + goto clear_master; + + ret =3D aie4_prepare_firmware(ndev, npufw, certfw, tbl); + aie4_release_firmware(ndev, npufw, certfw); + if (ret) + goto clear_master; + ret =3D aie4_irq_init(xdna); if (ret) goto clear_master; diff --git a/drivers/accel/amdxdna/aie4_pci.h b/drivers/accel/amdxdna/aie4_= pci.h index f3810a969431..ee388ccf7196 100644 --- a/drivers/accel/amdxdna/aie4_pci.h +++ b/drivers/accel/amdxdna/aie4_pci.h @@ -14,9 +14,13 @@ #include "amdxdna_mailbox.h" =20 struct amdxdna_dev_priv { + const char *npufw_path; + const char *certfw_path; u32 mbox_bar; u32 mbox_rbuf_bar; u64 mbox_info_off; + + struct aie_bar_off_pair psp_regs_off[PSP_MAX_REGS]; }; =20 struct amdxdna_dev_hdl { diff --git a/drivers/accel/amdxdna/aie_psp.c b/drivers/accel/amdxdna/aie_ps= p.c index 8743b812a449..458dca7cc5a0 100644 --- a/drivers/accel/amdxdna/aie_psp.c +++ b/drivers/accel/amdxdna/aie_psp.c @@ -18,6 +18,7 @@ #define PSP_VALIDATE 1 #define PSP_START 2 #define PSP_RELEASE_TMR 3 +#define PSP_VALIDATE_CERT 4 =20 /* PSP special arguments */ #define PSP_START_COPY_FW 1 @@ -27,10 +28,20 @@ #define PSP_ERROR_BAD_STATE 0xFFFF0007 =20 #define PSP_FW_ALIGN 0x10000 +#define PSP_CFW_ALIGN 0x8000 #define PSP_POLL_INTERVAL 20000 /* us */ #define PSP_POLL_TIMEOUT 1000000 /* us */ =20 -#define PSP_REG(p, reg) ((p)->psp_regs[reg]) +#define PSP_REG(p, reg) ((p)->conf.psp_regs[reg]) +#define PSP_SET_CMD(psp, reg_vals, cmd, arg0, arg1, arg2) \ +({ \ + u32 *_regs =3D reg_vals; \ + u32 _cmd =3D cmd; \ + _regs[0] =3D _cmd; \ + _regs[1] =3D arg0; \ + _regs[2] =3D arg1; \ + _regs[3] =3D ((arg2) | ((_cmd) << 24)) & (psp)->conf.arg2_mask; \ +}) =20 struct psp_device { struct drm_device *ddev; @@ -38,7 +49,9 @@ struct psp_device { u32 fw_buf_sz; u64 fw_paddr; void *fw_buffer; - void __iomem *psp_regs[PSP_MAX_REGS]; + u32 certfw_buf_sz; + u64 certfw_paddr; + void *certfw_buffer; }; =20 static int psp_exec(struct psp_device *psp, u32 *reg_vals) @@ -47,13 +60,22 @@ static int psp_exec(struct psp_device *psp, u32 *reg_va= ls) int ret, i; u32 ready; =20 + /* Check for PSP ready before any write */ + ret =3D readx_poll_timeout(readl, PSP_REG(psp, PSP_STATUS_REG), ready, + FIELD_GET(PSP_STATUS_READY, ready), + PSP_POLL_INTERVAL, PSP_POLL_TIMEOUT); + if (ret) { + drm_err(psp->ddev, "PSP is not ready, ret 0x%x", ret); + return ret; + } + /* Write command and argument registers */ for (i =3D 0; i < PSP_NUM_IN_REGS; i++) writel(reg_vals[i], PSP_REG(psp, i)); =20 /* clear and set PSP INTR register to kick off */ writel(0, PSP_REG(psp, PSP_INTR_REG)); - writel(1, PSP_REG(psp, PSP_INTR_REG)); + writel(psp->conf.notify_val, PSP_REG(psp, PSP_INTR_REG)); =20 /* PSP should be busy. Wait for ready, so we know task is done. */ ret =3D readx_poll_timeout(readl, PSP_REG(psp, PSP_STATUS_REG), ready, @@ -90,69 +112,124 @@ int aie_psp_waitmode_poll(struct psp_device *psp) =20 void aie_psp_stop(struct psp_device *psp) { - u32 reg_vals[PSP_NUM_IN_REGS] =3D { PSP_RELEASE_TMR, }; + u32 reg_vals[PSP_NUM_IN_REGS]; int ret; =20 + PSP_SET_CMD(psp, reg_vals, PSP_RELEASE_TMR, 0, 0, 0); + ret =3D psp_exec(psp, reg_vals); if (ret) drm_err(psp->ddev, "release tmr failed, ret %d", ret); } =20 -int aie_psp_start(struct psp_device *psp) +static int psp_validate_fw(struct psp_device *psp, u8 cmd, u64 paddr, u32 = buf_sz) { u32 reg_vals[PSP_NUM_IN_REGS]; int ret; =20 - reg_vals[0] =3D PSP_VALIDATE; - reg_vals[1] =3D lower_32_bits(psp->fw_paddr); - reg_vals[2] =3D upper_32_bits(psp->fw_paddr); - reg_vals[3] =3D psp->fw_buf_sz; + PSP_SET_CMD(psp, reg_vals, cmd, lower_32_bits(paddr), + upper_32_bits(paddr), buf_sz); =20 ret =3D psp_exec(psp, reg_vals); - if (ret) { + if (ret) drm_err(psp->ddev, "failed to validate fw, ret %d", ret); - return ret; - } =20 - memset(reg_vals, 0, sizeof(reg_vals)); - reg_vals[0] =3D PSP_START; - reg_vals[1] =3D PSP_START_COPY_FW; + return ret; +} + +static int psp_start(struct psp_device *psp) +{ + u32 reg_vals[PSP_NUM_IN_REGS]; + int ret; + + PSP_SET_CMD(psp, reg_vals, PSP_START, PSP_START_COPY_FW, 0, 0); + ret =3D psp_exec(psp, reg_vals); - if (ret) { + if (ret) drm_err(psp->ddev, "failed to start fw, ret %d", ret); + + return ret; +} + +int aie_psp_start(struct psp_device *psp) +{ + int ret; + + ret =3D psp_validate_fw(psp, PSP_VALIDATE, + psp->fw_paddr, psp->fw_buf_sz); + if (ret) return ret; - } =20 - return 0; + if (!psp->certfw_buf_sz) + goto psp_start; + + ret =3D psp_validate_fw(psp, PSP_VALIDATE_CERT, + psp->certfw_paddr, psp->certfw_buf_sz); + if (ret) + return ret; +psp_start: + return psp_start(psp); +} + +/* + * PSP requires host physical address to load firmware. + * Allocate a buffer, obtain its physical address, align, and copy data in. + */ +static void *psp_alloc_fw_buf(struct psp_device *psp, const void *fw_data, + u32 fw_size, u32 align, u32 *buf_sz, + u64 *paddr) +{ + u32 alloc_sz; + void *buffer; + u64 offset; + + *buf_sz =3D ALIGN(fw_size, align); + alloc_sz =3D *buf_sz + align; + + buffer =3D drmm_kmalloc(psp->ddev, alloc_sz, GFP_KERNEL); + if (!buffer) + return NULL; + + *paddr =3D virt_to_phys(buffer); + offset =3D ALIGN(*paddr, align) - *paddr; + *paddr +=3D offset; + memcpy(buffer + offset, fw_data, fw_size); + + return buffer; } =20 struct psp_device *aiem_psp_create(struct drm_device *ddev, struct psp_con= fig *conf) { struct psp_device *psp; - u64 offset; =20 psp =3D drmm_kzalloc(ddev, sizeof(*psp), GFP_KERNEL); if (!psp) return NULL; =20 psp->ddev =3D ddev; - memcpy(psp->psp_regs, conf->psp_regs, sizeof(psp->psp_regs)); + psp->fw_buffer =3D psp_alloc_fw_buf(psp, conf->fw_buf, conf->fw_size, + PSP_FW_ALIGN, &psp->fw_buf_sz, + &psp->fw_paddr); + if (!psp->fw_buffer) + return NULL; + + if (!conf->certfw_size) { + drm_dbg(ddev, "no cert fw"); + goto done; + } =20 - psp->fw_buf_sz =3D ALIGN(conf->fw_size, PSP_FW_ALIGN); - psp->fw_buffer =3D drmm_kmalloc(ddev, psp->fw_buf_sz + PSP_FW_ALIGN, GFP_= KERNEL); - if (!psp->fw_buffer) { - drm_err(ddev, "no memory for fw buffer"); + /* CERT firmware */ + psp->certfw_buffer =3D psp_alloc_fw_buf(psp, conf->certfw_buf, + conf->certfw_size, PSP_CFW_ALIGN, + &psp->certfw_buf_sz, + &psp->certfw_paddr); + if (!psp->certfw_buffer) { + drm_err(ddev, "no memory for cert fw buffer"); return NULL; } =20 - /* - * AMD Platform Security Processor(PSP) requires host physical - * address to load NPU firmware. - */ - psp->fw_paddr =3D virt_to_phys(psp->fw_buffer); - offset =3D ALIGN(psp->fw_paddr, PSP_FW_ALIGN) - psp->fw_paddr; - psp->fw_paddr +=3D offset; - memcpy(psp->fw_buffer + offset, conf->fw_buf, conf->fw_size); +done: + memcpy(&psp->conf, conf, sizeof(psp->conf)); =20 return psp; } diff --git a/drivers/accel/amdxdna/npu3_regs.c b/drivers/accel/amdxdna/npu3= _regs.c index f6e20f4858db..fb2bd60b8f00 100644 --- a/drivers/accel/amdxdna/npu3_regs.c +++ b/drivers/accel/amdxdna/npu3_regs.c @@ -16,6 +16,15 @@ =20 /* PCIe BAR Index for NPU3 */ #define NPU3_REG_BAR_INDEX 0 +#define NPU3_PSP_BAR_INDEX 4 + +#define MMNPU_APERTURE3_BASE 0x3810000 +#define NPU3_PSP_BAR_BASE MMNPU_APERTURE3_BASE + +#define MPASP_C2PMSG_123_ALT_1 0x3810AEC +#define MPASP_C2PMSG_156_ALT_1 0x3810B70 +#define MPASP_C2PMSG_157_ALT_1 0x3810B74 +#define MPASP_C2PMSG_73_ALT_1 0x3810A24 =20 static const struct amdxdna_fw_feature_tbl npu3_fw_feature_table[] =3D { { .major =3D 5, .min_minor =3D 10 }, @@ -23,14 +32,28 @@ static const struct amdxdna_fw_feature_tbl npu3_fw_feat= ure_table[] =3D { }; =20 static const struct amdxdna_dev_priv npu3_dev_priv =3D { + .npufw_path =3D "npu.dev.sbin", + .certfw_path =3D "cert.dev.sbin", .mbox_bar =3D NPU3_MBOX_BAR, .mbox_rbuf_bar =3D NPU3_MBOX_BUFFER_BAR, .mbox_info_off =3D NPU3_MBOX_INFO_OFF, + .psp_regs_off =3D { + DEFINE_BAR_OFFSET(PSP_CMD_REG, NPU3_PSP, MPASP_C2PMSG_123_ALT_1), + DEFINE_BAR_OFFSET(PSP_ARG0_REG, NPU3_PSP, MPASP_C2PMSG_156_ALT_1), + DEFINE_BAR_OFFSET(PSP_ARG1_REG, NPU3_PSP, MPASP_C2PMSG_157_ALT_1), + DEFINE_BAR_OFFSET(PSP_ARG2_REG, NPU3_PSP, MPASP_C2PMSG_123_ALT_1), + DEFINE_BAR_OFFSET(PSP_INTR_REG, NPU3_PSP, MPASP_C2PMSG_73_ALT_1), + DEFINE_BAR_OFFSET(PSP_STATUS_REG, NPU3_PSP, MPASP_C2PMSG_123_ALT_1), + DEFINE_BAR_OFFSET(PSP_RESP_REG, NPU3_PSP, MPASP_C2PMSG_156_ALT_1), + /* npu3 doesn't use 8th pwaitmode register */ + }, + }; =20 const struct amdxdna_dev_info dev_npu3_pf_info =3D { .mbox_bar =3D NPU3_MBOX_BAR, .sram_bar =3D NPU3_MBOX_BUFFER_BAR, + .psp_bar =3D NPU3_PSP_BAR_INDEX, .vbnv =3D "RyzenAI-npu3-pf", .device_type =3D AMDXDNA_DEV_TYPE_PF, .dev_priv =3D &npu3_dev_priv, --=20 2.34.1