Commit 5b32b6dd authored by Manikanta Pubbisetty's avatar Manikanta Pubbisetty Committed by Kalle Valo

ath11k: Remove core PCI references from PCI common code

Remove core PCI and ath11k PCI references(struct ath11k_pci)
from PCI common code. Since, PCI common code will be used
by hybrid bus devices, this code should be independent
from ATH11K PCI references and Linux core PCI references
like struct pci_dev.

Since this change introduces function callbacks for bus wakeup
and bus release operations, wakeup_mhi HW param is no longer
needed and hence it is removed completely. Alternatively, bus
wakeup/release ops for QCA9074 are initialized to NULL as
QCA9704 does not need bus wakeup/release for register accesses.

Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-00192-QCAHKSWPL_SILICONZ-1
Signed-off-by: default avatarManikanta Pubbisetty <quic_mpubbise@quicinc.com>
Signed-off-by: default avatarKalle Valo <quic_kvalo@quicinc.com>
Link: https://lore.kernel.org/r/20220328055714.6449-6-quic_mpubbise@quicinc.com
parent 0cfaf224
...@@ -96,7 +96,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { ...@@ -96,7 +96,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.hal_params = &ath11k_hw_hal_params_ipq8074, .hal_params = &ath11k_hw_hal_params_ipq8074,
.supports_dynamic_smps_6ghz = false, .supports_dynamic_smps_6ghz = false,
.alloc_cacheable_memory = true, .alloc_cacheable_memory = true,
.wakeup_mhi = false,
.supports_rssi_stats = false, .supports_rssi_stats = false,
.fw_wmi_diag_event = false, .fw_wmi_diag_event = false,
.current_cc_support = false, .current_cc_support = false,
...@@ -163,7 +162,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { ...@@ -163,7 +162,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.hal_params = &ath11k_hw_hal_params_ipq8074, .hal_params = &ath11k_hw_hal_params_ipq8074,
.supports_dynamic_smps_6ghz = false, .supports_dynamic_smps_6ghz = false,
.alloc_cacheable_memory = true, .alloc_cacheable_memory = true,
.wakeup_mhi = false,
.supports_rssi_stats = false, .supports_rssi_stats = false,
.fw_wmi_diag_event = false, .fw_wmi_diag_event = false,
.current_cc_support = false, .current_cc_support = false,
...@@ -229,7 +227,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { ...@@ -229,7 +227,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.hal_params = &ath11k_hw_hal_params_qca6390, .hal_params = &ath11k_hw_hal_params_qca6390,
.supports_dynamic_smps_6ghz = false, .supports_dynamic_smps_6ghz = false,
.alloc_cacheable_memory = false, .alloc_cacheable_memory = false,
.wakeup_mhi = true,
.supports_rssi_stats = true, .supports_rssi_stats = true,
.fw_wmi_diag_event = true, .fw_wmi_diag_event = true,
.current_cc_support = true, .current_cc_support = true,
...@@ -295,7 +292,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { ...@@ -295,7 +292,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.hal_params = &ath11k_hw_hal_params_ipq8074, .hal_params = &ath11k_hw_hal_params_ipq8074,
.supports_dynamic_smps_6ghz = true, .supports_dynamic_smps_6ghz = true,
.alloc_cacheable_memory = true, .alloc_cacheable_memory = true,
.wakeup_mhi = false,
.supports_rssi_stats = false, .supports_rssi_stats = false,
.fw_wmi_diag_event = false, .fw_wmi_diag_event = false,
.current_cc_support = false, .current_cc_support = false,
...@@ -361,7 +357,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { ...@@ -361,7 +357,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.hal_params = &ath11k_hw_hal_params_qca6390, .hal_params = &ath11k_hw_hal_params_qca6390,
.supports_dynamic_smps_6ghz = false, .supports_dynamic_smps_6ghz = false,
.alloc_cacheable_memory = false, .alloc_cacheable_memory = false,
.wakeup_mhi = true,
.supports_rssi_stats = true, .supports_rssi_stats = true,
.fw_wmi_diag_event = true, .fw_wmi_diag_event = true,
.current_cc_support = true, .current_cc_support = true,
...@@ -426,7 +421,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { ...@@ -426,7 +421,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.hal_params = &ath11k_hw_hal_params_qca6390, .hal_params = &ath11k_hw_hal_params_qca6390,
.supports_dynamic_smps_6ghz = false, .supports_dynamic_smps_6ghz = false,
.alloc_cacheable_memory = false, .alloc_cacheable_memory = false,
.wakeup_mhi = true,
.supports_rssi_stats = true, .supports_rssi_stats = true,
.fw_wmi_diag_event = true, .fw_wmi_diag_event = true,
.current_cc_support = true, .current_cc_support = true,
......
...@@ -239,6 +239,8 @@ enum ath11k_dev_flags { ...@@ -239,6 +239,8 @@ enum ath11k_dev_flags {
ATH11K_FLAG_CE_IRQ_ENABLED, ATH11K_FLAG_CE_IRQ_ENABLED,
ATH11K_FLAG_EXT_IRQ_ENABLED, ATH11K_FLAG_EXT_IRQ_ENABLED,
ATH11K_FLAG_FIXED_MEM_RGN, ATH11K_FLAG_FIXED_MEM_RGN,
ATH11K_FLAG_DEVICE_INIT_DONE,
ATH11K_FLAG_MULTI_MSI_VECTORS,
}; };
enum ath11k_monitor_flags { enum ath11k_monitor_flags {
...@@ -728,6 +730,14 @@ struct ath11k_bus_params { ...@@ -728,6 +730,14 @@ struct ath11k_bus_params {
bool static_window_map; bool static_window_map;
}; };
struct ath11k_pci_ops {
int (*wakeup)(struct ath11k_base *ab);
void (*release)(struct ath11k_base *ab);
int (*get_msi_irq)(struct ath11k_base *ab, unsigned int vector);
void (*window_write32)(struct ath11k_base *ab, u32 offset, u32 value);
u32 (*window_read32)(struct ath11k_base *ab, u32 offset);
};
/* IPQ8074 HW channel counters frequency value in hertz */ /* IPQ8074 HW channel counters frequency value in hertz */
#define IPQ8074_CC_FREQ_HERTZ 320000 #define IPQ8074_CC_FREQ_HERTZ 320000
...@@ -925,6 +935,8 @@ struct ath11k_base { ...@@ -925,6 +935,8 @@ struct ath11k_base {
u32 addr_lo; u32 addr_lo;
u32 addr_hi; u32 addr_hi;
} msi; } msi;
const struct ath11k_pci_ops *ops;
} pci; } pci;
/* must be last */ /* must be last */
......
/* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* SPDX-License-Identifier: BSD-3-Clause-Clear */
/* /*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#ifndef ATH11K_HW_H #ifndef ATH11K_HW_H
...@@ -189,7 +190,6 @@ struct ath11k_hw_params { ...@@ -189,7 +190,6 @@ struct ath11k_hw_params {
const struct ath11k_hw_hal_params *hal_params; const struct ath11k_hw_hal_params *hal_params;
bool supports_dynamic_smps_6ghz; bool supports_dynamic_smps_6ghz;
bool alloc_cacheable_memory; bool alloc_cacheable_memory;
bool wakeup_mhi;
bool supports_rssi_stats; bool supports_rssi_stats;
bool fw_wmi_diag_event; bool fw_wmi_diag_event;
bool current_cc_support; bool current_cc_support;
......
...@@ -273,10 +273,10 @@ static int ath11k_mhi_get_msi(struct ath11k_pci *ab_pci) ...@@ -273,10 +273,10 @@ static int ath11k_mhi_get_msi(struct ath11k_pci *ab_pci)
for (i = 0; i < num_vectors; i++) { for (i = 0; i < num_vectors; i++) {
msi_data = base_vector; msi_data = base_vector;
if (test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) if (test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags))
msi_data += i; msi_data += i;
irq[i] = ath11k_pcic_get_msi_irq(ab->dev, msi_data); irq[i] = ath11k_pci_get_msi_irq(ab, msi_data);
} }
ab_pci->mhi_ctrl->irq = irq; ab_pci->mhi_ctrl->irq = irq;
...@@ -406,7 +406,7 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci) ...@@ -406,7 +406,7 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci)
return ret; return ret;
} }
if (!test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) if (!test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags))
mhi_ctrl->irq_flags = IRQF_SHARED | IRQF_NOBALANCING; mhi_ctrl->irq_flags = IRQF_SHARED | IRQF_NOBALANCING;
if (test_bit(ATH11K_FLAG_FIXED_MEM_RGN, &ab->dev_flags)) { if (test_bit(ATH11K_FLAG_FIXED_MEM_RGN, &ab->dev_flags)) {
......
...@@ -36,6 +36,85 @@ static const struct pci_device_id ath11k_pci_id_table[] = { ...@@ -36,6 +36,85 @@ static const struct pci_device_id ath11k_pci_id_table[] = {
MODULE_DEVICE_TABLE(pci, ath11k_pci_id_table); MODULE_DEVICE_TABLE(pci, ath11k_pci_id_table);
static int ath11k_pci_bus_wake_up(struct ath11k_base *ab)
{
struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
return mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev);
}
static void ath11k_pci_bus_release(struct ath11k_base *ab)
{
struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
mhi_device_put(ab_pci->mhi_ctrl->mhi_dev);
}
static inline void ath11k_pci_select_window(struct ath11k_pci *ab_pci, u32 offset)
{
struct ath11k_base *ab = ab_pci->ab;
u32 window = FIELD_GET(ATH11K_PCI_WINDOW_VALUE_MASK, offset);
lockdep_assert_held(&ab_pci->window_lock);
if (window != ab_pci->register_window) {
iowrite32(ATH11K_PCI_WINDOW_ENABLE_BIT | window,
ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS);
ioread32(ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS);
ab_pci->register_window = window;
}
}
static void
ath11k_pci_window_write32(struct ath11k_base *ab, u32 offset, u32 value)
{
struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
u32 window_start = ATH11K_PCI_WINDOW_START;
spin_lock_bh(&ab_pci->window_lock);
ath11k_pci_select_window(ab_pci, offset);
iowrite32(value, ab->mem + window_start +
(offset & ATH11K_PCI_WINDOW_RANGE_MASK));
spin_unlock_bh(&ab_pci->window_lock);
}
static u32 ath11k_pci_window_read32(struct ath11k_base *ab, u32 offset)
{
struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
u32 window_start = ATH11K_PCI_WINDOW_START;
u32 val;
spin_lock_bh(&ab_pci->window_lock);
ath11k_pci_select_window(ab_pci, offset);
val = ioread32(ab->mem + window_start +
(offset & ATH11K_PCI_WINDOW_RANGE_MASK));
spin_unlock_bh(&ab_pci->window_lock);
return val;
}
int ath11k_pci_get_msi_irq(struct ath11k_base *ab, unsigned int vector)
{
struct pci_dev *pci_dev = to_pci_dev(ab->dev);
return pci_irq_vector(pci_dev, vector);
}
static const struct ath11k_pci_ops ath11k_pci_ops_qca6390 = {
.wakeup = ath11k_pci_bus_wake_up,
.release = ath11k_pci_bus_release,
.get_msi_irq = ath11k_pci_get_msi_irq,
.window_write32 = ath11k_pci_window_write32,
.window_read32 = ath11k_pci_window_read32,
};
static const struct ath11k_pci_ops ath11k_pci_ops_qcn9074 = {
.get_msi_irq = ath11k_pci_get_msi_irq,
.window_write32 = ath11k_pci_window_write32,
.window_read32 = ath11k_pci_window_read32,
};
static const struct ath11k_bus_params ath11k_pci_bus_params = { static const struct ath11k_bus_params ath11k_pci_bus_params = {
.mhi_support = true, .mhi_support = true,
.m3_fw_support = true, .m3_fw_support = true,
...@@ -318,8 +397,7 @@ static int ath11k_pci_alloc_msi(struct ath11k_pci *ab_pci) ...@@ -318,8 +397,7 @@ static int ath11k_pci_alloc_msi(struct ath11k_pci *ab_pci)
msi_config->total_vectors, msi_config->total_vectors,
PCI_IRQ_MSI); PCI_IRQ_MSI);
if (num_vectors == msi_config->total_vectors) { if (num_vectors == msi_config->total_vectors) {
set_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags); set_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags);
ab_pci->irq_flags = IRQF_SHARED;
} else { } else {
num_vectors = pci_alloc_irq_vectors(ab_pci->pdev, num_vectors = pci_alloc_irq_vectors(ab_pci->pdev,
1, 1,
...@@ -329,9 +407,8 @@ static int ath11k_pci_alloc_msi(struct ath11k_pci *ab_pci) ...@@ -329,9 +407,8 @@ static int ath11k_pci_alloc_msi(struct ath11k_pci *ab_pci)
ret = -EINVAL; ret = -EINVAL;
goto reset_msi_config; goto reset_msi_config;
} }
clear_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags); clear_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags);
ab->pci.msi.config = &msi_config_one_msi; ab->pci.msi.config = &msi_config_one_msi;
ab_pci->irq_flags = IRQF_SHARED | IRQF_NOBALANCING;
ath11k_dbg(ab, ATH11K_DBG_PCI, "request MSI one vector\n"); ath11k_dbg(ab, ATH11K_DBG_PCI, "request MSI one vector\n");
} }
ath11k_info(ab, "MSI vectors: %d\n", num_vectors); ath11k_info(ab, "MSI vectors: %d\n", num_vectors);
...@@ -487,13 +564,20 @@ static void ath11k_pci_aspm_disable(struct ath11k_pci *ab_pci) ...@@ -487,13 +564,20 @@ static void ath11k_pci_aspm_disable(struct ath11k_pci *ab_pci)
set_bit(ATH11K_PCI_ASPM_RESTORE, &ab_pci->flags); set_bit(ATH11K_PCI_ASPM_RESTORE, &ab_pci->flags);
} }
static void ath11k_pci_aspm_restore(struct ath11k_pci *ab_pci)
{
if (test_and_clear_bit(ATH11K_PCI_ASPM_RESTORE, &ab_pci->flags))
pcie_capability_write_word(ab_pci->pdev, PCI_EXP_LNKCTL,
ab_pci->link_ctl);
}
static int ath11k_pci_power_up(struct ath11k_base *ab) static int ath11k_pci_power_up(struct ath11k_base *ab)
{ {
struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
int ret; int ret;
ab_pci->register_window = 0; ab_pci->register_window = 0;
clear_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags); clear_bit(ATH11K_FLAG_DEVICE_INIT_DONE, &ab->dev_flags);
ath11k_pci_sw_reset(ab_pci->ab, true); ath11k_pci_sw_reset(ab_pci->ab, true);
/* Disable ASPM during firmware download due to problems switching /* Disable ASPM during firmware download due to problems switching
...@@ -520,14 +604,14 @@ static void ath11k_pci_power_down(struct ath11k_base *ab) ...@@ -520,14 +604,14 @@ static void ath11k_pci_power_down(struct ath11k_base *ab)
struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
/* restore aspm in case firmware bootup fails */ /* restore aspm in case firmware bootup fails */
ath11k_pcic_aspm_restore(ab_pci); ath11k_pci_aspm_restore(ab_pci);
ath11k_pci_force_wake(ab_pci->ab); ath11k_pci_force_wake(ab_pci->ab);
ath11k_pci_msi_disable(ab_pci); ath11k_pci_msi_disable(ab_pci);
ath11k_mhi_stop(ab_pci); ath11k_mhi_stop(ab_pci);
clear_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags); clear_bit(ATH11K_FLAG_DEVICE_INIT_DONE, &ab->dev_flags);
ath11k_pci_sw_reset(ab_pci->ab, false); ath11k_pci_sw_reset(ab_pci->ab, false);
} }
...@@ -559,8 +643,25 @@ static void ath11k_pci_hif_ce_irq_disable(struct ath11k_base *ab) ...@@ -559,8 +643,25 @@ static void ath11k_pci_hif_ce_irq_disable(struct ath11k_base *ab)
ath11k_pcic_ce_irq_disable_sync(ab); ath11k_pcic_ce_irq_disable_sync(ab);
} }
static int ath11k_pci_start(struct ath11k_base *ab)
{
struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
/* TODO: for now don't restore ASPM in case of single MSI
* vector as MHI register reading in M2 causes system hang.
*/
if (test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags))
ath11k_pci_aspm_restore(ab_pci);
else
ath11k_info(ab, "leaving PCI ASPM disabled to avoid MHI M2 problems\n");
ath11k_pcic_start(ab);
return 0;
}
static const struct ath11k_hif_ops ath11k_pci_hif_ops = { static const struct ath11k_hif_ops ath11k_pci_hif_ops = {
.start = ath11k_pcic_start, .start = ath11k_pci_start,
.stop = ath11k_pcic_stop, .stop = ath11k_pcic_stop,
.read32 = ath11k_pcic_read32, .read32 = ath11k_pcic_read32,
.write32 = ath11k_pcic_write32, .write32 = ath11k_pcic_write32,
...@@ -592,6 +693,15 @@ static void ath11k_pci_read_hw_version(struct ath11k_base *ab, u32 *major, u32 * ...@@ -592,6 +693,15 @@ static void ath11k_pci_read_hw_version(struct ath11k_base *ab, u32 *major, u32 *
*major, *minor); *major, *minor);
} }
static int ath11k_pci_set_irq_affinity_hint(struct ath11k_pci *ab_pci,
const struct cpumask *m)
{
if (test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab_pci->ab->dev_flags))
return 0;
return irq_set_affinity_hint(ab_pci->pdev->irq, m);
}
static int ath11k_pci_probe(struct pci_dev *pdev, static int ath11k_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *pci_dev) const struct pci_device_id *pci_dev)
{ {
...@@ -654,9 +764,12 @@ static int ath11k_pci_probe(struct pci_dev *pdev, ...@@ -654,9 +764,12 @@ static int ath11k_pci_probe(struct pci_dev *pdev,
ret = -EOPNOTSUPP; ret = -EOPNOTSUPP;
goto err_pci_free_region; goto err_pci_free_region;
} }
ab->pci.ops = &ath11k_pci_ops_qca6390;
break; break;
case QCN9074_DEVICE_ID: case QCN9074_DEVICE_ID:
ab->bus_params.static_window_map = true; ab->bus_params.static_window_map = true;
ab->pci.ops = &ath11k_pci_ops_qcn9074;
ab->hw_rev = ATH11K_HW_QCN9074_HW10; ab->hw_rev = ATH11K_HW_QCN9074_HW10;
break; break;
case WCN6855_DEVICE_ID: case WCN6855_DEVICE_ID:
...@@ -685,6 +798,8 @@ static int ath11k_pci_probe(struct pci_dev *pdev, ...@@ -685,6 +798,8 @@ static int ath11k_pci_probe(struct pci_dev *pdev,
ret = -EOPNOTSUPP; ret = -EOPNOTSUPP;
goto err_pci_free_region; goto err_pci_free_region;
} }
ab->pci.ops = &ath11k_pci_ops_qca6390;
break; break;
default: default:
dev_err(&pdev->dev, "Unknown PCI device found: 0x%x\n", dev_err(&pdev->dev, "Unknown PCI device found: 0x%x\n",
...@@ -733,6 +848,12 @@ static int ath11k_pci_probe(struct pci_dev *pdev, ...@@ -733,6 +848,12 @@ static int ath11k_pci_probe(struct pci_dev *pdev,
goto err_ce_free; goto err_ce_free;
} }
ret = ath11k_pci_set_irq_affinity_hint(ab_pci, cpumask_of(0));
if (ret) {
ath11k_err(ab, "failed to set irq affinity %d\n", ret);
goto err_free_irq;
}
/* kernel may allocate a dummy vector before request_irq and /* kernel may allocate a dummy vector before request_irq and
* then allocate a real vector when request_irq is called. * then allocate a real vector when request_irq is called.
* So get msi_data here again to avoid spurious interrupt * So get msi_data here again to avoid spurious interrupt
...@@ -741,16 +862,19 @@ static int ath11k_pci_probe(struct pci_dev *pdev, ...@@ -741,16 +862,19 @@ static int ath11k_pci_probe(struct pci_dev *pdev,
ret = ath11k_pci_config_msi_data(ab_pci); ret = ath11k_pci_config_msi_data(ab_pci);
if (ret) { if (ret) {
ath11k_err(ab, "failed to config msi_data: %d\n", ret); ath11k_err(ab, "failed to config msi_data: %d\n", ret);
goto err_free_irq; goto err_irq_affinity_cleanup;
} }
ret = ath11k_core_init(ab); ret = ath11k_core_init(ab);
if (ret) { if (ret) {
ath11k_err(ab, "failed to init core: %d\n", ret); ath11k_err(ab, "failed to init core: %d\n", ret);
goto err_free_irq; goto err_irq_affinity_cleanup;
} }
return 0; return 0;
err_irq_affinity_cleanup:
ath11k_pci_set_irq_affinity_hint(ab_pci, NULL);
err_free_irq: err_free_irq:
ath11k_pcic_free_irq(ab); ath11k_pcic_free_irq(ab);
...@@ -780,7 +904,7 @@ static void ath11k_pci_remove(struct pci_dev *pdev) ...@@ -780,7 +904,7 @@ static void ath11k_pci_remove(struct pci_dev *pdev)
struct ath11k_base *ab = pci_get_drvdata(pdev); struct ath11k_base *ab = pci_get_drvdata(pdev);
struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
ath11k_pcic_set_irq_affinity_hint(ab_pci, NULL); ath11k_pci_set_irq_affinity_hint(ab_pci, NULL);
if (test_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags)) { if (test_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags)) {
ath11k_pci_power_down(ab); ath11k_pci_power_down(ab);
......
...@@ -54,9 +54,7 @@ ...@@ -54,9 +54,7 @@
#define QFPROM_PWR_CTRL_VDD4BLOW_MASK 0x4 #define QFPROM_PWR_CTRL_VDD4BLOW_MASK 0x4
enum ath11k_pci_flags { enum ath11k_pci_flags {
ATH11K_PCI_FLAG_INIT_DONE,
ATH11K_PCI_ASPM_RESTORE, ATH11K_PCI_ASPM_RESTORE,
ATH11K_PCI_FLAG_MULTI_MSI_VECTORS,
}; };
struct ath11k_pci { struct ath11k_pci {
...@@ -74,8 +72,6 @@ struct ath11k_pci { ...@@ -74,8 +72,6 @@ struct ath11k_pci {
/* enum ath11k_pci_flags */ /* enum ath11k_pci_flags */
unsigned long flags; unsigned long flags;
u16 link_ctl; u16 link_ctl;
unsigned long irq_flags;
}; };
static inline struct ath11k_pci *ath11k_pci_priv(struct ath11k_base *ab) static inline struct ath11k_pci *ath11k_pci_priv(struct ath11k_base *ab)
...@@ -83,4 +79,5 @@ static inline struct ath11k_pci *ath11k_pci_priv(struct ath11k_base *ab) ...@@ -83,4 +79,5 @@ static inline struct ath11k_pci *ath11k_pci_priv(struct ath11k_base *ab)
return (struct ath11k_pci *)ab->drv_priv; return (struct ath11k_pci *)ab->drv_priv;
} }
int ath11k_pci_get_msi_irq(struct ath11k_base *ab, unsigned int vector);
#endif #endif
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
* Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <linux/pci.h>
#include "core.h" #include "core.h"
#include "pcic.h" #include "pcic.h"
#include "debug.h" #include "debug.h"
...@@ -132,29 +131,6 @@ int ath11k_pcic_init_msi_config(struct ath11k_base *ab) ...@@ -132,29 +131,6 @@ int ath11k_pcic_init_msi_config(struct ath11k_base *ab)
} }
EXPORT_SYMBOL(ath11k_pcic_init_msi_config); EXPORT_SYMBOL(ath11k_pcic_init_msi_config);
void ath11k_pcic_aspm_restore(struct ath11k_pci *ab_pci)
{
if (test_and_clear_bit(ATH11K_PCI_ASPM_RESTORE, &ab_pci->flags))
pcie_capability_write_word(ab_pci->pdev, PCI_EXP_LNKCTL,
ab_pci->link_ctl);
}
static inline void ath11k_pcic_select_window(struct ath11k_pci *ab_pci, u32 offset)
{
struct ath11k_base *ab = ab_pci->ab;
u32 window = FIELD_GET(ATH11K_PCI_WINDOW_VALUE_MASK, offset);
lockdep_assert_held(&ab_pci->window_lock);
if (window != ab_pci->register_window) {
iowrite32(ATH11K_PCI_WINDOW_ENABLE_BIT | window,
ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS);
ioread32(ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS);
ab_pci->register_window = window;
}
}
static inline u32 ath11k_pcic_get_window_start(struct ath11k_base *ab, static inline u32 ath11k_pcic_get_window_start(struct ath11k_base *ab,
u32 offset) u32 offset)
{ {
...@@ -174,17 +150,15 @@ static inline u32 ath11k_pcic_get_window_start(struct ath11k_base *ab, ...@@ -174,17 +150,15 @@ static inline u32 ath11k_pcic_get_window_start(struct ath11k_base *ab,
void ath11k_pcic_write32(struct ath11k_base *ab, u32 offset, u32 value) void ath11k_pcic_write32(struct ath11k_base *ab, u32 offset, u32 value)
{ {
struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
u32 window_start; u32 window_start;
int ret = 0; int ret = 0;
/* for offset beyond BAR + 4K - 32, may /* for offset beyond BAR + 4K - 32, may
* need to wakeup MHI to access. * need to wakeup the device to access.
*/ */
if (ab->hw_params.wakeup_mhi && if (test_bit(ATH11K_FLAG_DEVICE_INIT_DONE, &ab->dev_flags) &&
test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF && ab->pci.ops->wakeup)
offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF) ret = ab->pci.ops->wakeup(ab);
ret = mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev);
if (offset < ATH11K_PCI_WINDOW_START) { if (offset < ATH11K_PCI_WINDOW_START) {
iowrite32(value, ab->mem + offset); iowrite32(value, ab->mem + offset);
...@@ -194,38 +168,32 @@ void ath11k_pcic_write32(struct ath11k_base *ab, u32 offset, u32 value) ...@@ -194,38 +168,32 @@ void ath11k_pcic_write32(struct ath11k_base *ab, u32 offset, u32 value)
else else
window_start = ATH11K_PCI_WINDOW_START; window_start = ATH11K_PCI_WINDOW_START;
if (window_start == ATH11K_PCI_WINDOW_START) { if (window_start == ATH11K_PCI_WINDOW_START &&
spin_lock_bh(&ab_pci->window_lock); ab->pci.ops->window_write32) {
ath11k_pcic_select_window(ab_pci, offset); ab->pci.ops->window_write32(ab, offset, value);
iowrite32(value, ab->mem + window_start +
(offset & ATH11K_PCI_WINDOW_RANGE_MASK));
spin_unlock_bh(&ab_pci->window_lock);
} else { } else {
iowrite32(value, ab->mem + window_start + iowrite32(value, ab->mem + window_start +
(offset & ATH11K_PCI_WINDOW_RANGE_MASK)); (offset & ATH11K_PCI_WINDOW_RANGE_MASK));
} }
} }
if (ab->hw_params.wakeup_mhi && if (test_bit(ATH11K_FLAG_DEVICE_INIT_DONE, &ab->dev_flags) &&
test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF && ab->pci.ops->release &&
offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF &&
!ret) !ret)
mhi_device_put(ab_pci->mhi_ctrl->mhi_dev); ab->pci.ops->release(ab);
} }
u32 ath11k_pcic_read32(struct ath11k_base *ab, u32 offset) u32 ath11k_pcic_read32(struct ath11k_base *ab, u32 offset)
{ {
struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
u32 val, window_start; u32 val, window_start;
int ret = 0; int ret = 0;
/* for offset beyond BAR + 4K - 32, may /* for offset beyond BAR + 4K - 32, may
* need to wakeup MHI to access. * need to wakeup the device to access.
*/ */
if (ab->hw_params.wakeup_mhi && if (test_bit(ATH11K_FLAG_DEVICE_INIT_DONE, &ab->dev_flags) &&
test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF && ab->pci.ops->wakeup)
offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF) ret = ab->pci.ops->wakeup(ab);
ret = mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev);
if (offset < ATH11K_PCI_WINDOW_START) { if (offset < ATH11K_PCI_WINDOW_START) {
val = ioread32(ab->mem + offset); val = ioread32(ab->mem + offset);
...@@ -235,34 +203,23 @@ u32 ath11k_pcic_read32(struct ath11k_base *ab, u32 offset) ...@@ -235,34 +203,23 @@ u32 ath11k_pcic_read32(struct ath11k_base *ab, u32 offset)
else else
window_start = ATH11K_PCI_WINDOW_START; window_start = ATH11K_PCI_WINDOW_START;
if (window_start == ATH11K_PCI_WINDOW_START) { if (window_start == ATH11K_PCI_WINDOW_START &&
spin_lock_bh(&ab_pci->window_lock); ab->pci.ops->window_read32) {
ath11k_pcic_select_window(ab_pci, offset); val = ab->pci.ops->window_read32(ab, offset);
val = ioread32(ab->mem + window_start +
(offset & ATH11K_PCI_WINDOW_RANGE_MASK));
spin_unlock_bh(&ab_pci->window_lock);
} else { } else {
val = ioread32(ab->mem + window_start + val = ioread32(ab->mem + window_start +
(offset & ATH11K_PCI_WINDOW_RANGE_MASK)); (offset & ATH11K_PCI_WINDOW_RANGE_MASK));
} }
} }
if (ab->hw_params.wakeup_mhi && if (test_bit(ATH11K_FLAG_DEVICE_INIT_DONE, &ab->dev_flags) &&
test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF && ab->pci.ops->release &&
offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF &&
!ret) !ret)
mhi_device_put(ab_pci->mhi_ctrl->mhi_dev); ab->pci.ops->release(ab);
return val; return val;
} }
int ath11k_pcic_get_msi_irq(struct device *dev, unsigned int vector)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
return pci_irq_vector(pci_dev, vector);
}
void ath11k_pcic_get_msi_address(struct ath11k_base *ab, u32 *msi_addr_lo, void ath11k_pcic_get_msi_address(struct ath11k_base *ab, u32 *msi_addr_lo,
u32 *msi_addr_hi) u32 *msi_addr_hi)
{ {
...@@ -343,13 +300,12 @@ void ath11k_pcic_free_irq(struct ath11k_base *ab) ...@@ -343,13 +300,12 @@ void ath11k_pcic_free_irq(struct ath11k_base *ab)
static void ath11k_pcic_ce_irq_enable(struct ath11k_base *ab, u16 ce_id) static void ath11k_pcic_ce_irq_enable(struct ath11k_base *ab, u16 ce_id)
{ {
struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
u32 irq_idx; u32 irq_idx;
/* In case of one MSI vector, we handle irq enable/disable in a /* In case of one MSI vector, we handle irq enable/disable in a
* uniform way since we only have one irq * uniform way since we only have one irq
*/ */
if (!test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) if (!test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags))
return; return;
irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + ce_id; irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + ce_id;
...@@ -358,13 +314,12 @@ static void ath11k_pcic_ce_irq_enable(struct ath11k_base *ab, u16 ce_id) ...@@ -358,13 +314,12 @@ static void ath11k_pcic_ce_irq_enable(struct ath11k_base *ab, u16 ce_id)
static void ath11k_pcic_ce_irq_disable(struct ath11k_base *ab, u16 ce_id) static void ath11k_pcic_ce_irq_disable(struct ath11k_base *ab, u16 ce_id)
{ {
struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
u32 irq_idx; u32 irq_idx;
/* In case of one MSI vector, we handle irq enable/disable in a /* In case of one MSI vector, we handle irq enable/disable in a
* uniform way since we only have one irq * uniform way since we only have one irq
*/ */
if (!test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) if (!test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags))
return; return;
irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + ce_id; irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + ce_id;
...@@ -429,13 +384,13 @@ static irqreturn_t ath11k_pcic_ce_interrupt_handler(int irq, void *arg) ...@@ -429,13 +384,13 @@ static irqreturn_t ath11k_pcic_ce_interrupt_handler(int irq, void *arg)
static void ath11k_pcic_ext_grp_disable(struct ath11k_ext_irq_grp *irq_grp) static void ath11k_pcic_ext_grp_disable(struct ath11k_ext_irq_grp *irq_grp)
{ {
struct ath11k_pci *ab_pci = ath11k_pci_priv(irq_grp->ab); struct ath11k_base *ab = irq_grp->ab;
int i; int i;
/* In case of one MSI vector, we handle irq enable/disable /* In case of one MSI vector, we handle irq enable/disable
* in a uniform way since we only have one irq * in a uniform way since we only have one irq
*/ */
if (!test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) if (!test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags))
return; return;
for (i = 0; i < irq_grp->num_irq; i++) for (i = 0; i < irq_grp->num_irq; i++)
...@@ -463,13 +418,13 @@ static void __ath11k_pcic_ext_irq_disable(struct ath11k_base *sc) ...@@ -463,13 +418,13 @@ static void __ath11k_pcic_ext_irq_disable(struct ath11k_base *sc)
static void ath11k_pcic_ext_grp_enable(struct ath11k_ext_irq_grp *irq_grp) static void ath11k_pcic_ext_grp_enable(struct ath11k_ext_irq_grp *irq_grp)
{ {
struct ath11k_pci *ab_pci = ath11k_pci_priv(irq_grp->ab); struct ath11k_base *ab = irq_grp->ab;
int i; int i;
/* In case of one MSI vector, we handle irq enable/disable in a /* In case of one MSI vector, we handle irq enable/disable in a
* uniform way since we only have one irq * uniform way since we only have one irq
*/ */
if (!test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags)) if (!test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags))
return; return;
for (i = 0; i < irq_grp->num_irq; i++) for (i = 0; i < irq_grp->num_irq; i++)
...@@ -557,11 +512,22 @@ static irqreturn_t ath11k_pcic_ext_interrupt_handler(int irq, void *arg) ...@@ -557,11 +512,22 @@ static irqreturn_t ath11k_pcic_ext_interrupt_handler(int irq, void *arg)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static int
ath11k_pcic_get_msi_irq(struct ath11k_base *ab, unsigned int vector)
{
if (!ab->pci.ops->get_msi_irq) {
WARN_ONCE(1, "get_msi_irq pci op not defined");
return -EOPNOTSUPP;
}
return ab->pci.ops->get_msi_irq(ab, vector);
}
static int ath11k_pcic_ext_irq_config(struct ath11k_base *ab) static int ath11k_pcic_ext_irq_config(struct ath11k_base *ab)
{ {
struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
int i, j, ret, num_vectors = 0; int i, j, ret, num_vectors = 0;
u32 user_base_data = 0, base_vector = 0; u32 user_base_data = 0, base_vector = 0;
unsigned long irq_flags;
ret = ath11k_pcic_get_user_msi_assignment(ab, "DP", &num_vectors, ret = ath11k_pcic_get_user_msi_assignment(ab, "DP", &num_vectors,
&user_base_data, &user_base_data,
...@@ -569,6 +535,10 @@ static int ath11k_pcic_ext_irq_config(struct ath11k_base *ab) ...@@ -569,6 +535,10 @@ static int ath11k_pcic_ext_irq_config(struct ath11k_base *ab)
if (ret < 0) if (ret < 0)
return ret; return ret;
irq_flags = IRQF_SHARED;
if (!test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags))
irq_flags |= IRQF_NOBALANCING;
for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
u32 num_irq = 0; u32 num_irq = 0;
...@@ -596,7 +566,10 @@ static int ath11k_pcic_ext_irq_config(struct ath11k_base *ab) ...@@ -596,7 +566,10 @@ static int ath11k_pcic_ext_irq_config(struct ath11k_base *ab)
for (j = 0; j < irq_grp->num_irq; j++) { for (j = 0; j < irq_grp->num_irq; j++) {
int irq_idx = irq_grp->irqs[j]; int irq_idx = irq_grp->irqs[j];
int vector = (i % num_vectors) + base_vector; int vector = (i % num_vectors) + base_vector;
int irq = ath11k_pcic_get_msi_irq(ab->dev, vector); int irq = ath11k_pcic_get_msi_irq(ab, vector);
if (irq < 0)
return irq;
ab->irq_num[irq_idx] = irq; ab->irq_num[irq_idx] = irq;
...@@ -605,8 +578,7 @@ static int ath11k_pcic_ext_irq_config(struct ath11k_base *ab) ...@@ -605,8 +578,7 @@ static int ath11k_pcic_ext_irq_config(struct ath11k_base *ab)
irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY); irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY);
ret = request_irq(irq, ath11k_pcic_ext_interrupt_handler, ret = request_irq(irq, ath11k_pcic_ext_interrupt_handler,
ab_pci->irq_flags, irq_flags, "DP_EXT_IRQ", irq_grp);
"DP_EXT_IRQ", irq_grp);
if (ret) { if (ret) {
ath11k_err(ab, "failed request irq %d: %d\n", ath11k_err(ab, "failed request irq %d: %d\n",
vector, ret); vector, ret);
...@@ -619,35 +591,24 @@ static int ath11k_pcic_ext_irq_config(struct ath11k_base *ab) ...@@ -619,35 +591,24 @@ static int ath11k_pcic_ext_irq_config(struct ath11k_base *ab)
return 0; return 0;
} }
int ath11k_pcic_set_irq_affinity_hint(struct ath11k_pci *ab_pci,
const struct cpumask *m)
{
if (test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags))
return 0;
return irq_set_affinity_hint(ab_pci->pdev->irq, m);
}
int ath11k_pcic_config_irq(struct ath11k_base *ab) int ath11k_pcic_config_irq(struct ath11k_base *ab)
{ {
struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
struct ath11k_ce_pipe *ce_pipe; struct ath11k_ce_pipe *ce_pipe;
u32 msi_data_start; u32 msi_data_start;
u32 msi_data_count, msi_data_idx; u32 msi_data_count, msi_data_idx;
u32 msi_irq_start; u32 msi_irq_start;
unsigned int msi_data; unsigned int msi_data;
int irq, i, ret, irq_idx; int irq, i, ret, irq_idx;
unsigned long irq_flags;
ret = ath11k_pcic_get_user_msi_assignment(ab, "CE", &msi_data_count, ret = ath11k_pcic_get_user_msi_assignment(ab, "CE", &msi_data_count,
&msi_data_start, &msi_irq_start); &msi_data_start, &msi_irq_start);
if (ret) if (ret)
return ret; return ret;
ret = ath11k_pcic_set_irq_affinity_hint(ab_pci, cpumask_of(0)); irq_flags = IRQF_SHARED;
if (ret) { if (!test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags))
ath11k_err(ab, "failed to set irq affinity %d\n", ret); irq_flags |= IRQF_NOBALANCING;
return ret;
}
/* Configure CE irqs */ /* Configure CE irqs */
for (i = 0, msi_data_idx = 0; i < ab->hw_params.ce_count; i++) { for (i = 0, msi_data_idx = 0; i < ab->hw_params.ce_count; i++) {
...@@ -655,7 +616,10 @@ int ath11k_pcic_config_irq(struct ath11k_base *ab) ...@@ -655,7 +616,10 @@ int ath11k_pcic_config_irq(struct ath11k_base *ab)
continue; continue;
msi_data = (msi_data_idx % msi_data_count) + msi_irq_start; msi_data = (msi_data_idx % msi_data_count) + msi_irq_start;
irq = ath11k_pcic_get_msi_irq(ab->dev, msi_data); irq = ath11k_pcic_get_msi_irq(ab, msi_data);
if (irq < 0)
return irq;
ce_pipe = &ab->ce.ce_pipe[i]; ce_pipe = &ab->ce.ce_pipe[i];
irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + i; irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + i;
...@@ -663,12 +627,11 @@ int ath11k_pcic_config_irq(struct ath11k_base *ab) ...@@ -663,12 +627,11 @@ int ath11k_pcic_config_irq(struct ath11k_base *ab)
tasklet_setup(&ce_pipe->intr_tq, ath11k_pcic_ce_tasklet); tasklet_setup(&ce_pipe->intr_tq, ath11k_pcic_ce_tasklet);
ret = request_irq(irq, ath11k_pcic_ce_interrupt_handler, ret = request_irq(irq, ath11k_pcic_ce_interrupt_handler,
ab_pci->irq_flags, irq_name[irq_idx], irq_flags, irq_name[irq_idx], ce_pipe);
ce_pipe);
if (ret) { if (ret) {
ath11k_err(ab, "failed to request irq %d: %d\n", ath11k_err(ab, "failed to request irq %d: %d\n",
irq_idx, ret); irq_idx, ret);
goto err_irq_affinity_cleanup; return ret;
} }
ab->irq_num[irq_idx] = irq; ab->irq_num[irq_idx] = irq;
...@@ -679,13 +642,9 @@ int ath11k_pcic_config_irq(struct ath11k_base *ab) ...@@ -679,13 +642,9 @@ int ath11k_pcic_config_irq(struct ath11k_base *ab)
ret = ath11k_pcic_ext_irq_config(ab); ret = ath11k_pcic_ext_irq_config(ab);
if (ret) if (ret)
goto err_irq_affinity_cleanup; return ret;
return 0; return 0;
err_irq_affinity_cleanup:
ath11k_pcic_set_irq_affinity_hint(ab_pci, NULL);
return ret;
} }
void ath11k_pcic_ce_irqs_enable(struct ath11k_base *ab) void ath11k_pcic_ce_irqs_enable(struct ath11k_base *ab)
...@@ -730,17 +689,7 @@ void ath11k_pcic_stop(struct ath11k_base *ab) ...@@ -730,17 +689,7 @@ void ath11k_pcic_stop(struct ath11k_base *ab)
int ath11k_pcic_start(struct ath11k_base *ab) int ath11k_pcic_start(struct ath11k_base *ab)
{ {
struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); set_bit(ATH11K_FLAG_DEVICE_INIT_DONE, &ab->dev_flags);
set_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags);
/* TODO: for now don't restore ASPM in case of single MSI
* vector as MHI register reading in M2 causes system hang.
*/
if (test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags))
ath11k_pcic_aspm_restore(ab_pci);
else
ath11k_info(ab, "leaving PCI ASPM disabled to avoid MHI M2 problems\n");
ath11k_pcic_ce_irqs_enable(ab); ath11k_pcic_ce_irqs_enable(ab);
ath11k_ce_rx_post_buf(ab); ath11k_ce_rx_post_buf(ab);
......
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#define _ATH11K_PCI_CMN_H #define _ATH11K_PCI_CMN_H
#include "core.h" #include "core.h"
#include "pci.h"
#define ATH11K_PCI_IRQ_CE0_OFFSET 3 #define ATH11K_PCI_IRQ_CE0_OFFSET 3
#define ATH11K_PCI_IRQ_DP_OFFSET 14 #define ATH11K_PCI_IRQ_DP_OFFSET 14
...@@ -28,7 +27,6 @@ ...@@ -28,7 +27,6 @@
int ath11k_pcic_get_user_msi_assignment(struct ath11k_base *ab, char *user_name, int ath11k_pcic_get_user_msi_assignment(struct ath11k_base *ab, char *user_name,
int *num_vectors, u32 *user_base_data, int *num_vectors, u32 *user_base_data,
u32 *base_vector); u32 *base_vector);
int ath11k_pcic_get_msi_irq(struct device *dev, unsigned int vector);
void ath11k_pcic_write32(struct ath11k_base *ab, u32 offset, u32 value); void ath11k_pcic_write32(struct ath11k_base *ab, u32 offset, u32 value);
u32 ath11k_pcic_read32(struct ath11k_base *ab, u32 offset); u32 ath11k_pcic_read32(struct ath11k_base *ab, u32 offset);
void ath11k_pcic_get_msi_address(struct ath11k_base *ab, u32 *msi_addr_lo, void ath11k_pcic_get_msi_address(struct ath11k_base *ab, u32 *msi_addr_lo,
...@@ -44,8 +42,5 @@ int ath11k_pcic_map_service_to_pipe(struct ath11k_base *ab, u16 service_id, ...@@ -44,8 +42,5 @@ int ath11k_pcic_map_service_to_pipe(struct ath11k_base *ab, u16 service_id,
u8 *ul_pipe, u8 *dl_pipe); u8 *ul_pipe, u8 *dl_pipe);
void ath11k_pcic_ce_irqs_enable(struct ath11k_base *ab); void ath11k_pcic_ce_irqs_enable(struct ath11k_base *ab);
void ath11k_pcic_ce_irq_disable_sync(struct ath11k_base *ab); void ath11k_pcic_ce_irq_disable_sync(struct ath11k_base *ab);
void ath11k_pcic_aspm_restore(struct ath11k_pci *ab_pci);
int ath11k_pcic_set_irq_affinity_hint(struct ath11k_pci *ab_pci,
const struct cpumask *m);
int ath11k_pcic_init_msi_config(struct ath11k_base *ab); int ath11k_pcic_init_msi_config(struct ath11k_base *ab);
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment