@@ -3,6 +3,7 @@
#include <linux/msi.h>
#include <linux/pci.h>
+#include <linux/of.h>
#include "core.h"
#include "debug.h"
@@ -317,6 +318,7 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci)
struct mhi_controller *mhi_ctrl;
struct mhi_controller_config *ath11k_mhi_config;
int ret;
+ u32 addr;
mhi_ctrl = mhi_alloc_controller();
if (!mhi_ctrl)
@@ -339,8 +341,16 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci)
return ret;
}
- mhi_ctrl->iova_start = 0;
- mhi_ctrl->iova_stop = 0xffffffff;
+ if (!of_property_read_u32(ab->dev->of_node, "qcom,start-addr", &addr))
+ mhi_ctrl->iova_start = addr;
+ else
+ mhi_ctrl->iova_start = 0;
+
+ if (!of_property_read_u32(ab->dev->of_node, "qcom,end-addr", &addr))
+ mhi_ctrl->iova_stop = addr;
+ else
+ mhi_ctrl->iova_stop = 0xffffffff;
+
mhi_ctrl->sbl_size = SZ_512K;
mhi_ctrl->seg_len = SZ_512K;
mhi_ctrl->fbc_download = true;
@@ -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,13 @@ 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.
+ */
+ if (!of_property_read_u32(ab->dev->of_node, "qcom,base-addr", &addr))
+ ab->bus_params.fixed_mem_region = true;
+
ret = ath11k_pci_claim(ab_pci, pdev);
if (ret) {
ath11k_err(ab, "failed to claim device: %d\n", ret);
@@ -1815,10 +1815,11 @@ 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 &&
+ ab->qmi.target_mem[i].iaddr)
+ iounmap(ab->qmi.target_mem[i].iaddr);
+
if (!ab->qmi.target_mem[i].vaddr)
continue;
@@ -1866,10 +1867,25 @@ static int ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base *ab)
static int ath11k_qmi_assign_target_mem_chunk(struct ath11k_base *ab)
{
+ struct device *dev = ab->dev;
+ u32 addr = 0;
int i, idx;
for (i = 0, idx = 0; i < ab->qmi.mem_seg_count; i++) {
switch (ab->qmi.target_mem[i].type) {
+ case HOST_DDR_REGION_TYPE:
+ if (of_property_read_u32(dev->of_node, "qcom,base-addr", &addr)) {
+ ath11k_warn(ab, "qmi fail to get base-addr from dt\n");
+ return -ENOENT;
+ }
+ ab->qmi.target_mem[idx].paddr = addr;
+ 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;
+ 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 +1900,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 (!of_property_read_u32(dev->of_node,
+ "qcom,caldb-addr", &addr)) {
+ ab->qmi.target_mem[idx].paddr = addr;
+ 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;
@@ -95,6 +95,7 @@ struct target_mem_chunk {
u32 type;
dma_addr_t paddr;
u32 *vaddr;
+ void __iomem *iaddr;
};
struct target_info {
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> --- drivers/net/wireless/ath/ath11k/mhi.c | 14 ++++++++++++-- drivers/net/wireless/ath/ath11k/pci.c | 10 +++++++++- drivers/net/wireless/ath/ath11k/qmi.c | 36 ++++++++++++++++++++++++++++------- drivers/net/wireless/ath/ath11k/qmi.h | 1 + 4 files changed, 51 insertions(+), 10 deletions(-)