/*
 * Copyright (c) 2010 Broadcom Corporation
 *
 * 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.
 */

#include <linux/string.h>
#include <linuxver.h>
#include <bcmdefs.h>
#include <osl.h>
#include <bcmutils.h>
#include <siutils.h>
#include <hndsoc.h>
#include <bcmdevs.h>
#include <sbchipc.h>
#include <pci_core.h>
#include <pcie_core.h>
#include <nicpci.h>
#include <pcicfg.h>

typedef struct {
	union {
		sbpcieregs_t *pcieregs;
		struct sbpciregs *pciregs;
	} regs;			/* Memory mapped register to the core */

	si_t *sih;		/* System interconnect handle */
	osl_t *osh;		/* OSL handle */
	u8 pciecap_lcreg_offset;	/* PCIE capability LCreg offset in the config space */
	bool pcie_pr42767;
	u8 pcie_polarity;
	u8 pcie_war_aspm_ovr;	/* Override ASPM/Clkreq settings */

	u8 pmecap_offset;	/* PM Capability offset in the config space */
	bool pmecap;		/* Capable of generating PME */
} pcicore_info_t;

/* debug/trace */
#define	PCI_ERROR(args)
#define PCIE_PUB(sih) ((BUSTYPE((sih)->bustype) == PCI_BUS) && ((sih)->buscoretype == PCIE_CORE_ID))

/* routines to access mdio slave device registers */
static bool pcie_mdiosetblock(pcicore_info_t *pi, uint blk);
static int pcie_mdioop(pcicore_info_t *pi, uint physmedia, uint regaddr,
		       bool write, uint *val);
static int pcie_mdiowrite(pcicore_info_t *pi, uint physmedia, uint readdr,
			  uint val);
static int pcie_mdioread(pcicore_info_t *pi, uint physmedia, uint readdr,
			 uint *ret_val);

static void pcie_extendL1timer(pcicore_info_t *pi, bool extend);
static void pcie_clkreq_upd(pcicore_info_t *pi, uint state);

static void pcie_war_aspm_clkreq(pcicore_info_t *pi);
static void pcie_war_serdes(pcicore_info_t *pi);
static void pcie_war_noplldown(pcicore_info_t *pi);
static void pcie_war_polarity(pcicore_info_t *pi);
static void pcie_war_pci_setup(pcicore_info_t *pi);

static bool pcicore_pmecap(pcicore_info_t *pi);

#define PCIE_ASPM(sih)	((PCIE_PUB(sih)) && (((sih)->buscorerev >= 3) && ((sih)->buscorerev <= 5)))

#define DWORD_ALIGN(x)  (x & ~(0x03))
#define BYTE_POS(x) (x & 0x3)
#define WORD_POS(x) (x & 0x1)

#define BYTE_SHIFT(x)  (8 * BYTE_POS(x))
#define WORD_SHIFT(x)  (16 * WORD_POS(x))

#define BYTE_VAL(a, x) ((a >> BYTE_SHIFT(x)) & 0xFF)
#define WORD_VAL(a, x) ((a >> WORD_SHIFT(x)) & 0xFFFF)

#define read_pci_cfg_byte(a) \
	(BYTE_VAL(OSL_PCI_READ_CONFIG(osh, DWORD_ALIGN(a), 4), a) & 0xff)

#define read_pci_cfg_word(a) \
	(WORD_VAL(OSL_PCI_READ_CONFIG(osh, DWORD_ALIGN(a), 4), a) & 0xffff)

#define write_pci_cfg_byte(a, val) do { \
	u32 tmpval; \
	tmpval = (OSL_PCI_READ_CONFIG(osh, DWORD_ALIGN(a), 4) & ~0xFF << BYTE_POS(a)) | \
		val << BYTE_POS(a); \
	OSL_PCI_WRITE_CONFIG(osh, DWORD_ALIGN(a), 4, tmpval); \
	} while (0)

#define write_pci_cfg_word(a, val) do { \
	u32 tmpval; \
	tmpval = (OSL_PCI_READ_CONFIG(osh, DWORD_ALIGN(a), 4) & ~0xFFFF << WORD_POS(a)) | \
		val << WORD_POS(a); \
	OSL_PCI_WRITE_CONFIG(osh, DWORD_ALIGN(a), 4, tmpval); \
	} while (0)

/* delay needed between the mdio control/ mdiodata register data access */
#define PR28829_DELAY() udelay(10)

