Commit b504075f authored by Rafał Miłecki's avatar Rafał Miłecki Committed by Kalle Valo

bcma: add early_init function for PCIe core and move some fix into it

There are some PCIe core fixes that need to be applied before accessing
SPROM, otherwise reading it may fail.
Signed-off-by: default avatarRafał Miłecki <zajec5@gmail.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent ae8ce289
...@@ -144,6 +144,47 @@ static u16 bcma_pcie_mdio_writeread(struct bcma_drv_pci *pc, u16 device, ...@@ -144,6 +144,47 @@ static u16 bcma_pcie_mdio_writeread(struct bcma_drv_pci *pc, u16 device,
return bcma_pcie_mdio_read(pc, device, address); return bcma_pcie_mdio_read(pc, device, address);
} }
/**************************************************
* Early init.
**************************************************/
static void bcma_core_pci_fixcfg(struct bcma_drv_pci *pc)
{
struct bcma_device *core = pc->core;
u16 val16, core_index;
uint regoff;
regoff = BCMA_CORE_PCI_SPROM(BCMA_CORE_PCI_SPROM_PI_OFFSET);
core_index = (u16)core->core_index;
val16 = pcicore_read16(pc, regoff);
if (((val16 & BCMA_CORE_PCI_SPROM_PI_MASK) >> BCMA_CORE_PCI_SPROM_PI_SHIFT)
!= core_index) {
val16 = (core_index << BCMA_CORE_PCI_SPROM_PI_SHIFT) |
(val16 & ~BCMA_CORE_PCI_SPROM_PI_MASK);
pcicore_write16(pc, regoff, val16);
}
}
/*
* Apply some early fixes required before accessing SPROM.
* See also si_pci_fixcfg.
*/
void bcma_core_pci_early_init(struct bcma_drv_pci *pc)
{
if (pc->early_setup_done)
return;
pc->hostmode = bcma_core_pci_is_in_hostmode(pc);
if (pc->hostmode)
goto out;
bcma_core_pci_fixcfg(pc);
out:
pc->early_setup_done = true;
}
/************************************************** /**************************************************
* Workarounds. * Workarounds.
**************************************************/ **************************************************/
...@@ -175,24 +216,6 @@ static void bcma_pcicore_serdes_workaround(struct bcma_drv_pci *pc) ...@@ -175,24 +216,6 @@ static void bcma_pcicore_serdes_workaround(struct bcma_drv_pci *pc)
tmp & ~BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN); tmp & ~BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN);
} }
static void bcma_core_pci_fixcfg(struct bcma_drv_pci *pc)
{
struct bcma_device *core = pc->core;
u16 val16, core_index;
uint regoff;
regoff = BCMA_CORE_PCI_SPROM(BCMA_CORE_PCI_SPROM_PI_OFFSET);
core_index = (u16)core->core_index;
val16 = pcicore_read16(pc, regoff);
if (((val16 & BCMA_CORE_PCI_SPROM_PI_MASK) >> BCMA_CORE_PCI_SPROM_PI_SHIFT)
!= core_index) {
val16 = (core_index << BCMA_CORE_PCI_SPROM_PI_SHIFT) |
(val16 & ~BCMA_CORE_PCI_SPROM_PI_MASK);
pcicore_write16(pc, regoff, val16);
}
}
/* Fix MISC config to allow coming out of L2/L3-Ready state w/o PRST */ /* Fix MISC config to allow coming out of L2/L3-Ready state w/o PRST */
/* Needs to happen when coming out of 'standby'/'hibernate' */ /* Needs to happen when coming out of 'standby'/'hibernate' */
static void bcma_core_pci_config_fixup(struct bcma_drv_pci *pc) static void bcma_core_pci_config_fixup(struct bcma_drv_pci *pc)
...@@ -216,7 +239,6 @@ static void bcma_core_pci_config_fixup(struct bcma_drv_pci *pc) ...@@ -216,7 +239,6 @@ static void bcma_core_pci_config_fixup(struct bcma_drv_pci *pc)
static void bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc) static void bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc)
{ {
bcma_core_pci_fixcfg(pc);
bcma_pcicore_serdes_workaround(pc); bcma_pcicore_serdes_workaround(pc);
bcma_core_pci_config_fixup(pc); bcma_core_pci_config_fixup(pc);
} }
...@@ -226,11 +248,11 @@ void bcma_core_pci_init(struct bcma_drv_pci *pc) ...@@ -226,11 +248,11 @@ void bcma_core_pci_init(struct bcma_drv_pci *pc)
if (pc->setup_done) if (pc->setup_done)
return; return;
pc->hostmode = bcma_core_pci_is_in_hostmode(pc); bcma_core_pci_early_init(pc);
if (pc->hostmode) if (pc->hostmode)
bcma_core_pci_hostmode_init(pc); bcma_core_pci_hostmode_init(pc);
else
if (!pc->hostmode)
bcma_core_pci_clientmode_init(pc); bcma_core_pci_clientmode_init(pc);
} }
......
...@@ -402,6 +402,13 @@ int bcma_bus_register(struct bcma_bus *bus) ...@@ -402,6 +402,13 @@ int bcma_bus_register(struct bcma_bus *bus)
bcma_core_chipcommon_early_init(&bus->drv_cc); bcma_core_chipcommon_early_init(&bus->drv_cc);
} }
/* Early init PCIE core */
core = bcma_find_core(bus, BCMA_CORE_PCIE);
if (core) {
bus->drv_pci[0].core = core;
bcma_core_pci_early_init(&bus->drv_pci[0]);
}
/* Cores providing flash access go before SPROM init */ /* Cores providing flash access go before SPROM init */
list_for_each_entry(core, &bus->cores, list) { list_for_each_entry(core, &bus->cores, list) {
if (bcma_is_core_needed_early(core->id.id)) if (bcma_is_core_needed_early(core->id.id))
......
...@@ -223,6 +223,7 @@ struct bcma_drv_pci_host { ...@@ -223,6 +223,7 @@ struct bcma_drv_pci_host {
struct bcma_drv_pci { struct bcma_drv_pci {
struct bcma_device *core; struct bcma_device *core;
u8 early_setup_done:1;
u8 setup_done:1; u8 setup_done:1;
u8 hostmode:1; u8 hostmode:1;
...@@ -237,6 +238,7 @@ struct bcma_drv_pci { ...@@ -237,6 +238,7 @@ struct bcma_drv_pci {
#define pcicore_write16(pc, offset, val) bcma_write16((pc)->core, offset, val) #define pcicore_write16(pc, offset, val) bcma_write16((pc)->core, offset, val)
#define pcicore_write32(pc, offset, val) bcma_write32((pc)->core, offset, val) #define pcicore_write32(pc, offset, val) bcma_write32((pc)->core, offset, val)
extern void bcma_core_pci_early_init(struct bcma_drv_pci *pc);
extern void bcma_core_pci_init(struct bcma_drv_pci *pc); extern void bcma_core_pci_init(struct bcma_drv_pci *pc);
extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc,
struct bcma_device *core, bool enable); struct bcma_device *core, bool enable);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment