xref: /openbmc/linux/drivers/bcma/driver_pci.c (revision b504075f5903b969a54ef3a6ae994c0872edb259)
18369ae33SRafał Miłecki /*
28369ae33SRafał Miłecki  * Broadcom specific AMBA
38369ae33SRafał Miłecki  * PCI Core
48369ae33SRafał Miłecki  *
549dc9577SHauke Mehrtens  * Copyright 2005, 2011, Broadcom Corporation
6eb032b98SMichael Büsch  * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
72be25cacSHauke Mehrtens  * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
88369ae33SRafał Miłecki  *
98369ae33SRafał Miłecki  * Licensed under the GNU/GPL. See COPYING for details.
108369ae33SRafał Miłecki  */
118369ae33SRafał Miłecki 
128369ae33SRafał Miłecki #include "bcma_private.h"
1344a8e377SPaul Gortmaker #include <linux/export.h>
148369ae33SRafał Miłecki #include <linux/bcma/bcma.h>
158369ae33SRafał Miłecki 
168369ae33SRafał Miłecki /**************************************************
178369ae33SRafał Miłecki  * R/W ops.
188369ae33SRafał Miłecki  **************************************************/
198369ae33SRafał Miłecki 
204b259a5cSHauke Mehrtens u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address)
218369ae33SRafał Miłecki {
222be25cacSHauke Mehrtens 	pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address);
232be25cacSHauke Mehrtens 	pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR);
242be25cacSHauke Mehrtens 	return pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_DATA);
258369ae33SRafał Miłecki }
268369ae33SRafał Miłecki 
278369ae33SRafał Miłecki static void bcma_pcie_write(struct bcma_drv_pci *pc, u32 address, u32 data)
288369ae33SRafał Miłecki {
292be25cacSHauke Mehrtens 	pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address);
302be25cacSHauke Mehrtens 	pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR);
312be25cacSHauke Mehrtens 	pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_DATA, data);
328369ae33SRafał Miłecki }
338369ae33SRafał Miłecki 
34521deea6SHauke Mehrtens static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u16 phy)
358369ae33SRafał Miłecki {
368369ae33SRafał Miłecki 	u32 v;
378369ae33SRafał Miłecki 	int i;
388369ae33SRafał Miłecki 
392be25cacSHauke Mehrtens 	v = BCMA_CORE_PCI_MDIODATA_START;
402be25cacSHauke Mehrtens 	v |= BCMA_CORE_PCI_MDIODATA_WRITE;
412be25cacSHauke Mehrtens 	v |= (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
422be25cacSHauke Mehrtens 	      BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
432be25cacSHauke Mehrtens 	v |= (BCMA_CORE_PCI_MDIODATA_BLK_ADDR <<
442be25cacSHauke Mehrtens 	      BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
452be25cacSHauke Mehrtens 	v |= BCMA_CORE_PCI_MDIODATA_TA;
468369ae33SRafał Miłecki 	v |= (phy << 4);
472be25cacSHauke Mehrtens 	pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
488369ae33SRafał Miłecki 
498369ae33SRafał Miłecki 	udelay(10);
508369ae33SRafał Miłecki 	for (i = 0; i < 200; i++) {
512be25cacSHauke Mehrtens 		v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
522be25cacSHauke Mehrtens 		if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE)
538369ae33SRafał Miłecki 			break;
541fd41a65SRafał Miłecki 		usleep_range(1000, 2000);
558369ae33SRafał Miłecki 	}
568369ae33SRafał Miłecki }
578369ae33SRafał Miłecki 
58521deea6SHauke Mehrtens static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u16 device, u8 address)
598369ae33SRafał Miłecki {
608369ae33SRafał Miłecki 	int max_retries = 10;
618369ae33SRafał Miłecki 	u16 ret = 0;
628369ae33SRafał Miłecki 	u32 v;
638369ae33SRafał Miłecki 	int i;
648369ae33SRafał Miłecki 
652be25cacSHauke Mehrtens 	/* enable mdio access to SERDES */
662be25cacSHauke Mehrtens 	v = BCMA_CORE_PCI_MDIOCTL_PREAM_EN;
672be25cacSHauke Mehrtens 	v |= BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL;
682be25cacSHauke Mehrtens 	pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, v);
698369ae33SRafał Miłecki 
708369ae33SRafał Miłecki 	if (pc->core->id.rev >= 10) {
718369ae33SRafał Miłecki 		max_retries = 200;
728369ae33SRafał Miłecki 		bcma_pcie_mdio_set_phy(pc, device);
732be25cacSHauke Mehrtens 		v = (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
742be25cacSHauke Mehrtens 		     BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
752be25cacSHauke Mehrtens 		v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
762be25cacSHauke Mehrtens 	} else {
772be25cacSHauke Mehrtens 		v = (device << BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD);
782be25cacSHauke Mehrtens 		v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD);
798369ae33SRafał Miłecki 	}
808369ae33SRafał Miłecki 
812be25cacSHauke Mehrtens 	v = BCMA_CORE_PCI_MDIODATA_START;
822be25cacSHauke Mehrtens 	v |= BCMA_CORE_PCI_MDIODATA_READ;
832be25cacSHauke Mehrtens 	v |= BCMA_CORE_PCI_MDIODATA_TA;
842be25cacSHauke Mehrtens 
852be25cacSHauke Mehrtens 	pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
868369ae33SRafał Miłecki 	/* Wait for the device to complete the transaction */
878369ae33SRafał Miłecki 	udelay(10);
88f1a9c1e6SRafał Miłecki 	for (i = 0; i < max_retries; i++) {
892be25cacSHauke Mehrtens 		v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
902be25cacSHauke Mehrtens 		if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE) {
918369ae33SRafał Miłecki 			udelay(10);
922be25cacSHauke Mehrtens 			ret = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_DATA);
938369ae33SRafał Miłecki 			break;
948369ae33SRafał Miłecki 		}
951fd41a65SRafał Miłecki 		usleep_range(1000, 2000);
968369ae33SRafał Miłecki 	}
972be25cacSHauke Mehrtens 	pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
988369ae33SRafał Miłecki 	return ret;
998369ae33SRafał Miłecki }
1008369ae33SRafał Miłecki 
101521deea6SHauke Mehrtens static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u16 device,
1028369ae33SRafał Miłecki 				u8 address, u16 data)
1038369ae33SRafał Miłecki {
1048369ae33SRafał Miłecki 	int max_retries = 10;
1058369ae33SRafał Miłecki 	u32 v;
1068369ae33SRafał Miłecki 	int i;
1078369ae33SRafał Miłecki 
1082be25cacSHauke Mehrtens 	/* enable mdio access to SERDES */
1092be25cacSHauke Mehrtens 	v = BCMA_CORE_PCI_MDIOCTL_PREAM_EN;
1102be25cacSHauke Mehrtens 	v |= BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL;
1112be25cacSHauke Mehrtens 	pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, v);
1128369ae33SRafał Miłecki 
1138369ae33SRafał Miłecki 	if (pc->core->id.rev >= 10) {
1148369ae33SRafał Miłecki 		max_retries = 200;
1158369ae33SRafał Miłecki 		bcma_pcie_mdio_set_phy(pc, device);
1162be25cacSHauke Mehrtens 		v = (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
1172be25cacSHauke Mehrtens 		     BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
1182be25cacSHauke Mehrtens 		v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
1192be25cacSHauke Mehrtens 	} else {
1202be25cacSHauke Mehrtens 		v = (device << BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD);
1212be25cacSHauke Mehrtens 		v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD);
1228369ae33SRafał Miłecki 	}
1238369ae33SRafał Miłecki 
1242be25cacSHauke Mehrtens 	v = BCMA_CORE_PCI_MDIODATA_START;
1252be25cacSHauke Mehrtens 	v |= BCMA_CORE_PCI_MDIODATA_WRITE;
1262be25cacSHauke Mehrtens 	v |= BCMA_CORE_PCI_MDIODATA_TA;
1278369ae33SRafał Miłecki 	v |= data;
1282be25cacSHauke Mehrtens 	pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
1298369ae33SRafał Miłecki 	/* Wait for the device to complete the transaction */
1308369ae33SRafał Miłecki 	udelay(10);
1318369ae33SRafał Miłecki 	for (i = 0; i < max_retries; i++) {
1322be25cacSHauke Mehrtens 		v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
1332be25cacSHauke Mehrtens 		if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE)
1348369ae33SRafał Miłecki 			break;
1351fd41a65SRafał Miłecki 		usleep_range(1000, 2000);
1368369ae33SRafał Miłecki 	}
1372be25cacSHauke Mehrtens 	pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
1388369ae33SRafał Miłecki }
1398369ae33SRafał Miłecki 
140521deea6SHauke Mehrtens static u16 bcma_pcie_mdio_writeread(struct bcma_drv_pci *pc, u16 device,
141521deea6SHauke Mehrtens 				    u8 address, u16 data)
142521deea6SHauke Mehrtens {
143521deea6SHauke Mehrtens 	bcma_pcie_mdio_write(pc, device, address, data);
144521deea6SHauke Mehrtens 	return bcma_pcie_mdio_read(pc, device, address);
145521deea6SHauke Mehrtens }
146521deea6SHauke Mehrtens 
1478369ae33SRafał Miłecki /**************************************************
148*b504075fSRafał Miłecki  * Early init.
149*b504075fSRafał Miłecki  **************************************************/
150*b504075fSRafał Miłecki 
151*b504075fSRafał Miłecki static void bcma_core_pci_fixcfg(struct bcma_drv_pci *pc)
152*b504075fSRafał Miłecki {
153*b504075fSRafał Miłecki 	struct bcma_device *core = pc->core;
154*b504075fSRafał Miłecki 	u16 val16, core_index;
155*b504075fSRafał Miłecki 	uint regoff;
156*b504075fSRafał Miłecki 
157*b504075fSRafał Miłecki 	regoff = BCMA_CORE_PCI_SPROM(BCMA_CORE_PCI_SPROM_PI_OFFSET);
158*b504075fSRafał Miłecki 	core_index = (u16)core->core_index;
159*b504075fSRafał Miłecki 
160*b504075fSRafał Miłecki 	val16 = pcicore_read16(pc, regoff);
161*b504075fSRafał Miłecki 	if (((val16 & BCMA_CORE_PCI_SPROM_PI_MASK) >> BCMA_CORE_PCI_SPROM_PI_SHIFT)
162*b504075fSRafał Miłecki 	     != core_index) {
163*b504075fSRafał Miłecki 		val16 = (core_index << BCMA_CORE_PCI_SPROM_PI_SHIFT) |
164*b504075fSRafał Miłecki 			(val16 & ~BCMA_CORE_PCI_SPROM_PI_MASK);
165*b504075fSRafał Miłecki 		pcicore_write16(pc, regoff, val16);
166*b504075fSRafał Miłecki 	}
167*b504075fSRafał Miłecki }
168*b504075fSRafał Miłecki 
169*b504075fSRafał Miłecki /*
170*b504075fSRafał Miłecki  * Apply some early fixes required before accessing SPROM.
171*b504075fSRafał Miłecki  * See also si_pci_fixcfg.
172*b504075fSRafał Miłecki  */
173*b504075fSRafał Miłecki void bcma_core_pci_early_init(struct bcma_drv_pci *pc)
174*b504075fSRafał Miłecki {
175*b504075fSRafał Miłecki 	if (pc->early_setup_done)
176*b504075fSRafał Miłecki 		return;
177*b504075fSRafał Miłecki 
178*b504075fSRafał Miłecki 	pc->hostmode = bcma_core_pci_is_in_hostmode(pc);
179*b504075fSRafał Miłecki 	if (pc->hostmode)
180*b504075fSRafał Miłecki 		goto out;
181*b504075fSRafał Miłecki 
182*b504075fSRafał Miłecki 	bcma_core_pci_fixcfg(pc);
183*b504075fSRafał Miłecki 
184*b504075fSRafał Miłecki out:
185*b504075fSRafał Miłecki 	pc->early_setup_done = true;
186*b504075fSRafał Miłecki }
187*b504075fSRafał Miłecki 
188*b504075fSRafał Miłecki /**************************************************
1898369ae33SRafał Miłecki  * Workarounds.
1908369ae33SRafał Miłecki  **************************************************/
1918369ae33SRafał Miłecki 
1928369ae33SRafał Miłecki static u8 bcma_pcicore_polarity_workaround(struct bcma_drv_pci *pc)
1938369ae33SRafał Miłecki {
1942be25cacSHauke Mehrtens 	u32 tmp;
1952be25cacSHauke Mehrtens 
1962be25cacSHauke Mehrtens 	tmp = bcma_pcie_read(pc, BCMA_CORE_PCI_PLP_STATUSREG);
1972be25cacSHauke Mehrtens 	if (tmp & BCMA_CORE_PCI_PLP_POLARITYINV_STAT)
1982be25cacSHauke Mehrtens 		return BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE |
1992be25cacSHauke Mehrtens 		       BCMA_CORE_PCI_SERDES_RX_CTRL_POLARITY;
2002be25cacSHauke Mehrtens 	else
2012be25cacSHauke Mehrtens 		return BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE;
2028369ae33SRafał Miłecki }
2038369ae33SRafał Miłecki 
2048369ae33SRafał Miłecki static void bcma_pcicore_serdes_workaround(struct bcma_drv_pci *pc)
2058369ae33SRafał Miłecki {
2068369ae33SRafał Miłecki 	u16 tmp;
2078369ae33SRafał Miłecki 
2082be25cacSHauke Mehrtens 	bcma_pcie_mdio_write(pc, BCMA_CORE_PCI_MDIODATA_DEV_RX,
2092be25cacSHauke Mehrtens 	                     BCMA_CORE_PCI_SERDES_RX_CTRL,
2108369ae33SRafał Miłecki 			     bcma_pcicore_polarity_workaround(pc));
2112be25cacSHauke Mehrtens 	tmp = bcma_pcie_mdio_read(pc, BCMA_CORE_PCI_MDIODATA_DEV_PLL,
2122be25cacSHauke Mehrtens 	                          BCMA_CORE_PCI_SERDES_PLL_CTRL);
2132be25cacSHauke Mehrtens 	if (tmp & BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN)
2142be25cacSHauke Mehrtens 		bcma_pcie_mdio_write(pc, BCMA_CORE_PCI_MDIODATA_DEV_PLL,
2152be25cacSHauke Mehrtens 		                     BCMA_CORE_PCI_SERDES_PLL_CTRL,
2162be25cacSHauke Mehrtens 		                     tmp & ~BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN);
2178369ae33SRafał Miłecki }
2188369ae33SRafał Miłecki 
2192b2715b8SHauke Mehrtens /* Fix MISC config to allow coming out of L2/L3-Ready state w/o PRST */
2202b2715b8SHauke Mehrtens /* Needs to happen when coming out of 'standby'/'hibernate' */
2212b2715b8SHauke Mehrtens static void bcma_core_pci_config_fixup(struct bcma_drv_pci *pc)
2222b2715b8SHauke Mehrtens {
2232b2715b8SHauke Mehrtens 	u16 val16;
2242b2715b8SHauke Mehrtens 	uint regoff;
2252b2715b8SHauke Mehrtens 
2262b2715b8SHauke Mehrtens 	regoff = BCMA_CORE_PCI_SPROM(BCMA_CORE_PCI_SPROM_MISC_CONFIG);
2272b2715b8SHauke Mehrtens 
2282b2715b8SHauke Mehrtens 	val16 = pcicore_read16(pc, regoff);
2292b2715b8SHauke Mehrtens 
2302b2715b8SHauke Mehrtens 	if (!(val16 & BCMA_CORE_PCI_SPROM_L23READY_EXIT_NOPERST)) {
2312b2715b8SHauke Mehrtens 		val16 |= BCMA_CORE_PCI_SPROM_L23READY_EXIT_NOPERST;
2322b2715b8SHauke Mehrtens 		pcicore_write16(pc, regoff, val16);
2332b2715b8SHauke Mehrtens 	}
2342b2715b8SHauke Mehrtens }
2352b2715b8SHauke Mehrtens 
2368369ae33SRafał Miłecki /**************************************************
2378369ae33SRafał Miłecki  * Init.
2388369ae33SRafał Miłecki  **************************************************/
2398369ae33SRafał Miłecki 
2400f58a01dSGreg Kroah-Hartman static void bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc)
2418369ae33SRafał Miłecki {
2428369ae33SRafał Miłecki 	bcma_pcicore_serdes_workaround(pc);
2432b2715b8SHauke Mehrtens 	bcma_core_pci_config_fixup(pc);
2448369ae33SRafał Miłecki }
2451de520f4SRafał Miłecki 
2460f58a01dSGreg Kroah-Hartman void bcma_core_pci_init(struct bcma_drv_pci *pc)
2479352f69cSRafał Miłecki {
248517f43e5SHauke Mehrtens 	if (pc->setup_done)
249517f43e5SHauke Mehrtens 		return;
250517f43e5SHauke Mehrtens 
251*b504075fSRafał Miłecki 	bcma_core_pci_early_init(pc);
252*b504075fSRafał Miłecki 
25349dc9577SHauke Mehrtens 	if (pc->hostmode)
2549352f69cSRafał Miłecki 		bcma_core_pci_hostmode_init(pc);
255*b504075fSRafał Miłecki 	else
25649dc9577SHauke Mehrtens 		bcma_core_pci_clientmode_init(pc);
2579352f69cSRafał Miłecki }
2589352f69cSRafał Miłecki 
2592bedea8fSArend van Spriel void bcma_core_pci_power_save(struct bcma_bus *bus, bool up)
2602bedea8fSArend van Spriel {
2612bedea8fSArend van Spriel 	struct bcma_drv_pci *pc;
2622bedea8fSArend van Spriel 	u16 data;
2632bedea8fSArend van Spriel 
2642bedea8fSArend van Spriel 	if (bus->hosttype != BCMA_HOSTTYPE_PCI)
2652bedea8fSArend van Spriel 		return;
2662bedea8fSArend van Spriel 
2672bedea8fSArend van Spriel 	pc = &bus->drv_pci[0];
2682bedea8fSArend van Spriel 
2692bedea8fSArend van Spriel 	if (pc->core->id.rev >= 15 && pc->core->id.rev <= 20) {
2702bedea8fSArend van Spriel 		data = up ? 0x74 : 0x7C;
2712bedea8fSArend van Spriel 		bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
2722bedea8fSArend van Spriel 					 BCMA_CORE_PCI_MDIO_BLK1_MGMT1, 0x7F64);
2732bedea8fSArend van Spriel 		bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
2742bedea8fSArend van Spriel 					 BCMA_CORE_PCI_MDIO_BLK1_MGMT3, data);
2752bedea8fSArend van Spriel 	} else if (pc->core->id.rev >= 21 && pc->core->id.rev <= 22) {
2762bedea8fSArend van Spriel 		data = up ? 0x75 : 0x7D;
2772bedea8fSArend van Spriel 		bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
2782bedea8fSArend van Spriel 					 BCMA_CORE_PCI_MDIO_BLK1_MGMT1, 0x7E65);
2792bedea8fSArend van Spriel 		bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
2802bedea8fSArend van Spriel 					 BCMA_CORE_PCI_MDIO_BLK1_MGMT3, data);
2812bedea8fSArend van Spriel 	}
2822bedea8fSArend van Spriel }
2832bedea8fSArend van Spriel EXPORT_SYMBOL_GPL(bcma_core_pci_power_save);
2842bedea8fSArend van Spriel 
2851de520f4SRafał Miłecki int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
2861de520f4SRafał Miłecki 			  bool enable)
2871de520f4SRafał Miłecki {
288e7027075SHauke Mehrtens 	struct pci_dev *pdev;
2891de520f4SRafał Miłecki 	u32 coremask, tmp;
290ecd177c2SHauke Mehrtens 	int err = 0;
291ecd177c2SHauke Mehrtens 
292e7027075SHauke Mehrtens 	if (!pc || core->bus->hosttype != BCMA_HOSTTYPE_PCI) {
293ecd177c2SHauke Mehrtens 		/* This bcma device is not on a PCI host-bus. So the IRQs are
294ecd177c2SHauke Mehrtens 		 * not routed through the PCI core.
295ecd177c2SHauke Mehrtens 		 * So we must not enable routing through the PCI core. */
296ecd177c2SHauke Mehrtens 		goto out;
297ecd177c2SHauke Mehrtens 	}
2981de520f4SRafał Miłecki 
299e7027075SHauke Mehrtens 	pdev = pc->core->bus->host_pci;
300e7027075SHauke Mehrtens 
3011de520f4SRafał Miłecki 	err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp);
3021de520f4SRafał Miłecki 	if (err)
3031de520f4SRafał Miłecki 		goto out;
3041de520f4SRafał Miłecki 
3051de520f4SRafał Miłecki 	coremask = BIT(core->core_index) << 8;
3061de520f4SRafał Miłecki 	if (enable)
3071de520f4SRafał Miłecki 		tmp |= coremask;
3081de520f4SRafał Miłecki 	else
3091de520f4SRafał Miłecki 		tmp &= ~coremask;
3101de520f4SRafał Miłecki 
3111de520f4SRafał Miłecki 	err = pci_write_config_dword(pdev, BCMA_PCI_IRQMASK, tmp);
3121de520f4SRafał Miłecki 
3131de520f4SRafał Miłecki out:
3141de520f4SRafał Miłecki 	return err;
3151de520f4SRafał Miłecki }
316440ca98fSRafał Miłecki EXPORT_SYMBOL_GPL(bcma_core_pci_irq_ctl);
31729f6b3d8SHauke Mehrtens 
318780335acSHauke Mehrtens static void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend)
31929f6b3d8SHauke Mehrtens {
32029f6b3d8SHauke Mehrtens 	u32 w;
32129f6b3d8SHauke Mehrtens 
32229f6b3d8SHauke Mehrtens 	w = bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG);
32329f6b3d8SHauke Mehrtens 	if (extend)
32429f6b3d8SHauke Mehrtens 		w |= BCMA_CORE_PCI_ASPMTIMER_EXTEND;
32529f6b3d8SHauke Mehrtens 	else
32629f6b3d8SHauke Mehrtens 		w &= ~BCMA_CORE_PCI_ASPMTIMER_EXTEND;
32729f6b3d8SHauke Mehrtens 	bcma_pcie_write(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG, w);
32829f6b3d8SHauke Mehrtens 	bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG);
32929f6b3d8SHauke Mehrtens }
330cfe51ec1SHauke Mehrtens 
331cfe51ec1SHauke Mehrtens void bcma_core_pci_up(struct bcma_bus *bus)
332cfe51ec1SHauke Mehrtens {
333cfe51ec1SHauke Mehrtens 	struct bcma_drv_pci *pc;
334cfe51ec1SHauke Mehrtens 
335cfe51ec1SHauke Mehrtens 	if (bus->hosttype != BCMA_HOSTTYPE_PCI)
336cfe51ec1SHauke Mehrtens 		return;
337cfe51ec1SHauke Mehrtens 
338cfe51ec1SHauke Mehrtens 	pc = &bus->drv_pci[0];
339cfe51ec1SHauke Mehrtens 
340cfe51ec1SHauke Mehrtens 	bcma_core_pci_extend_L1timer(pc, true);
341cfe51ec1SHauke Mehrtens }
342cfe51ec1SHauke Mehrtens EXPORT_SYMBOL_GPL(bcma_core_pci_up);
343cfe51ec1SHauke Mehrtens 
344cfe51ec1SHauke Mehrtens void bcma_core_pci_down(struct bcma_bus *bus)
345cfe51ec1SHauke Mehrtens {
346cfe51ec1SHauke Mehrtens 	struct bcma_drv_pci *pc;
347cfe51ec1SHauke Mehrtens 
348cfe51ec1SHauke Mehrtens 	if (bus->hosttype != BCMA_HOSTTYPE_PCI)
349cfe51ec1SHauke Mehrtens 		return;
350cfe51ec1SHauke Mehrtens 
351cfe51ec1SHauke Mehrtens 	pc = &bus->drv_pci[0];
352cfe51ec1SHauke Mehrtens 
353cfe51ec1SHauke Mehrtens 	bcma_core_pci_extend_L1timer(pc, false);
354cfe51ec1SHauke Mehrtens }
355cfe51ec1SHauke Mehrtens EXPORT_SYMBOL_GPL(bcma_core_pci_down);
356