/* Initialize the PCI core. It's caller's responsibility to make sure that this is done
 * only once
 */
void *pcicore_init(si_t *sih, osl_t *osh, void *regs)
{
	pcicore_info_t *pi;

	ASSERT(sih->bustype == PCI_BUS);

	/* alloc pcicore_info_t */
	pi = kzalloc(sizeof(pcicore_info_t), GFP_ATOMIC);
	if (pi == NULL) {
		PCI_ERROR(("pci_attach: malloc failed!\n"));
		return NULL;
	}

	pi->sih = sih;
	pi->osh = osh;

	if (sih->buscoretype == PCIE_CORE_ID) {
		u8 cap_ptr;
		pi->regs.pcieregs = (sbpcieregs_t *) regs;
		cap_ptr =
		    pcicore_find_pci_capability(pi->osh, PCI_CAP_PCIECAP_ID,
						NULL, NULL);
		ASSERT(cap_ptr);
		pi->pciecap_lcreg_offset = cap_ptr + PCIE_CAP_LINKCTRL_OFFSET;
	} else
		pi->regs.pciregs = (struct sbpciregs *) regs;

	return pi;
}

void pcicore_deinit(void *pch)
{
	pcicore_info_t *pi = (pcicore_info_t *) pch;

	if (pi == NULL)
		return;
	kfree(pi);
}

/* return cap_offset if requested capability exists in the PCI config space */
/* Note that it's caller's responsibility to make sure it's a pci bus */
u8
pcicore_find_pci_capability(osl_t *osh, u8 req_cap_id, unsigned char *buf,
			    u32 *buflen)
{
	u8 cap_id;
	u8 cap_ptr = 0;
	u32 bufsize;
	u8 byte_val;

	/* check for Header type 0 */
	byte_val = read_pci_cfg_byte(PCI_CFG_HDR);
	if ((byte_val & 0x7f) != PCI_HEADER_NORMAL)
		goto end;

	/* check if the capability pointer field exists */
	byte_val = read_pci_cfg_byte(PCI_CFG_STAT);
	if (!(byte_val & PCI_CAPPTR_PRESENT))
		goto end;

	cap_ptr = read_pci_cfg_byte(PCI_CFG_CAPPTR);
	/* check if the capability pointer is 0x00 */
	if (cap_ptr == 0x00)
		goto end;

	/* loop thr'u the capability list and see if the pcie capabilty exists */

	cap_id = read_pci_cfg_byte(cap_ptr);

	while (cap_id != req_cap_id) {
		cap_ptr = read_pci_cfg_byte((cap_ptr + 1));
		if (cap_ptr == 0x00)
			break;
		cap_id = read_pci_cfg_byte(cap_ptr);
	}
	if (cap_id != req_cap_id) {
		goto end;
	}
	/* found the caller requested capability */
	if ((buf != NULL) && (buflen != NULL)) {
		u8 cap_data;

		bufsize = *buflen;
		if (!bufsize)
			goto end;
		*buflen = 0;
		/* copy the cpability data excluding cap ID and next ptr */
		cap_data = cap_ptr + 2;
		if ((bufsize + cap_data) > SZPCR)
			bufsize = SZPCR - cap_data;
		*buflen = bufsize;
		while (bufsize--) {
			*buf = read_pci_cfg_byte(cap_data);
			cap_data++;
			buf++;
		}
	}
 end:
	return cap_ptr;
}

/* ***** Register Access API */
uint
pcie_readreg(osl_t *osh, sbpcieregs_t *pcieregs, uint addrtype, uint offset)
{
	uint retval = 0xFFFFFFFF;

	ASSERT(pcieregs != NULL);

	switch (addrtype) {
	case PCIE_CONFIGREGS:
		W_REG(osh, (&pcieregs->configaddr), offset);
		(void)R_REG(osh, (&pcieregs->configaddr));
		retval = R_REG(osh, &(pcieregs->configdata));
		break;
	case PCIE_PCIEREGS:
		W_REG(osh, &(pcieregs->pcieindaddr), offset);
		(void)R_REG(osh, (&pcieregs->pcieindaddr));
		retval = R_REG(osh, &(pcieregs->pcieinddata));
		break;
	default:
		ASSERT(0);
		break;
	}

	return retval;
}

uint
pcie_writereg(osl_t *osh, sbpcieregs_t *pcieregs, uint addrtype, uint offset,
	      uint val)
{
	ASSERT(pcieregs != NULL);

	switch (addrtype) {
	case PCIE_CONFIGREGS:
		W_REG(osh, (&pcieregs->configaddr), offset);
		W_REG(osh, (&pcieregs->configdata), val);
		break;
	case PCIE_PCIEREGS:
		W_REG(osh, (&pcieregs->pcieindaddr), offset);
		W_REG(osh, (&pcieregs->pcieinddata), val);
		break;
	default:
		ASSERT(0);
		break;
	}
	return 0;
}

static bool pcie_mdiosetblock(pcicore_info_t *pi, uint blk)
{
	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
	uint mdiodata, i = 0;
	uint pcie_serdes_spinwait = 200;

	mdiodata =
	    MDIODATA_START | MDIODATA_WRITE | (MDIODATA_DEV_ADDR <<
					       MDIODATA_DEVADDR_SHF) |
	    (MDIODATA_BLK_ADDR << MDIODATA_REGADDR_SHF) | MDIODATA_TA | (blk <<
									 4);
	W_REG(pi->osh, &pcieregs->mdiodata, mdiodata);

	PR28829_DELAY();
	/* retry till the transaction is complete */
	while (i < pcie_serdes_spinwait) {
		if (R_REG(pi->osh, &(pcieregs->mdiocontrol)) &
		    MDIOCTL_ACCESS_DONE) {
			break;
		}
		udelay(1000);
		i++;
	}

	if (i >= pcie_serdes_spinwait) {
		PCI_ERROR(("pcie_mdiosetblock: timed out\n"));
		return false;
	}

	return true;
}

static int
pcie_mdioop(pcicore_info_t *pi, uint physmedia, uint regaddr, bool write,
	    uint *val)
{
	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
	uint mdiodata;
	uint i = 0;
	uint pcie_serdes_spinwait = 10;

	/* enable mdio access to SERDES */
	W_REG(pi->osh, (&pcieregs->mdiocontrol),
	      MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);

	if (pi->sih->buscorerev >= 10) {
		/* new serdes is slower in rw, using two layers of reg address mapping */
		if (!pcie_mdiosetblock(pi, physmedia))
			return 1;
		mdiodata = (MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) |
		    (regaddr << MDIODATA_REGADDR_SHF);
		pcie_serdes_spinwait *= 20;
	} else {
		mdiodata = (physmedia << MDIODATA_DEVADDR_SHF_OLD) |
		    (regaddr << MDIODATA_REGADDR_SHF_OLD);
	}

	if (!write)
		mdiodata |= (MDIODATA_START | MDIODATA_READ | MDIODATA_TA);
	else
		mdiodata |=
		    (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA | *val);

	W_REG(pi->osh, &pcieregs->mdiodata, mdiodata);

	PR28829_DELAY();

	/* retry till the transaction is complete */
	while (i < pcie_serdes_spinwait) {
		if (R_REG(pi->osh, &(pcieregs->mdiocontrol)) &
		    MDIOCTL_ACCESS_DONE) {
			if (!write) {
				PR28829_DELAY();
				*val =
				    (R_REG(pi->osh, &(pcieregs->mdiodata)) &
				     MDIODATA_MASK);
			}
			/* Disable mdio access to SERDES */
			W_REG(pi->osh, (&pcieregs->mdiocontrol), 0);
			return 0;
		}
		udelay(1000);
		i++;
	}

	PCI_ERROR(("pcie_mdioop: timed out op: %d\n", write));
	/* Disable mdio access to SERDES */
	W_REG(pi->osh, (&pcieregs->mdiocontrol), 0);
	return 1;
}

/* use the mdio interface to read from mdio slaves */
static int
pcie_mdioread(pcicore_info_t *pi, uint physmedia, uint regaddr, uint *regval)
{
	return pcie_mdioop(pi, physmedia, regaddr, false, regval);
}

/* use the mdio interface to write to mdio slaves */
static int
pcie_mdiowrite(pcicore_info_t *pi, uint physmedia, uint regaddr, uint val)
{
	return pcie_mdioop(pi, physmedia, regaddr, true, &val);
}

