qcacmn: Removing pre lithium wlan driver support in 12.x Software
code related to IPQ4019 removed if_ahb.c and if_ahb_reset.c Change-Id: I3da65b975221f011ed4190b92177f85ced677785
Bu işleme şunda yer alıyor:

işlemeyi yapan:
Madan Koyyalamudi

ebeveyn
aad4011dcc
işleme
0bdaa8fb8a
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2018,2020-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
@@ -27,7 +28,6 @@ void hif_ahb_close(struct hif_softc *hif_ctx);
|
||||
|
||||
void hif_ahb_disable_isr(struct hif_softc *hif_ctx);
|
||||
void hif_ahb_nointrs(struct hif_softc *scn);
|
||||
void hif_ahb_reset_soc(struct hif_softc *hif_ctx);
|
||||
QDF_STATUS hif_ahb_enable_bus(struct hif_softc *ol_sc,
|
||||
struct device *dev, void *bdev,
|
||||
const struct hif_bus_id *bid,
|
||||
@@ -40,12 +40,6 @@ void hif_ahb_exec_grp_irq_disable(struct hif_exec_context *hif_ext_grp);
|
||||
void hif_ahb_exec_grp_irq_enable(struct hif_exec_context *hif_ext_grp);
|
||||
int hif_ahb_dump_registers(struct hif_softc *scn);
|
||||
|
||||
int hif_ahb_configure_legacy_irq(struct hif_pci_softc *sc);
|
||||
int hif_ahb_clk_enable_disable(struct device *dev, int enable);
|
||||
void hif_ahb_device_reset(struct hif_softc *scn);
|
||||
int hif_ahb_enable_radio(struct hif_pci_softc *sc,
|
||||
struct platform_device *pdev,
|
||||
const struct platform_device_id *id);
|
||||
int hif_ahb_configure_irq(struct hif_pci_softc *sc);
|
||||
int hif_ahb_configure_irq_by_ceid(struct hif_softc *sc, int ce_id);
|
||||
int hif_ahb_configure_grp_irq(struct hif_softc *scn,
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2018,2020-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
@@ -39,7 +39,7 @@ QDF_STATUS hif_initialize_ahb_ops(struct hif_bus_ops *bus_ops)
|
||||
bus_ops->hif_bus_open = &hif_ahb_open;
|
||||
bus_ops->hif_bus_close = &hif_ahb_close;
|
||||
bus_ops->hif_bus_prevent_linkdown = &hif_dummy_bus_prevent_linkdown;
|
||||
bus_ops->hif_reset_soc = &hif_ahb_reset_soc;
|
||||
bus_ops->hif_reset_soc = &hif_dummy_reset_soc;
|
||||
bus_ops->hif_bus_suspend = &hif_dummy_bus_suspend;
|
||||
bus_ops->hif_bus_resume = &hif_dummy_bus_resume;
|
||||
bus_ops->hif_target_sleep_state_adjust =
|
||||
|
@@ -2770,12 +2770,6 @@ void hif_target_dump_access_log(void)
|
||||
#endif
|
||||
|
||||
#ifndef HIF_AHB
|
||||
int hif_ahb_configure_legacy_irq(struct hif_pci_softc *sc)
|
||||
{
|
||||
QDF_BUG(0);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int hif_ahb_configure_irq(struct hif_pci_softc *sc)
|
||||
{
|
||||
QDF_BUG(0);
|
||||
@@ -3286,9 +3280,6 @@ int hif_configure_irq(struct hif_softc *scn)
|
||||
}
|
||||
|
||||
switch (scn->target_info.target_type) {
|
||||
case TARGET_TYPE_IPQ4019:
|
||||
ret = hif_ahb_configure_legacy_irq(sc);
|
||||
break;
|
||||
case TARGET_TYPE_QCA8074:
|
||||
case TARGET_TYPE_QCA8074V2:
|
||||
case TARGET_TYPE_QCA6018:
|
||||
|
@@ -202,62 +202,6 @@ int hif_ahb_bus_configure(struct hif_softc *scn)
|
||||
return hif_pci_bus_configure(scn);
|
||||
}
|
||||
|
||||
/**
|
||||
* hif_configure_msi_ahb - Configure MSI interrupts
|
||||
* @sc : pointer to the hif context
|
||||
*
|
||||
* return: 0 for success. nonzero for failure.
|
||||
*/
|
||||
|
||||
int hif_configure_msi_ahb(struct hif_pci_softc *sc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* hif_ahb_configure_legacy_irq() - Configure Legacy IRQ
|
||||
* @sc: pointer to the hif context.
|
||||
*
|
||||
* This function registers the irq handler and enables legacy interrupts
|
||||
*
|
||||
* return: 0 for success. nonzero for failure.
|
||||
*/
|
||||
int hif_ahb_configure_legacy_irq(struct hif_pci_softc *sc)
|
||||
{
|
||||
int ret = 0;
|
||||
struct hif_softc *scn = HIF_GET_SOFTC(sc);
|
||||
struct platform_device *pdev = (struct platform_device *)sc->pdev;
|
||||
int irq = 0;
|
||||
|
||||
/* do not support MSI or MSI IRQ failed */
|
||||
tasklet_init(&sc->intr_tq, wlan_tasklet, (unsigned long)sc);
|
||||
qal_vbus_get_irq((struct qdf_pfm_hndl *)pdev, "legacy", &irq);
|
||||
if (irq < 0) {
|
||||
dev_err(&pdev->dev, "Unable to get irq\n");
|
||||
ret = -EFAULT;
|
||||
goto end;
|
||||
}
|
||||
ret = request_irq(irq, hif_pci_legacy_ce_interrupt_handler,
|
||||
IRQF_DISABLED, "wlan_ahb", sc);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "ath_request_irq failed\n");
|
||||
ret = -EFAULT;
|
||||
goto end;
|
||||
}
|
||||
sc->irq = irq;
|
||||
|
||||
/* Use Legacy PCI Interrupts */
|
||||
hif_write32_mb(sc, sc->mem + (SOC_CORE_BASE_ADDRESS |
|
||||
PCIE_INTR_ENABLE_ADDRESS),
|
||||
PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL);
|
||||
/* read once to flush */
|
||||
hif_read32_mb(sc, sc->mem + (SOC_CORE_BASE_ADDRESS |
|
||||
PCIE_INTR_ENABLE_ADDRESS));
|
||||
|
||||
end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void hif_ahb_get_soc_info_pld(struct hif_pci_softc *sc,
|
||||
struct device *dev)
|
||||
{
|
||||
@@ -428,63 +372,6 @@ irqreturn_t hif_ahb_interrupt_handler(int irq, void *context)
|
||||
return ce_dispatch_interrupt(tasklet_entry->ce_id, tasklet_entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* hif_target_sync() : ensure the target is ready
|
||||
* @scn: hif control structure
|
||||
*
|
||||
* Informs fw that we plan to use legacy interupts so that
|
||||
* it can begin booting. Ensures that the fw finishes booting
|
||||
* before continuing. Should be called before trying to write
|
||||
* to the targets other registers for the first time.
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
int hif_target_sync_ahb(struct hif_softc *scn)
|
||||
{
|
||||
int val = 0;
|
||||
int limit = 0;
|
||||
|
||||
while (limit < 50) {
|
||||
hif_write32_mb(scn, scn->mem +
|
||||
(SOC_CORE_BASE_ADDRESS | PCIE_INTR_ENABLE_ADDRESS),
|
||||
PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL);
|
||||
qdf_mdelay(10);
|
||||
val = hif_read32_mb(scn, scn->mem +
|
||||
(SOC_CORE_BASE_ADDRESS | PCIE_INTR_ENABLE_ADDRESS));
|
||||
if (val == 0)
|
||||
break;
|
||||
limit++;
|
||||
}
|
||||
hif_write32_mb(scn, scn->mem +
|
||||
(SOC_CORE_BASE_ADDRESS | PCIE_INTR_ENABLE_ADDRESS),
|
||||
PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL);
|
||||
hif_write32_mb(scn, scn->mem + FW_INDICATOR_ADDRESS, FW_IND_HOST_READY);
|
||||
if (HAS_FW_INDICATOR) {
|
||||
int wait_limit = 500;
|
||||
int fw_ind = 0;
|
||||
|
||||
while (1) {
|
||||
fw_ind = hif_read32_mb(scn, scn->mem +
|
||||
FW_INDICATOR_ADDRESS);
|
||||
if (fw_ind & FW_IND_INITIALIZED)
|
||||
break;
|
||||
if (wait_limit-- < 0)
|
||||
break;
|
||||
hif_write32_mb(scn, scn->mem + (SOC_CORE_BASE_ADDRESS |
|
||||
PCIE_INTR_ENABLE_ADDRESS),
|
||||
PCIE_INTR_FIRMWARE_MASK);
|
||||
qdf_mdelay(10);
|
||||
}
|
||||
if (wait_limit < 0) {
|
||||
hif_info("FW signal timed out");
|
||||
return -EIO;
|
||||
}
|
||||
hif_info("Got FW signal, retries = %x", 500-wait_limit);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* hif_disable_bus() - Disable the bus
|
||||
* @scn : pointer to the hif context
|
||||
@@ -519,17 +406,6 @@ void hif_ahb_disable_bus(struct hif_softc *scn)
|
||||
if (memres)
|
||||
mem_pa_size = memres->end - memres->start + 1;
|
||||
|
||||
/* Should not be executed on 8074 platform */
|
||||
if ((tgt_info->target_type != TARGET_TYPE_QCA8074) &&
|
||||
(tgt_info->target_type != TARGET_TYPE_QCA8074V2) &&
|
||||
(tgt_info->target_type != TARGET_TYPE_QCA9574) &&
|
||||
(tgt_info->target_type != TARGET_TYPE_QCA5018) &&
|
||||
(tgt_info->target_type != TARGET_TYPE_QCN6122) &&
|
||||
(tgt_info->target_type != TARGET_TYPE_QCA6018)) {
|
||||
hif_ahb_clk_enable_disable(&pdev->dev, 0);
|
||||
|
||||
hif_ahb_device_reset(scn);
|
||||
}
|
||||
if (tgt_info->target_type == TARGET_TYPE_QCA5018) {
|
||||
iounmap(sc->mem_ce);
|
||||
sc->mem_ce = NULL;
|
||||
@@ -668,58 +544,14 @@ QDF_STATUS hif_ahb_enable_bus(struct hif_softc *ol_sc,
|
||||
ol_sc->mem_ce = sc->mem_ce;
|
||||
}
|
||||
|
||||
if ((tgt_info->target_type != TARGET_TYPE_QCA8074) &&
|
||||
(tgt_info->target_type != TARGET_TYPE_QCA8074V2) &&
|
||||
(tgt_info->target_type != TARGET_TYPE_QCA9574) &&
|
||||
(tgt_info->target_type != TARGET_TYPE_QCA5018) &&
|
||||
(tgt_info->target_type != TARGET_TYPE_QCN6122) &&
|
||||
(tgt_info->target_type != TARGET_TYPE_QCA6018)) {
|
||||
if (hif_ahb_enable_radio(sc, pdev, id) != 0) {
|
||||
hif_err("error in enabling soc");
|
||||
return QDF_STATUS_E_IO;
|
||||
}
|
||||
|
||||
if (hif_target_sync_ahb(ol_sc) < 0) {
|
||||
status = QDF_STATUS_E_IO;
|
||||
goto err_target_sync;
|
||||
}
|
||||
}
|
||||
hif_info("X - hif_type = 0x%x, target_type = 0x%x",
|
||||
hif_type, target_type);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
err_target_sync:
|
||||
if ((tgt_info->target_type != TARGET_TYPE_QCA8074) &&
|
||||
(tgt_info->target_type != TARGET_TYPE_QCA8074V2) &&
|
||||
(tgt_info->target_type != TARGET_TYPE_QCA9574) &&
|
||||
(tgt_info->target_type != TARGET_TYPE_QCN6122) &&
|
||||
(tgt_info->target_type != TARGET_TYPE_QCA5018) &&
|
||||
(tgt_info->target_type != TARGET_TYPE_QCA6018)) {
|
||||
hif_err("Disabling target");
|
||||
hif_ahb_disable_bus(ol_sc);
|
||||
}
|
||||
err_cleanup1:
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hif_reset_soc() - reset soc
|
||||
*
|
||||
* @hif_ctx: HIF context
|
||||
*
|
||||
* This function resets soc and helds the
|
||||
* target in reset state
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
/* Function to reset SoC */
|
||||
void hif_ahb_reset_soc(struct hif_softc *hif_ctx)
|
||||
{
|
||||
hif_ahb_device_reset(hif_ctx);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hif_nointrs() - disable IRQ
|
||||
*
|
||||
|
@@ -1,428 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
* above copyright notice and this permission notice appear in all
|
||||
* copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOC: if_ahb_reset.c
|
||||
*
|
||||
* c file for ahb ipq4019 specific implementations.
|
||||
*/
|
||||
|
||||
#include "hif.h"
|
||||
#include "target_type.h"
|
||||
#include "hif_main.h"
|
||||
#include "hif_debug.h"
|
||||
#include "hif_io32.h"
|
||||
#include "ce_main.h"
|
||||
#include "ce_tasklet.h"
|
||||
#include "ahb_api.h"
|
||||
#include "if_ahb.h"
|
||||
#include "qal_vbus_dev.h"
|
||||
#include "qal_devnode.h"
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/of.h>
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
|
||||
#include <linux/reset.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* clk_enable_disable() - Enable/disable clock
|
||||
* @dev : pointer to device structure
|
||||
* @str : clock name
|
||||
* @enable : should be true, if the clock needs to be enabled
|
||||
* should be false, if the clock needs to be enabled
|
||||
*
|
||||
* This is a helper function for hif_ahb_clk_enable_disable to enable
|
||||
* disable clocks.
|
||||
* clk_prepare_enable will enable the clock
|
||||
* clk_disable_unprepare will disable the clock
|
||||
*
|
||||
* Return: zero on success, non-zero incase of error.
|
||||
*/
|
||||
|
||||
static int clk_enable_disable(struct device *dev, const char *str, int enable)
|
||||
{
|
||||
struct clk *clk_t = NULL;
|
||||
int ret;
|
||||
QDF_STATUS status;
|
||||
|
||||
clk_t = clk_get(dev, str);
|
||||
if (IS_ERR(clk_t)) {
|
||||
hif_err("Failed to get %s clk %ld", str, PTR_ERR(clk_t));
|
||||
return -EFAULT;
|
||||
}
|
||||
if (true == enable) {
|
||||
/* Prepare and Enable clk */
|
||||
status = qal_vbus_enable_devclk((struct qdf_dev_clk *)clk_t);
|
||||
ret = qdf_status_to_os_return(status);
|
||||
if (ret) {
|
||||
hif_err("enabling clk: %s, error: %d", str, ret);
|
||||
}
|
||||
} else {
|
||||
/* Disable and unprepare clk */
|
||||
status = qal_vbus_disable_devclk((struct qdf_dev_clk *)clk_t);
|
||||
ret = qdf_status_to_os_return(status);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hif_ahb_clk_enable_disable() - Enable/disable ahb clock
|
||||
* @dev : pointer to device structure
|
||||
* @enable : should be true, if the clock needs to be enabled
|
||||
* should be false, if the clock needs to be enabled
|
||||
*
|
||||
* This functions helps to enable/disable all the necesasary clocks
|
||||
* for bus access.
|
||||
*
|
||||
* Return: zero on success, non-zero incase of error
|
||||
*/
|
||||
int hif_ahb_clk_enable_disable(struct device *dev, int enable)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = clk_enable_disable(dev, "wifi_wcss_cmd", enable);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = clk_enable_disable(dev, "wifi_wcss_ref", enable);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = clk_enable_disable(dev, "wifi_wcss_rtc", enable);
|
||||
if (ret)
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* hif_enable_radio() - Enable the target radio.
|
||||
* @sc : pointer to the hif context
|
||||
*
|
||||
* This function helps to release the target from reset state
|
||||
*
|
||||
* Return : zero on success, non-zero incase of error.
|
||||
*/
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
|
||||
int hif_ahb_enable_radio(struct hif_pci_softc *sc,
|
||||
struct platform_device *pdev,
|
||||
const struct platform_device_id *id)
|
||||
{
|
||||
struct reset_control *reset_ctl = NULL;
|
||||
uint32_t msi_addr, msi_base, wifi_core_id;
|
||||
struct hif_softc *scn = HIF_GET_SOFTC(sc);
|
||||
struct device_node *dev_node = pdev->dev.of_node;
|
||||
bool msienable = false;
|
||||
int ret = 0;
|
||||
struct qdf_vbus_rstctl *vrstctl = NULL;
|
||||
|
||||
ret = qal_devnode_read_u32(dev_node, "qca,msi_addr", &msi_addr);
|
||||
if (ret) {
|
||||
hif_err("Unable to get msi_addr - error :%d", ret);
|
||||
return -EIO;
|
||||
}
|
||||
ret = qal_devnode_read_u32(dev_node, "qca,msi_base", &msi_base);
|
||||
if (ret) {
|
||||
hif_err("Unable to get msi_base - error: %d", ret);
|
||||
return -EIO;
|
||||
}
|
||||
ret = qal_devnode_read_u32(dev_node, "core-id", &wifi_core_id);
|
||||
if (ret) {
|
||||
hif_err("Unable to get core-id - error: %d", ret);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* Program the above values into Wifi scratch regists */
|
||||
if (msienable) {
|
||||
hif_write32_mb(sc, sc->mem + FW_AXI_MSI_ADDR, msi_addr);
|
||||
hif_write32_mb(sc, sc->mem + FW_AXI_MSI_DATA, msi_base);
|
||||
}
|
||||
|
||||
/* TBD: Temporary changes. Frequency should be
|
||||
* retrieved through clk_xxx once kernel GCC driver is available
|
||||
*/
|
||||
{
|
||||
void __iomem *mem_gcc;
|
||||
uint32_t clk_sel;
|
||||
uint32_t gcc_fepll_pll_div;
|
||||
uint32_t wifi_cpu_freq[4] = {266700000, 250000000, 222200000,
|
||||
200000000};
|
||||
uint32_t current_freq = 0;
|
||||
|
||||
/* Enable WIFI clock input */
|
||||
if (scn->target_info.target_type == TARGET_TYPE_IPQ4019) {
|
||||
ret = hif_ahb_clk_enable_disable(&pdev->dev, 1);
|
||||
if (ret) {
|
||||
hif_err("Error while enabling clock :%d", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
mem_gcc = ioremap_nocache(GCC_BASE, GCC_SIZE);
|
||||
if (IS_ERR(mem_gcc)) {
|
||||
hif_err("GCC ioremap failed");
|
||||
return PTR_ERR(mem_gcc);
|
||||
}
|
||||
gcc_fepll_pll_div = hif_read32_mb(sc, mem_gcc +
|
||||
GCC_FEPLL_PLL_DIV);
|
||||
clk_sel = (wifi_core_id == 0) ? ((gcc_fepll_pll_div &
|
||||
GCC_FEPLL_PLL_CLK_WIFI_0_SEL_MASK) >>
|
||||
GCC_FEPLL_PLL_CLK_WIFI_0_SEL_SHIFT) :
|
||||
((gcc_fepll_pll_div & GCC_FEPLL_PLL_CLK_WIFI_1_SEL_MASK)
|
||||
>> GCC_FEPLL_PLL_CLK_WIFI_1_SEL_SHIFT);
|
||||
current_freq = wifi_cpu_freq[clk_sel];
|
||||
|
||||
hif_debug("Wifi%d CPU frequency %u", wifi_core_id, current_freq);
|
||||
hif_write32_mb(sc, sc->mem + FW_CPU_PLL_CONFIG,
|
||||
gcc_fepll_pll_div);
|
||||
iounmap(mem_gcc);
|
||||
}
|
||||
|
||||
/* De-assert radio cold reset */
|
||||
qal_vbus_get_dev_rstctl((struct qdf_pfm_hndl *)&pdev->dev,
|
||||
"wifi_radio_cold", &vrstctl);
|
||||
reset_ctl = (struct reset_control *)vrstctl;
|
||||
if (IS_ERR(reset_ctl)) {
|
||||
hif_err("Failed to get radio cold reset control");
|
||||
ret = PTR_ERR(reset_ctl);
|
||||
goto err_reset;
|
||||
}
|
||||
qal_vbus_deactivate_dev_rstctl((struct qdf_pfm_hndl *)&pdev->dev,
|
||||
(struct qdf_vbus_rstctl *)reset_ctl);
|
||||
qal_vbus_release_dev_rstctl((struct qdf_pfm_hndl *)&pdev->dev,
|
||||
(struct qdf_vbus_rstctl *)reset_ctl);
|
||||
|
||||
/* De-assert radio warm reset */
|
||||
qal_vbus_get_dev_rstctl((struct qdf_pfm_hndl *)&pdev->dev,
|
||||
"wifi_radio_warm", &vrstctl);
|
||||
reset_ctl = (struct reset_control *)vrstctl;
|
||||
if (IS_ERR(reset_ctl)) {
|
||||
hif_err("Failed to get radio warm reset control");
|
||||
ret = PTR_ERR(reset_ctl);
|
||||
goto err_reset;
|
||||
}
|
||||
qal_vbus_deactivate_dev_rstctl((struct qdf_pfm_hndl *)&pdev->dev,
|
||||
(struct qdf_vbus_rstctl *)reset_ctl);
|
||||
qal_vbus_release_dev_rstctl((struct qdf_pfm_hndl *)&pdev->dev,
|
||||
(struct qdf_vbus_rstctl *)reset_ctl);
|
||||
|
||||
/* De-assert radio srif reset */
|
||||
qal_vbus_get_dev_rstctl((struct qdf_pfm_hndl *)&pdev->dev,
|
||||
"wifi_radio_srif", &vrstctl);
|
||||
reset_ctl = (struct reset_control *)vrstctl;
|
||||
if (IS_ERR(reset_ctl)) {
|
||||
hif_err("Failed to get radio srif reset control");
|
||||
ret = PTR_ERR(reset_ctl);
|
||||
goto err_reset;
|
||||
}
|
||||
qal_vbus_deactivate_dev_rstctl((struct qdf_pfm_hndl *)&pdev->dev,
|
||||
(struct qdf_vbus_rstctl *)reset_ctl);
|
||||
qal_vbus_release_dev_rstctl((struct qdf_pfm_hndl *)&pdev->dev,
|
||||
(struct qdf_vbus_rstctl *)reset_ctl);
|
||||
|
||||
/* De-assert target CPU reset */
|
||||
qal_vbus_get_dev_rstctl((struct qdf_pfm_hndl *)&pdev->dev,
|
||||
"wifi_cpu_init", &vrstctl);
|
||||
reset_ctl = (struct reset_control *)vrstctl;
|
||||
if (IS_ERR(reset_ctl)) {
|
||||
hif_err("Failed to get cpu init reset control");
|
||||
ret = PTR_ERR(reset_ctl);
|
||||
goto err_reset;
|
||||
}
|
||||
qal_vbus_deactivate_dev_rstctl((struct qdf_pfm_hndl *)&pdev->dev,
|
||||
(struct qdf_vbus_rstctl *)reset_ctl);
|
||||
qal_vbus_release_dev_rstctl((struct qdf_pfm_hndl *)&pdev->dev,
|
||||
(struct qdf_vbus_rstctl *)reset_ctl);
|
||||
|
||||
return 0;
|
||||
|
||||
err_reset:
|
||||
return -EIO;
|
||||
}
|
||||
#else
|
||||
int hif_ahb_enable_radio(struct hif_pci_softc *sc,
|
||||
struct platform_device *pdev,
|
||||
const struct platform_device_id *id)
|
||||
{
|
||||
qdf_print("%s:%d:Reset routines not available in kernel version.",
|
||||
__func__, __LINE__);
|
||||
return -EIO;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* "wifi_core_warm" is the other reset type */
|
||||
#define AHB_RESET_TYPE "wifi_core_cold"
|
||||
|
||||
/**
|
||||
* hif_ahb_device_reset() - Disable the radio and held the radio is reset state.
|
||||
* @scn : pointer to the hif context
|
||||
*
|
||||
* This function will hold the target in reset state.
|
||||
* Will be called while unload the driver or any graceful unload path.
|
||||
*
|
||||
* Return : n/a.
|
||||
*/
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
|
||||
void hif_ahb_device_reset(struct hif_softc *scn)
|
||||
{
|
||||
struct reset_control *resetctl = NULL;
|
||||
struct reset_control *core_resetctl = NULL;
|
||||
struct hif_pci_softc *sc = HIF_GET_PCI_SOFTC(scn);
|
||||
struct platform_device *pdev = (struct platform_device *)(sc->pdev);
|
||||
uint32_t glb_cfg_offset;
|
||||
uint32_t haltreq_offset;
|
||||
uint32_t haltack_offset;
|
||||
void __iomem *mem_tcsr;
|
||||
uint32_t wifi_core_id = 0XFFFFFFFF;
|
||||
uint32_t reg_value;
|
||||
int wait_limit = ATH_AHB_RESET_WAIT_MAX;
|
||||
struct qdf_vbus_rstctl *vrstctl = NULL;
|
||||
|
||||
|
||||
wifi_core_id = hif_read32_mb(sc, sc->mem +
|
||||
WLAN_SUBSYSTEM_CORE_ID_ADDRESS);
|
||||
glb_cfg_offset = (wifi_core_id == 0) ? TCSR_WIFI0_GLB_CFG :
|
||||
TCSR_WIFI1_GLB_CFG;
|
||||
haltreq_offset = (wifi_core_id == 0) ? TCSR_WCSS0_HALTREQ :
|
||||
TCSR_WCSS1_HALTREQ;
|
||||
haltack_offset = (wifi_core_id == 0) ? TCSR_WCSS0_HALTACK :
|
||||
TCSR_WCSS1_HALTACK;
|
||||
|
||||
mem_tcsr = ioremap_nocache(TCSR_BASE, TCSR_SIZE);
|
||||
if (IS_ERR(mem_tcsr)) {
|
||||
hif_err("TCSR ioremap failed");
|
||||
return;
|
||||
}
|
||||
reg_value = hif_read32_mb(sc, mem_tcsr + haltreq_offset);
|
||||
hif_write32_mb(sc, mem_tcsr + haltreq_offset, reg_value | 0x1);
|
||||
/* Wait for halt ack before asserting reset */
|
||||
while (wait_limit) {
|
||||
|
||||
if (hif_read32_mb(sc, mem_tcsr + haltack_offset) & 0x1)
|
||||
break;
|
||||
|
||||
qdf_mdelay(1);
|
||||
wait_limit--;
|
||||
}
|
||||
|
||||
reg_value = hif_read32_mb(sc, mem_tcsr + glb_cfg_offset);
|
||||
hif_write32_mb(sc, mem_tcsr + glb_cfg_offset, reg_value | (1 << 25));
|
||||
|
||||
qal_vbus_get_dev_rstctl((struct qdf_pfm_hndl *)&pdev->dev,
|
||||
AHB_RESET_TYPE, &vrstctl);
|
||||
core_resetctl = (struct reset_control *)vrstctl;
|
||||
if (IS_ERR(core_resetctl)) {
|
||||
hif_err("Failed to get wifi core cold reset control");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Reset wifi core */
|
||||
qal_vbus_activate_dev_rstctl((struct qdf_pfm_hndl *)&pdev->dev,
|
||||
(struct qdf_vbus_rstctl *)core_resetctl);
|
||||
|
||||
/* TBD: Check if we should also assert other bits (radio_cold, radio_
|
||||
* warm, radio_srif, cpu_ini)
|
||||
*/
|
||||
qdf_mdelay(1); /* TBD: Get reqd delay from HW team */
|
||||
|
||||
/* Assert radio cold reset */
|
||||
qal_vbus_get_dev_rstctl((struct qdf_pfm_hndl *)&pdev->dev,
|
||||
"wifi_radio_cold", &vrstctl);
|
||||
resetctl = (struct reset_control *)vrstctl;
|
||||
if (IS_ERR(resetctl)) {
|
||||
hif_err("Failed to get radio cold reset control");
|
||||
return;
|
||||
}
|
||||
qal_vbus_activate_dev_rstctl((struct qdf_pfm_hndl *)&pdev->dev,
|
||||
(struct qdf_vbus_rstctl *)resetctl);
|
||||
qdf_mdelay(1); /* TBD: Get reqd delay from HW team */
|
||||
qal_vbus_release_dev_rstctl((struct qdf_pfm_hndl *)&pdev->dev,
|
||||
(struct qdf_vbus_rstctl *)resetctl);
|
||||
|
||||
/* Assert radio warm reset */
|
||||
qal_vbus_get_dev_rstctl((struct qdf_pfm_hndl *)&pdev->dev,
|
||||
"wifi_radio_warm", &vrstctl);
|
||||
resetctl = (struct reset_control *)vrstctl;
|
||||
if (IS_ERR(resetctl)) {
|
||||
hif_err("Failed to get radio warm reset control");
|
||||
return;
|
||||
}
|
||||
qal_vbus_activate_dev_rstctl((struct qdf_pfm_hndl *)&pdev->dev,
|
||||
(struct qdf_vbus_rstctl *)resetctl);
|
||||
qdf_mdelay(1); /* TBD: Get reqd delay from HW team */
|
||||
qal_vbus_release_dev_rstctl((struct qdf_pfm_hndl *)&pdev->dev,
|
||||
(struct qdf_vbus_rstctl *)resetctl);
|
||||
|
||||
/* Assert radio srif reset */
|
||||
qal_vbus_get_dev_rstctl((struct qdf_pfm_hndl *)&pdev->dev,
|
||||
"wifi_radio_srif", &vrstctl);
|
||||
resetctl = (struct reset_control *)vrstctl;
|
||||
if (IS_ERR(resetctl)) {
|
||||
hif_err("Failed to get radio srif reset control");
|
||||
return;
|
||||
}
|
||||
qal_vbus_activate_dev_rstctl((struct qdf_pfm_hndl *)&pdev->dev,
|
||||
(struct qdf_vbus_rstctl *)resetctl);
|
||||
qdf_mdelay(1); /* TBD: Get reqd delay from HW team */
|
||||
qal_vbus_release_dev_rstctl((struct qdf_pfm_hndl *)&pdev->dev,
|
||||
(struct qdf_vbus_rstctl *)resetctl);
|
||||
|
||||
/* Assert target CPU reset */
|
||||
qal_vbus_get_dev_rstctl((struct qdf_pfm_hndl *)&pdev->dev,
|
||||
"wifi_cpu_init", &vrstctl);
|
||||
resetctl = (struct reset_control *)vrstctl;
|
||||
if (IS_ERR(resetctl)) {
|
||||
hif_err("Failed to get cpu init reset control");
|
||||
return;
|
||||
}
|
||||
qal_vbus_activate_dev_rstctl((struct qdf_pfm_hndl *)&pdev->dev,
|
||||
(struct qdf_vbus_rstctl *)resetctl);
|
||||
qdf_mdelay(10); /* TBD: Get reqd delay from HW team */
|
||||
qal_vbus_release_dev_rstctl((struct qdf_pfm_hndl *)&pdev->dev,
|
||||
(struct qdf_vbus_rstctl *)resetctl);
|
||||
|
||||
/* Clear gbl_cfg and haltreq before clearing Wifi core reset */
|
||||
reg_value = hif_read32_mb(sc, mem_tcsr + haltreq_offset);
|
||||
hif_write32_mb(sc, mem_tcsr + haltreq_offset, reg_value & ~0x1);
|
||||
reg_value = hif_read32_mb(sc, mem_tcsr + glb_cfg_offset);
|
||||
hif_write32_mb(sc, mem_tcsr + glb_cfg_offset, reg_value & ~(1 << 25));
|
||||
|
||||
/* de-assert wifi core reset */
|
||||
qal_vbus_deactivate_dev_rstctl((struct qdf_pfm_hndl *)&pdev->dev,
|
||||
(struct qdf_vbus_rstctl *)core_resetctl);
|
||||
|
||||
qdf_mdelay(1); /* TBD: Get reqd delay from HW team */
|
||||
|
||||
/* TBD: Check if we should de-assert other bits here */
|
||||
qal_vbus_release_dev_rstctl((struct qdf_pfm_hndl *)&pdev->dev,
|
||||
(struct qdf_vbus_rstctl *)core_resetctl);
|
||||
iounmap(mem_tcsr);
|
||||
hif_info("Reset complete for wifi core id: %d", wifi_core_id);
|
||||
}
|
||||
#else
|
||||
void hif_ahb_device_reset(struct hif_softc *scn)
|
||||
{
|
||||
qdf_print("%s:%d:Reset routines not available in kernel version.",
|
||||
__func__, __LINE__);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
Yeni konuda referans
Bir kullanıcı engelle