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