/* ***** Support functions ***** */
u8 pcie_clkreq(void *pch, u32 mask, u32 val)
{
	pcicore_info_t *pi = (pcicore_info_t *) pch;
	u32 reg_val;
	u8 offset;

	offset = pi->pciecap_lcreg_offset;
	if (!offset)
		return 0;

	reg_val = OSL_PCI_READ_CONFIG(pi->osh, offset, sizeof(u32));
	/* set operation */
	if (mask) {
		if (val)
			reg_val |= PCIE_CLKREQ_ENAB;
		else
			reg_val &= ~PCIE_CLKREQ_ENAB;
		OSL_PCI_WRITE_CONFIG(pi->osh, offset, sizeof(u32), reg_val);
		reg_val = OSL_PCI_READ_CONFIG(pi->osh, offset, sizeof(u32));
	}
	if (reg_val & PCIE_CLKREQ_ENAB)
		return 1;
	else
		return 0;
}

static void pcie_extendL1timer(pcicore_info_t *pi, bool extend)
{
	u32 w;
	si_t *sih = pi->sih;
	osl_t *osh = pi->osh;
	sbpcieregs_t *pcieregs = pi->regs.pcieregs;

	if (!PCIE_PUB(sih) || sih->buscorerev < 7)
		return;

	w = pcie_readreg(osh, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
	if (extend)
		w |= PCIE_ASPMTIMER_EXTEND;
	else
		w &= ~PCIE_ASPMTIMER_EXTEND;
	pcie_writereg(osh, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG, w);
	w = pcie_readreg(osh, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
}

/* centralized clkreq control policy */
static void pcie_clkreq_upd(pcicore_info_t *pi, uint state)
{
	si_t *sih = pi->sih;
	ASSERT(PCIE_PUB(sih));

	switch (state) {
	case SI_DOATTACH:
		if (PCIE_ASPM(sih))
			pcie_clkreq((void *)pi, 1, 0);
		break;
	case SI_PCIDOWN:
		if (sih->buscorerev == 6) {	/* turn on serdes PLL down */
			si_corereg(sih, SI_CC_IDX,
				   offsetof(chipcregs_t, chipcontrol_addr), ~0,
				   0);
			si_corereg(sih, SI_CC_IDX,
				   offsetof(chipcregs_t, chipcontrol_data),
				   ~0x40, 0);
		} else if (pi->pcie_pr42767) {
			pcie_clkreq((void *)pi, 1, 1);
		}
		break;
	case SI_PCIUP:
		if (sih->buscorerev == 6) {	/* turn off serdes PLL down */
			si_corereg(sih, SI_CC_IDX,
				   offsetof(chipcregs_t, chipcontrol_addr), ~0,
				   0);
			si_corereg(sih, SI_CC_IDX,
				   offsetof(chipcregs_t, chipcontrol_data),
				   ~0x40, 0x40);
		} else if (PCIE_ASPM(sih)) {	/* disable clkreq */
			pcie_clkreq((void *)pi, 1, 0);
		}
		break;
	default:
		ASSERT(0);
		break;
	}
}

/* ***** PCI core WARs ***** */
/* Done only once at attach time */
static void pcie_war_polarity(pcicore_info_t *pi)
{
	u32 w;

	if (pi->pcie_polarity != 0)
		return;

	w = pcie_readreg(pi->osh, pi->regs.pcieregs, PCIE_PCIEREGS,
			 PCIE_PLP_STATUSREG);

	/* Detect the current polarity at attach and force that polarity and
	 * disable changing the polarity
	 */
	if ((w & PCIE_PLP_POLARITYINV_STAT) == 0)
		pi->pcie_polarity = (SERDES_RX_CTRL_FORCE);
	else
		pi->pcie_polarity =
		    (SERDES_RX_CTRL_FORCE | SERDES_RX_CTRL_POLARITY);
}

/* enable ASPM and CLKREQ if srom doesn't have it */
/* Needs to happen when update to shadow SROM is needed
 *   : Coming out of 'standby'/'hibernate'
 *   : If pcie_war_aspm_ovr state changed
 */
static void pcie_war_aspm_clkreq(pcicore_info_t *pi)
{
	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
	si_t *sih = pi->sih;
	u16 val16, *reg16;
	u32 w;

	if (!PCIE_ASPM(sih))
		return;

	/* bypass this on QT or VSIM */
	if (!ISSIM_ENAB(sih)) {

		reg16 = &pcieregs->sprom[SRSH_ASPM_OFFSET];
		val16 = R_REG(pi->osh, reg16);

		val16 &= ~SRSH_ASPM_ENB;
		if (pi->pcie_war_aspm_ovr == PCIE_ASPM_ENAB)
			val16 |= SRSH_ASPM_ENB;
		else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L1_ENAB)
			val16 |= SRSH_ASPM_L1_ENB;
		else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L0s_ENAB)
			val16 |= SRSH_ASPM_L0s_ENB;

		W_REG(pi->osh, reg16, val16);

		w = OSL_PCI_READ_CONFIG(pi->osh, pi->pciecap_lcreg_offset,
					sizeof(u32));
		w &= ~PCIE_ASPM_ENAB;
		w |= pi->pcie_war_aspm_ovr;
		OSL_PCI_WRITE_CONFIG(pi->osh, pi->pciecap_lcreg_offset,
				     sizeof(u32), w);
	}

	reg16 = &pcieregs->sprom[SRSH_CLKREQ_OFFSET_REV5];
	val16 = R_REG(pi->osh, reg16);

	if (pi->pcie_war_aspm_ovr != PCIE_ASPM_DISAB) {
		val16 |= SRSH_CLKREQ_ENB;
		pi->pcie_pr42767 = true;
	} else
		val16 &= ~SRSH_CLKREQ_ENB;

	W_REG(pi->osh, reg16, val16);
}

