From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from SN4PR2101CU001.outbound.protection.outlook.com (mail-southcentralusazon11012039.outbound.protection.outlook.com [40.93.195.39]) (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 DE2293112B3; Wed, 29 Oct 2025 07:39:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.93.195.39 ARC-Seal:i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761723561; cv=fail; b=NIkySbtOC7/kSUjlaeHk8RXq0kqiP9wMIE0cHo637AOd2oSlV3UTUa+3M1Rx7whItW7UIEQcZJFDWpzvCcwVIzoAvW9NBHw38IIHgVVUo2o+vVlvJld+vx9lp+kmAF8u5BigfCzZ0Uy0GKPCbqmk0yPKwLjiW3IOtICk1ADT4nM= ARC-Message-Signature:i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761723561; c=relaxed/simple; bh=FlnavPYSETihk8gUzTBC49yc3pUQR57XuZ7loNhqJUo=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=d1LfQrEFnOtNyHPmgC1iXHb78SJxWTCeDKJoU5T0O97F3njeF7L/tMMfLIPadW+AW5BH60gZDcXmp2xPwkSGLwm30+PSMun0rfQc+W2bd5cWGI5abxq49LsjOaXqAy0nUeVV7qu7UV3dh8+zrE2eQwkNRS4dh08H1M9x02aIRBo= 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=Ny+RcFJn; arc=fail smtp.client-ip=40.93.195.39 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="Ny+RcFJn" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=kW67UjaEdxiLRJJoTm0Y/lf1alud7r+Iv6RYrBET3TEKiVvAJY6ARM1fiPLCR9BSrowfXSIAjmlqBtQMeW3UjO1JWqJC1hx/6v/uJ9xvnF4KyA1+5Ulx17IBVYmP9OKVHORnLSbAQ6vj2xDp9JORS5ldgMOy4hU11dEy2jYxhTyvxkmbXLo+qSZgl7h1Yf3JI1NUddD40cJ3L0zuBTK9n8+aaMe+hKhxanCmYhYC88SZ0ZAOMm6gzvjvu7rA92SiOx2XhOcBBLutoW3PLFyb6N1ZGzxCm29bec5JIpLLaX4+ddIraUWhZVZaR0Gz8uT/10egxIY0SOzYsb/x4psIFw== 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=ER5RVZfHRUhwDhGFD8g3Lu5NcYprNJZGO7ijbgkkS+g=; b=kk+D/xEhmCam8ErM2uWKwb07ILg0f3giffHpy25lYUBHZ4WArywc+PPATQQUjkbFz6VLxcVBdy5ePxaCuuC7cV0+HHHN5NZXWo5eLolYXGac6KQDhMYF6QXOjCBKs3VeCuBqgYxOYml7R+nUJkbrWCvvGyDOjCLwXvynIhB5n79boOZCNkpgxnDqoCPcBdB+tGIWpGG7Q/P8CWVFSKCvKZ/0+2mr6JNIGA++mJsr0m7sYxOFGlv6pB8VvDcmtDBT8V5/kM1dgsuFvMv4vyBymZw1lr6QLM9defe6AfcW6XU08vQkwx8oNPL+bpPZ8z+0wsBM0pvQDLvE+Gj8PY1VNA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=google.com 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=ER5RVZfHRUhwDhGFD8g3Lu5NcYprNJZGO7ijbgkkS+g=; b=Ny+RcFJn2zozRezb/vm3hSGph3gmeaQMt1th6hC7laRSzPwPdRqBaYoVgpqMA0C2e3aP2T772UYDvF7MP5httmenFRYcL7KslC9EEGahAwDt5iqqWza+0wPKijjOWWQoxpvQFsaNhtDVZV729tHH/DBT+M4OrshOsS0BXsy+uG0= Received: from MW4P221CA0009.NAMP221.PROD.OUTLOOK.COM (2603:10b6:303:8b::14) by SJ2PR12MB7893.namprd12.prod.outlook.com (2603:10b6:a03:4cc::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9253.12; Wed, 29 Oct 2025 07:39:14 +0000 Received: from MWH0EPF000989E8.namprd02.prod.outlook.com (2603:10b6:303:8b:cafe::8b) by MW4P221CA0009.outlook.office365.com (2603:10b6:303:8b::14) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9253.18 via Frontend Transport; Wed, 29 Oct 2025 07:39:14 +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 MWH0EPF000989E8.mail.protection.outlook.com (10.167.241.135) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9253.7 via Frontend Transport; Wed, 29 Oct 2025 07:39:14 +0000 Received: from SATLEXMB04.amd.com (10.181.40.145) by satlexmb08.amd.com (10.181.42.217) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.2.2562.17; Wed, 29 Oct 2025 00:39:13 -0700 Received: from satlexmb08.amd.com (10.181.42.217) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Wed, 29 Oct 2025 02:39:13 -0500 Received: from xhdapps-pcie2.xilinx.com (10.180.168.240) by satlexmb08.amd.com (10.181.42.217) with Microsoft SMTP Server id 15.2.2562.17 via Frontend Transport; Wed, 29 Oct 2025 00:39:11 -0700 From: Devendra K Verma To: , , CC: , , , , Subject: [PATCH v6 2/2] dmaengine: dw-edma: Add non-LL mode Date: Wed, 29 Oct 2025 13:09:05 +0530 Message-ID: <20251029073905.40409-3-devendra.verma@amd.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251029073905.40409-1-devendra.verma@amd.com> References: <20251029073905.40409-1-devendra.verma@amd.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain Received-SPF: None (SATLEXMB04.amd.com: devendra.verma@amd.com does not designate permitted sender hosts) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: MWH0EPF000989E8:EE_|SJ2PR12MB7893:EE_ X-MS-Office365-Filtering-Correlation-Id: 90cb24a3-7a8f-4c0f-8c51-08de16be426a X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|82310400026|36860700013|1800799024; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?mO2iflK5ZjRZssGK+fZUuHkg1+o7gDjxFUBQssuZaefuH3N4YaR8x82zdGl/?= =?us-ascii?Q?Bf7N7cGD1QzyVmnmZ2+BHmhEC4w9QNGJjNR+Qsttddpnn9yCbIhYwqj9Y1vo?= =?us-ascii?Q?XkyyWyOG58MWa0rsAx2jCMY8up+MYsZfzKA64DMAqB7elcrwsCW47W4m05BS?= =?us-ascii?Q?g5LVGDDcimT8P9sXf3z4WL4r7BaoioOmnyrWDdBDlUfmWmHGX3F7aBdO2ZCA?= =?us-ascii?Q?g5lrrs3ex7AMngoLD15UaIXrc4eNTVM4ZxTUO4EQRKYZEafW5eyIztPMq3T6?= =?us-ascii?Q?s2Yo/Oog7dO9op4njY0tVxEb1/B0og9e7Awrx72HRwkCeEH0P9wfRFgoHyOh?= =?us-ascii?Q?xPjONFCGlFQlZJ5x4Va0Qn1uceGyzf8/LOivaZpQQjTXQeCvmGPFe+8M6jXj?= =?us-ascii?Q?goBARElVsiavmWsBKdQk1v1rYPbb68dJTKUGR1nA37R+mOZ9L295O1cFadBd?= =?us-ascii?Q?omR1boomPGbPTbar/CgfeCtM7trRCH4kMwZpFwM9J0eDSdxEoS8Ma6Z6q/xo?= =?us-ascii?Q?Jcod+q12CqRaDpl1kbQXR5mEyQQjGa4dUKWER5zgA4bo8Jf25wkMW/n6MJ6J?= =?us-ascii?Q?w9RWikBMgPgJN8QLOlmtAobSzh/kK4/+k7cDvRGVzmMPMDHOAeBjD6IjDbhd?= =?us-ascii?Q?0vpM4r/ToYVbfAMZnmc3N/gvcE3a9DKI2ELEkreMaXJIv3ADHpwyIr4ieKm+?= =?us-ascii?Q?ezj7BNYuosq7dSjkwEFPXaDzq1tYHBZr9NPHc9SWnPD97sLdnR1pus3djjyG?= =?us-ascii?Q?67IlUsJZloYktwajfd1fkDXIiD0vj8KdqNjC8TkJ8iPZviqfXq/EcTPEAqxG?= =?us-ascii?Q?ctvaKS+8opISobDacfk5BJFVOHt9yuuXgeH9kv3OkgMoAD2MdhpdZImN7YMB?= =?us-ascii?Q?qjDCvwnvOIL13x5Rnm9TPnDHohKq8gA4Lqz1avEYzWxHohBwfS38G9HtCR7P?= =?us-ascii?Q?cCEy/OR0gBmJfw7HoTQd0ixbD6TKr0LWUxM0OXfY9ML0yBLmFB90EXEfE+Xs?= =?us-ascii?Q?GCQNk7L6MR3mRfPmJn8sZd9LHkXuF7CSbz74mDJ1w04YhbKC/GuffL88DPK1?= =?us-ascii?Q?CurgXsx7VIIZ5/V5QUqI8Ot1uiWSAXjo0Yo4y2JK56t+8FtkL/hFuO3GZL30?= =?us-ascii?Q?aMGfscKf7SoBcTKdbAzuiL7ZwPCeFnB1cil496NBOH3HcTYZs1KfxFWX7FL1?= =?us-ascii?Q?VTV/M1z8i2/83Oj1xLCOZxrF4+j0dYAQ0ahhcdcc9oyMqHkkMPXFrnBmRcc/?= =?us-ascii?Q?vMlRwdiIuE4iQm/kaF4h3XfMbY4Z9pkQU2DttS1dALlcRSiAteixI2bVST/Q?= =?us-ascii?Q?+kwCOB84dma2MpxmCXOTRf6BhZhpbKUdZU42KvIe5FZikcdV0GMdCSe4PDe1?= =?us-ascii?Q?OJV/cytOmCIxxujN6jshfF6SZrOVUMaEZFFte9In97Ar3BM3P1llGgOUvA11?= =?us-ascii?Q?rH+SOd8latpPM2j8BZn+N0AEJmzeH0zGIITGKCZ5TnEU3ELJn/9Ka0LaJR/h?= =?us-ascii?Q?rdiQHJ0cRE2zjMnulbENbaVTfwnXK2eK7eHbKsypKADTjm8vL1Lk5bM8kAfv?= =?us-ascii?Q?cal9qiXRNryTyP9orfY=3D?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:satlexmb08.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(376014)(82310400026)(36860700013)(1800799024);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 29 Oct 2025 07:39:14.5690 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 90cb24a3-7a8f-4c0f-8c51-08de16be426a 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: MWH0EPF000989E8.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SJ2PR12MB7893 AMD MDB IP supports Linked List (LL) mode as well as non-LL mode. The current code does not have the mechanisms to enable the DMA transactions using the non-LL mode. The following two cases are added with this patch: - When a valid physical base address is not configured via the Xilinx VSEC capability then the IP can still be used in non-LL mode. The default mode for all the DMA transactions and for all the DMA channels then is non-LL mode. - When a valid physical base address is configured but the client wants to use the non-LL mode for DMA transactions then also the flexibility is provided via the peripheral_config struct member of dma_slave_config. In this case the channels can be individually configured in non-LL mode. This use case is desirable for single DMA transfer of a chunk, this saves the effort of preparing the Link List. This particular scenario is applicable to AMD as well as Synopsys IP. Signed-off-by: Devendra K Verma --- Changes in v6 Gave definition to bits used for channel configuration. Removed the comment related to doorbell. Changes in v5 Variable name 'nollp' changed to 'non_ll'. In the dw_edma_device_config() WARN_ON replaced with dev_err(). Comments follow the 80-column guideline. Changes in v4 No change Changes in v3 No change Changes in v2 Reverted the function return type to u64 for dw_edma_get_phys_addr(). Changes in v1 Changed the function return type for dw_edma_get_phys_addr(). Corrected the typo raised in review. --- drivers/dma/dw-edma/dw-edma-core.c | 41 ++++++++++++++++++++--- drivers/dma/dw-edma/dw-edma-core.h | 1 + drivers/dma/dw-edma/dw-edma-pcie.c | 44 +++++++++++++++++-------- drivers/dma/dw-edma/dw-hdma-v0-core.c | 61 ++++++++++++++++++++++++++++++++++- drivers/dma/dw-edma/dw-hdma-v0-regs.h | 1 + include/linux/dma/edma.h | 1 + 6 files changed, 130 insertions(+), 19 deletions(-) diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c index b43255f..60a3279 100644 --- a/drivers/dma/dw-edma/dw-edma-core.c +++ b/drivers/dma/dw-edma/dw-edma-core.c @@ -223,8 +223,31 @@ static int dw_edma_device_config(struct dma_chan *dchan, struct dma_slave_config *config) { struct dw_edma_chan *chan = dchan2dw_edma_chan(dchan); + int non_ll = 0; + + if (config->peripheral_config && + config->peripheral_size != sizeof(int)) { + dev_err(dchan->device->dev, + "config param peripheral size mismatch\n"); + return -EINVAL; + } memcpy(&chan->config, config, sizeof(*config)); + + /* + * When there is no valid LLP base address available then the default + * DMA ops will use the non-LL mode. + * Cases where LL mode is enabled and client wants to use the non-LL + * mode then also client can do so via providing the peripheral_config + * param. + */ + if (config->peripheral_config) + non_ll = *(int *)config->peripheral_config; + + chan->non_ll = false; + if (chan->dw->chip->non_ll || (!chan->dw->chip->non_ll && non_ll)) + chan->non_ll = true; + chan->configured = true; return 0; @@ -353,7 +376,7 @@ static void dw_edma_device_issue_pending(struct dma_chan *dchan) struct dw_edma_chan *chan = dchan2dw_edma_chan(xfer->dchan); enum dma_transfer_direction dir = xfer->direction; struct scatterlist *sg = NULL; - struct dw_edma_chunk *chunk; + struct dw_edma_chunk *chunk = NULL; struct dw_edma_burst *burst; struct dw_edma_desc *desc; u64 src_addr, dst_addr; @@ -419,9 +442,11 @@ static void dw_edma_device_issue_pending(struct dma_chan *dchan) if (unlikely(!desc)) goto err_alloc; - chunk = dw_edma_alloc_chunk(desc); - if (unlikely(!chunk)) - goto err_alloc; + if (!chan->non_ll) { + chunk = dw_edma_alloc_chunk(desc); + if (unlikely(!chunk)) + goto err_alloc; + } if (xfer->type == EDMA_XFER_INTERLEAVED) { src_addr = xfer->xfer.il->src_start; @@ -450,7 +475,13 @@ static void dw_edma_device_issue_pending(struct dma_chan *dchan) if (xfer->type == EDMA_XFER_SCATTER_GATHER && !sg) break; - if (chunk->bursts_alloc == chan->ll_max) { + /* + * For non-LL mode, only a single burst can be handled + * in a single chunk unlike LL mode where multiple bursts + * can be configured in a single chunk. + */ + if ((chunk && chunk->bursts_alloc == chan->ll_max) || + chan->non_ll) { chunk = dw_edma_alloc_chunk(desc); if (unlikely(!chunk)) goto err_alloc; diff --git a/drivers/dma/dw-edma/dw-edma-core.h b/drivers/dma/dw-edma/dw-edma-core.h index 71894b9..c8e3d19 100644 --- a/drivers/dma/dw-edma/dw-edma-core.h +++ b/drivers/dma/dw-edma/dw-edma-core.h @@ -86,6 +86,7 @@ struct dw_edma_chan { u8 configured; struct dma_slave_config config; + bool non_ll; }; struct dw_edma_irq { diff --git a/drivers/dma/dw-edma/dw-edma-pcie.c b/drivers/dma/dw-edma/dw-edma-pcie.c index 3d7247c..e7e95df 100644 --- a/drivers/dma/dw-edma/dw-edma-pcie.c +++ b/drivers/dma/dw-edma/dw-edma-pcie.c @@ -269,6 +269,15 @@ static void dw_edma_pcie_get_vsec_dma_data(struct pci_dev *pdev, pdata->devmem_phys_off = off; } +static u64 dw_edma_get_phys_addr(struct pci_dev *pdev, + struct dw_edma_pcie_data *pdata, + enum pci_barno bar) +{ + if (pdev->vendor == PCI_VENDOR_ID_XILINX) + return pdata->devmem_phys_off; + return pci_bus_address(pdev, bar); +} + static int dw_edma_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *pid) { @@ -278,6 +287,7 @@ static int dw_edma_pcie_probe(struct pci_dev *pdev, struct dw_edma_chip *chip; int err, nr_irqs; int i, mask; + bool non_ll = false; vsec_data = kmalloc(sizeof(*vsec_data), GFP_KERNEL); if (!vsec_data) @@ -302,21 +312,24 @@ static int dw_edma_pcie_probe(struct pci_dev *pdev, if (pdev->vendor == PCI_VENDOR_ID_XILINX) { /* * There is no valid address found for the LL memory - * space on the device side. + * space on the device side. In the absence of LL base + * address use the non-LL mode or simple mode supported by + * the HDMA IP. */ if (vsec_data->devmem_phys_off == DW_PCIE_AMD_MDB_INVALID_ADDR) - return -ENOMEM; + non_ll = true; /* * Configure the channel LL and data blocks if number of * channels enabled in VSEC capability are more than the * channels configured in amd_mdb_data. */ - dw_edma_set_chan_region_offset(vsec_data, BAR_2, 0, - DW_PCIE_XILINX_LL_OFF_GAP, - DW_PCIE_XILINX_LL_SIZE, - DW_PCIE_XILINX_DT_OFF_GAP, - DW_PCIE_XILINX_DT_SIZE); + if (!non_ll) + dw_edma_set_chan_region_offset(vsec_data, BAR_2, 0, + DW_PCIE_XILINX_LL_OFF_GAP, + DW_PCIE_XILINX_LL_SIZE, + DW_PCIE_XILINX_DT_OFF_GAP, + DW_PCIE_XILINX_DT_SIZE); } /* Mapping PCI BAR regions */ @@ -364,6 +377,7 @@ static int dw_edma_pcie_probe(struct pci_dev *pdev, chip->mf = vsec_data->mf; chip->nr_irqs = nr_irqs; chip->ops = &dw_edma_pcie_plat_ops; + chip->non_ll = non_ll; chip->ll_wr_cnt = vsec_data->wr_ch_cnt; chip->ll_rd_cnt = vsec_data->rd_ch_cnt; @@ -372,7 +386,7 @@ static int dw_edma_pcie_probe(struct pci_dev *pdev, if (!chip->reg_base) return -ENOMEM; - for (i = 0; i < chip->ll_wr_cnt; i++) { + for (i = 0; i < chip->ll_wr_cnt && !non_ll; i++) { struct dw_edma_region *ll_region = &chip->ll_region_wr[i]; struct dw_edma_region *dt_region = &chip->dt_region_wr[i]; struct dw_edma_block *ll_block = &vsec_data->ll_wr[i]; @@ -383,7 +397,8 @@ static int dw_edma_pcie_probe(struct pci_dev *pdev, return -ENOMEM; ll_region->vaddr.io += ll_block->off; - ll_region->paddr = pci_bus_address(pdev, ll_block->bar); + ll_region->paddr = dw_edma_get_phys_addr(pdev, vsec_data, + ll_block->bar); ll_region->paddr += ll_block->off; ll_region->sz = ll_block->sz; @@ -392,12 +407,13 @@ static int dw_edma_pcie_probe(struct pci_dev *pdev, return -ENOMEM; dt_region->vaddr.io += dt_block->off; - dt_region->paddr = pci_bus_address(pdev, dt_block->bar); + dt_region->paddr = dw_edma_get_phys_addr(pdev, vsec_data, + dt_block->bar); dt_region->paddr += dt_block->off; dt_region->sz = dt_block->sz; } - for (i = 0; i < chip->ll_rd_cnt; i++) { + for (i = 0; i < chip->ll_rd_cnt && !non_ll; i++) { struct dw_edma_region *ll_region = &chip->ll_region_rd[i]; struct dw_edma_region *dt_region = &chip->dt_region_rd[i]; struct dw_edma_block *ll_block = &vsec_data->ll_rd[i]; @@ -408,7 +424,8 @@ static int dw_edma_pcie_probe(struct pci_dev *pdev, return -ENOMEM; ll_region->vaddr.io += ll_block->off; - ll_region->paddr = pci_bus_address(pdev, ll_block->bar); + ll_region->paddr = dw_edma_get_phys_addr(pdev, vsec_data, + ll_block->bar); ll_region->paddr += ll_block->off; ll_region->sz = ll_block->sz; @@ -417,7 +434,8 @@ static int dw_edma_pcie_probe(struct pci_dev *pdev, return -ENOMEM; dt_region->vaddr.io += dt_block->off; - dt_region->paddr = pci_bus_address(pdev, dt_block->bar); + dt_region->paddr = dw_edma_get_phys_addr(pdev, vsec_data, + dt_block->bar); dt_region->paddr += dt_block->off; dt_region->sz = dt_block->sz; } diff --git a/drivers/dma/dw-edma/dw-hdma-v0-core.c b/drivers/dma/dw-edma/dw-hdma-v0-core.c index e3f8db4..ee31c9a 100644 --- a/drivers/dma/dw-edma/dw-hdma-v0-core.c +++ b/drivers/dma/dw-edma/dw-hdma-v0-core.c @@ -225,7 +225,7 @@ static void dw_hdma_v0_sync_ll_data(struct dw_edma_chunk *chunk) readl(chunk->ll_region.vaddr.io); } -static void dw_hdma_v0_core_start(struct dw_edma_chunk *chunk, bool first) +static void dw_hdma_v0_core_ll_start(struct dw_edma_chunk *chunk, bool first) { struct dw_edma_chan *chan = chunk->chan; struct dw_edma *dw = chan->dw; @@ -263,6 +263,65 @@ static void dw_hdma_v0_core_start(struct dw_edma_chunk *chunk, bool first) SET_CH_32(dw, chan->dir, chan->id, doorbell, HDMA_V0_DOORBELL_START); } +static void dw_hdma_v0_core_non_ll_start(struct dw_edma_chunk *chunk) +{ + struct dw_edma_chan *chan = chunk->chan; + struct dw_edma *dw = chan->dw; + struct dw_edma_burst *child; + u32 val; + + list_for_each_entry(child, &chunk->burst->list, list) { + SET_CH_32(dw, chan->dir, chan->id, ch_en, HDMA_V0_CH_EN); + + /* Source address */ + SET_CH_32(dw, chan->dir, chan->id, sar.lsb, + lower_32_bits(child->sar)); + SET_CH_32(dw, chan->dir, chan->id, sar.msb, + upper_32_bits(child->sar)); + + /* Destination address */ + SET_CH_32(dw, chan->dir, chan->id, dar.lsb, + lower_32_bits(child->dar)); + SET_CH_32(dw, chan->dir, chan->id, dar.msb, + upper_32_bits(child->dar)); + + /* Transfer size */ + SET_CH_32(dw, chan->dir, chan->id, transfer_size, child->sz); + + /* Interrupt setup */ + val = GET_CH_32(dw, chan->dir, chan->id, int_setup) | + HDMA_V0_STOP_INT_MASK | + HDMA_V0_ABORT_INT_MASK | + HDMA_V0_LOCAL_STOP_INT_EN | + HDMA_V0_LOCAL_ABORT_INT_EN; + + if (!(dw->chip->flags & DW_EDMA_CHIP_LOCAL)) { + val |= HDMA_V0_REMOTE_STOP_INT_EN | + HDMA_V0_REMOTE_ABORT_INT_EN; + } + + SET_CH_32(dw, chan->dir, chan->id, int_setup, val); + + /* Channel control setup */ + val = GET_CH_32(dw, chan->dir, chan->id, control1); + val &= ~HDMA_V0_LINKLIST_EN; + SET_CH_32(dw, chan->dir, chan->id, control1, val); + + SET_CH_32(dw, chan->dir, chan->id, doorbell, + HDMA_V0_DOORBELL_START); + } +} + +static void dw_hdma_v0_core_start(struct dw_edma_chunk *chunk, bool first) +{ + struct dw_edma_chan *chan = chunk->chan; + + if (!chan->non_ll) + dw_hdma_v0_core_ll_start(chunk, first); + else + dw_hdma_v0_core_non_ll_start(chunk); +} + static void dw_hdma_v0_core_ch_config(struct dw_edma_chan *chan) { struct dw_edma *dw = chan->dw; diff --git a/drivers/dma/dw-edma/dw-hdma-v0-regs.h b/drivers/dma/dw-edma/dw-hdma-v0-regs.h index eab5fd7..7759ba9 100644 --- a/drivers/dma/dw-edma/dw-hdma-v0-regs.h +++ b/drivers/dma/dw-edma/dw-hdma-v0-regs.h @@ -12,6 +12,7 @@ #include #define HDMA_V0_MAX_NR_CH 8 +#define HDMA_V0_CH_EN BIT(0) #define HDMA_V0_LOCAL_ABORT_INT_EN BIT(6) #define HDMA_V0_REMOTE_ABORT_INT_EN BIT(5) #define HDMA_V0_LOCAL_STOP_INT_EN BIT(4) diff --git a/include/linux/dma/edma.h b/include/linux/dma/edma.h index 3080747..78ce31b 100644 --- a/include/linux/dma/edma.h +++ b/include/linux/dma/edma.h @@ -99,6 +99,7 @@ struct dw_edma_chip { enum dw_edma_map_format mf; struct dw_edma *dw; + bool non_ll; }; /* Export to the platform drivers */ -- 1.8.3.1