From b504075f5903b969a54ef3a6ae994c0872edb259 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sun, 25 Jan 2015 11:11:14 +0100 Subject: bcma: add early_init function for PCIe core and move some fix into it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are some PCIe core fixes that need to be applied before accessing SPROM, otherwise reading it may fail. Signed-off-by: Rafał Miłecki Signed-off-by: Kalle Valo --- drivers/bcma/driver_pci.c | 66 +++++++++++++++++++++++++++++++---------------- drivers/bcma/main.c | 7 +++++ 2 files changed, 51 insertions(+), 22 deletions(-) (limited to 'drivers/bcma') diff --git a/drivers/bcma/driver_pci.c b/drivers/bcma/driver_pci.c index b85a505603e6..786666488a2d 100644 --- a/drivers/bcma/driver_pci.c +++ b/drivers/bcma/driver_pci.c @@ -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); } +/************************************************** + * 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. **************************************************/ @@ -175,24 +216,6 @@ static void bcma_pcicore_serdes_workaround(struct bcma_drv_pci *pc) 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 */ /* Needs to happen when coming out of 'standby'/'hibernate' */ 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) { - bcma_core_pci_fixcfg(pc); bcma_pcicore_serdes_workaround(pc); bcma_core_pci_config_fixup(pc); } @@ -226,11 +248,11 @@ void bcma_core_pci_init(struct bcma_drv_pci *pc) if (pc->setup_done) return; - pc->hostmode = bcma_core_pci_is_in_hostmode(pc); + bcma_core_pci_early_init(pc); + if (pc->hostmode) bcma_core_pci_hostmode_init(pc); - - if (!pc->hostmode) + else bcma_core_pci_clientmode_init(pc); } diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index 73b2ee3de972..38bde6eab8a4 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c @@ -402,6 +402,13 @@ int bcma_bus_register(struct bcma_bus *bus) 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 */ list_for_each_entry(core, &bus->cores, list) { if (bcma_is_core_needed_early(core->id.id)) -- cgit v1.2.3