/* Apply the polarity determined at the start */
/* Needs to happen when coming out of 'standby'/'hibernate' */
static void pcie_war_serdes(pcicore_info_t *pi)
{
	u32 w = 0;

	if (pi->pcie_polarity != 0)
		pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CTRL,
			       pi->pcie_polarity);

	pcie_mdioread(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, &w);
	if (w & PLL_CTRL_FREQDET_EN) {
		w &= ~PLL_CTRL_FREQDET_EN;
		pcie_mdiowrite(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, w);
	}
}

/* Fix MISC config to allow coming out of L2/L3-Ready state w/o PRST */
/* Needs to happen when coming out of 'standby'/'hibernate' */
static void pcie_misc_config_fixup(pcicore_info_t *pi)
{
	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
	u16 val16, *reg16;

	reg16 = &pcieregs->sprom[SRSH_PCIE_MISC_CONFIG];
	val16 = R_REG(pi->osh, reg16);

	if ((val16 & SRSH_L23READY_EXIT_NOPERST) == 0) {
		val16 |= SRSH_L23READY_EXIT_NOPERST;
		W_REG(pi->osh, reg16, val16);
	}
}

/* quick hack for testing */
/* Needs to happen when coming out of 'standby'/'hibernate' */
static void pcie_war_noplldown(pcicore_info_t *pi)
{
	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
	u16 *reg16;

	ASSERT(pi->sih->buscorerev == 7);

	/* turn off serdes PLL down */
	si_corereg(pi->sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol),
		   CHIPCTRL_4321_PLL_DOWN, CHIPCTRL_4321_PLL_DOWN);

	/*  clear srom shadow backdoor */
	reg16 = &pcieregs->sprom[SRSH_BD_OFFSET];
	W_REG(pi->osh, reg16, 0);
}

/* Needs to happen when coming out of 'standby'/'hibernate' */
static void pcie_war_pci_setup(pcicore_info_t *pi)
{
	si_t *sih = pi->sih;
	osl_t *osh = pi->osh;
	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
	u32 w;

	if ((sih->buscorerev == 0) || (sih->buscorerev == 1)) {
		w = pcie_readreg(osh, pcieregs, PCIE_PCIEREGS,
				 PCIE_TLP_WORKAROUNDSREG);
		w |= 0x8;
		pcie_writereg(osh, pcieregs, PCIE_PCIEREGS,
			      PCIE_TLP_WORKAROUNDSREG, w);
	}

	if (sih->buscorerev == 1) {
		w = pcie_readreg(osh, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG);
		w |= (0x40);
		pcie_writereg(osh, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG, w);
	}

	if (sih->buscorerev == 0) {
		pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_TIMER1, 0x8128);
		pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDR, 0x0100);
		pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDRBW, 0x1466);
	} else if (PCIE_ASPM(sih)) {
		/* Change the L1 threshold for better performance */
		w = pcie_readreg(osh, pcieregs, PCIE_PCIEREGS,
				 PCIE_DLLP_PMTHRESHREG);
		w &= ~(PCIE_L1THRESHOLDTIME_MASK);
		w |= (PCIE_L1THRESHOLD_WARVAL << PCIE_L1THRESHOLDTIME_SHIFT);
		pcie_writereg(osh, pcieregs, PCIE_PCIEREGS,
			      PCIE_DLLP_PMTHRESHREG, w);

		pcie_war_serdes(pi);

		pcie_war_aspm_clkreq(pi);
	} else if (pi->sih->buscorerev == 7)
		pcie_war_noplldown(pi);

	/* Note that the fix is actually in the SROM, that's why this is open-ended */
	if (pi->sih->buscorerev >= 6)
		pcie_misc_config_fixup(pi);
}

