From patchwork Mon Dec 2 08:54:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vignesh Raghavendra X-Patchwork-Id: 1203023 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="xQVgaKCZ"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 47RJtr469qz9sP3 for ; Mon, 2 Dec 2019 19:58:44 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 37EB4C21DB3; Mon, 2 Dec 2019 08:55:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 30495C21E1A; Mon, 2 Dec 2019 08:55:03 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 792C1C21E0F; Mon, 2 Dec 2019 08:54:28 +0000 (UTC) Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) by lists.denx.de (Postfix) with ESMTPS id AC460C21DB3 for ; Mon, 2 Dec 2019 08:54:25 +0000 (UTC) Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id xB28sNGw048020; Mon, 2 Dec 2019 02:54:23 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1575276863; bh=3Ub8DkaWpTjt89cPkzdUP23AxxdSFuS0RH+aI3dVVXs=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=xQVgaKCZ3ARqB+v9mKNBMnP68axMopUqe9Vyy3TKx0FAKASsGFFTte8GSu0C/Xd85 s/6Aoacmz8xTa6OJuQsr9VjnpRPYsw+jHg4cVvFu46757+Qh87b1QgWrUj22NQR/i/ zGI6Jo5lN5W+lwxT07cfkj/Xe9o6IPiTL4J/ztLI= Received: from DLEE104.ent.ti.com (dlee104.ent.ti.com [157.170.170.34]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id xB28sNSb008183 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 2 Dec 2019 02:54:23 -0600 Received: from DLEE115.ent.ti.com (157.170.170.26) by DLEE104.ent.ti.com (157.170.170.34) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1847.3; Mon, 2 Dec 2019 02:54:23 -0600 Received: from lelv0326.itg.ti.com (10.180.67.84) by DLEE115.ent.ti.com (157.170.170.26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1847.3 via Frontend Transport; Mon, 2 Dec 2019 02:54:22 -0600 Received: from a0132425.dhcp.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by lelv0326.itg.ti.com (8.15.2/8.15.2) with ESMTP id xB28sGZ3098983; Mon, 2 Dec 2019 02:54:21 -0600 From: Vignesh Raghavendra To: Tom Rini Date: Mon, 2 Dec 2019 14:24:36 +0530 Message-ID: <20191202085444.29848-3-vigneshr@ti.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191202085444.29848-1-vigneshr@ti.com> References: <20191202085444.29848-1-vigneshr@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: u-boot@lists.denx.de Subject: [U-Boot] [PATCH RESEND v2 02/10] dma: ti: k3-udma: Query DMA channels allocated from Resource Manager X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" On K3 SoCs, DMA channels are shared across multiple entities, therefore U-Boot DMA driver needs to query resource range from centralised resource management controller i.e SystemFirmware and use DMA channels allocated for A72 host. Add support for the same. Signed-off-by: Vignesh Raghavendra --- v2: Address comments on v1 from Grygorii Squash patch 5 (of v1) into this patch drivers/dma/ti/k3-udma-hwdef.h | 19 +++ drivers/dma/ti/k3-udma.c | 274 +++++++++++++++++++++++---------- 2 files changed, 214 insertions(+), 79 deletions(-) diff --git a/drivers/dma/ti/k3-udma-hwdef.h b/drivers/dma/ti/k3-udma-hwdef.h index c88399a815ea..228a44cb73cf 100644 --- a/drivers/dma/ti/k3-udma-hwdef.h +++ b/drivers/dma/ti/k3-udma-hwdef.h @@ -181,4 +181,23 @@ #define PDMA_STATIC_TR_Z(x) \ (((x) << PDMA_STATIC_TR_Z_SHIFT) & PDMA_STATIC_TR_Z_MASK) +enum udma_rm_range { + RM_RANGE_TCHAN = 0, + RM_RANGE_RCHAN, + RM_RANGE_RFLOW, + RM_RANGE_LAST, +}; + +struct udma_tisci_rm { + const struct ti_sci_handle *tisci; + const struct ti_sci_rm_udmap_ops *tisci_udmap_ops; + u32 tisci_dev_id; + + /* tisci information for PSI-L thread pairing/unpairing */ + const struct ti_sci_rm_psil_ops *tisci_psil_ops; + u32 tisci_navss_dev_id; + + struct ti_sci_resource *rm_ranges[RM_RANGE_LAST]; +}; + #endif /* K3_NAVSS_UDMA_HWDEF_H_ */ diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c index a5fc7809bc41..2f82ab0955a4 100644 --- a/drivers/dma/ti/k3-udma.c +++ b/drivers/dma/ti/k3-udma.c @@ -11,12 +11,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -30,6 +32,8 @@ #define RINGACC_RING_USE_PROXY (1) #endif +#define K3_UDMA_MAX_RFLOWS 1024 + struct udma_chan; enum udma_mmr { @@ -64,9 +68,10 @@ struct udma_rflow { }; struct udma_dev { - struct device *dev; + struct udevice *dev; void __iomem *mmrs[MMR_LAST]; + struct udma_tisci_rm tisci_rm; struct k3_nav_ringacc *ringacc; u32 features; @@ -78,6 +83,7 @@ struct udma_dev { unsigned long *tchan_map; unsigned long *rchan_map; unsigned long *rflow_map; + unsigned long *rflow_map_reserved; struct udma_tchan *tchans; struct udma_rchan *rchans; @@ -87,11 +93,6 @@ struct udma_dev { u32 psil_base; u32 ch_count; - const struct ti_sci_handle *tisci; - const struct ti_sci_rm_udmap_ops *tisci_udmap_ops; - const struct ti_sci_rm_psil_ops *tisci_psil_ops; - u32 tisci_dev_id; - u32 tisci_navss_dev_id; bool is_coherent; }; @@ -200,19 +201,25 @@ static inline void udma_rchanrt_write(struct udma_rchan *rchan, static inline int udma_navss_psil_pair(struct udma_dev *ud, u32 src_thread, u32 dst_thread) { + struct udma_tisci_rm *tisci_rm = &ud->tisci_rm; + dst_thread |= UDMA_PSIL_DST_THREAD_ID_OFFSET; - return ud->tisci_psil_ops->pair(ud->tisci, - ud->tisci_navss_dev_id, - src_thread, dst_thread); + + return tisci_rm->tisci_psil_ops->pair(tisci_rm->tisci, + tisci_rm->tisci_navss_dev_id, + src_thread, dst_thread); } static inline int udma_navss_psil_unpair(struct udma_dev *ud, u32 src_thread, u32 dst_thread) { + struct udma_tisci_rm *tisci_rm = &ud->tisci_rm; + dst_thread |= UDMA_PSIL_DST_THREAD_ID_OFFSET; - return ud->tisci_psil_ops->unpair(ud->tisci, - ud->tisci_navss_dev_id, - src_thread, dst_thread); + + return tisci_rm->tisci_psil_ops->unpair(tisci_rm->tisci, + tisci_rm->tisci_navss_dev_id, + src_thread, dst_thread); } static inline char *udma_get_dir_text(enum dma_direction dir) @@ -535,6 +542,28 @@ static void udma_poll_completion(struct udma_chan *uc, dma_addr_t *paddr) } } +static struct udma_rflow *__udma_reserve_rflow(struct udma_dev *ud, int id) +{ + DECLARE_BITMAP(tmp, K3_UDMA_MAX_RFLOWS); + + if (id >= 0) { + if (test_bit(id, ud->rflow_map)) { + dev_err(ud->dev, "rflow%d is in use\n", id); + return ERR_PTR(-ENOENT); + } + } else { + bitmap_or(tmp, ud->rflow_map, ud->rflow_map_reserved, + ud->rflow_cnt); + + id = find_next_zero_bit(tmp, ud->rflow_cnt, ud->rchan_cnt); + if (id >= ud->rflow_cnt) + return ERR_PTR(-ENOENT); + } + + __set_bit(id, ud->rflow_map); + return &ud->rflows[id]; +} + #define UDMA_RESERVE_RESOURCE(res) \ static struct udma_##res *__udma_reserve_##res(struct udma_dev *ud, \ int id) \ @@ -557,7 +586,6 @@ static struct udma_##res *__udma_reserve_##res(struct udma_dev *ud, \ UDMA_RESERVE_RESOURCE(tchan); UDMA_RESERVE_RESOURCE(rchan); -UDMA_RESERVE_RESOURCE(rflow); static int udma_get_tchan(struct udma_chan *uc) { @@ -843,6 +871,7 @@ static int udma_alloc_tchan_sci_req(struct udma_chan *uc) struct udma_dev *ud = uc->ud; int tc_ring = k3_nav_ringacc_get_ring_id(uc->tchan->tc_ring); struct ti_sci_msg_rm_udmap_tx_ch_cfg req; + struct udma_tisci_rm *tisci_rm = &ud->tisci_rm; u32 mode; int ret; @@ -854,7 +883,7 @@ static int udma_alloc_tchan_sci_req(struct udma_chan *uc) req.valid_params = TI_SCI_MSG_VALUE_RM_UDMAP_CH_CHAN_TYPE_VALID | TI_SCI_MSG_VALUE_RM_UDMAP_CH_FETCH_SIZE_VALID | TI_SCI_MSG_VALUE_RM_UDMAP_CH_CQ_QNUM_VALID; - req.nav_id = ud->tisci_dev_id; + req.nav_id = tisci_rm->tisci_dev_id; req.index = uc->tchan->id; req.tx_chan_type = mode; if (uc->dir == DMA_MEM_TO_MEM) @@ -865,7 +894,7 @@ static int udma_alloc_tchan_sci_req(struct udma_chan *uc) 0) >> 2; req.txcq_qnum = tc_ring; - ret = ud->tisci_udmap_ops->tx_ch_cfg(ud->tisci, &req); + ret = tisci_rm->tisci_udmap_ops->tx_ch_cfg(tisci_rm->tisci, &req); if (ret) dev_err(ud->dev, "tisci tx alloc failed %d\n", ret); @@ -880,6 +909,7 @@ static int udma_alloc_rchan_sci_req(struct udma_chan *uc) int tc_ring = k3_nav_ringacc_get_ring_id(uc->tchan->tc_ring); struct ti_sci_msg_rm_udmap_rx_ch_cfg req = { 0 }; struct ti_sci_msg_rm_udmap_flow_cfg flow_req = { 0 }; + struct udma_tisci_rm *tisci_rm = &ud->tisci_rm; u32 mode; int ret; @@ -891,7 +921,7 @@ static int udma_alloc_rchan_sci_req(struct udma_chan *uc) req.valid_params = TI_SCI_MSG_VALUE_RM_UDMAP_CH_FETCH_SIZE_VALID | TI_SCI_MSG_VALUE_RM_UDMAP_CH_CQ_QNUM_VALID | TI_SCI_MSG_VALUE_RM_UDMAP_CH_CHAN_TYPE_VALID; - req.nav_id = ud->tisci_dev_id; + req.nav_id = tisci_rm->tisci_dev_id; req.index = uc->rchan->id; req.rx_chan_type = mode; if (uc->dir == DMA_MEM_TO_MEM) { @@ -911,7 +941,7 @@ static int udma_alloc_rchan_sci_req(struct udma_chan *uc) TI_SCI_MSG_VALUE_RM_UDMAP_CH_RX_FLOWID_CNT_VALID; } - ret = ud->tisci_udmap_ops->rx_ch_cfg(ud->tisci, &req); + ret = tisci_rm->tisci_udmap_ops->rx_ch_cfg(tisci_rm->tisci, &req); if (ret) { dev_err(ud->dev, "tisci rx %u cfg failed %d\n", uc->rchan->id, ret); @@ -936,7 +966,7 @@ static int udma_alloc_rchan_sci_req(struct udma_chan *uc) TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_FDQ3_QNUM_VALID | TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_PS_LOCATION_VALID; - flow_req.nav_id = ud->tisci_dev_id; + flow_req.nav_id = tisci_rm->tisci_dev_id; flow_req.flow_index = uc->rflow->id; if (uc->needs_epib) @@ -962,7 +992,8 @@ static int udma_alloc_rchan_sci_req(struct udma_chan *uc) flow_req.rx_fdq3_qnum = fd_ring; flow_req.rx_ps_location = 0; - ret = ud->tisci_udmap_ops->rx_flow_cfg(ud->tisci, &flow_req); + ret = tisci_rm->tisci_udmap_ops->rx_flow_cfg(tisci_rm->tisci, + &flow_req); if (ret) dev_err(ud->dev, "tisci rx %u flow %u cfg failed %d\n", uc->rchan->id, uc->rflow->id, ret); @@ -1103,16 +1134,134 @@ static int udma_get_mmrs(struct udevice *dev) return 0; } -#define UDMA_MAX_CHANNELS 192 +static int udma_setup_resources(struct udma_dev *ud) +{ + struct udevice *dev = ud->dev; + int ch_count, i; + u32 cap2, cap3; + struct ti_sci_resource_desc *rm_desc; + struct ti_sci_resource *rm_res; + struct udma_tisci_rm *tisci_rm = &ud->tisci_rm; + static const char * const range_names[] = { "ti,sci-rm-range-tchan", + "ti,sci-rm-range-rchan", + "ti,sci-rm-range-rflow" }; + cap2 = udma_read(ud->mmrs[MMR_GCFG], 0x28); + cap3 = udma_read(ud->mmrs[MMR_GCFG], 0x2c); + + ud->rflow_cnt = cap3 & 0x3fff; + ud->tchan_cnt = cap2 & 0x1ff; + ud->echan_cnt = (cap2 >> 9) & 0x1ff; + ud->rchan_cnt = (cap2 >> 18) & 0x1ff; + ch_count = ud->tchan_cnt + ud->rchan_cnt; + + ud->tchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->tchan_cnt), + sizeof(unsigned long), GFP_KERNEL); + ud->tchans = devm_kcalloc(dev, ud->tchan_cnt, sizeof(*ud->tchans), + GFP_KERNEL); + ud->rchan_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->rchan_cnt), + sizeof(unsigned long), GFP_KERNEL); + ud->rchans = devm_kcalloc(dev, ud->rchan_cnt, sizeof(*ud->rchans), + GFP_KERNEL); + ud->rflow_map = devm_kmalloc_array(dev, BITS_TO_LONGS(ud->rflow_cnt), + sizeof(unsigned long), GFP_KERNEL); + ud->rflow_map_reserved = devm_kcalloc(dev, BITS_TO_LONGS(ud->rflow_cnt), + sizeof(unsigned long), + GFP_KERNEL); + ud->rflows = devm_kcalloc(dev, ud->rflow_cnt, sizeof(*ud->rflows), + GFP_KERNEL); + + if (!ud->tchan_map || !ud->rchan_map || !ud->rflow_map || + !ud->rflow_map_reserved || !ud->tchans || !ud->rchans || + !ud->rflows) + return -ENOMEM; + + /* + * RX flows with the same Ids as RX channels are reserved to be used + * as default flows if remote HW can't generate flow_ids. Those + * RX flows can be requested only explicitly by id. + */ + bitmap_set(ud->rflow_map_reserved, 0, ud->rchan_cnt); + + /* Get resource ranges from tisci */ + for (i = 0; i < RM_RANGE_LAST; i++) + tisci_rm->rm_ranges[i] = + devm_ti_sci_get_of_resource(tisci_rm->tisci, dev, + tisci_rm->tisci_dev_id, + (char *)range_names[i]); + + /* tchan ranges */ + rm_res = tisci_rm->rm_ranges[RM_RANGE_TCHAN]; + if (IS_ERR(rm_res)) { + bitmap_zero(ud->tchan_map, ud->tchan_cnt); + } else { + bitmap_fill(ud->tchan_map, ud->tchan_cnt); + for (i = 0; i < rm_res->sets; i++) { + rm_desc = &rm_res->desc[i]; + bitmap_clear(ud->tchan_map, rm_desc->start, + rm_desc->num); + } + } + + /* rchan and matching default flow ranges */ + rm_res = tisci_rm->rm_ranges[RM_RANGE_RCHAN]; + if (IS_ERR(rm_res)) { + bitmap_zero(ud->rchan_map, ud->rchan_cnt); + bitmap_zero(ud->rflow_map, ud->rchan_cnt); + } else { + bitmap_fill(ud->rchan_map, ud->rchan_cnt); + bitmap_fill(ud->rflow_map, ud->rchan_cnt); + for (i = 0; i < rm_res->sets; i++) { + rm_desc = &rm_res->desc[i]; + bitmap_clear(ud->rchan_map, rm_desc->start, + rm_desc->num); + bitmap_clear(ud->rflow_map, rm_desc->start, + rm_desc->num); + } + } + + /* GP rflow ranges */ + rm_res = tisci_rm->rm_ranges[RM_RANGE_RFLOW]; + if (IS_ERR(rm_res)) { + bitmap_clear(ud->rflow_map, ud->rchan_cnt, + ud->rflow_cnt - ud->rchan_cnt); + } else { + bitmap_set(ud->rflow_map, ud->rchan_cnt, + ud->rflow_cnt - ud->rchan_cnt); + for (i = 0; i < rm_res->sets; i++) { + rm_desc = &rm_res->desc[i]; + bitmap_clear(ud->rflow_map, rm_desc->start, + rm_desc->num); + } + } + + ch_count -= bitmap_weight(ud->tchan_map, ud->tchan_cnt); + ch_count -= bitmap_weight(ud->rchan_map, ud->rchan_cnt); + if (!ch_count) + return -ENODEV; + + ud->channels = devm_kcalloc(dev, ch_count, sizeof(*ud->channels), + GFP_KERNEL); + if (!ud->channels) + return -ENOMEM; + + dev_info(dev, + "Channels: %d (tchan: %u, echan: %u, rchan: %u, rflow: %u)\n", + ch_count, ud->tchan_cnt, ud->echan_cnt, ud->rchan_cnt, + ud->rflow_cnt); + + return ch_count; +} static int udma_probe(struct udevice *dev) { struct dma_dev_priv *uc_priv = dev_get_uclass_priv(dev); struct udma_dev *ud = dev_get_priv(dev); int i, ret; - u32 cap2, cap3; struct udevice *tmp; struct udevice *tisci_dev = NULL; + struct udma_tisci_rm *tisci_rm = &ud->tisci_rm; + ofnode navss_ofnode = ofnode_get_parent(dev_ofnode(dev)); + ret = udma_get_mmrs(dev); if (ret) @@ -1131,79 +1280,46 @@ static int udma_probe(struct udevice *dev) return -EINVAL; } - ret = uclass_get_device_by_name(UCLASS_FIRMWARE, "dmsc", &tisci_dev); + ret = uclass_get_device_by_phandle(UCLASS_FIRMWARE, dev, + "ti,sci", &tisci_dev); if (ret) { - debug("TISCI RA RM get failed (%d)\n", ret); - ud->tisci = NULL; - return 0; + debug("Failed to get TISCI phandle (%d)\n", ret); + tisci_rm->tisci = NULL; + return -EINVAL; } - ud->tisci = (struct ti_sci_handle *) - (ti_sci_get_handle_from_sysfw(tisci_dev)); + tisci_rm->tisci = (struct ti_sci_handle *) + (ti_sci_get_handle_from_sysfw(tisci_dev)); - ret = dev_read_u32_default(dev, "ti,sci", 0); - if (!ret) { - dev_err(dev, "TISCI RA RM disabled\n"); - ud->tisci = NULL; + tisci_rm->tisci_dev_id = -1; + ret = dev_read_u32(dev, "ti,sci-dev-id", &tisci_rm->tisci_dev_id); + if (ret) { + dev_err(dev, "ti,sci-dev-id read failure %d\n", ret); + return ret; } - if (ud->tisci) { - ofnode navss_ofnode = ofnode_get_parent(dev_ofnode(dev)); - - ud->tisci_dev_id = -1; - ret = dev_read_u32(dev, "ti,sci-dev-id", &ud->tisci_dev_id); - if (ret) { - dev_err(dev, "ti,sci-dev-id read failure %d\n", ret); - return ret; - } - - ud->tisci_navss_dev_id = -1; - ret = ofnode_read_u32(navss_ofnode, "ti,sci-dev-id", - &ud->tisci_navss_dev_id); - if (ret) { - dev_err(dev, "navss sci-dev-id read failure %d\n", ret); - return ret; - } - - ud->tisci_udmap_ops = &ud->tisci->ops.rm_udmap_ops; - ud->tisci_psil_ops = &ud->tisci->ops.rm_psil_ops; + tisci_rm->tisci_navss_dev_id = -1; + ret = ofnode_read_u32(navss_ofnode, "ti,sci-dev-id", + &tisci_rm->tisci_navss_dev_id); + if (ret) { + dev_err(dev, "navss sci-dev-id read failure %d\n", ret); + return ret; } ud->is_coherent = dev_read_bool(dev, "dma-coherent"); + tisci_rm->tisci_udmap_ops = &tisci_rm->tisci->ops.rm_udmap_ops; + tisci_rm->tisci_psil_ops = &tisci_rm->tisci->ops.rm_psil_ops; - cap2 = udma_read(ud->mmrs[MMR_GCFG], 0x28); - cap3 = udma_read(ud->mmrs[MMR_GCFG], 0x2c); - - ud->rflow_cnt = cap3 & 0x3fff; - ud->tchan_cnt = cap2 & 0x1ff; - ud->echan_cnt = (cap2 >> 9) & 0x1ff; - ud->rchan_cnt = (cap2 >> 18) & 0x1ff; - ud->ch_count = ud->tchan_cnt + ud->rchan_cnt; + ud->dev = dev; + ud->ch_count = udma_setup_resources(ud); + if (ud->ch_count <= 0) + return ud->ch_count; dev_info(dev, "Number of channels: %u (tchan: %u, echan: %u, rchan: %u dev-id %u)\n", ud->ch_count, ud->tchan_cnt, ud->echan_cnt, ud->rchan_cnt, - ud->tisci_dev_id); + tisci_rm->tisci_dev_id); dev_info(dev, "Number of rflows: %u\n", ud->rflow_cnt); - ud->channels = devm_kcalloc(dev, ud->ch_count, sizeof(*ud->channels), - GFP_KERNEL); - ud->tchan_map = devm_kcalloc(dev, BITS_TO_LONGS(ud->tchan_cnt), - sizeof(unsigned long), GFP_KERNEL); - ud->tchans = devm_kcalloc(dev, ud->tchan_cnt, - sizeof(*ud->tchans), GFP_KERNEL); - ud->rchan_map = devm_kcalloc(dev, BITS_TO_LONGS(ud->rchan_cnt), - sizeof(unsigned long), GFP_KERNEL); - ud->rchans = devm_kcalloc(dev, ud->rchan_cnt, - sizeof(*ud->rchans), GFP_KERNEL); - ud->rflow_map = devm_kcalloc(dev, BITS_TO_LONGS(ud->rflow_cnt), - sizeof(unsigned long), GFP_KERNEL); - ud->rflows = devm_kcalloc(dev, ud->rflow_cnt, - sizeof(*ud->rflows), GFP_KERNEL); - - if (!ud->channels || !ud->tchan_map || !ud->rchan_map || - !ud->rflow_map || !ud->tchans || !ud->rchans || !ud->rflows) - return -ENOMEM; - for (i = 0; i < ud->tchan_cnt; i++) { struct udma_tchan *tchan = &ud->tchans[i];