brintos

brintos / linux-shallow public Read only

0
0
Text · 27.4 KiB · be9d2c6 Raw
1081 lines · c
1// SPDX-License-Identifier: BSD-3-Clause-Clear2/*3 * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.4 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.5 */6 7#include <linux/module.h>8#include <linux/msi.h>9#include <linux/pci.h>10#include <linux/of.h>11 12#include "pci.h"13#include "core.h"14#include "hif.h"15#include "mhi.h"16#include "debug.h"17#include "pcic.h"18#include "qmi.h"19 20#define ATH11K_PCI_BAR_NUM		021#define ATH11K_PCI_DMA_MASK		3622#define ATH11K_PCI_COHERENT_DMA_MASK	3223 24#define TCSR_SOC_HW_VERSION		0x022425#define TCSR_SOC_HW_VERSION_MAJOR_MASK	GENMASK(11, 8)26#define TCSR_SOC_HW_VERSION_MINOR_MASK	GENMASK(7, 0)27 28#define QCA6390_DEVICE_ID		0x110129#define QCN9074_DEVICE_ID		0x110430#define WCN6855_DEVICE_ID		0x110331 32#define TCSR_SOC_HW_SUB_VER	0x191001033 34static const struct pci_device_id ath11k_pci_id_table[] = {35	{ PCI_VDEVICE(QCOM, QCA6390_DEVICE_ID) },36	{ PCI_VDEVICE(QCOM, WCN6855_DEVICE_ID) },37	{ PCI_VDEVICE(QCOM, QCN9074_DEVICE_ID) },38	{0}39};40 41MODULE_DEVICE_TABLE(pci, ath11k_pci_id_table);42 43static int ath11k_pci_bus_wake_up(struct ath11k_base *ab)44{45	struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);46 47	return mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev);48}49 50static void ath11k_pci_bus_release(struct ath11k_base *ab)51{52	struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);53 54	mhi_device_put(ab_pci->mhi_ctrl->mhi_dev);55}56 57static u32 ath11k_pci_get_window_start(struct ath11k_base *ab, u32 offset)58{59	if (!ab->hw_params.static_window_map)60		return ATH11K_PCI_WINDOW_START;61 62	if ((offset ^ HAL_SEQ_WCSS_UMAC_OFFSET) < ATH11K_PCI_WINDOW_RANGE_MASK)63		/* if offset lies within DP register range, use 3rd window */64		return 3 * ATH11K_PCI_WINDOW_START;65	else if ((offset ^ HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab)) <66		 ATH11K_PCI_WINDOW_RANGE_MASK)67		 /* if offset lies within CE register range, use 2nd window */68		return 2 * ATH11K_PCI_WINDOW_START;69	else70		return ATH11K_PCI_WINDOW_START;71}72 73static inline void ath11k_pci_select_window(struct ath11k_pci *ab_pci, u32 offset)74{75	struct ath11k_base *ab = ab_pci->ab;76 77	u32 window = FIELD_GET(ATH11K_PCI_WINDOW_VALUE_MASK, offset);78 79	lockdep_assert_held(&ab_pci->window_lock);80 81	if (window != ab_pci->register_window) {82		iowrite32(ATH11K_PCI_WINDOW_ENABLE_BIT | window,83			  ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS);84		ioread32(ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS);85		ab_pci->register_window = window;86	}87}88 89static void90ath11k_pci_window_write32(struct ath11k_base *ab, u32 offset, u32 value)91{92	struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);93	u32 window_start;94 95	window_start = ath11k_pci_get_window_start(ab, offset);96 97	if (window_start == ATH11K_PCI_WINDOW_START) {98		spin_lock_bh(&ab_pci->window_lock);99		ath11k_pci_select_window(ab_pci, offset);100		iowrite32(value, ab->mem + window_start +101			  (offset & ATH11K_PCI_WINDOW_RANGE_MASK));102		spin_unlock_bh(&ab_pci->window_lock);103	} else {104		iowrite32(value, ab->mem + window_start +105			  (offset & ATH11K_PCI_WINDOW_RANGE_MASK));106	}107}108 109static u32 ath11k_pci_window_read32(struct ath11k_base *ab, u32 offset)110{111	struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);112	u32 window_start, val;113 114	window_start = ath11k_pci_get_window_start(ab, offset);115 116	if (window_start == ATH11K_PCI_WINDOW_START) {117		spin_lock_bh(&ab_pci->window_lock);118		ath11k_pci_select_window(ab_pci, offset);119		val = ioread32(ab->mem + window_start +120			       (offset & ATH11K_PCI_WINDOW_RANGE_MASK));121		spin_unlock_bh(&ab_pci->window_lock);122	} else {123		val = ioread32(ab->mem + window_start +124			       (offset & ATH11K_PCI_WINDOW_RANGE_MASK));125	}126 127	return val;128}129 130int ath11k_pci_get_msi_irq(struct ath11k_base *ab, unsigned int vector)131{132	struct pci_dev *pci_dev = to_pci_dev(ab->dev);133 134	return pci_irq_vector(pci_dev, vector);135}136 137static const struct ath11k_pci_ops ath11k_pci_ops_qca6390 = {138	.wakeup = ath11k_pci_bus_wake_up,139	.release = ath11k_pci_bus_release,140	.get_msi_irq = ath11k_pci_get_msi_irq,141	.window_write32 = ath11k_pci_window_write32,142	.window_read32 = ath11k_pci_window_read32,143};144 145static const struct ath11k_pci_ops ath11k_pci_ops_qcn9074 = {146	.wakeup = NULL,147	.release = NULL,148	.get_msi_irq = ath11k_pci_get_msi_irq,149	.window_write32 = ath11k_pci_window_write32,150	.window_read32 = ath11k_pci_window_read32,151};152 153static const struct ath11k_msi_config msi_config_one_msi = {154	.total_vectors = 1,155	.total_users = 4,156	.users = (struct ath11k_msi_user[]) {157		{ .name = "MHI", .num_vectors = 3, .base_vector = 0 },158		{ .name = "CE", .num_vectors = 1, .base_vector = 0 },159		{ .name = "WAKE", .num_vectors = 1, .base_vector = 0 },160		{ .name = "DP", .num_vectors = 1, .base_vector = 0 },161	},162};163 164static inline void ath11k_pci_select_static_window(struct ath11k_pci *ab_pci)165{166	u32 umac_window;167	u32 ce_window;168	u32 window;169 170	umac_window = FIELD_GET(ATH11K_PCI_WINDOW_VALUE_MASK, HAL_SEQ_WCSS_UMAC_OFFSET);171	ce_window = FIELD_GET(ATH11K_PCI_WINDOW_VALUE_MASK, HAL_CE_WFSS_CE_REG_BASE);172	window = (umac_window << 12) | (ce_window << 6);173 174	iowrite32(ATH11K_PCI_WINDOW_ENABLE_BIT | window,175		  ab_pci->ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS);176}177 178static void ath11k_pci_soc_global_reset(struct ath11k_base *ab)179{180	u32 val, delay;181 182	val = ath11k_pcic_read32(ab, PCIE_SOC_GLOBAL_RESET);183 184	val |= PCIE_SOC_GLOBAL_RESET_V;185 186	ath11k_pcic_write32(ab, PCIE_SOC_GLOBAL_RESET, val);187 188	/* TODO: exact time to sleep is uncertain */189	delay = 10;190	mdelay(delay);191 192	/* Need to toggle V bit back otherwise stuck in reset status */193	val &= ~PCIE_SOC_GLOBAL_RESET_V;194 195	ath11k_pcic_write32(ab, PCIE_SOC_GLOBAL_RESET, val);196 197	mdelay(delay);198 199	val = ath11k_pcic_read32(ab, PCIE_SOC_GLOBAL_RESET);200	if (val == 0xffffffff)201		ath11k_warn(ab, "link down error during global reset\n");202}203 204static void ath11k_pci_clear_dbg_registers(struct ath11k_base *ab)205{206	u32 val;207 208	/* read cookie */209	val = ath11k_pcic_read32(ab, PCIE_Q6_COOKIE_ADDR);210	ath11k_dbg(ab, ATH11K_DBG_PCI, "pcie_q6_cookie_addr 0x%x\n", val);211 212	val = ath11k_pcic_read32(ab, WLAON_WARM_SW_ENTRY);213	ath11k_dbg(ab, ATH11K_DBG_PCI, "wlaon_warm_sw_entry 0x%x\n", val);214 215	/* TODO: exact time to sleep is uncertain */216	mdelay(10);217 218	/* write 0 to WLAON_WARM_SW_ENTRY to prevent Q6 from219	 * continuing warm path and entering dead loop.220	 */221	ath11k_pcic_write32(ab, WLAON_WARM_SW_ENTRY, 0);222	mdelay(10);223 224	val = ath11k_pcic_read32(ab, WLAON_WARM_SW_ENTRY);225	ath11k_dbg(ab, ATH11K_DBG_PCI, "wlaon_warm_sw_entry 0x%x\n", val);226 227	/* A read clear register. clear the register to prevent228	 * Q6 from entering wrong code path.229	 */230	val = ath11k_pcic_read32(ab, WLAON_SOC_RESET_CAUSE_REG);231	ath11k_dbg(ab, ATH11K_DBG_PCI, "soc reset cause %d\n", val);232}233 234static int ath11k_pci_set_link_reg(struct ath11k_base *ab,235				   u32 offset, u32 value, u32 mask)236{237	u32 v;238	int i;239 240	v = ath11k_pcic_read32(ab, offset);241	if ((v & mask) == value)242		return 0;243 244	for (i = 0; i < 10; i++) {245		ath11k_pcic_write32(ab, offset, (v & ~mask) | value);246 247		v = ath11k_pcic_read32(ab, offset);248		if ((v & mask) == value)249			return 0;250 251		mdelay(2);252	}253 254	ath11k_warn(ab, "failed to set pcie link register 0x%08x: 0x%08x != 0x%08x\n",255		    offset, v & mask, value);256 257	return -ETIMEDOUT;258}259 260static int ath11k_pci_fix_l1ss(struct ath11k_base *ab)261{262	int ret;263 264	ret = ath11k_pci_set_link_reg(ab,265				      PCIE_QSERDES_COM_SYSCLK_EN_SEL_REG(ab),266				      PCIE_QSERDES_COM_SYSCLK_EN_SEL_VAL,267				      PCIE_QSERDES_COM_SYSCLK_EN_SEL_MSK);268	if (ret) {269		ath11k_warn(ab, "failed to set sysclk: %d\n", ret);270		return ret;271	}272 273	ret = ath11k_pci_set_link_reg(ab,274				      PCIE_PCS_OSC_DTCT_CONFIG1_REG(ab),275				      PCIE_PCS_OSC_DTCT_CONFIG1_VAL,276				      PCIE_PCS_OSC_DTCT_CONFIG_MSK);277	if (ret) {278		ath11k_warn(ab, "failed to set dtct config1 error: %d\n", ret);279		return ret;280	}281 282	ret = ath11k_pci_set_link_reg(ab,283				      PCIE_PCS_OSC_DTCT_CONFIG2_REG(ab),284				      PCIE_PCS_OSC_DTCT_CONFIG2_VAL,285				      PCIE_PCS_OSC_DTCT_CONFIG_MSK);286	if (ret) {287		ath11k_warn(ab, "failed to set dtct config2: %d\n", ret);288		return ret;289	}290 291	ret = ath11k_pci_set_link_reg(ab,292				      PCIE_PCS_OSC_DTCT_CONFIG4_REG(ab),293				      PCIE_PCS_OSC_DTCT_CONFIG4_VAL,294				      PCIE_PCS_OSC_DTCT_CONFIG_MSK);295	if (ret) {296		ath11k_warn(ab, "failed to set dtct config4: %d\n", ret);297		return ret;298	}299 300	return 0;301}302 303static void ath11k_pci_enable_ltssm(struct ath11k_base *ab)304{305	u32 val;306	int i;307 308	val = ath11k_pcic_read32(ab, PCIE_PCIE_PARF_LTSSM);309 310	/* PCIE link seems very unstable after the Hot Reset*/311	for (i = 0; val != PARM_LTSSM_VALUE && i < 5; i++) {312		if (val == 0xffffffff)313			mdelay(5);314 315		ath11k_pcic_write32(ab, PCIE_PCIE_PARF_LTSSM, PARM_LTSSM_VALUE);316		val = ath11k_pcic_read32(ab, PCIE_PCIE_PARF_LTSSM);317	}318 319	ath11k_dbg(ab, ATH11K_DBG_PCI, "ltssm 0x%x\n", val);320 321	val = ath11k_pcic_read32(ab, GCC_GCC_PCIE_HOT_RST);322	val |= GCC_GCC_PCIE_HOT_RST_VAL;323	ath11k_pcic_write32(ab, GCC_GCC_PCIE_HOT_RST, val);324	val = ath11k_pcic_read32(ab, GCC_GCC_PCIE_HOT_RST);325 326	ath11k_dbg(ab, ATH11K_DBG_PCI, "pcie_hot_rst 0x%x\n", val);327 328	mdelay(5);329}330 331static void ath11k_pci_clear_all_intrs(struct ath11k_base *ab)332{333	/* This is a WAR for PCIE Hotreset.334	 * When target receive Hotreset, but will set the interrupt.335	 * So when download SBL again, SBL will open Interrupt and336	 * receive it, and crash immediately.337	 */338	ath11k_pcic_write32(ab, PCIE_PCIE_INT_ALL_CLEAR, PCIE_INT_CLEAR_ALL);339}340 341static void ath11k_pci_set_wlaon_pwr_ctrl(struct ath11k_base *ab)342{343	u32 val;344 345	val = ath11k_pcic_read32(ab, WLAON_QFPROM_PWR_CTRL_REG);346	val &= ~QFPROM_PWR_CTRL_VDD4BLOW_MASK;347	ath11k_pcic_write32(ab, WLAON_QFPROM_PWR_CTRL_REG, val);348}349 350static void ath11k_pci_force_wake(struct ath11k_base *ab)351{352	ath11k_pcic_write32(ab, PCIE_SOC_WAKE_PCIE_LOCAL_REG, 1);353	mdelay(5);354}355 356static void ath11k_pci_sw_reset(struct ath11k_base *ab, bool power_on)357{358	mdelay(100);359 360	if (power_on) {361		ath11k_pci_enable_ltssm(ab);362		ath11k_pci_clear_all_intrs(ab);363		ath11k_pci_set_wlaon_pwr_ctrl(ab);364		if (ab->hw_params.fix_l1ss)365			ath11k_pci_fix_l1ss(ab);366	}367 368	ath11k_mhi_clear_vector(ab);369	ath11k_pci_clear_dbg_registers(ab);370	ath11k_pci_soc_global_reset(ab);371	ath11k_mhi_set_mhictrl_reset(ab);372}373 374static void ath11k_pci_init_qmi_ce_config(struct ath11k_base *ab)375{376	struct ath11k_qmi_ce_cfg *cfg = &ab->qmi.ce_cfg;377 378	cfg->tgt_ce = ab->hw_params.target_ce_config;379	cfg->tgt_ce_len = ab->hw_params.target_ce_count;380 381	cfg->svc_to_ce_map = ab->hw_params.svc_to_ce_map;382	cfg->svc_to_ce_map_len = ab->hw_params.svc_to_ce_map_len;383	ab->qmi.service_ins_id = ab->hw_params.qmi_service_ins_id;384 385	ath11k_ce_get_shadow_config(ab, &cfg->shadow_reg_v2,386				    &cfg->shadow_reg_v2_len);387}388 389static void ath11k_pci_msi_config(struct ath11k_pci *ab_pci, bool enable)390{391	struct pci_dev *dev = ab_pci->pdev;392	u16 control;393 394	pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control);395 396	if (enable)397		control |= PCI_MSI_FLAGS_ENABLE;398	else399		control &= ~PCI_MSI_FLAGS_ENABLE;400 401	pci_write_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, control);402}403 404static void ath11k_pci_msi_enable(struct ath11k_pci *ab_pci)405{406	ath11k_pci_msi_config(ab_pci, true);407}408 409static void ath11k_pci_msi_disable(struct ath11k_pci *ab_pci)410{411	ath11k_pci_msi_config(ab_pci, false);412}413 414static int ath11k_pci_alloc_msi(struct ath11k_pci *ab_pci)415{416	struct ath11k_base *ab = ab_pci->ab;417	const struct ath11k_msi_config *msi_config = ab->pci.msi.config;418	struct pci_dev *pci_dev = ab_pci->pdev;419	struct msi_desc *msi_desc;420	int num_vectors;421	int ret;422 423	num_vectors = pci_alloc_irq_vectors(pci_dev,424					    msi_config->total_vectors,425					    msi_config->total_vectors,426					    PCI_IRQ_MSI);427	if (num_vectors == msi_config->total_vectors) {428		set_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags);429	} else {430		num_vectors = pci_alloc_irq_vectors(ab_pci->pdev,431						    1,432						    1,433						    PCI_IRQ_MSI);434		if (num_vectors < 0) {435			ret = -EINVAL;436			goto reset_msi_config;437		}438		clear_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags);439		ab->pci.msi.config = &msi_config_one_msi;440		ath11k_dbg(ab, ATH11K_DBG_PCI, "request one msi vector\n");441	}442	ath11k_info(ab, "MSI vectors: %d\n", num_vectors);443 444	ath11k_pci_msi_disable(ab_pci);445 446	msi_desc = irq_get_msi_desc(ab_pci->pdev->irq);447	if (!msi_desc) {448		ath11k_err(ab, "msi_desc is NULL!\n");449		ret = -EINVAL;450		goto free_msi_vector;451	}452 453	ab->pci.msi.ep_base_data = msi_desc->msg.data;454 455	pci_read_config_dword(pci_dev, pci_dev->msi_cap + PCI_MSI_ADDRESS_LO,456			      &ab->pci.msi.addr_lo);457 458	if (msi_desc->pci.msi_attrib.is_64) {459		pci_read_config_dword(pci_dev, pci_dev->msi_cap + PCI_MSI_ADDRESS_HI,460				      &ab->pci.msi.addr_hi);461	} else {462		ab->pci.msi.addr_hi = 0;463	}464 465	ath11k_dbg(ab, ATH11K_DBG_PCI, "msi base data is %d\n", ab->pci.msi.ep_base_data);466 467	return 0;468 469free_msi_vector:470	pci_free_irq_vectors(ab_pci->pdev);471 472reset_msi_config:473	return ret;474}475 476static void ath11k_pci_free_msi(struct ath11k_pci *ab_pci)477{478	pci_free_irq_vectors(ab_pci->pdev);479}480 481static int ath11k_pci_config_msi_data(struct ath11k_pci *ab_pci)482{483	struct msi_desc *msi_desc;484 485	msi_desc = irq_get_msi_desc(ab_pci->pdev->irq);486	if (!msi_desc) {487		ath11k_err(ab_pci->ab, "msi_desc is NULL!\n");488		pci_free_irq_vectors(ab_pci->pdev);489		return -EINVAL;490	}491 492	ab_pci->ab->pci.msi.ep_base_data = msi_desc->msg.data;493 494	ath11k_dbg(ab_pci->ab, ATH11K_DBG_PCI, "after request_irq msi_ep_base_data %d\n",495		   ab_pci->ab->pci.msi.ep_base_data);496 497	return 0;498}499 500static int ath11k_pci_claim(struct ath11k_pci *ab_pci, struct pci_dev *pdev)501{502	struct ath11k_base *ab = ab_pci->ab;503	u16 device_id;504	int ret = 0;505 506	pci_read_config_word(pdev, PCI_DEVICE_ID, &device_id);507	if (device_id != ab_pci->dev_id)  {508		ath11k_err(ab, "pci device id mismatch: 0x%x 0x%x\n",509			   device_id, ab_pci->dev_id);510		ret = -EIO;511		goto out;512	}513 514	ret = pci_assign_resource(pdev, ATH11K_PCI_BAR_NUM);515	if (ret) {516		ath11k_err(ab, "failed to assign pci resource: %d\n", ret);517		goto out;518	}519 520	ret = pci_enable_device(pdev);521	if (ret) {522		ath11k_err(ab, "failed to enable pci device: %d\n", ret);523		goto out;524	}525 526	ret = pci_request_region(pdev, ATH11K_PCI_BAR_NUM, "ath11k_pci");527	if (ret) {528		ath11k_err(ab, "failed to request pci region: %d\n", ret);529		goto disable_device;530	}531 532	ret = dma_set_mask(&pdev->dev,533			   DMA_BIT_MASK(ATH11K_PCI_DMA_MASK));534	if (ret) {535		ath11k_err(ab, "failed to set pci dma mask to %d: %d\n",536			   ATH11K_PCI_DMA_MASK, ret);537		goto release_region;538	}539 540	ab_pci->dma_mask = DMA_BIT_MASK(ATH11K_PCI_DMA_MASK);541 542	ret = dma_set_coherent_mask(&pdev->dev,543				    DMA_BIT_MASK(ATH11K_PCI_COHERENT_DMA_MASK));544	if (ret) {545		ath11k_err(ab, "failed to set pci coherent dma mask to %d: %d\n",546			   ATH11K_PCI_COHERENT_DMA_MASK, ret);547		goto release_region;548	}549 550	pci_set_master(pdev);551 552	ab->mem_len = pci_resource_len(pdev, ATH11K_PCI_BAR_NUM);553	ab->mem = pci_iomap(pdev, ATH11K_PCI_BAR_NUM, 0);554	if (!ab->mem) {555		ath11k_err(ab, "failed to map pci bar %d\n", ATH11K_PCI_BAR_NUM);556		ret = -EIO;557		goto release_region;558	}559 560	ab->mem_ce = ab->mem;561 562	ath11k_dbg(ab, ATH11K_DBG_BOOT, "pci_mem 0x%p\n", ab->mem);563	return 0;564 565release_region:566	pci_release_region(pdev, ATH11K_PCI_BAR_NUM);567disable_device:568	pci_disable_device(pdev);569out:570	return ret;571}572 573static void ath11k_pci_free_region(struct ath11k_pci *ab_pci)574{575	struct ath11k_base *ab = ab_pci->ab;576	struct pci_dev *pci_dev = ab_pci->pdev;577 578	pci_iounmap(pci_dev, ab->mem);579	ab->mem = NULL;580	pci_release_region(pci_dev, ATH11K_PCI_BAR_NUM);581	if (pci_is_enabled(pci_dev))582		pci_disable_device(pci_dev);583}584 585static void ath11k_pci_aspm_disable(struct ath11k_pci *ab_pci)586{587	struct ath11k_base *ab = ab_pci->ab;588 589	pcie_capability_read_word(ab_pci->pdev, PCI_EXP_LNKCTL,590				  &ab_pci->link_ctl);591 592	ath11k_dbg(ab, ATH11K_DBG_PCI, "link_ctl 0x%04x L0s %d L1 %d\n",593		   ab_pci->link_ctl,594		   u16_get_bits(ab_pci->link_ctl, PCI_EXP_LNKCTL_ASPM_L0S),595		   u16_get_bits(ab_pci->link_ctl, PCI_EXP_LNKCTL_ASPM_L1));596 597	/* disable L0s and L1 */598	pcie_capability_clear_word(ab_pci->pdev, PCI_EXP_LNKCTL,599				   PCI_EXP_LNKCTL_ASPMC);600 601	set_bit(ATH11K_PCI_ASPM_RESTORE, &ab_pci->flags);602}603 604static void ath11k_pci_aspm_restore(struct ath11k_pci *ab_pci)605{606	if (test_and_clear_bit(ATH11K_PCI_ASPM_RESTORE, &ab_pci->flags))607		pcie_capability_clear_and_set_word(ab_pci->pdev, PCI_EXP_LNKCTL,608						   PCI_EXP_LNKCTL_ASPMC,609						   ab_pci->link_ctl &610						   PCI_EXP_LNKCTL_ASPMC);611}612 613static int ath11k_pci_power_up(struct ath11k_base *ab)614{615	struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);616	int ret;617 618	ab_pci->register_window = 0;619	clear_bit(ATH11K_FLAG_DEVICE_INIT_DONE, &ab->dev_flags);620	ath11k_pci_sw_reset(ab_pci->ab, true);621 622	/* Disable ASPM during firmware download due to problems switching623	 * to AMSS state.624	 */625	ath11k_pci_aspm_disable(ab_pci);626 627	ath11k_pci_msi_enable(ab_pci);628 629	ret = ath11k_mhi_start(ab_pci);630	if (ret) {631		ath11k_err(ab, "failed to start mhi: %d\n", ret);632		return ret;633	}634 635	if (ab->hw_params.static_window_map)636		ath11k_pci_select_static_window(ab_pci);637 638	return 0;639}640 641static void ath11k_pci_power_down(struct ath11k_base *ab)642{643	struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);644 645	/* restore aspm in case firmware bootup fails */646	ath11k_pci_aspm_restore(ab_pci);647 648	ath11k_pci_force_wake(ab_pci->ab);649 650	ath11k_pci_msi_disable(ab_pci);651 652	ath11k_mhi_stop(ab_pci);653	clear_bit(ATH11K_FLAG_DEVICE_INIT_DONE, &ab->dev_flags);654	ath11k_pci_sw_reset(ab_pci->ab, false);655}656 657static int ath11k_pci_hif_suspend(struct ath11k_base *ab)658{659	struct ath11k_pci *ar_pci = ath11k_pci_priv(ab);660 661	return ath11k_mhi_suspend(ar_pci);662}663 664static int ath11k_pci_hif_resume(struct ath11k_base *ab)665{666	struct ath11k_pci *ar_pci = ath11k_pci_priv(ab);667 668	return ath11k_mhi_resume(ar_pci);669}670 671static void ath11k_pci_hif_ce_irq_enable(struct ath11k_base *ab)672{673	ath11k_pcic_ce_irqs_enable(ab);674}675 676static void ath11k_pci_hif_ce_irq_disable(struct ath11k_base *ab)677{678	ath11k_pcic_ce_irq_disable_sync(ab);679}680 681static int ath11k_pci_start(struct ath11k_base *ab)682{683	struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);684 685	/* TODO: for now don't restore ASPM in case of single MSI686	 * vector as MHI register reading in M2 causes system hang.687	 */688	if (test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags))689		ath11k_pci_aspm_restore(ab_pci);690	else691		ath11k_info(ab, "leaving PCI ASPM disabled to avoid MHI M2 problems\n");692 693	ath11k_pcic_start(ab);694 695	return 0;696}697 698static const struct ath11k_hif_ops ath11k_pci_hif_ops = {699	.start = ath11k_pci_start,700	.stop = ath11k_pcic_stop,701	.read32 = ath11k_pcic_read32,702	.write32 = ath11k_pcic_write32,703	.read = ath11k_pcic_read,704	.power_down = ath11k_pci_power_down,705	.power_up = ath11k_pci_power_up,706	.suspend = ath11k_pci_hif_suspend,707	.resume = ath11k_pci_hif_resume,708	.irq_enable = ath11k_pcic_ext_irq_enable,709	.irq_disable = ath11k_pcic_ext_irq_disable,710	.get_msi_address =  ath11k_pcic_get_msi_address,711	.get_user_msi_vector = ath11k_pcic_get_user_msi_assignment,712	.map_service_to_pipe = ath11k_pcic_map_service_to_pipe,713	.ce_irq_enable = ath11k_pci_hif_ce_irq_enable,714	.ce_irq_disable = ath11k_pci_hif_ce_irq_disable,715	.get_ce_msi_idx = ath11k_pcic_get_ce_msi_idx,716};717 718static void ath11k_pci_read_hw_version(struct ath11k_base *ab, u32 *major, u32 *minor)719{720	u32 soc_hw_version;721 722	soc_hw_version = ath11k_pcic_read32(ab, TCSR_SOC_HW_VERSION);723	*major = FIELD_GET(TCSR_SOC_HW_VERSION_MAJOR_MASK,724			   soc_hw_version);725	*minor = FIELD_GET(TCSR_SOC_HW_VERSION_MINOR_MASK,726			   soc_hw_version);727 728	ath11k_dbg(ab, ATH11K_DBG_PCI, "tcsr_soc_hw_version major %d minor %d\n",729		   *major, *minor);730}731 732static int ath11k_pci_set_irq_affinity_hint(struct ath11k_pci *ab_pci,733					    const struct cpumask *m)734{735	if (test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab_pci->ab->dev_flags))736		return 0;737 738	return irq_set_affinity_hint(ab_pci->pdev->irq, m);739}740 741static int ath11k_pci_probe(struct pci_dev *pdev,742			    const struct pci_device_id *pci_dev)743{744	struct ath11k_base *ab;745	struct ath11k_pci *ab_pci;746	u32 soc_hw_version_major, soc_hw_version_minor, addr;747	int ret;748	u32 sub_version;749 750	ab = ath11k_core_alloc(&pdev->dev, sizeof(*ab_pci), ATH11K_BUS_PCI);751 752	if (!ab) {753		dev_err(&pdev->dev, "failed to allocate ath11k base\n");754		return -ENOMEM;755	}756 757	ab->dev = &pdev->dev;758	pci_set_drvdata(pdev, ab);759	ab_pci = ath11k_pci_priv(ab);760	ab_pci->dev_id = pci_dev->device;761	ab_pci->ab = ab;762	ab_pci->pdev = pdev;763	ab->hif.ops = &ath11k_pci_hif_ops;764	ab->fw_mode = ATH11K_FIRMWARE_MODE_NORMAL;765	pci_set_drvdata(pdev, ab);766	spin_lock_init(&ab_pci->window_lock);767 768	/* Set fixed_mem_region to true for platforms support reserved memory769	 * from DT. If memory is reserved from DT for FW, ath11k driver need not770	 * allocate memory.771	 */772	ret = of_property_read_u32(ab->dev->of_node, "memory-region", &addr);773	if (!ret)774		set_bit(ATH11K_FLAG_FIXED_MEM_RGN, &ab->dev_flags);775 776	ret = ath11k_pci_claim(ab_pci, pdev);777	if (ret) {778		ath11k_err(ab, "failed to claim device: %d\n", ret);779		goto err_free_core;780	}781 782	ath11k_dbg(ab, ATH11K_DBG_BOOT, "pci probe %04x:%04x %04x:%04x\n",783		   pdev->vendor, pdev->device,784		   pdev->subsystem_vendor, pdev->subsystem_device);785 786	ab->id.vendor = pdev->vendor;787	ab->id.device = pdev->device;788	ab->id.subsystem_vendor = pdev->subsystem_vendor;789	ab->id.subsystem_device = pdev->subsystem_device;790 791	switch (pci_dev->device) {792	case QCA6390_DEVICE_ID:793		ret = ath11k_pcic_register_pci_ops(ab, &ath11k_pci_ops_qca6390);794		if (ret) {795			ath11k_err(ab, "failed to register PCI ops: %d\n", ret);796			goto err_pci_free_region;797		}798 799		ath11k_pci_read_hw_version(ab, &soc_hw_version_major,800					   &soc_hw_version_minor);801		switch (soc_hw_version_major) {802		case 2:803			ab->hw_rev = ATH11K_HW_QCA6390_HW20;804			break;805		default:806			dev_err(&pdev->dev, "Unsupported QCA6390 SOC hardware version: %d %d\n",807				soc_hw_version_major, soc_hw_version_minor);808			ret = -EOPNOTSUPP;809			goto err_pci_free_region;810		}811 812		break;813	case QCN9074_DEVICE_ID:814		ret = ath11k_pcic_register_pci_ops(ab, &ath11k_pci_ops_qcn9074);815		if (ret) {816			ath11k_err(ab, "failed to register PCI ops: %d\n", ret);817			goto err_pci_free_region;818		}819		ab->hw_rev = ATH11K_HW_QCN9074_HW10;820		break;821	case WCN6855_DEVICE_ID:822		ret = ath11k_pcic_register_pci_ops(ab, &ath11k_pci_ops_qca6390);823		if (ret) {824			ath11k_err(ab, "failed to register PCI ops: %d\n", ret);825			goto err_pci_free_region;826		}827		ab->id.bdf_search = ATH11K_BDF_SEARCH_BUS_AND_BOARD;828		ath11k_pci_read_hw_version(ab, &soc_hw_version_major,829					   &soc_hw_version_minor);830		switch (soc_hw_version_major) {831		case 2:832			switch (soc_hw_version_minor) {833			case 0x00:834			case 0x01:835				ab->hw_rev = ATH11K_HW_WCN6855_HW20;836				break;837			case 0x10:838			case 0x11:839				sub_version = ath11k_pcic_read32(ab, TCSR_SOC_HW_SUB_VER);840				ath11k_dbg(ab, ATH11K_DBG_PCI, "sub_version 0x%x\n",841					   sub_version);842				switch (sub_version) {843				case 0x1019A0E1:844				case 0x1019B0E1:845				case 0x1019C0E1:846				case 0x1019D0E1:847					ab->hw_rev = ATH11K_HW_QCA2066_HW21;848					break;849				default:850					ab->hw_rev = ATH11K_HW_WCN6855_HW21;851				}852				break;853			default:854				goto unsupported_wcn6855_soc;855			}856			break;857		default:858unsupported_wcn6855_soc:859			dev_err(&pdev->dev, "Unsupported WCN6855 SOC hardware version: %d %d\n",860				soc_hw_version_major, soc_hw_version_minor);861			ret = -EOPNOTSUPP;862			goto err_pci_free_region;863		}864 865		break;866	default:867		dev_err(&pdev->dev, "Unknown PCI device found: 0x%x\n",868			pci_dev->device);869		ret = -EOPNOTSUPP;870		goto err_pci_free_region;871	}872 873	ret = ath11k_pcic_init_msi_config(ab);874	if (ret) {875		ath11k_err(ab, "failed to init msi config: %d\n", ret);876		goto err_pci_free_region;877	}878 879	ret = ath11k_pci_alloc_msi(ab_pci);880	if (ret) {881		ath11k_err(ab, "failed to enable msi: %d\n", ret);882		goto err_pci_free_region;883	}884 885	ret = ath11k_core_pre_init(ab);886	if (ret)887		goto err_pci_disable_msi;888 889	ret = ath11k_pci_set_irq_affinity_hint(ab_pci, cpumask_of(0));890	if (ret) {891		ath11k_err(ab, "failed to set irq affinity %d\n", ret);892		goto err_pci_disable_msi;893	}894 895	ret = ath11k_mhi_register(ab_pci);896	if (ret) {897		ath11k_err(ab, "failed to register mhi: %d\n", ret);898		goto err_irq_affinity_cleanup;899	}900 901	ret = ath11k_hal_srng_init(ab);902	if (ret)903		goto err_mhi_unregister;904 905	ret = ath11k_ce_alloc_pipes(ab);906	if (ret) {907		ath11k_err(ab, "failed to allocate ce pipes: %d\n", ret);908		goto err_hal_srng_deinit;909	}910 911	ath11k_pci_init_qmi_ce_config(ab);912 913	ret = ath11k_pcic_config_irq(ab);914	if (ret) {915		ath11k_err(ab, "failed to config irq: %d\n", ret);916		goto err_ce_free;917	}918 919	/* kernel may allocate a dummy vector before request_irq and920	 * then allocate a real vector when request_irq is called.921	 * So get msi_data here again to avoid spurious interrupt922	 * as msi_data will configured to srngs.923	 */924	ret = ath11k_pci_config_msi_data(ab_pci);925	if (ret) {926		ath11k_err(ab, "failed to config msi_data: %d\n", ret);927		goto err_free_irq;928	}929 930	ret = ath11k_core_init(ab);931	if (ret) {932		ath11k_err(ab, "failed to init core: %d\n", ret);933		goto err_free_irq;934	}935	ath11k_qmi_fwreset_from_cold_boot(ab);936	return 0;937 938err_free_irq:939	ath11k_pcic_free_irq(ab);940 941err_ce_free:942	ath11k_ce_free_pipes(ab);943 944err_hal_srng_deinit:945	ath11k_hal_srng_deinit(ab);946 947err_mhi_unregister:948	ath11k_mhi_unregister(ab_pci);949 950err_irq_affinity_cleanup:951	ath11k_pci_set_irq_affinity_hint(ab_pci, NULL);952 953err_pci_disable_msi:954	ath11k_pci_free_msi(ab_pci);955 956err_pci_free_region:957	ath11k_pci_free_region(ab_pci);958 959err_free_core:960	ath11k_core_free(ab);961 962	return ret;963}964 965static void ath11k_pci_remove(struct pci_dev *pdev)966{967	struct ath11k_base *ab = pci_get_drvdata(pdev);968	struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);969 970	ath11k_pci_set_irq_affinity_hint(ab_pci, NULL);971 972	if (test_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags)) {973		ath11k_pci_power_down(ab);974		ath11k_debugfs_soc_destroy(ab);975		ath11k_qmi_deinit_service(ab);976		goto qmi_fail;977	}978 979	set_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags);980 981	ath11k_core_deinit(ab);982 983qmi_fail:984	ath11k_mhi_unregister(ab_pci);985 986	ath11k_pcic_free_irq(ab);987	ath11k_pci_free_msi(ab_pci);988	ath11k_pci_free_region(ab_pci);989 990	ath11k_hal_srng_deinit(ab);991	ath11k_ce_free_pipes(ab);992	ath11k_core_free(ab);993}994 995static void ath11k_pci_shutdown(struct pci_dev *pdev)996{997	struct ath11k_base *ab = pci_get_drvdata(pdev);998	struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);999 1000	ath11k_pci_set_irq_affinity_hint(ab_pci, NULL);1001	ath11k_pci_power_down(ab);1002}1003 1004static __maybe_unused int ath11k_pci_pm_suspend(struct device *dev)1005{1006	struct ath11k_base *ab = dev_get_drvdata(dev);1007	int ret;1008 1009	if (test_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags)) {1010		ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot skipping pci suspend as qmi is not initialised\n");1011		return 0;1012	}1013 1014	ret = ath11k_core_suspend(ab);1015	if (ret)1016		ath11k_warn(ab, "failed to suspend core: %d\n", ret);1017 1018	return 0;1019}1020 1021static __maybe_unused int ath11k_pci_pm_resume(struct device *dev)1022{1023	struct ath11k_base *ab = dev_get_drvdata(dev);1024	int ret;1025 1026	if (test_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags)) {1027		ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot skipping pci resume as qmi is not initialised\n");1028		return 0;1029	}1030 1031	ret = ath11k_core_resume(ab);1032	if (ret)1033		ath11k_warn(ab, "failed to resume core: %d\n", ret);1034 1035	return ret;1036}1037 1038static SIMPLE_DEV_PM_OPS(ath11k_pci_pm_ops,1039			 ath11k_pci_pm_suspend,1040			 ath11k_pci_pm_resume);1041 1042static struct pci_driver ath11k_pci_driver = {1043	.name = "ath11k_pci",1044	.id_table = ath11k_pci_id_table,1045	.probe = ath11k_pci_probe,1046	.remove = ath11k_pci_remove,1047	.shutdown = ath11k_pci_shutdown,1048#ifdef CONFIG_PM1049	.driver.pm = &ath11k_pci_pm_ops,1050#endif1051};1052 1053static int ath11k_pci_init(void)1054{1055	int ret;1056 1057	ret = pci_register_driver(&ath11k_pci_driver);1058	if (ret)1059		pr_err("failed to register ath11k pci driver: %d\n",1060		       ret);1061 1062	return ret;1063}1064module_init(ath11k_pci_init);1065 1066static void ath11k_pci_exit(void)1067{1068	pci_unregister_driver(&ath11k_pci_driver);1069}1070 1071module_exit(ath11k_pci_exit);1072 1073MODULE_DESCRIPTION("Driver support for Qualcomm Technologies PCIe 802.11ax WLAN devices");1074MODULE_LICENSE("Dual BSD/GPL");1075 1076/* firmware files */1077MODULE_FIRMWARE(ATH11K_FW_DIR "/QCA6390/hw2.0/*");1078MODULE_FIRMWARE(ATH11K_FW_DIR "/QCN9074/hw1.0/*");1079MODULE_FIRMWARE(ATH11K_FW_DIR "/WCN6855/hw2.0/*");1080MODULE_FIRMWARE(ATH11K_FW_DIR "/WCN6855/hw2.1/*");1081