void pcie_war_ovr_aspm_update(void *pch, u8 aspm)
{
	pcicore_info_t *pi = (pcicore_info_t *) pch;

	if (!PCIE_ASPM(pi->sih))
		return;

	/* Validate */
	if (aspm > PCIE_ASPM_ENAB)
		return;

	pi->pcie_war_aspm_ovr = aspm;

	/* Update the current state */
	pcie_war_aspm_clkreq(pi);
}

/* ***** Functions called during driver state changes ***** */
void pcicore_attach(void *pch, char *pvars, int state)
{
	pcicore_info_t *pi = (pcicore_info_t *) pch;
	si_t *sih = pi->sih;

	/* Determine if this board needs override */
	if (PCIE_ASPM(sih)) {
		if ((u32) getintvar(pvars, "boardflags2") & BFL2_PCIEWAR_OVR) {
			pi->pcie_war_aspm_ovr = PCIE_ASPM_DISAB;
		} else {
			pi->pcie_war_aspm_ovr = PCIE_ASPM_ENAB;
		}
	}

	/* These need to happen in this order only */
	pcie_war_polarity(pi);

	pcie_war_serdes(pi);

	pcie_war_aspm_clkreq(pi);

	pcie_clkreq_upd(pi, state);

}

void pcicore_hwup(void *pch)
{
	pcicore_info_t *pi = (pcicore_info_t *) pch;

	if (!pi || !PCIE_PUB(pi->sih))
		return;

	pcie_war_pci_setup(pi);
}

void pcicore_up(void *pch, int state)
{
	pcicore_info_t *pi = (pcicore_info_t *) pch;

	if (!pi || !PCIE_PUB(pi->sih))
		return;

	/* Restore L1 timer for better performance */
	pcie_extendL1timer(pi, true);

	pcie_clkreq_upd(pi, state);
}

/* When the device is going to enter D3 state (or the system is going to enter S3/S4 states */
void pcicore_sleep(void *pch)
{
	pcicore_info_t *pi = (pcicore_info_t *) pch;
	u32 w;

	if (!pi || !PCIE_ASPM(pi->sih))
		return;

	w = OSL_PCI_READ_CONFIG(pi->osh, pi->pciecap_lcreg_offset,
				sizeof(u32));
	w &= ~PCIE_CAP_LCREG_ASPML1;
	OSL_PCI_WRITE_CONFIG(pi->osh, pi->pciecap_lcreg_offset, sizeof(u32),
			     w);

	pi->pcie_pr42767 = false;
}

void pcicore_down(void *pch, int state)
{
	pcicore_info_t *pi = (pcicore_info_t *) pch;

	if (!pi || !PCIE_PUB(pi->sih))
		return;

	pcie_clkreq_upd(pi, state);

	/* Reduce L1 timer for better power savings */
	pcie_extendL1timer(pi, false);
}

/* ***** Wake-on-wireless-LAN (WOWL) support functions ***** */
/* Just uses PCI config accesses to find out, when needed before sb_attach is done */
bool pcicore_pmecap_fast(osl_t *osh)
{
	u8 cap_ptr;
	u32 pmecap;

	cap_ptr =
	    pcicore_find_pci_capability(osh, PCI_CAP_POWERMGMTCAP_ID, NULL,
					NULL);

	if (!cap_ptr)
		return false;

	pmecap = OSL_PCI_READ_CONFIG(osh, cap_ptr, sizeof(u32));

	return (pmecap & PME_CAP_PM_STATES) != 0;
}

/* return true if PM capability exists in the pci config space
 * Uses and caches the information using core handle
 */
