Hi,
This patch adds support for PCI to AArch64. It is based on my v7 patch
that adds support for creating generic host bridge structure from
device tree. With that in place, I was able to boot a platform that
has PCIe host bridge support and use a PCIe network card.
I have dropped the RFC tag from the subject as I now have the ambitious goal
of trying to get it mainlined.
Changes from v6:
- Guard the pci_domain_nr() inline implementation with #ifdef CONFIG_PCI as
to avoid conflict with default empty version present in include/linux/pci.h.
Thanks to Jingoo Han for catching this.
Changes from v5:
- Removed pcibios_fixup_bridge_ranges() as the week default version is fine.
- Removed the ALIGN() call in pcibios_align_resource()
- Stopped exporting pcibios_align_resource()
Changes from v4:
- Fixed the pci_domain_nr() implementation for arm64. Now we use
find_pci_host_bride() to find the host bridge before we retrieve
the domain number.
Changes from v3:
- Added Acks accumulated so far ;)
- Still carrying Catalin's patch for moving the PCI_IO_BASE until it
lands in linux-next or mainline, in order to ease applying the series
Changes from v2:
- Implement an arch specific version of pci_register_io_range() and
pci_address_to_pio().
- Return 1 from pci_proc_domain().
Changes from v1:
- Added Catalin's patch for moving the PCI_IO_BASE location and extend
its size to 16MB
- Integrated Arnd's version of pci_ioremap_io that uses a bitmap for
keeping track of assigned IO space and returns an io_offset. At the
moment the code is added in arch/arm64 but it can be moved in drivers/pci.
- Added a fix for the generic ioport_map() function when !CONFIG_GENERIC_IOMAP
as suggested by Arnd.
v6 thread here: https://lkml.org/lkml/2014/3/5/41
v5 thread here: https://lkml.org/lkml/2014/3/4/307
v4 thread here: https://lkml.org/lkml/2014/3/3/298
v3 thread here: https://lkml.org/lkml/2014/2/28/211
v2 thread here: https://lkml.org/lkml/2014/2/27/255
v1 thread here: https://lkml.org/lkml/2014/2/3/389
The API used is different from the one used by ARM architecture. There is
no pci_common_init_dev() function and no hw_pci structure, as that is no
longer needed. Once the last signature is added to the legal agreement, I
will post the host bridge driver code that I am using. Meanwhile, here
is an example of what the probe function looks like, posted as an example:
static int myhostbridge_probe(struct platform_device *pdev)
{
int err;
struct device_node *dev;
struct pci_host_bridge *bridge;
struct myhostbridge_port *pp;
resource_size_t lastbus;
dev = pdev->dev.of_node;
if (!of_device_is_available(dev)) {
pr_warn("%s: disabled\n", dev->full_name);
return -ENODEV;
}
pp = kzalloc(sizeof(struct myhostbridge_port), GFP_KERNEL);
if (!pp)
return -ENOMEM;
bridge = of_create_pci_host_bridge(&pdev->dev, &myhostbridge_ops, pp);
if (IS_ERR(bridge)) {
err = PTR_ERR(bridge);
goto bridge_create_fail;
}
err = myhostbridge_setup(bridge->bus);
if (err)
goto bridge_setup_fail;
/* We always enable PCI domains and we keep domain 0 backward
* compatible in /proc for video cards
*/
pci_add_flags(PCI_ENABLE_PROC_DOMAINS);
pci_add_flags(PCI_REASSIGN_ALL_BUS | PCI_REASSIGN_ALL_RSRC);
lastbus = pci_scan_child_bus(bridge->bus);
pci_bus_update_busn_res_end(bridge->bus, lastbus);
pci_assign_unassigned_bus_resources(bridge->bus);
pci_bus_add_devices(bridge->bus);
return 0;
bridge_setup_fail:
put_device(&bridge->dev);
device_unregister(&bridge->dev);
bridge_create_fail:
kfree(pp);
return err;
}
Best regards,
Liviu
Catalin Marinas (1):
arm64: Extend the PCI I/O space to 16MB
Liviu Dudau (2):
Fix ioport_map() for !CONFIG_GENERIC_IOMAP cases.
arm64: Add architecture support for PCI
Documentation/arm64/memory.txt | 16 +--
arch/arm64/Kconfig | 19 +++-
arch/arm64/include/asm/Kbuild | 1 +
arch/arm64/include/asm/io.h | 5 +-
arch/arm64/include/asm/pci.h | 51 +++++++++
arch/arm64/kernel/Makefile | 1 +
arch/arm64/kernel/pci.c | 173 +++++++++++++++++++++++++++++++
include/asm-generic/io.h | 2 +-
8 files changed, 258 insertions(+), 10 deletions(-)
create mode 100644 arch/arm64/include/asm/pci.h
create mode 100644 arch/arm64/kernel/pci.c
--
1.9.0
Kevin,
As we discussed at ELC, it would be nice to test ARM big endian in the
board farm. Here are some instructions on how to get this running:
1 Take the Buildroot branch at
http://git.free-electrons.com/users/thomas-petazzoni/buildroot/log/?h=for-k….
It is Buildroot 2014.02 + one patch for the AArch64 symlink + one
patch for the ARM big endian Linaro toolchain.
2 Build a Buildroot configuration such as:
BR2_armeb=y
BR2_cortex_a8=y
BR2_ARM_EABIHF=y
BR2_TOOLCHAIN_EXTERNAL=y
BR2_TARGET_ROOTFS_CPIO=y
# BR2_TARGET_ROOTFS_TAR is not set
3 Build mvebu_v7_defconfig or multi_v7_defconfig with
CONFIG_CPU_BIG_ENDIAN=y (no other change is needed, except your own
configuration stuff maybe, like initrd support, devtmpfs and so on).
4 Boot
I've tested this right now on Armada XP OpenBlocks AX3-4. It is worth
noting that in BE mode, the ATAGS are not used, so if your OpenBlocks
has only 1 GB of RAM, the boot will crash (with some weird tty related
panic). That's because the Device Tree for the OpenBlocks AX3-4 encodes
a memory size of 3 GB, which some OpenBlocks have. If you fall into this
issue, then change the memory node in the DT to use 1 GB only.
Normally, this should also work on Armada 370 Mirabox, though I haven't
tested right now.
Do you think you could add this big endian test to the board farm?
In addition to this, it would be interesting if you could also test
LPAE on Armada XP OpenBlocks AX3-4 (it should work on little endian,
however I have never tested LPAE/big-endian).
Thanks a lot!
Thomas
--
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
Douglas Anderson, recently pointed out an interesting problem due to which
udelay() was expiring earlier than it should.
While transitioning between frequencies few platforms may temporarily switch to
a stable frequency, waiting for the main PLL to stabilize.
For example: When we transition between very low frequencies on exynos, like
between 200MHz and 300MHz, we may temporarily switch to a PLL running at 800MHz.
No CPUFREQ notification is sent for that. That means there's a period of time
when we're running at 800MHz but loops_per_jiffy is calibrated at between 200MHz
and 300MHz. And so udelay behaves badly.
To get this fixed in a generic way, lets introduce another set of callbacks
get_intermediate() and target_intermediate(), only for drivers with
target_index() and CPUFREQ_ASYNC_NOTIFICATION unset.
get_intermediate should return a stable intermediate frequency platform wants to
switch to, and target_intermediate() should set CPU to to that frequency, before
jumping to the frequency corresponding to 'index'. Core will take care of
sending notifications and driver doesn't have to handle them in
target_intermediate() or target_index().
This patchset also update Tegra to use this new infrastructure and is already
tested by Stephen.
NOTE: Once set to intermediate frequency, driver isn't expected to fail for the
following ->target_index() call, if it fails core will issue a WARN().
V2-V3:
- Fix spelling error: s/Uset/Used
- Update tegra with the changes Stephen suggested
- Include a dependency patch sent separately earlier (3/4)
V1-V2: Almost changed completely, V1 was here: https://lkml.org/lkml/2014/5/15/40
Viresh Kumar (4):
cpufreq: handle calls to ->target_index() in separate routine
cpufreq: add support for intermediate (stable) frequencies
cpufreq: Tegra: drop wrapper around tegra_update_cpu_speed()
cpufreq: Tegra: implement intermediate frequency callbacks
Documentation/cpu-freq/cpu-drivers.txt | 19 +++++++-
drivers/cpufreq/cpufreq.c | 82 ++++++++++++++++++++++++----------
drivers/cpufreq/tegra-cpufreq.c | 80 ++++++++++++++++-----------------
include/linux/cpufreq.h | 15 +++++++
4 files changed, 129 insertions(+), 67 deletions(-)
--
2.0.0.rc2