1/** @file pcie_core.c 2 * 3 * Contains PCIe related functions that are shared between different driver models (e.g. firmware 4 * builds, DHD builds, BMAC builds), in order to avoid code duplication. 5 * 6 * Copyright (C) 2015, Broadcom Corporation. All Rights Reserved. 7 * 8 * Permission to use, copy, modify, and/or distribute this software for any 9 * purpose with or without fee is hereby granted, provided that the above 10 * copyright notice and this permission notice appear in all copies. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 15 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 17 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 18 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 * 20 * $Id: pcie_core.c 444841 2013-12-21 04:32:29Z $ 21 */ 22 23#include <bcm_cfg.h> 24#include <typedefs.h> 25#include <bcmutils.h> 26#include <bcmdefs.h> 27#include <osl.h> 28#include <siutils.h> 29#include <hndsoc.h> 30#include <sbchipc.h> 31 32#include "pcie_core.h" 33 34/* local prototypes */ 35 36/* local variables */ 37 38/* function definitions */ 39 40 41void pcie_watchdog_reset(osl_t *osh, si_t *sih, sbpcieregs_t *sbpcieregs) 42{ 43 uint32 val, i, lsc; 44 uint16 cfg_offset[] = {PCIECFGREG_STATUS_CMD, PCIECFGREG_PM_CSR, 45 PCIECFGREG_MSI_CAP, PCIECFGREG_MSI_ADDR_L, 46 PCIECFGREG_MSI_ADDR_H, PCIECFGREG_MSI_DATA, 47 PCIECFGREG_LINK_STATUS_CTRL2, PCIECFGREG_RBAR_CTRL, 48 PCIECFGREG_PML1_SUB_CTRL1, PCIECFGREG_REG_BAR2_CONFIG, 49 PCIECFGREG_REG_BAR3_CONFIG}; 50 uint32 origidx = si_coreidx(sih); 51 52 /* Disable/restore ASPM Control to protect the watchdog reset */ 53 W_REG(osh, &sbpcieregs->configaddr, PCIECFGREG_LINK_STATUS_CTRL); 54 lsc = R_REG(osh, &sbpcieregs->configdata); 55 val = lsc & (~PCIE_ASPM_ENAB); 56 W_REG(osh, &sbpcieregs->configdata, val); 57 58 si_setcore(sih, PCIE2_CORE_ID, 0); 59 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, watchdog), ~0, 4); 60 OSL_DELAY(100000); 61#ifdef BCMQT 62 OSL_DELAY(200000); 63#endif /* BCMQT */ 64 65 W_REG(osh, &sbpcieregs->configaddr, PCIECFGREG_LINK_STATUS_CTRL); 66 W_REG(osh, &sbpcieregs->configdata, lsc); 67 68 /* Write configuration registers back to the shadow registers 69 * cause shadow registers are cleared out after watchdog reset. 70 */ 71 for (i = 0; i < ARRAYSIZE(cfg_offset); i++) { 72 W_REG(osh, &sbpcieregs->configaddr, cfg_offset[i]); 73 val = R_REG(osh, &sbpcieregs->configdata); 74 W_REG(osh, &sbpcieregs->configdata, val); 75 } 76 si_setcoreidx(sih, origidx); 77} 78 79