static bool pcicore_pmecap(pcicore_info_t *pi)
{
	u8 cap_ptr;
	u32 pmecap;

	if (!pi->pmecap_offset) {
		cap_ptr =
		    pcicore_find_pci_capability(pi->osh,
						PCI_CAP_POWERMGMTCAP_ID, NULL,
						NULL);
		if (!cap_ptr)
			return false;

		pi->pmecap_offset = cap_ptr;

		pmecap =
		    OSL_PCI_READ_CONFIG(pi->osh, pi->pmecap_offset,
					sizeof(u32));

		/* At least one state can generate PME */
		pi->pmecap = (pmecap & PME_CAP_PM_STATES) != 0;
	}

	return pi->pmecap;
}

/* Enable PME generation */
void pcicore_pmeen(void *pch)
{
	pcicore_info_t *pi = (pcicore_info_t *) pch;
	u32 w;

	/* if not pmecapable return */
	if (!pcicore_pmecap(pi))
		return;

	w = OSL_PCI_READ_CONFIG(pi->osh, pi->pmecap_offset + PME_CSR_OFFSET,
				sizeof(u32));
	w |= (PME_CSR_PME_EN);
	OSL_PCI_WRITE_CONFIG(pi->osh, pi->pmecap_offset + PME_CSR_OFFSET,
			     sizeof(u32), w);
}

/*
 * Return true if PME status set
 */
bool pcicore_pmestat(void *pch)
{
	pcicore_info_t *pi = (pcicore_info_t *) pch;
	u32 w;

	if (!pcicore_pmecap(pi))
		return false;

	w = OSL_PCI_READ_CONFIG(pi->osh, pi->pmecap_offset + PME_CSR_OFFSET,
				sizeof(u32));

	return (w & PME_CSR_PME_STAT) == PME_CSR_PME_STAT;
}

/* Disable PME generation, clear the PME status bit if set
 */
void pcicore_pmeclr(void *pch)
{
	pcicore_info_t *pi = (pcicore_info_t *) pch;
	u32 w;

	if (!pcicore_pmecap(pi))
		return;

	w = OSL_PCI_READ_CONFIG(pi->osh, pi->pmecap_offset + PME_CSR_OFFSET,
				sizeof(u32));

	PCI_ERROR(("pcicore_pci_pmeclr PMECSR : 0x%x\n", w));

	/* PMESTAT is cleared by writing 1 to it */
	w &= ~(PME_CSR_PME_EN);

	OSL_PCI_WRITE_CONFIG(pi->osh, pi->pmecap_offset + PME_CSR_OFFSET,
			     sizeof(u32), w);
}

u32 pcie_lcreg(void *pch, u32 mask, u32 val)
{
	pcicore_info_t *pi = (pcicore_info_t *) pch;
	u8 offset;

	offset = pi->pciecap_lcreg_offset;
	if (!offset)
		return 0;

	/* set operation */
	if (mask)
		OSL_PCI_WRITE_CONFIG(pi->osh, offset, sizeof(u32), val);

	return OSL_PCI_READ_CONFIG(pi->osh, offset, sizeof(u32));
}

u32
pcicore_pciereg(void *pch, u32 offset, u32 mask, u32 val, uint type)
{
	u32 reg_val = 0;
	pcicore_info_t *pi = (pcicore_info_t *) pch;
	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
	osl_t *osh = pi->osh;

	if (mask) {
		PCI_ERROR(("PCIEREG: 0x%x writeval  0x%x\n", offset, val));
		pcie_writereg(osh, pcieregs, type, offset, val);
	}

	/* Should not read register 0x154 */
	if (pi->sih->buscorerev <= 5 && offset == PCIE_DLLP_PCIE11
	    && type == PCIE_PCIEREGS)
		return reg_val;

	reg_val = pcie_readreg(osh, pcieregs, type, offset);
	PCI_ERROR(("PCIEREG: 0x%x readval is 0x%x\n", offset, reg_val));

	return reg_val;
}

u32
pcicore_pcieserdesreg(void *pch, u32 mdioslave, u32 offset, u32 mask,
		      u32 val)
{
	u32 reg_val = 0;
	pcicore_info_t *pi = (pcicore_info_t *) pch;

	if (mask) {
		PCI_ERROR(("PCIEMDIOREG: 0x%x writeval  0x%x\n", offset, val));
		pcie_mdiowrite(pi, mdioslave, offset, val);
	}

	if (pcie_mdioread(pi, mdioslave, offset, &reg_val))
		reg_val = 0xFFFFFFFF;
	PCI_ERROR(("PCIEMDIOREG: dev 0x%x offset 0x%x read 0x%x\n", mdioslave,
		   offset, reg_val));

	return reg_val;
}
