brintos

brintos / linux-shallow public Read only

0
0
Text · 20.4 KiB · f0441b3 Raw
863 lines · c
1// SPDX-License-Identifier: ISC2/*3 * Copyright (c) 2016-2017 Qualcomm Atheros, Inc. All rights reserved.4 * Copyright (c) 2015 The Linux Foundation. All rights reserved.5 */6#include <linux/module.h>7#include <linux/of.h>8#include <linux/platform_device.h>9#include <linux/clk.h>10#include <linux/reset.h>11#include "core.h"12#include "debug.h"13#include "pci.h"14#include "ahb.h"15 16static const struct of_device_id ath10k_ahb_of_match[] = {17	{ .compatible = "qcom,ipq4019-wifi",18	  .data = (void *)ATH10K_HW_QCA401919	},20	{ }21};22 23MODULE_DEVICE_TABLE(of, ath10k_ahb_of_match);24 25#define QCA4019_SRAM_ADDR      0x000C000026#define QCA4019_SRAM_LEN       0x00040000 /* 256 kb */27 28static inline struct ath10k_ahb *ath10k_ahb_priv(struct ath10k *ar)29{30	return &ath10k_pci_priv(ar)->ahb[0];31}32 33static void ath10k_ahb_write32(struct ath10k *ar, u32 offset, u32 value)34{35	struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);36 37	iowrite32(value, ar_ahb->mem + offset);38}39 40static u32 ath10k_ahb_read32(struct ath10k *ar, u32 offset)41{42	struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);43 44	return ioread32(ar_ahb->mem + offset);45}46 47static u32 ath10k_ahb_gcc_read32(struct ath10k *ar, u32 offset)48{49	struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);50 51	return ioread32(ar_ahb->gcc_mem + offset);52}53 54static void ath10k_ahb_tcsr_write32(struct ath10k *ar, u32 offset, u32 value)55{56	struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);57 58	iowrite32(value, ar_ahb->tcsr_mem + offset);59}60 61static u32 ath10k_ahb_tcsr_read32(struct ath10k *ar, u32 offset)62{63	struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);64 65	return ioread32(ar_ahb->tcsr_mem + offset);66}67 68static u32 ath10k_ahb_soc_read32(struct ath10k *ar, u32 addr)69{70	return ath10k_ahb_read32(ar, RTC_SOC_BASE_ADDRESS + addr);71}72 73static int ath10k_ahb_get_num_banks(struct ath10k *ar)74{75	if (ar->hw_rev == ATH10K_HW_QCA4019)76		return 1;77 78	ath10k_warn(ar, "unknown number of banks, assuming 1\n");79	return 1;80}81 82static int ath10k_ahb_clock_init(struct ath10k *ar)83{84	struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);85	struct device *dev;86 87	dev = &ar_ahb->pdev->dev;88 89	ar_ahb->cmd_clk = devm_clk_get(dev, "wifi_wcss_cmd");90	if (IS_ERR_OR_NULL(ar_ahb->cmd_clk)) {91		ath10k_err(ar, "failed to get cmd clk: %ld\n",92			   PTR_ERR(ar_ahb->cmd_clk));93		return ar_ahb->cmd_clk ? PTR_ERR(ar_ahb->cmd_clk) : -ENODEV;94	}95 96	ar_ahb->ref_clk = devm_clk_get(dev, "wifi_wcss_ref");97	if (IS_ERR_OR_NULL(ar_ahb->ref_clk)) {98		ath10k_err(ar, "failed to get ref clk: %ld\n",99			   PTR_ERR(ar_ahb->ref_clk));100		return ar_ahb->ref_clk ? PTR_ERR(ar_ahb->ref_clk) : -ENODEV;101	}102 103	ar_ahb->rtc_clk = devm_clk_get(dev, "wifi_wcss_rtc");104	if (IS_ERR_OR_NULL(ar_ahb->rtc_clk)) {105		ath10k_err(ar, "failed to get rtc clk: %ld\n",106			   PTR_ERR(ar_ahb->rtc_clk));107		return ar_ahb->rtc_clk ? PTR_ERR(ar_ahb->rtc_clk) : -ENODEV;108	}109 110	return 0;111}112 113static void ath10k_ahb_clock_deinit(struct ath10k *ar)114{115	struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);116 117	ar_ahb->cmd_clk = NULL;118	ar_ahb->ref_clk = NULL;119	ar_ahb->rtc_clk = NULL;120}121 122static int ath10k_ahb_clock_enable(struct ath10k *ar)123{124	struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);125	int ret;126 127	if (IS_ERR_OR_NULL(ar_ahb->cmd_clk) ||128	    IS_ERR_OR_NULL(ar_ahb->ref_clk) ||129	    IS_ERR_OR_NULL(ar_ahb->rtc_clk)) {130		ath10k_err(ar, "clock(s) is/are not initialized\n");131		ret = -EIO;132		goto out;133	}134 135	ret = clk_prepare_enable(ar_ahb->cmd_clk);136	if (ret) {137		ath10k_err(ar, "failed to enable cmd clk: %d\n", ret);138		goto out;139	}140 141	ret = clk_prepare_enable(ar_ahb->ref_clk);142	if (ret) {143		ath10k_err(ar, "failed to enable ref clk: %d\n", ret);144		goto err_cmd_clk_disable;145	}146 147	ret = clk_prepare_enable(ar_ahb->rtc_clk);148	if (ret) {149		ath10k_err(ar, "failed to enable rtc clk: %d\n", ret);150		goto err_ref_clk_disable;151	}152 153	return 0;154 155err_ref_clk_disable:156	clk_disable_unprepare(ar_ahb->ref_clk);157 158err_cmd_clk_disable:159	clk_disable_unprepare(ar_ahb->cmd_clk);160 161out:162	return ret;163}164 165static void ath10k_ahb_clock_disable(struct ath10k *ar)166{167	struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);168 169	clk_disable_unprepare(ar_ahb->cmd_clk);170 171	clk_disable_unprepare(ar_ahb->ref_clk);172 173	clk_disable_unprepare(ar_ahb->rtc_clk);174}175 176static int ath10k_ahb_rst_ctrl_init(struct ath10k *ar)177{178	struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);179	struct device *dev;180 181	dev = &ar_ahb->pdev->dev;182 183	ar_ahb->core_cold_rst = devm_reset_control_get_exclusive(dev,184								 "wifi_core_cold");185	if (IS_ERR(ar_ahb->core_cold_rst)) {186		ath10k_err(ar, "failed to get core cold rst ctrl: %ld\n",187			   PTR_ERR(ar_ahb->core_cold_rst));188		return PTR_ERR(ar_ahb->core_cold_rst);189	}190 191	ar_ahb->radio_cold_rst = devm_reset_control_get_exclusive(dev,192								  "wifi_radio_cold");193	if (IS_ERR(ar_ahb->radio_cold_rst)) {194		ath10k_err(ar, "failed to get radio cold rst ctrl: %ld\n",195			   PTR_ERR(ar_ahb->radio_cold_rst));196		return PTR_ERR(ar_ahb->radio_cold_rst);197	}198 199	ar_ahb->radio_warm_rst = devm_reset_control_get_exclusive(dev,200								  "wifi_radio_warm");201	if (IS_ERR(ar_ahb->radio_warm_rst)) {202		ath10k_err(ar, "failed to get radio warm rst ctrl: %ld\n",203			   PTR_ERR(ar_ahb->radio_warm_rst));204		return PTR_ERR(ar_ahb->radio_warm_rst);205	}206 207	ar_ahb->radio_srif_rst = devm_reset_control_get_exclusive(dev,208								  "wifi_radio_srif");209	if (IS_ERR(ar_ahb->radio_srif_rst)) {210		ath10k_err(ar, "failed to get radio srif rst ctrl: %ld\n",211			   PTR_ERR(ar_ahb->radio_srif_rst));212		return PTR_ERR(ar_ahb->radio_srif_rst);213	}214 215	ar_ahb->cpu_init_rst = devm_reset_control_get_exclusive(dev,216								"wifi_cpu_init");217	if (IS_ERR(ar_ahb->cpu_init_rst)) {218		ath10k_err(ar, "failed to get cpu init rst ctrl: %ld\n",219			   PTR_ERR(ar_ahb->cpu_init_rst));220		return PTR_ERR(ar_ahb->cpu_init_rst);221	}222 223	return 0;224}225 226static void ath10k_ahb_rst_ctrl_deinit(struct ath10k *ar)227{228	struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);229 230	ar_ahb->core_cold_rst = NULL;231	ar_ahb->radio_cold_rst = NULL;232	ar_ahb->radio_warm_rst = NULL;233	ar_ahb->radio_srif_rst = NULL;234	ar_ahb->cpu_init_rst = NULL;235}236 237static int ath10k_ahb_release_reset(struct ath10k *ar)238{239	struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);240	int ret;241 242	if (IS_ERR_OR_NULL(ar_ahb->radio_cold_rst) ||243	    IS_ERR_OR_NULL(ar_ahb->radio_warm_rst) ||244	    IS_ERR_OR_NULL(ar_ahb->radio_srif_rst) ||245	    IS_ERR_OR_NULL(ar_ahb->cpu_init_rst)) {246		ath10k_err(ar, "rst ctrl(s) is/are not initialized\n");247		return -EINVAL;248	}249 250	ret = reset_control_deassert(ar_ahb->radio_cold_rst);251	if (ret) {252		ath10k_err(ar, "failed to deassert radio cold rst: %d\n", ret);253		return ret;254	}255 256	ret = reset_control_deassert(ar_ahb->radio_warm_rst);257	if (ret) {258		ath10k_err(ar, "failed to deassert radio warm rst: %d\n", ret);259		return ret;260	}261 262	ret = reset_control_deassert(ar_ahb->radio_srif_rst);263	if (ret) {264		ath10k_err(ar, "failed to deassert radio srif rst: %d\n", ret);265		return ret;266	}267 268	ret = reset_control_deassert(ar_ahb->cpu_init_rst);269	if (ret) {270		ath10k_err(ar, "failed to deassert cpu init rst: %d\n", ret);271		return ret;272	}273 274	return 0;275}276 277static void ath10k_ahb_halt_axi_bus(struct ath10k *ar, u32 haltreq_reg,278				    u32 haltack_reg)279{280	unsigned long timeout;281	u32 val;282 283	/* Issue halt axi bus request */284	val = ath10k_ahb_tcsr_read32(ar, haltreq_reg);285	val |= AHB_AXI_BUS_HALT_REQ;286	ath10k_ahb_tcsr_write32(ar, haltreq_reg, val);287 288	/* Wait for axi bus halted ack */289	timeout = jiffies + msecs_to_jiffies(ATH10K_AHB_AXI_BUS_HALT_TIMEOUT);290	do {291		val = ath10k_ahb_tcsr_read32(ar, haltack_reg);292		if (val & AHB_AXI_BUS_HALT_ACK)293			break;294 295		mdelay(1);296	} while (time_before(jiffies, timeout));297 298	if (!(val & AHB_AXI_BUS_HALT_ACK)) {299		ath10k_err(ar, "failed to halt axi bus: %d\n", val);300		return;301	}302 303	ath10k_dbg(ar, ATH10K_DBG_AHB, "axi bus halted\n");304}305 306static void ath10k_ahb_halt_chip(struct ath10k *ar)307{308	struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);309	u32 core_id, glb_cfg_reg, haltreq_reg, haltack_reg;310	u32 val;311	int ret;312 313	if (IS_ERR_OR_NULL(ar_ahb->core_cold_rst) ||314	    IS_ERR_OR_NULL(ar_ahb->radio_cold_rst) ||315	    IS_ERR_OR_NULL(ar_ahb->radio_warm_rst) ||316	    IS_ERR_OR_NULL(ar_ahb->radio_srif_rst) ||317	    IS_ERR_OR_NULL(ar_ahb->cpu_init_rst)) {318		ath10k_err(ar, "rst ctrl(s) is/are not initialized\n");319		return;320	}321 322	core_id = ath10k_ahb_read32(ar, ATH10K_AHB_WLAN_CORE_ID_REG);323 324	switch (core_id) {325	case 0:326		glb_cfg_reg = ATH10K_AHB_TCSR_WIFI0_GLB_CFG;327		haltreq_reg = ATH10K_AHB_TCSR_WCSS0_HALTREQ;328		haltack_reg = ATH10K_AHB_TCSR_WCSS0_HALTACK;329		break;330	case 1:331		glb_cfg_reg = ATH10K_AHB_TCSR_WIFI1_GLB_CFG;332		haltreq_reg = ATH10K_AHB_TCSR_WCSS1_HALTREQ;333		haltack_reg = ATH10K_AHB_TCSR_WCSS1_HALTACK;334		break;335	default:336		ath10k_err(ar, "invalid core id %d found, skipping reset sequence\n",337			   core_id);338		return;339	}340 341	ath10k_ahb_halt_axi_bus(ar, haltreq_reg, haltack_reg);342 343	val = ath10k_ahb_tcsr_read32(ar, glb_cfg_reg);344	val |= TCSR_WIFIX_GLB_CFG_DISABLE_CORE_CLK;345	ath10k_ahb_tcsr_write32(ar, glb_cfg_reg, val);346 347	ret = reset_control_assert(ar_ahb->core_cold_rst);348	if (ret)349		ath10k_err(ar, "failed to assert core cold rst: %d\n", ret);350	msleep(1);351 352	ret = reset_control_assert(ar_ahb->radio_cold_rst);353	if (ret)354		ath10k_err(ar, "failed to assert radio cold rst: %d\n", ret);355	msleep(1);356 357	ret = reset_control_assert(ar_ahb->radio_warm_rst);358	if (ret)359		ath10k_err(ar, "failed to assert radio warm rst: %d\n", ret);360	msleep(1);361 362	ret = reset_control_assert(ar_ahb->radio_srif_rst);363	if (ret)364		ath10k_err(ar, "failed to assert radio srif rst: %d\n", ret);365	msleep(1);366 367	ret = reset_control_assert(ar_ahb->cpu_init_rst);368	if (ret)369		ath10k_err(ar, "failed to assert cpu init rst: %d\n", ret);370	msleep(10);371 372	/* Clear halt req and core clock disable req before373	 * deasserting wifi core reset.374	 */375	val = ath10k_ahb_tcsr_read32(ar, haltreq_reg);376	val &= ~AHB_AXI_BUS_HALT_REQ;377	ath10k_ahb_tcsr_write32(ar, haltreq_reg, val);378 379	val = ath10k_ahb_tcsr_read32(ar, glb_cfg_reg);380	val &= ~TCSR_WIFIX_GLB_CFG_DISABLE_CORE_CLK;381	ath10k_ahb_tcsr_write32(ar, glb_cfg_reg, val);382 383	ret = reset_control_deassert(ar_ahb->core_cold_rst);384	if (ret)385		ath10k_err(ar, "failed to deassert core cold rst: %d\n", ret);386 387	ath10k_dbg(ar, ATH10K_DBG_AHB, "core %d reset done\n", core_id);388}389 390static irqreturn_t ath10k_ahb_interrupt_handler(int irq, void *arg)391{392	struct ath10k *ar = arg;393 394	if (!ath10k_pci_irq_pending(ar))395		return IRQ_NONE;396 397	ath10k_pci_disable_and_clear_intx_irq(ar);398	ath10k_pci_irq_msi_fw_mask(ar);399	napi_schedule(&ar->napi);400 401	return IRQ_HANDLED;402}403 404static int ath10k_ahb_request_irq_intx(struct ath10k *ar)405{406	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);407	struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);408	int ret;409 410	ret = request_irq(ar_ahb->irq,411			  ath10k_ahb_interrupt_handler,412			  IRQF_SHARED, "ath10k_ahb", ar);413	if (ret) {414		ath10k_warn(ar, "failed to request legacy irq %d: %d\n",415			    ar_ahb->irq, ret);416		return ret;417	}418	ar_pci->oper_irq_mode = ATH10K_PCI_IRQ_INTX;419 420	return 0;421}422 423static void ath10k_ahb_release_irq_intx(struct ath10k *ar)424{425	struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);426 427	free_irq(ar_ahb->irq, ar);428}429 430static void ath10k_ahb_irq_disable(struct ath10k *ar)431{432	ath10k_ce_disable_interrupts(ar);433	ath10k_pci_disable_and_clear_intx_irq(ar);434}435 436static int ath10k_ahb_resource_init(struct ath10k *ar)437{438	struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);439	struct platform_device *pdev;440	struct resource *res;441	int ret;442 443	pdev = ar_ahb->pdev;444 445	ar_ahb->mem = devm_platform_get_and_ioremap_resource(pdev, 0, &res);446	if (IS_ERR(ar_ahb->mem)) {447		ath10k_err(ar, "mem ioremap error\n");448		ret = PTR_ERR(ar_ahb->mem);449		goto out;450	}451 452	ar_ahb->mem_len = resource_size(res);453 454	ar_ahb->gcc_mem = ioremap(ATH10K_GCC_REG_BASE,455				  ATH10K_GCC_REG_SIZE);456	if (!ar_ahb->gcc_mem) {457		ath10k_err(ar, "gcc mem ioremap error\n");458		ret = -ENOMEM;459		goto err_mem_unmap;460	}461 462	ar_ahb->tcsr_mem = ioremap(ATH10K_TCSR_REG_BASE,463				   ATH10K_TCSR_REG_SIZE);464	if (!ar_ahb->tcsr_mem) {465		ath10k_err(ar, "tcsr mem ioremap error\n");466		ret = -ENOMEM;467		goto err_gcc_mem_unmap;468	}469 470	ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));471	if (ret) {472		ath10k_err(ar, "failed to set 32-bit dma mask: %d\n", ret);473		goto err_tcsr_mem_unmap;474	}475 476	ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));477	if (ret) {478		ath10k_err(ar, "failed to set 32-bit consistent dma: %d\n",479			   ret);480		goto err_tcsr_mem_unmap;481	}482 483	ret = ath10k_ahb_clock_init(ar);484	if (ret)485		goto err_tcsr_mem_unmap;486 487	ret = ath10k_ahb_rst_ctrl_init(ar);488	if (ret)489		goto err_clock_deinit;490 491	ar_ahb->irq = platform_get_irq_byname(pdev, "legacy");492	if (ar_ahb->irq < 0) {493		ath10k_err(ar, "failed to get irq number: %d\n", ar_ahb->irq);494		ret = ar_ahb->irq;495		goto err_clock_deinit;496	}497 498	ath10k_dbg(ar, ATH10K_DBG_BOOT, "irq: %d\n", ar_ahb->irq);499 500	ath10k_dbg(ar, ATH10K_DBG_BOOT, "mem: 0x%pK mem_len: %lu gcc mem: 0x%pK tcsr_mem: 0x%pK\n",501		   ar_ahb->mem, ar_ahb->mem_len,502		   ar_ahb->gcc_mem, ar_ahb->tcsr_mem);503	return 0;504 505err_clock_deinit:506	ath10k_ahb_clock_deinit(ar);507 508err_tcsr_mem_unmap:509	iounmap(ar_ahb->tcsr_mem);510 511err_gcc_mem_unmap:512	ar_ahb->tcsr_mem = NULL;513	iounmap(ar_ahb->gcc_mem);514 515err_mem_unmap:516	ar_ahb->gcc_mem = NULL;517	devm_iounmap(&pdev->dev, ar_ahb->mem);518 519out:520	ar_ahb->mem = NULL;521	return ret;522}523 524static void ath10k_ahb_resource_deinit(struct ath10k *ar)525{526	struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);527	struct device *dev;528 529	dev = &ar_ahb->pdev->dev;530 531	if (ar_ahb->mem)532		devm_iounmap(dev, ar_ahb->mem);533 534	if (ar_ahb->gcc_mem)535		iounmap(ar_ahb->gcc_mem);536 537	if (ar_ahb->tcsr_mem)538		iounmap(ar_ahb->tcsr_mem);539 540	ar_ahb->mem = NULL;541	ar_ahb->gcc_mem = NULL;542	ar_ahb->tcsr_mem = NULL;543 544	ath10k_ahb_clock_deinit(ar);545	ath10k_ahb_rst_ctrl_deinit(ar);546}547 548static int ath10k_ahb_prepare_device(struct ath10k *ar)549{550	u32 val;551	int ret;552 553	ret = ath10k_ahb_clock_enable(ar);554	if (ret) {555		ath10k_err(ar, "failed to enable clocks\n");556		return ret;557	}558 559	/* Clock for the target is supplied from outside of target (ie,560	 * external clock module controlled by the host). Target needs561	 * to know what frequency target cpu is configured which is needed562	 * for target internal use. Read target cpu frequency info from563	 * gcc register and write into target's scratch register where564	 * target expects this information.565	 */566	val = ath10k_ahb_gcc_read32(ar, ATH10K_AHB_GCC_FEPLL_PLL_DIV);567	ath10k_ahb_write32(ar, ATH10K_AHB_WIFI_SCRATCH_5_REG, val);568 569	ret = ath10k_ahb_release_reset(ar);570	if (ret)571		goto err_clk_disable;572 573	ath10k_ahb_irq_disable(ar);574 575	ath10k_ahb_write32(ar, FW_INDICATOR_ADDRESS, FW_IND_HOST_READY);576 577	ret = ath10k_pci_wait_for_target_init(ar);578	if (ret)579		goto err_halt_chip;580 581	return 0;582 583err_halt_chip:584	ath10k_ahb_halt_chip(ar);585 586err_clk_disable:587	ath10k_ahb_clock_disable(ar);588 589	return ret;590}591 592static int ath10k_ahb_chip_reset(struct ath10k *ar)593{594	int ret;595 596	ath10k_ahb_halt_chip(ar);597	ath10k_ahb_clock_disable(ar);598 599	ret = ath10k_ahb_prepare_device(ar);600	if (ret)601		return ret;602 603	return 0;604}605 606static int ath10k_ahb_wake_target_cpu(struct ath10k *ar)607{608	u32 addr, val;609 610	addr = SOC_CORE_BASE_ADDRESS | CORE_CTRL_ADDRESS;611	val = ath10k_ahb_read32(ar, addr);612	val |= ATH10K_AHB_CORE_CTRL_CPU_INTR_MASK;613	ath10k_ahb_write32(ar, addr, val);614 615	return 0;616}617 618static int ath10k_ahb_hif_start(struct ath10k *ar)619{620	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot ahb hif start\n");621 622	ath10k_core_napi_enable(ar);623	ath10k_ce_enable_interrupts(ar);624	ath10k_pci_enable_intx_irq(ar);625 626	ath10k_pci_rx_post(ar);627 628	return 0;629}630 631static void ath10k_ahb_hif_stop(struct ath10k *ar)632{633	struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);634 635	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot ahb hif stop\n");636 637	ath10k_ahb_irq_disable(ar);638	synchronize_irq(ar_ahb->irq);639 640	ath10k_core_napi_sync_disable(ar);641 642	ath10k_pci_flush(ar);643}644 645static int ath10k_ahb_hif_power_up(struct ath10k *ar,646				   enum ath10k_firmware_mode fw_mode)647{648	int ret;649 650	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot ahb hif power up\n");651 652	ret = ath10k_ahb_chip_reset(ar);653	if (ret) {654		ath10k_err(ar, "failed to reset chip: %d\n", ret);655		goto out;656	}657 658	ret = ath10k_pci_init_pipes(ar);659	if (ret) {660		ath10k_err(ar, "failed to initialize CE: %d\n", ret);661		goto out;662	}663 664	ret = ath10k_pci_init_config(ar);665	if (ret) {666		ath10k_err(ar, "failed to setup init config: %d\n", ret);667		goto err_ce_deinit;668	}669 670	ret = ath10k_ahb_wake_target_cpu(ar);671	if (ret) {672		ath10k_err(ar, "could not wake up target CPU: %d\n", ret);673		goto err_ce_deinit;674	}675 676	return 0;677 678err_ce_deinit:679	ath10k_pci_ce_deinit(ar);680out:681	return ret;682}683 684static u32 ath10k_ahb_qca4019_targ_cpu_to_ce_addr(struct ath10k *ar, u32 addr)685{686	u32 val = 0, region = addr & 0xfffff;687 688	val = ath10k_pci_read32(ar, PCIE_BAR_REG_ADDRESS);689 690	if (region >= QCA4019_SRAM_ADDR && region <=691	    (QCA4019_SRAM_ADDR + QCA4019_SRAM_LEN)) {692		/* SRAM contents for QCA4019 can be directly accessed and693		 * no conversions are required694		 */695		val |= region;696	} else {697		val |= 0x100000 | region;698	}699 700	return val;701}702 703static const struct ath10k_hif_ops ath10k_ahb_hif_ops = {704	.tx_sg                  = ath10k_pci_hif_tx_sg,705	.diag_read              = ath10k_pci_hif_diag_read,706	.diag_write             = ath10k_pci_diag_write_mem,707	.exchange_bmi_msg       = ath10k_pci_hif_exchange_bmi_msg,708	.start                  = ath10k_ahb_hif_start,709	.stop                   = ath10k_ahb_hif_stop,710	.map_service_to_pipe    = ath10k_pci_hif_map_service_to_pipe,711	.get_default_pipe       = ath10k_pci_hif_get_default_pipe,712	.send_complete_check    = ath10k_pci_hif_send_complete_check,713	.get_free_queue_number  = ath10k_pci_hif_get_free_queue_number,714	.power_up               = ath10k_ahb_hif_power_up,715	.power_down             = ath10k_pci_hif_power_down,716	.read32                 = ath10k_ahb_read32,717	.write32                = ath10k_ahb_write32,718};719 720static const struct ath10k_bus_ops ath10k_ahb_bus_ops = {721	.read32		= ath10k_ahb_read32,722	.write32	= ath10k_ahb_write32,723	.get_num_banks	= ath10k_ahb_get_num_banks,724};725 726static int ath10k_ahb_probe(struct platform_device *pdev)727{728	struct ath10k *ar;729	struct ath10k_ahb *ar_ahb;730	struct ath10k_pci *ar_pci;731	enum ath10k_hw_rev hw_rev;732	size_t size;733	int ret;734	struct ath10k_bus_params bus_params = {};735 736	hw_rev = (uintptr_t)of_device_get_match_data(&pdev->dev);737	if (!hw_rev) {738		dev_err(&pdev->dev, "OF data missing\n");739		return -EINVAL;740	}741 742	size = sizeof(*ar_pci) + sizeof(*ar_ahb);743	ar = ath10k_core_create(size, &pdev->dev, ATH10K_BUS_AHB,744				hw_rev, &ath10k_ahb_hif_ops);745	if (!ar) {746		dev_err(&pdev->dev, "failed to allocate core\n");747		return -ENOMEM;748	}749 750	ath10k_dbg(ar, ATH10K_DBG_BOOT, "ahb probe\n");751 752	ar_pci = ath10k_pci_priv(ar);753	ar_ahb = ath10k_ahb_priv(ar);754 755	ar_ahb->pdev = pdev;756	platform_set_drvdata(pdev, ar);757 758	ret = ath10k_ahb_resource_init(ar);759	if (ret)760		goto err_core_destroy;761 762	ar->dev_id = 0;763	ar_pci->mem = ar_ahb->mem;764	ar_pci->mem_len = ar_ahb->mem_len;765	ar_pci->ar = ar;766	ar_pci->ce.bus_ops = &ath10k_ahb_bus_ops;767	ar_pci->targ_cpu_to_ce_addr = ath10k_ahb_qca4019_targ_cpu_to_ce_addr;768	ar->ce_priv = &ar_pci->ce;769 770	ret = ath10k_pci_setup_resource(ar);771	if (ret) {772		ath10k_err(ar, "failed to setup resource: %d\n", ret);773		goto err_resource_deinit;774	}775 776	ath10k_pci_init_napi(ar);777 778	ret = ath10k_ahb_request_irq_intx(ar);779	if (ret)780		goto err_free_pipes;781 782	ret = ath10k_ahb_prepare_device(ar);783	if (ret)784		goto err_free_irq;785 786	ath10k_pci_ce_deinit(ar);787 788	bus_params.dev_type = ATH10K_DEV_TYPE_LL;789	bus_params.chip_id = ath10k_ahb_soc_read32(ar, SOC_CHIP_ID_ADDRESS);790	if (bus_params.chip_id == 0xffffffff) {791		ath10k_err(ar, "failed to get chip id\n");792		ret = -ENODEV;793		goto err_halt_device;794	}795 796	ret = ath10k_core_register(ar, &bus_params);797	if (ret) {798		ath10k_err(ar, "failed to register driver core: %d\n", ret);799		goto err_halt_device;800	}801 802	return 0;803 804err_halt_device:805	ath10k_ahb_halt_chip(ar);806	ath10k_ahb_clock_disable(ar);807 808err_free_irq:809	ath10k_ahb_release_irq_intx(ar);810 811err_free_pipes:812	ath10k_pci_release_resource(ar);813 814err_resource_deinit:815	ath10k_ahb_resource_deinit(ar);816 817err_core_destroy:818	ath10k_core_destroy(ar);819 820	return ret;821}822 823static void ath10k_ahb_remove(struct platform_device *pdev)824{825	struct ath10k *ar = platform_get_drvdata(pdev);826 827	ath10k_dbg(ar, ATH10K_DBG_AHB, "ahb remove\n");828 829	ath10k_core_unregister(ar);830	ath10k_ahb_irq_disable(ar);831	ath10k_ahb_release_irq_intx(ar);832	ath10k_pci_release_resource(ar);833	ath10k_ahb_halt_chip(ar);834	ath10k_ahb_clock_disable(ar);835	ath10k_ahb_resource_deinit(ar);836	ath10k_core_destroy(ar);837}838 839static struct platform_driver ath10k_ahb_driver = {840	.driver         = {841		.name   = "ath10k_ahb",842		.of_match_table = ath10k_ahb_of_match,843	},844	.probe  = ath10k_ahb_probe,845	.remove_new = ath10k_ahb_remove,846};847 848int ath10k_ahb_init(void)849{850	int ret;851 852	ret = platform_driver_register(&ath10k_ahb_driver);853	if (ret)854		printk(KERN_ERR "failed to register ath10k ahb driver: %d\n",855		       ret);856	return ret;857}858 859void ath10k_ahb_exit(void)860{861	platform_driver_unregister(&ath10k_ahb_driver);862}863