Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c2794437 authored by Rob Herring's avatar Rob Herring
Browse files

ARM: Add fixed PCI i/o mapping



This adds a fixed virtual mapping for PCI i/o addresses. The mapping is
located at the last 2MB of vmalloc region (0xfee00000-0xff000000). 2MB
is used to align with PMD size, but IO_SPACE_LIMIT is 1MB. The space
is reserved after .map_io and can be mapped at any time later with
pci_ioremap_io. Platforms which need early i/o mapping (e.g. for vga
console) can call pci_map_io_early in their .map_io function.

This has changed completely from the 1st implementation which only
supported creating the static mapping at .map_io.

Signed-off-by: default avatarRob Herring <rob.herring@calxeda.com>
Cc: Russell King <linux@arm.linux.org.uk>
Acked-by: default avatarNicolas Pitre <nico@linaro.org>
parent 701eb264
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -51,6 +51,9 @@ ffc00000 ffefffff DMA memory mapping region. Memory returned
ff000000	ffbfffff	Reserved for future expansion of DMA
				mapping region.

fee00000	feffffff	Mapping of PCI I/O space. This is a static
				mapping within the vmalloc space.

VMALLOC_START	VMALLOC_END-1	vmalloc() / ioremap() space.
				Memory returned by vmalloc/ioremap will
				be dynamically placed in this region.
+8 −0
Original line number Diff line number Diff line
@@ -113,11 +113,19 @@ static inline void __iomem *__typesafe_io(unsigned long addr)
#define __iowmb()		do { } while (0)
#endif

/* PCI fixed i/o mapping */
#define PCI_IO_VIRT_BASE	0xfee00000

extern int pci_ioremap_io(unsigned int offset, phys_addr_t phys_addr);

/*
 * Now, pick up the machine-defined IO definitions
 */
#ifdef CONFIG_NEED_MACH_IO_H
#include <mach/io.h>
#elif defined(CONFIG_PCI)
#define IO_SPACE_LIMIT	((resource_size_t)0xfffff)
#define __io(a)		__typesafe_io(PCI_IO_VIRT_BASE + ((a) & IO_SPACE_LIMIT))
#else
#define __io(a)		__typesafe_io((a) & IO_SPACE_LIMIT)
#endif
+8 −0
Original line number Diff line number Diff line
@@ -9,6 +9,9 @@
 *
 *  Page table mapping constructs and function prototypes
 */
#ifndef __ASM_MACH_MAP_H
#define __ASM_MACH_MAP_H

#include <asm/io.h>

struct map_desc {
@@ -34,6 +37,8 @@ struct map_desc {

#ifdef CONFIG_MMU
extern void iotable_init(struct map_desc *, int);
extern void vm_reserve_area_early(unsigned long addr, unsigned long size,
				  void *caller);

struct mem_type;
extern const struct mem_type *get_mem_type(unsigned int type);
@@ -44,4 +49,7 @@ extern int ioremap_page(unsigned long virt, unsigned long phys,
			const struct mem_type *mtype);
#else
#define iotable_init(map,num)	do { } while (0)
#define vm_reserve_area_early(a,s,c)	do { } while (0)
#endif

#endif
+10 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#ifndef __ASM_MACH_PCI_H
#define __ASM_MACH_PCI_H


struct pci_sys_data;
struct pci_ops;
struct pci_bus;
@@ -54,6 +55,15 @@ struct pci_sys_data {
 */
void pci_common_init(struct hw_pci *);

/*
 * Setup early fixed I/O mapping.
 */
#if defined(CONFIG_PCI)
extern void pci_map_io_early(unsigned long pfn);
#else
static inline void pci_map_io_early(unsigned long pfn) {}
#endif

/*
 * PCI controllers
 */
+13 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
#include <linux/io.h>

#include <asm/mach-types.h>
#include <asm/mach/map.h>
#include <asm/mach/pci.h>

static int debug_pci;
@@ -627,3 +628,15 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,

	return 0;
}

void __init pci_map_io_early(unsigned long pfn)
{
	struct map_desc pci_io_desc = {
		.virtual	= PCI_IO_VIRT_BASE,
		.type		= MT_DEVICE,
		.length		= SZ_64K,
	};

	pci_io_desc.pfn = pfn;
	iotable_init(&pci_io_desc, 1);
}
Loading