From mboxrd@z Thu Jan 1 00:00:00 1970 From: zajec5@gmail.com (=?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?=) Date: Wed, 13 Apr 2011 21:40:19 +0200 Subject: [RFC][PATCH V4] axi: add AXI bus driver In-Reply-To: <4DA5EA73.2040803@lwfinger.net> References: <1302634375-2378-1-git-send-email-zajec5@gmail.com> <4DA5EA73.2040803@lwfinger.net> Message-ID: To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org 2011/4/13 Larry Finger : > On 04/12/2011 01:52 PM, Rafa? Mi?ecki wrote: >> >> Cc: Greg KH >> Cc: Michael B?sch >> Cc: Larry Finger >> Cc: George Kashperko >> Cc: Arend van Spriel >> Cc: linux-arm-kernel at lists.infradead.org >> Cc: Russell King >> Cc: Arnd Bergmann >> Cc: Andy Botting >> Cc: linuxdriverproject >> Cc: linux-kernel at vger.kernel.org >> Signed-off-by: Rafa? Mi?ecki >> --- >> Greg: is this what you expected from dynamic allocation and documentation? >> >> Did I miss any other comments about something to change? >> >> V2: Rename to axi >> ? ? Use DEFINE_PCI_DEVICE_TABLE in bridge >> ? ? Make use of pr_fmt and pr_* >> ? ? Store core class >> ? ? Rename bridge to not b43 specific >> ? ? Replace magic 0x1000 with BCMAI_CORE_SIZE >> ? ? Remove some old "ssb" names and defines >> ? ? Move BCMAI_ADDR_BASE def >> ? ? Add drvdata field >> V3: Fix reloading (kfree issue) >> ? ? Add 14e4:0x4331 >> ? ? Fix non-initialized struct issue >> ? ? Drop useless inline functions wrappers for pci core drv >> ? ? Proper pr_* usage >> V3.1: Include forgotten changes (pr_* and include related) >> ? ? Explain why we dare to implement empty release function >> V4: Add ABI documentation >> ? ? Move struct device to wrapper and alloc it dynamically >> ? ? checkpatch.pl pointed fixes >> --- >> ?Documentation/ABI/testing/sysfs-bus-axi ? | ? 31 +++ >> ?drivers/Kconfig ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ?2 + >> ?drivers/Makefile ? ? ? ? ? ? ? ? ? ? ? ? ?| ? ?1 + >> ?drivers/axi/Kconfig ? ? ? ? ? ? ? ? ? ? ? | ? 33 +++ >> ?drivers/axi/Makefile ? ? ? ? ? ? ? ? ? ? ?| ? ?7 + >> ?drivers/axi/TODO ? ? ? ? ? ? ? ? ? ? ? ? ?| ? ?3 + >> ?drivers/axi/axi_pci_bridge.c ? ? ? ? ? ? ?| ? 33 +++ >> ?drivers/axi/axi_private.h ? ? ? ? ? ? ? ? | ? 37 +++ >> ?drivers/axi/core.c ? ? ? ? ? ? ? ? ? ? ? ?| ? 51 ++++ >> ?drivers/axi/driver_chipcommon.c ? ? ? ? ? | ? 87 +++++++ >> ?drivers/axi/driver_chipcommon_pmu.c ? ? ? | ?134 ++++++++++ >> ?drivers/axi/driver_pci.c ? ? ? ? ? ? ? ? ?| ?163 ++++++++++++ >> ?drivers/axi/host_pci.c ? ? ? ? ? ? ? ? ? ?| ?178 +++++++++++++ >> ?drivers/axi/main.c ? ? ? ? ? ? ? ? ? ? ? ?| ?271 ++++++++++++++++++++ >> ?drivers/axi/scan.c ? ? ? ? ? ? ? ? ? ? ? ?| ?392 >> +++++++++++++++++++++++++++++ >> ?drivers/axi/scan.h ? ? ? ? ? ? ? ? ? ? ? ?| ? 56 ++++ >> ?include/linux/axi/axi.h ? ? ? ? ? ? ? ? ? | ?227 +++++++++++++++++ >> ?include/linux/axi/axi_driver_chipcommon.h | ?308 ++++++++++++++++++++++ >> ?include/linux/axi/axi_driver_pci.h ? ? ? ?| ? 89 +++++++ >> ?include/linux/axi/axi_regs.h ? ? ? ? ? ? ?| ? 34 +++ >> ?include/linux/mod_devicetable.h ? ? ? ? ? | ? 17 ++ >> ?scripts/mod/file2alias.c ? ? ? ? ? ? ? ? ?| ? 21 ++ >> ?22 files changed, 2175 insertions(+), 0 deletions(-) >> ?create mode 100644 Documentation/ABI/testing/sysfs-bus-axi >> ?create mode 100644 drivers/axi/Kconfig >> ?create mode 100644 drivers/axi/Makefile >> ?create mode 100644 drivers/axi/TODO >> ?create mode 100644 drivers/axi/axi_pci_bridge.c >> ?create mode 100644 drivers/axi/axi_private.h >> ?create mode 100644 drivers/axi/core.c >> ?create mode 100644 drivers/axi/driver_chipcommon.c >> ?create mode 100644 drivers/axi/driver_chipcommon_pmu.c >> ?create mode 100644 drivers/axi/driver_pci.c >> ?create mode 100644 drivers/axi/host_pci.c >> ?create mode 100644 drivers/axi/main.c >> ?create mode 100644 drivers/axi/scan.c >> ?create mode 100644 drivers/axi/scan.h >> ?create mode 100644 include/linux/axi/axi.h >> ?create mode 100644 include/linux/axi/axi_driver_chipcommon.h >> ?create mode 100644 include/linux/axi/axi_driver_pci.h >> ?create mode 100644 include/linux/axi/axi_regs.h >> >> diff --git a/Documentation/ABI/testing/sysfs-bus-axi >> b/Documentation/ABI/testing/sysfs-bus-axi >> new file mode 100644 >> index 0000000..6223612 >> --- /dev/null >> +++ b/Documentation/ABI/testing/sysfs-bus-axi >> @@ -0,0 +1,31 @@ >> +What: ? ? ? ? ?/sys/bus/axi/devices/.../class >> +Date: ? ? ? ? ?April 2011 >> +KernelVersion: 2.6.40 >> +Contact: ? ? ? Rafa? Mi?ecki >> +Description: >> + ? ? ? ? ? ? ? Each AXI core is identified by few fields, including class >> it >> + ? ? ? ? ? ? ? belongs to. See include/linux/axi/axi.h for possible >> values. >> + >> +What: ? ? ? ? ?/sys/bus/axi/devices/.../manuf >> +Date: ? ? ? ? ?April 2011 >> +KernelVersion: 2.6.40 >> +Contact: ? ? ? Rafa? Mi?ecki >> +Description: >> + ? ? ? ? ? ? ? Each AXI core has it's manufacturer id. See >> + ? ? ? ? ? ? ? include/linux/axi/axi.h for possible values. >> + >> +What: ? ? ? ? ?/sys/bus/axi/devices/.../rev >> +Date: ? ? ? ? ?April 2011 >> +KernelVersion: 2.6.40 >> +Contact: ? ? ? Rafa? Mi?ecki >> +Description: >> + ? ? ? ? ? ? ? AXI cores of the same type can still slightly differ >> depending >> + ? ? ? ? ? ? ? on their revision. Use it for detailed programming. >> + >> +What: ? ? ? ? ?/sys/bus/axi/devices/.../id >> +Date: ? ? ? ? ?April 2011 >> +KernelVersion: 2.6.40 >> +Contact: ? ? ? Rafa? Mi?ecki >> +Description: >> + ? ? ? ? ? ? ? There are a few types of AXI cores, they can be identified >> by >> + ? ? ? ? ? ? ? id field. >> diff --git a/drivers/Kconfig b/drivers/Kconfig >> index 177c7d1..1244e8c 100644 >> --- a/drivers/Kconfig >> +++ b/drivers/Kconfig >> @@ -68,6 +68,8 @@ source "drivers/watchdog/Kconfig" >> >> ?source "drivers/ssb/Kconfig" >> >> +source "drivers/axi/Kconfig" >> + >> ?source "drivers/mfd/Kconfig" >> >> ?source "drivers/regulator/Kconfig" >> diff --git a/drivers/Makefile b/drivers/Makefile >> index 3f135b6..6e1979b 100644 >> --- a/drivers/Makefile >> +++ b/drivers/Makefile >> @@ -110,6 +110,7 @@ obj-$(CONFIG_HID) ? ? ? ? ? += hid/ >> ?obj-$(CONFIG_PPC_PS3) ? ? ? ? += ps3/ >> ?obj-$(CONFIG_OF) ? ? ? ? ? ? ?+= of/ >> ?obj-$(CONFIG_SSB) ? ? ? ? ? ? += ssb/ >> +obj-$(CONFIG_AXI) ? ? ? ? ? ? ?+= axi/ >> ?obj-$(CONFIG_VHOST_NET) ? ? ? ? ? ? ? += vhost/ >> ?obj-$(CONFIG_VLYNQ) ? ? ? ? ? += vlynq/ >> ?obj-$(CONFIG_STAGING) ? ? ? ? += staging/ >> diff --git a/drivers/axi/Kconfig b/drivers/axi/Kconfig >> new file mode 100644 >> index 0000000..6221af0 >> --- /dev/null >> +++ b/drivers/axi/Kconfig >> @@ -0,0 +1,33 @@ >> +config AXI_POSSIBLE >> + ? ? ? bool >> + ? ? ? depends on HAS_IOMEM&& ?HAS_DMA >> + ? ? ? default y >> + >> +menu "AMBA AXI" >> + ? ? ? depends on AXI_POSSIBLE >> + >> +config AXI >> + ? ? ? tristate "AXI support" >> + ? ? ? depends on AXI_POSSIBLE >> + ? ? ? help >> + ? ? ? ? Bus driver for one of the Advanced Microcontroller Bus >> Architecture >> + ? ? ? ? interfaces: Advanced eXtensible Interface. >> + >> +config AXI_HOST_PCI_POSSIBLE >> + ? ? ? bool >> + ? ? ? depends on AXI&& ?PCI = y >> + ? ? ? default y >> + >> +config AXI_HOST_PCI >> + ? ? ? bool "Support for AXI on PCI-host bus" >> + ? ? ? depends on AXI_HOST_PCI_POSSIBLE >> + >> +config AXI_DEBUG >> + ? ? ? bool "AXI debugging" >> + ? ? ? depends on AXI >> + ? ? ? help >> + ? ? ? ? This turns on additional debugging messages. >> + >> + ? ? ? ? If unsure, say N >> + >> +endmenu >> diff --git a/drivers/axi/Makefile b/drivers/axi/Makefile >> new file mode 100644 >> index 0000000..50d6797 >> --- /dev/null >> +++ b/drivers/axi/Makefile >> @@ -0,0 +1,7 @@ >> +axi-y ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?+= main.o scan.o core.o >> +axi-y ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?+= driver_chipcommon.o >> driver_chipcommon_pmu.o >> +axi-y ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?+= driver_pci.o >> +axi-$(CONFIG_AXI_HOST_PCI) ? ? ? ? ? ? += host_pci.o axi_pci_bridge.o >> +obj-$(CONFIG_AXI) ? ? ? ? ? ? ? ? ? ? ?+= axi.o >> + >> +ccflags-$(CONFIG_AXI_DEBUG) ? ? ? ? ? ?:= -DDEBUG >> diff --git a/drivers/axi/TODO b/drivers/axi/TODO >> new file mode 100644 >> index 0000000..5190336 >> --- /dev/null >> +++ b/drivers/axi/TODO >> @@ -0,0 +1,3 @@ >> +- Interrupts >> +- Defines for PCI core driver >> +- Convert axi_bus->cores into linked list >> diff --git a/drivers/axi/axi_pci_bridge.c b/drivers/axi/axi_pci_bridge.c >> new file mode 100644 >> index 0000000..17e882c >> --- /dev/null >> +++ b/drivers/axi/axi_pci_bridge.c >> @@ -0,0 +1,33 @@ >> +/* >> + * AXI PCI bridge module >> + * >> + * Licensed under the GNU/GPL. See COPYING for details. >> + */ >> + >> +#include "axi_private.h" >> + >> +#include >> +#include >> + >> +static DEFINE_PCI_DEVICE_TABLE(axi_pci_bridge_tbl) = { >> + ? ? ? { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) }, >> + ? ? ? { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) }, >> + ? ? ? { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, >> + ? ? ? { 0, }, >> +}; >> +MODULE_DEVICE_TABLE(pci, axi_pci_bridge_tbl); >> + >> +static struct pci_driver axi_pci_bridge_driver = { >> + ? ? ? .name = "axi-pci-bridge", >> + ? ? ? .id_table = axi_pci_bridge_tbl, >> +}; >> + >> +int __init axi_pci_bridge_init(void) >> +{ >> + ? ? ? return axi_host_pci_register(&axi_pci_bridge_driver); >> +} >> + >> +void __exit axi_pci_bridge_exit(void) >> +{ >> + ? ? ? axi_host_pci_unregister(&axi_pci_bridge_driver); >> +} >> diff --git a/drivers/axi/axi_private.h b/drivers/axi/axi_private.h >> new file mode 100644 >> index 0000000..756efb6 >> --- /dev/null >> +++ b/drivers/axi/axi_private.h >> @@ -0,0 +1,37 @@ >> +#ifndef LINUX_AXI_PRIVATE_H_ >> +#define LINUX_AXI_PRIVATE_H_ >> + >> +#ifndef pr_fmt >> +#define pr_fmt(fmt) ? ? ? ? ? ?KBUILD_MODNAME ": " fmt >> +#endif >> + >> +#include >> + >> +#define AXI_ADDR_BASE ? ? ? ? ?0x18000000 >> +#define AXI_WRAP_BASE ? ? ? ? ?0x18100000 >> + >> +#define AXI_CORE_SIZE ? ? ? ? ?0x1000 >> + >> +struct axi_bus; >> + >> +/* main.c */ >> +extern int axi_bus_register(struct axi_bus *bus); >> +extern void axi_bus_unregister(struct axi_bus *bus); >> + >> +/* scan.c */ >> +int axi_bus_scan(struct axi_bus *bus); >> + >> +#ifdef CONFIG_AXI_HOST_PCI >> +/* b43_pci_ai_bridge.c */ >> +extern int __init axi_pci_bridge_init(void); >> +extern void __exit axi_pci_bridge_exit(void); >> + >> +/* host_pci.c */ >> +extern int axi_host_pci_register(struct pci_driver *driver); >> +static inline void axi_host_pci_unregister(struct pci_driver *driver) >> +{ >> + ? ? ? pci_unregister_driver(driver); >> +} >> +#endif /* CONFIG_AXI_HOST_PCI */ >> + >> +#endif >> diff --git a/drivers/axi/core.c b/drivers/axi/core.c >> new file mode 100644 >> index 0000000..3d79749 >> --- /dev/null >> +++ b/drivers/axi/core.c >> @@ -0,0 +1,51 @@ >> +/* >> + * AMBA AXI >> + * Core ops >> + * >> + * Licensed under the GNU/GPL. See COPYING for details. >> + */ >> + >> +#include "axi_private.h" >> +#include > > #include > >> + >> +bool axi_core_is_enabled(struct axi_device *core) >> +{ >> + ? ? ? if ((axi_aread32(core, AXI_IOCTL)& ?(AXI_IOCTL_CLK | >> AXI_IOCTL_FGC)) >> + ? ? ? ? ? != AXI_IOCTL_CLK) >> + ? ? ? ? ? ? ? return false; >> + ? ? ? if (axi_aread32(core, AXI_RESET_CTL)& ?AXI_RESET_CTL_RESET) >> + ? ? ? ? ? ? ? return false; >> + ? ? ? return true; >> +} >> +EXPORT_SYMBOL(axi_core_is_enabled); >> + >> +static void axi_core_disable(struct axi_device *core, u32 flags) >> +{ >> + ? ? ? if (axi_aread32(core, AXI_RESET_CTL)& ?AXI_RESET_CTL_RESET) >> + ? ? ? ? ? ? ? return; >> + >> + ? ? ? axi_awrite32(core, AXI_IOCTL, flags); >> + ? ? ? axi_aread32(core, AXI_IOCTL); >> + ? ? ? udelay(10); >> + >> + ? ? ? axi_awrite32(core, AXI_RESET_CTL, AXI_RESET_CTL_RESET); >> + ? ? ? udelay(1); >> +} >> + >> +int axi_core_enable(struct axi_device *core, u32 flags) >> +{ >> + ? ? ? axi_core_disable(core, flags); >> + >> + ? ? ? axi_awrite32(core, AXI_IOCTL, (AXI_IOCTL_CLK | AXI_IOCTL_FGC | >> flags)); >> + ? ? ? axi_aread32(core, AXI_IOCTL); >> + >> + ? ? ? axi_awrite32(core, AXI_RESET_CTL, 0); >> + ? ? ? udelay(1); >> + >> + ? ? ? axi_awrite32(core, AXI_IOCTL, (AXI_IOCTL_CLK | flags)); >> + ? ? ? axi_aread32(core, AXI_IOCTL); >> + ? ? ? udelay(1); >> + >> + ? ? ? return 0; >> +} >> +EXPORT_SYMBOL(axi_core_enable); >> diff --git a/drivers/axi/driver_chipcommon.c >> b/drivers/axi/driver_chipcommon.c >> new file mode 100644 >> index 0000000..b3087df >> --- /dev/null >> +++ b/drivers/axi/driver_chipcommon.c >> @@ -0,0 +1,87 @@ >> +/* >> + * AMBA AXI >> + * ChipCommon core driver >> + * >> + * Copyright 2005, Broadcom Corporation >> + * Copyright 2006, 2007, Michael Buesch >> + * >> + * Licensed under the GNU/GPL. See COPYING for details. >> + */ >> + >> +#include "axi_private.h" >> +#include >> + >> +static inline u32 axi_cc_write32_masked(struct axi_drv_cc *cc, u16 >> offset, >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? u32 mask, u32 value) >> +{ >> + ? ? ? value&= mask; >> + ? ? ? value |= axi_cc_read32(cc, offset)& ?~mask; >> + ? ? ? axi_cc_write32(cc, offset, value); >> + >> + ? ? ? return value; >> +} >> + >> +void axi_core_chipcommon_init(struct axi_drv_cc *cc) >> +{ >> + ? ? ? if (cc->core->id.rev>= 11) >> + ? ? ? ? ? ? ? cc->status = axi_cc_read32(cc, AXI_CC_CHIPSTAT); >> + ? ? ? cc->capabilities = axi_cc_read32(cc, AXI_CC_CAP); >> + ? ? ? if (cc->core->id.rev>= 35) >> + ? ? ? ? ? ? ? cc->capabilities_ext = axi_cc_read32(cc, AXI_CC_CAP_EXT); >> + >> + ? ? ? axi_cc_write32(cc, 0x58, 0); >> + ? ? ? axi_cc_write32(cc, 0x5C, 0); >> + >> + ? ? ? if (cc->capabilities& ?AXI_CC_CAP_PMU) >> + ? ? ? ? ? ? ? axi_pmu_init(cc); >> + ? ? ? if (cc->capabilities& ?AXI_CC_CAP_PCTL) >> + ? ? ? ? ? ? ? pr_err("Power control not implemented!\n"); >> +} >> + >> +/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */ >> +void axi_chipco_watchdog_timer_set(struct axi_drv_cc *cc, u32 ticks) >> +{ >> + ? ? ? /* instant NMI */ >> + ? ? ? axi_cc_write32(cc, AXI_CC_WATCHDOG, ticks); >> +} >> + >> +void axi_chipco_irq_mask(struct axi_drv_cc *cc, u32 mask, u32 value) >> +{ >> + ? ? ? axi_cc_write32_masked(cc, AXI_CC_IRQMASK, mask, value); >> +} >> + >> +u32 axi_chipco_irq_status(struct axi_drv_cc *cc, u32 mask) >> +{ >> + ? ? ? return axi_cc_read32(cc, AXI_CC_IRQSTAT)& ?mask; >> +} >> + >> +u32 axi_chipco_gpio_in(struct axi_drv_cc *cc, u32 mask) >> +{ >> + ? ? ? return axi_cc_read32(cc, AXI_CC_GPIOIN)& ?mask; >> +} >> + >> +u32 axi_chipco_gpio_out(struct axi_drv_cc *cc, u32 mask, u32 value) >> +{ >> + ? ? ? return axi_cc_write32_masked(cc, AXI_CC_GPIOOUT, mask, value); >> +} >> + >> +u32 axi_chipco_gpio_outen(struct axi_drv_cc *cc, u32 mask, u32 value) >> +{ >> + ? ? ? return axi_cc_write32_masked(cc, AXI_CC_GPIOOUTEN, mask, value); >> +} >> + >> +u32 xaxi_chipco_gpio_control(struct axi_drv_cc *cc, u32 mask, u32 value) >> +{ >> + ? ? ? return axi_cc_write32_masked(cc, AXI_CC_GPIOCTL, mask, value); >> +} >> +EXPORT_SYMBOL(xaxi_chipco_gpio_control); >> + >> +u32 axi_chipco_gpio_intmask(struct axi_drv_cc *cc, u32 mask, u32 value) >> +{ >> + ? ? ? return axi_cc_write32_masked(cc, AXI_CC_GPIOIRQ, mask, value); >> +} >> + >> +u32 axi_chipco_gpio_polarity(struct axi_drv_cc *cc, u32 mask, u32 value) >> +{ >> + ? ? ? return axi_cc_write32_masked(cc, AXI_CC_GPIOPOL, mask, value); >> +} >> diff --git a/drivers/axi/driver_chipcommon_pmu.c >> b/drivers/axi/driver_chipcommon_pmu.c >> new file mode 100644 >> index 0000000..b57a9d0 >> --- /dev/null >> +++ b/drivers/axi/driver_chipcommon_pmu.c >> @@ -0,0 +1,134 @@ >> +/* >> + * AMBA AXI >> + * ChipCommon Power Management Unit driver >> + * >> + * Copyright 2009, Michael Buesch >> + * Copyright 2007, Broadcom Corporation >> + * >> + * Licensed under the GNU/GPL. See COPYING for details. >> + */ >> + >> +#include "axi_private.h" >> +#include >> + >> +static void axi_chipco_chipctl_maskset(struct axi_drv_cc *cc, >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?u32 offset, u32 mask, u32 set) >> +{ >> + ? ? ? u32 value; >> + >> + ? ? ? axi_cc_read32(cc, AXI_CC_CHIPCTL_ADDR); >> + ? ? ? axi_cc_write32(cc, AXI_CC_CHIPCTL_ADDR, offset); >> + ? ? ? axi_cc_read32(cc, AXI_CC_CHIPCTL_ADDR); >> + ? ? ? value = axi_cc_read32(cc, AXI_CC_CHIPCTL_DATA); >> + ? ? ? value&= mask; >> + ? ? ? value |= set; >> + ? ? ? axi_cc_write32(cc, AXI_CC_CHIPCTL_DATA, value); >> + ? ? ? axi_cc_read32(cc, AXI_CC_CHIPCTL_DATA); >> +} >> + >> +static void axi_pmu_pll_init(struct axi_drv_cc *cc) >> +{ >> + ? ? ? struct axi_bus *bus = cc->core->bus; >> + >> + ? ? ? switch (bus->chipinfo.id) { >> + ? ? ? case 0x4313: >> + ? ? ? case 0x4331: >> + ? ? ? case 43224: >> + ? ? ? case 43225: >> + ? ? ? ? ? ? ? break; >> + ? ? ? default: >> + ? ? ? ? ? ? ? pr_err("PLL init unknown for device 0x%04X\n", >> + ? ? ? ? ? ? ? ? ? ? ? bus->chipinfo.id); >> + ? ? ? } >> +} >> + >> +static void axi_pmu_resources_init(struct axi_drv_cc *cc) >> +{ >> + ? ? ? struct axi_bus *bus = cc->core->bus; >> + ? ? ? u32 min_msk = 0, max_msk = 0; >> + >> + ? ? ? switch (bus->chipinfo.id) { >> + ? ? ? case 0x4313: >> + ? ? ? ? ? ? ? min_msk = 0x200D; >> + ? ? ? ? ? ? ? max_msk = 0xFFFF; >> + ? ? ? ? ? ? ? break; >> + ? ? ? case 43224: >> + ? ? ? ? ? ? ? break; >> + ? ? ? default: >> + ? ? ? ? ? ? ? pr_err("PMU resource config unknown for device 0x%04X\n", >> + ? ? ? ? ? ? ? ? ? ? ? bus->chipinfo.id); >> + ? ? ? } >> + >> + ? ? ? /* Set the resource masks. */ >> + ? ? ? if (min_msk) >> + ? ? ? ? ? ? ? axi_cc_write32(cc, AXI_CC_PMU_MINRES_MSK, min_msk); >> + ? ? ? if (max_msk) >> + ? ? ? ? ? ? ? axi_cc_write32(cc, AXI_CC_PMU_MAXRES_MSK, max_msk); >> +} >> + >> +void axi_pmu_swreg_init(struct axi_drv_cc *cc) >> +{ >> + ? ? ? struct axi_bus *bus = cc->core->bus; >> + >> + ? ? ? switch (bus->chipinfo.id) { >> + ? ? ? case 0x4313: >> + ? ? ? case 0x4331: >> + ? ? ? case 43224: >> + ? ? ? ? ? ? ? break; >> + ? ? ? default: >> + ? ? ? ? ? ? ? pr_err("PMU switch/regulators init unknown for device " >> + ? ? ? ? ? ? ? ? ? ? ? "0x%04X\n", bus->chipinfo.id); >> + ? ? ? } >> +} >> + >> +void axi_pmu_workarounds(struct axi_drv_cc *cc) >> +{ >> + ? ? ? struct axi_bus *bus = cc->core->bus; >> + >> + ? ? ? switch (bus->chipinfo.id) { >> + ? ? ? case 0x4313: >> + ? ? ? ? ? ? ? axi_chipco_chipctl_maskset(cc, 0, ~0, 0x7); >> + ? ? ? ? ? ? ? break; >> + ? ? ? case 0x4331: >> + ? ? ? ? ? ? ? pr_err("Enabling Ext PA lines not implemented\n"); >> + ? ? ? ? ? ? ? break; >> + ? ? ? case 43224: >> + ? ? ? ? ? ? ? if (bus->chipinfo.rev == 0) { >> + ? ? ? ? ? ? ? ? ? ? ? pr_err("Workarounds for 43224 rev 0 not fully " >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "implemented\n"); >> + ? ? ? ? ? ? ? ? ? ? ? axi_chipco_chipctl_maskset(cc, 0, ~0, 0xF0); >> + ? ? ? ? ? ? ? } else { >> + ? ? ? ? ? ? ? ? ? ? ? axi_chipco_chipctl_maskset(cc, 0, ~0, 0xF0); >> + ? ? ? ? ? ? ? } >> + ? ? ? ? ? ? ? break; >> + ? ? ? default: >> + ? ? ? ? ? ? ? pr_err("Workarounds unknown for device 0x%04X\n", >> + ? ? ? ? ? ? ? ? ? ? ? bus->chipinfo.id); >> + ? ? ? } >> +} >> + >> +void axi_pmu_init(struct axi_drv_cc *cc) >> +{ >> + ? ? ? u32 pmucap; >> + >> + ? ? ? pmucap = axi_cc_read32(cc, AXI_CC_PMU_CAP); >> + ? ? ? cc->pmu.rev = (pmucap& ?AXI_CC_PMU_CAP_REVISION); >> + >> + ? ? ? pr_debug("Found rev %u PMU (capabilities 0x%08X)\n", cc->pmu.rev, >> + ? ? ? ? ? ? ? ?pmucap); >> + >> + ? ? ? if (cc->pmu.rev == 1) >> + ? ? ? ? ? ? ? axi_cc_mask32(cc, AXI_CC_PMU_CTL, >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ~AXI_CC_PMU_CTL_NOILPONW); >> + ? ? ? else >> + ? ? ? ? ? ? ? axi_cc_set32(cc, AXI_CC_PMU_CTL, >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?AXI_CC_PMU_CTL_NOILPONW); >> + >> + ? ? ? if (cc->core->id.id == 0x4329&& ?cc->core->id.rev == 2) >> + ? ? ? ? ? ? ? pr_err("Fix for 4329b0 bad LPOM state not >> implemented!\n"); >> + >> + ? ? ? axi_pmu_pll_init(cc); >> + ? ? ? axi_pmu_resources_init(cc); >> + ? ? ? axi_pmu_swreg_init(cc); >> + ? ? ? axi_pmu_workarounds(cc); >> +} >> diff --git a/drivers/axi/driver_pci.c b/drivers/axi/driver_pci.c >> new file mode 100644 >> index 0000000..fc4ab25 >> --- /dev/null >> +++ b/drivers/axi/driver_pci.c >> @@ -0,0 +1,163 @@ >> +/* >> + * AMBA AXI >> + * PCI Core >> + * >> + * Copyright 2005, Broadcom Corporation >> + * Copyright 2006, 2007, Michael Buesch >> + * >> + * Licensed under the GNU/GPL. See COPYING for details. >> + */ >> + >> +#include "axi_private.h" >> +#include > > #include > > > Are you compiling for i386 architecture? For some reason, delay.h is not > included for my x86_64 system, and the include is needed for core.c and > driver_pci.c. Yes, I use x86. Will include delay.h in next version, thanks for reporting. -- Rafa?