* [PATCH v4 1/2] dt: bindings: add new DT entry for ath11k PCI device support @ 2021-11-21 14:22 Anilkumar Kolli 2021-11-21 14:22 ` [PATCH v4 2/2] ath11k: Use reserved host DDR addresses from DT for PCI devices Anilkumar Kolli 0 siblings, 1 reply; 6+ messages in thread From: Anilkumar Kolli @ 2021-11-21 14:22 UTC (permalink / raw) To: ath11k; +Cc: linux-wireless, devicetree, robh, Anilkumar Kolli Ath11k driver supports PCI devices such as QCN9074/QCA6390. Ath11k firmware uses host DDR memory, DT entry is used to reserve host DDR memory regions, send these memory base addresses using DT entries. Signed-off-by: Anilkumar Kolli <akolli@codeaurora.org> --- V4: - Fix dt_binding_check warnings (Rob) V2: - Use reserved-memory (Rob) .../bindings/net/wireless/qcom,ath11k.yaml | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Documentation/devicetree/bindings/net/wireless/qcom,ath11k.yaml b/Documentation/devicetree/bindings/net/wireless/qcom,ath11k.yaml index 85c2f699d602..cdf7b873b419 100644 --- a/Documentation/devicetree/bindings/net/wireless/qcom,ath11k.yaml +++ b/Documentation/devicetree/bindings/net/wireless/qcom,ath11k.yaml @@ -150,6 +150,12 @@ properties: string to uniquely identify variant of the calibration data in the board-2.bin for designs with colliding bus and device specific ids + memory-region: + maxItems: 1 + description: + phandle to a node describing reserved memory (System RAM memory) + used by ath11k firmware (see bindings/reserved-memory/reserved-memory.txt) + required: - compatible - reg @@ -279,3 +285,27 @@ examples: "tcl2host-status-ring"; qcom,rproc = <&q6v5_wcss>; }; + + - | + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + + qcn9074_0: qcn9074_0@51100000 { + no-map; + reg = <0x0 0x51100000 0x0 0x03500000>; + }; + }; + + pci { + pcie0 { + #size-cells = <2>; + #address-cells = <3>; + + wifi_0: wifi@0 { + reg = <0 0 0 0 0>; + memory-region = <&qcn9074_0>; + }; + }; + }; -- 2.7.4 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v4 2/2] ath11k: Use reserved host DDR addresses from DT for PCI devices 2021-11-21 14:22 [PATCH v4 1/2] dt: bindings: add new DT entry for ath11k PCI device support Anilkumar Kolli @ 2021-11-21 14:22 ` Anilkumar Kolli 2021-11-21 14:45 ` Sven Eckelmann 0 siblings, 1 reply; 6+ messages in thread From: Anilkumar Kolli @ 2021-11-21 14:22 UTC (permalink / raw) To: ath11k; +Cc: linux-wireless, devicetree, robh, Anilkumar Kolli Host DDR memory (contiguous 45 MB in mode-0 or 15 MB in mode-2) is reserved through DT entries for firmware usage. Send the base address from DT entries. If DT entry is available, PCI device will work with fixed_mem_region else host allocates multiple segments. IPQ8074 on HK10 board supports multiple PCI devices. IPQ8074 + QCN9074 is tested with this patch. Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.4.0.1-01838-QCAHKSWPL_SILICONZ-1 Signed-off-by: Anilkumar Kolli <akolli@codeaurora.org> --- V4: - Update code review comments to handle return (Kalle) V3: - remove type cast and use of_property_read_u32_array() (Kalle) V2: - Use of_ API to read from dt node (Rob) drivers/net/wireless/ath/ath11k/core.h | 1 + drivers/net/wireless/ath/ath11k/mhi.c | 34 ++++++++++++++- drivers/net/wireless/ath/ath11k/pci.c | 11 ++++- drivers/net/wireless/ath/ath11k/qmi.c | 77 +++++++++++++++++++++++++++++----- drivers/net/wireless/ath/ath11k/qmi.h | 1 + 5 files changed, 111 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index 2f1e10b7cc17..8492ca7efb92 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -194,6 +194,7 @@ enum ath11k_dev_flags { ATH11K_FLAG_REGISTERED, ATH11K_FLAG_QMI_FAIL, ATH11K_FLAG_HTC_SUSPEND_COMPLETE, + ATH11K_FLAG_FIXED_MEM_RGN, }; enum ath11k_monitor_flags { diff --git a/drivers/net/wireless/ath/ath11k/mhi.c b/drivers/net/wireless/ath/ath11k/mhi.c index 26c7ae242db6..16d0934b1836 100644 --- a/drivers/net/wireless/ath/ath11k/mhi.c +++ b/drivers/net/wireless/ath/ath11k/mhi.c @@ -3,6 +3,7 @@ #include <linux/msi.h> #include <linux/pci.h> +#include <linux/of.h> #include "core.h" #include "debug.h" @@ -311,6 +312,28 @@ static void ath11k_mhi_op_write_reg(struct mhi_controller *mhi_cntrl, writel(val, addr); } +static int ath11k_mhi_read_addr_from_dt(struct mhi_controller *mhi_ctrl) +{ + struct device_node *np; + dma_addr_t start; + u32 reg[4]; + int ret; + + np = of_find_node_by_type(NULL, "memory"); + if (!np) + return -ENOENT; + + ret = of_property_read_u32_array(np, "reg", reg, 4); + if (ret) + return ret; + + start = reg[0] + reg[1]; + mhi_ctrl->iova_start = start + 0x1000000; + mhi_ctrl->iova_stop = start + reg[2] + reg[3]; + + return 0; +} + int ath11k_mhi_register(struct ath11k_pci *ab_pci) { struct ath11k_base *ab = ab_pci->ab; @@ -339,8 +362,15 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci) return ret; } - mhi_ctrl->iova_start = 0; - mhi_ctrl->iova_stop = 0xffffffff; + if ((test_bit(ATH11K_FLAG_FIXED_MEM_RGN, &ab->dev_flags))) { + ret = ath11k_mhi_read_addr_from_dt(mhi_ctrl); + if (ret < 0) + return ret; + } else { + mhi_ctrl->iova_start = 0; + mhi_ctrl->iova_stop = 0xFFFFFFFF; + } + mhi_ctrl->sbl_size = SZ_512K; mhi_ctrl->seg_len = SZ_512K; mhi_ctrl->fbc_download = true; diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c index 3d353e7c9d5c..e12d9753f113 100644 --- a/drivers/net/wireless/ath/ath11k/pci.c +++ b/drivers/net/wireless/ath/ath11k/pci.c @@ -6,6 +6,7 @@ #include <linux/module.h> #include <linux/msi.h> #include <linux/pci.h> +#include <linux/of.h> #include "pci.h" #include "core.h" @@ -1225,7 +1226,7 @@ static int ath11k_pci_probe(struct pci_dev *pdev, { struct ath11k_base *ab; struct ath11k_pci *ab_pci; - u32 soc_hw_version_major, soc_hw_version_minor; + u32 soc_hw_version_major, soc_hw_version_minor, addr; int ret; ab = ath11k_core_alloc(&pdev->dev, sizeof(*ab_pci), ATH11K_BUS_PCI, @@ -1245,6 +1246,14 @@ static int ath11k_pci_probe(struct pci_dev *pdev, pci_set_drvdata(pdev, ab); spin_lock_init(&ab_pci->window_lock); + /* Set fixed_mem_region to true for platforms support reserved memory + * from DT. If memory is reserved from DT for FW, ath11k driver need not + * allocate memory. + */ + ret = of_property_read_u32(ab->dev->of_node, "memory-region", &addr); + if (!ret) + set_bit(ATH11K_FLAG_FIXED_MEM_RGN, &ab->dev_flags); + ret = ath11k_pci_claim(ab_pci, pdev); if (ret) { ath11k_err(ab, "failed to claim device: %d\n", ret); diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c index fa73118de6db..2dc6368d6577 100644 --- a/drivers/net/wireless/ath/ath11k/qmi.c +++ b/drivers/net/wireless/ath/ath11k/qmi.c @@ -1749,7 +1749,9 @@ static int ath11k_qmi_respond_fw_mem_request(struct ath11k_base *ab) * failure to FW and FW will then request mulitple blocks of small * chunk size memory. */ - if (!ab->bus_params.fixed_mem_region && ab->qmi.target_mem_delayed) { + if (!(ab->bus_params.fixed_mem_region || + test_bit(ATH11K_FLAG_FIXED_MEM_RGN, &ab->dev_flags)) && + ab->qmi.target_mem_delayed) { delayed = true; ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi delays mem_request %d\n", ab->qmi.mem_seg_count); @@ -1815,10 +1817,12 @@ static void ath11k_qmi_free_target_mem_chunk(struct ath11k_base *ab) { int i; - if (ab->bus_params.fixed_mem_region) - return; - for (i = 0; i < ab->qmi.mem_seg_count; i++) { + if ((ab->bus_params.fixed_mem_region || + test_bit(ATH11K_FLAG_FIXED_MEM_RGN, &ab->dev_flags)) && + ab->qmi.target_mem[i].iaddr) + iounmap(ab->qmi.target_mem[i].iaddr); + if (!ab->qmi.target_mem[i].vaddr) continue; @@ -1866,10 +1870,56 @@ static int ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base *ab) static int ath11k_qmi_assign_target_mem_chunk(struct ath11k_base *ab) { - int i, idx; + struct device *dev = ab->dev; + struct device_node *hremote_node = NULL; + phandle hremote_phandle; + dma_addr_t start; + u32 reg[4], size, host_ddr_sz; + int i, idx, ret; for (i = 0, idx = 0; i < ab->qmi.mem_seg_count; i++) { switch (ab->qmi.target_mem[i].type) { + case HOST_DDR_REGION_TYPE: + ret = of_property_read_u32(dev->of_node, "memory-region", + &hremote_phandle); + if (ret) { + ath11k_dbg(ab, ATH11K_DBG_QMI, + "qmi fail to get hremote phandle\n"); + return ret; + } + + hremote_node = of_find_node_by_phandle(hremote_phandle); + if (!hremote_node) { + ath11k_dbg(ab, ATH11K_DBG_QMI, + "qmi fail to get hremote_node\n"); + return ret; + } + + ret = of_property_read_u32_array(hremote_node, "reg", reg, 4); + if (ret) { + ath11k_dbg(ab, ATH11K_DBG_QMI, + "qmi fail to get reg from hremote\n"); + return ret; + } + + start = reg[0] + reg[1]; + size = reg[2] + reg[3]; + + if (size < ab->qmi.target_mem[i].size) { + ath11k_dbg(ab, ATH11K_DBG_QMI, + "qmi fail to assign memory of sz %u\n", size); + return -EINVAL; + } + + ab->qmi.target_mem[idx].paddr = start; + ab->qmi.target_mem[idx].iaddr = + ioremap(ab->qmi.target_mem[idx].paddr, + ab->qmi.target_mem[i].size); + ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size; + host_ddr_sz = ab->qmi.target_mem[i].size; + ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type; + idx++; + break; case BDF_MEM_REGION_TYPE: ab->qmi.target_mem[idx].paddr = ab->hw_params.bdf_addr; ab->qmi.target_mem[idx].vaddr = NULL; @@ -1884,10 +1934,16 @@ static int ath11k_qmi_assign_target_mem_chunk(struct ath11k_base *ab) } if (ath11k_cold_boot_cal && ab->hw_params.cold_boot_calib) { - ab->qmi.target_mem[idx].paddr = - ATH11K_QMI_CALDB_ADDRESS; - ab->qmi.target_mem[idx].vaddr = - (void *)ATH11K_QMI_CALDB_ADDRESS; + if (hremote_node) { + ab->qmi.target_mem[idx].paddr = + start + host_ddr_sz; + ab->qmi.target_mem[idx].iaddr = + ioremap(ab->qmi.target_mem[idx].paddr, + ab->qmi.target_mem[i].size); + } else { + ab->qmi.target_mem[idx].paddr = + ATH11K_QMI_CALDB_ADDRESS; + } } else { ab->qmi.target_mem[idx].paddr = 0; ab->qmi.target_mem[idx].vaddr = NULL; @@ -2614,7 +2670,8 @@ static void ath11k_qmi_msg_mem_request_cb(struct qmi_handle *qmi_hdl, msg->mem_seg[i].type, msg->mem_seg[i].size); } - if (ab->bus_params.fixed_mem_region) { + if (ab->bus_params.fixed_mem_region || + test_bit(ATH11K_FLAG_FIXED_MEM_RGN, &ab->dev_flags)) { ret = ath11k_qmi_assign_target_mem_chunk(ab); if (ret) { ath11k_warn(ab, "failed to assign qmi target memory: %d\n", diff --git a/drivers/net/wireless/ath/ath11k/qmi.h b/drivers/net/wireless/ath/ath11k/qmi.h index 3bb0f9ef7996..f8d45b7dc821 100644 --- a/drivers/net/wireless/ath/ath11k/qmi.h +++ b/drivers/net/wireless/ath/ath11k/qmi.h @@ -95,6 +95,7 @@ struct target_mem_chunk { u32 type; dma_addr_t paddr; u32 *vaddr; + void __iomem *iaddr; }; struct target_info { -- 2.7.4 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v4 2/2] ath11k: Use reserved host DDR addresses from DT for PCI devices 2021-11-21 14:22 ` [PATCH v4 2/2] ath11k: Use reserved host DDR addresses from DT for PCI devices Anilkumar Kolli @ 2021-11-21 14:45 ` Sven Eckelmann 2021-11-22 6:12 ` Anilkumar Kolli 0 siblings, 1 reply; 6+ messages in thread From: Sven Eckelmann @ 2021-11-21 14:45 UTC (permalink / raw) To: ath11k, Manivannan Sadhasivam Cc: linux-wireless, devicetree, robh, Anilkumar Kolli On Sunday, 21 November 2021 15:22:01 CET Anilkumar Kolli wrote: [...] > +static int ath11k_mhi_read_addr_from_dt(struct mhi_controller *mhi_ctrl) > +{ > + struct device_node *np; > + dma_addr_t start; > + u32 reg[4]; > + int ret; > + > + np = of_find_node_by_type(NULL, "memory"); > + if (!np) > + return -ENOENT; > + > + ret = of_property_read_u32_array(np, "reg", reg, 4); > + if (ret) > + return ret; > + > + start = reg[0] + reg[1]; > + mhi_ctrl->iova_start = start + 0x1000000; > + mhi_ctrl->iova_stop = start + reg[2] + reg[3]; > + > + return 0; > +} > + [...] > + ret = of_property_read_u32(dev->of_node, "memory-region", > + &hremote_phandle); > + if (ret) { > + ath11k_dbg(ab, ATH11K_DBG_QMI, > + "qmi fail to get hremote phandle\n"); > + return ret; > + } > + > + hremote_node = of_find_node_by_phandle(hremote_phandle); > + if (!hremote_node) { > + ath11k_dbg(ab, ATH11K_DBG_QMI, > + "qmi fail to get hremote_node\n"); > + return ret; > + } > + > + ret = of_property_read_u32_array(hremote_node, "reg", reg, 4); > + if (ret) { > + ath11k_dbg(ab, ATH11K_DBG_QMI, > + "qmi fail to get reg from hremote\n"); > + return ret; > + } > + > + start = reg[0] + reg[1]; > + size = reg[2] + reg[3]; See my messages for v2 [1] and v3 [2] Kind regards, Sven [1] https://patchwork.kernel.org/project/linux-wireless/patch/1637082058-6398-2-git-send-email-akolli@codeaurora.org/#24605391 [2] https://patchwork.kernel.org/project/linux-wireless/patch/1637244892-27267-2-git-send-email-akolli@codeaurora.org/#24605417 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v4 2/2] ath11k: Use reserved host DDR addresses from DT for PCI devices 2021-11-21 14:45 ` Sven Eckelmann @ 2021-11-22 6:12 ` Anilkumar Kolli 2021-11-22 7:50 ` Sven Eckelmann 0 siblings, 1 reply; 6+ messages in thread From: Anilkumar Kolli @ 2021-11-22 6:12 UTC (permalink / raw) To: Sven Eckelmann Cc: ath11k, Manivannan Sadhasivam, linux-wireless, devicetree, robh On 2021-11-21 20:15, Sven Eckelmann wrote: > On Sunday, 21 November 2021 15:22:01 CET Anilkumar Kolli wrote: > [...] >> +static int ath11k_mhi_read_addr_from_dt(struct mhi_controller >> *mhi_ctrl) >> +{ >> + struct device_node *np; >> + dma_addr_t start; >> + u32 reg[4]; >> + int ret; >> + >> + np = of_find_node_by_type(NULL, "memory"); >> + if (!np) >> + return -ENOENT; >> + >> + ret = of_property_read_u32_array(np, "reg", reg, 4); >> + if (ret) >> + return ret; >> + >> + start = reg[0] + reg[1]; >> + mhi_ctrl->iova_start = start + 0x1000000; >> + mhi_ctrl->iova_stop = start + reg[2] + reg[3]; >> + >> + return 0; >> +} >> + > [...] >> + ret = of_property_read_u32(dev->of_node, "memory-region", >> + &hremote_phandle); >> + if (ret) { >> + ath11k_dbg(ab, ATH11K_DBG_QMI, >> + "qmi fail to get hremote phandle\n"); >> + return ret; >> + } >> + >> + hremote_node = of_find_node_by_phandle(hremote_phandle); >> + if (!hremote_node) { >> + ath11k_dbg(ab, ATH11K_DBG_QMI, >> + "qmi fail to get hremote_node\n"); >> + return ret; >> + } >> + >> + ret = of_property_read_u32_array(hremote_node, "reg", reg, 4); >> + if (ret) { >> + ath11k_dbg(ab, ATH11K_DBG_QMI, >> + "qmi fail to get reg from hremote\n"); >> + return ret; >> + } >> + >> + start = reg[0] + reg[1]; >> + size = reg[2] + reg[3]; > > See my messages for v2 [1] and v3 [2] > > Thanks for the review, Here addresses are always within 32-bit. so I will change the API to read only 2 integers and update start addresss and size. > [1] > https://patchwork.kernel.org/project/linux-wireless/patch/1637082058-6398-2-git-send-email-akolli@codeaurora.org/#24605391 > [2] > https://patchwork.kernel.org/project/linux-wireless/patch/1637244892-27267-2-git-send-email-akolli@codeaurora.org/#24605417 - Anil. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v4 2/2] ath11k: Use reserved host DDR addresses from DT for PCI devices 2021-11-22 6:12 ` Anilkumar Kolli @ 2021-11-22 7:50 ` Sven Eckelmann 2021-11-23 10:39 ` Anilkumar Kolli 0 siblings, 1 reply; 6+ messages in thread From: Sven Eckelmann @ 2021-11-22 7:50 UTC (permalink / raw) To: Anilkumar Kolli Cc: ath11k, Manivannan Sadhasivam, linux-wireless, devicetree, robh On Monday, 22 November 2021 07:12:27 CET Anilkumar Kolli wrote: [...] > >> + start = reg[0] + reg[1]; > >> + size = reg[2] + reg[3]; > > > > See my messages for v2 [1] and v3 [2] > > > > > Thanks for the review, > > Here addresses are always within 32-bit. > so I will change the API to read only 2 integers and update start > addresss and size. The size of address and size depends on the reserved-memory node - not the qcn9074 node. So please don't make such assumptions in your code. Kind regards, Sven ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v4 2/2] ath11k: Use reserved host DDR addresses from DT for PCI devices 2021-11-22 7:50 ` Sven Eckelmann @ 2021-11-23 10:39 ` Anilkumar Kolli 0 siblings, 0 replies; 6+ messages in thread From: Anilkumar Kolli @ 2021-11-23 10:39 UTC (permalink / raw) To: Sven Eckelmann Cc: ath11k, Manivannan Sadhasivam, linux-wireless, devicetree, robh On 2021-11-22 13:20, Sven Eckelmann wrote: > On Monday, 22 November 2021 07:12:27 CET Anilkumar Kolli wrote: > [...] >> >> + start = reg[0] + reg[1]; >> >> + size = reg[2] + reg[3]; >> > >> > See my messages for v2 [1] and v3 [2] >> > >> > >> Thanks for the review, >> >> Here addresses are always within 32-bit. >> so I will change the API to read only 2 integers and update start >> addresss and size. > > The size of address and size depends on the reserved-memory node - not > the > qcn9074 node. So please don't make such assumptions in your code. > Yes, correct. of_address_to_resource() returns start/end address properly. I will update and send next version. - Anil. ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2021-11-23 10:39 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2021-11-21 14:22 [PATCH v4 1/2] dt: bindings: add new DT entry for ath11k PCI device support Anilkumar Kolli 2021-11-21 14:22 ` [PATCH v4 2/2] ath11k: Use reserved host DDR addresses from DT for PCI devices Anilkumar Kolli 2021-11-21 14:45 ` Sven Eckelmann 2021-11-22 6:12 ` Anilkumar Kolli 2021-11-22 7:50 ` Sven Eckelmann 2021-11-23 10:39 ` Anilkumar Kolli
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).