提交 2f284c84 编写于 作者: L Linus Torvalds

Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm

* 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm: (35 commits)
  ARM: Update (and cut down) mach-types
  ARM: 6771/1: vexpress: add support for multiple core tiles
  ARM: 6797/1: hw_breakpoint: Fix newlines in WARNings
  ARM: 6751/1: vexpress: select applicable errata workarounds in Kconfig
  ARM: 6753/1: omap4: Enable ARM local timers with OMAP4430 es1.0 exception
  ARM: 6759/1: smp: Select local timers vs broadcast timer support runtime
  ARM: pgtable: add pud-level code
  ARM: 6673/1: LPAE: use phys_addr_t instead of unsigned long for start of membanks
  ARM: Use long long format when printing meminfo physical addresses
  ARM: integrator: add Integrator/CP sched_clock support
  ARM: realview/vexpress: consolidate SMP bringup code
  ARM: realview/vexpress: consolidate localtimer support
  ARM: integrator/versatile: consolidate FPGA IRQ handling code
  ARM: rationalize versatile family Kconfig/Makefile
  ARM: realview: remove old AMBA device DMA definitions
  ARM: versatile: remove old AMBA device DMA definitions
  ARM: vexpress: use new init_early for clock tree and sched_clock init
  ARM: realview: use new init_early for clock tree and sched_clock init
  ARM: versatile: use new init_early for clock tree and sched_clock init
  ARM: integrator: use new init_early for clock tree init
  ...
...@@ -235,6 +235,7 @@ config ARCH_INTEGRATOR ...@@ -235,6 +235,7 @@ config ARCH_INTEGRATOR
select ICST select ICST
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select PLAT_VERSATILE select PLAT_VERSATILE
select PLAT_VERSATILE_FPGA_IRQ
help help
Support for ARM's Integrator platform. Support for ARM's Integrator platform.
...@@ -242,11 +243,11 @@ config ARCH_REALVIEW ...@@ -242,11 +243,11 @@ config ARCH_REALVIEW
bool "ARM Ltd. RealView family" bool "ARM Ltd. RealView family"
select ARM_AMBA select ARM_AMBA
select CLKDEV_LOOKUP select CLKDEV_LOOKUP
select HAVE_SCHED_CLOCK
select ICST select ICST
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select ARCH_WANT_OPTIONAL_GPIOLIB select ARCH_WANT_OPTIONAL_GPIOLIB
select PLAT_VERSATILE select PLAT_VERSATILE
select PLAT_VERSATILE_CLCD
select ARM_TIMER_SP804 select ARM_TIMER_SP804
select GPIO_PL061 if GPIOLIB select GPIO_PL061 if GPIOLIB
help help
...@@ -257,11 +258,12 @@ config ARCH_VERSATILE ...@@ -257,11 +258,12 @@ config ARCH_VERSATILE
select ARM_AMBA select ARM_AMBA
select ARM_VIC select ARM_VIC
select CLKDEV_LOOKUP select CLKDEV_LOOKUP
select HAVE_SCHED_CLOCK
select ICST select ICST
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select ARCH_WANT_OPTIONAL_GPIOLIB select ARCH_WANT_OPTIONAL_GPIOLIB
select PLAT_VERSATILE select PLAT_VERSATILE
select PLAT_VERSATILE_CLCD
select PLAT_VERSATILE_FPGA_IRQ
select ARM_TIMER_SP804 select ARM_TIMER_SP804
help help
This enables support for ARM Ltd Versatile board. This enables support for ARM Ltd Versatile board.
...@@ -274,9 +276,10 @@ config ARCH_VEXPRESS ...@@ -274,9 +276,10 @@ config ARCH_VEXPRESS
select CLKDEV_LOOKUP select CLKDEV_LOOKUP
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select HAVE_CLK select HAVE_CLK
select HAVE_SCHED_CLOCK select HAVE_PATA_PLATFORM
select ICST select ICST
select PLAT_VERSATILE select PLAT_VERSATILE
select PLAT_VERSATILE_CLCD
help help
This enables support for the ARM Ltd Versatile Express boards. This enables support for the ARM Ltd Versatile Express boards.
...@@ -1011,6 +1014,7 @@ source "arch/arm/mach-ux500/Kconfig" ...@@ -1011,6 +1014,7 @@ source "arch/arm/mach-ux500/Kconfig"
source "arch/arm/mach-versatile/Kconfig" source "arch/arm/mach-versatile/Kconfig"
source "arch/arm/mach-vexpress/Kconfig" source "arch/arm/mach-vexpress/Kconfig"
source "arch/arm/plat-versatile/Kconfig"
source "arch/arm/mach-vt8500/Kconfig" source "arch/arm/mach-vt8500/Kconfig"
......
...@@ -44,8 +44,14 @@ int local_timer_ack(void); ...@@ -44,8 +44,14 @@ int local_timer_ack(void);
/* /*
* Setup a local timer interrupt for a CPU. * Setup a local timer interrupt for a CPU.
*/ */
void local_timer_setup(struct clock_event_device *); int local_timer_setup(struct clock_event_device *);
#else
static inline int local_timer_setup(struct clock_event_device *evt)
{
return -ENXIO;
}
#endif #endif
#endif #endif
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#ifndef __ASM_OUTERCACHE_H #ifndef __ASM_OUTERCACHE_H
#define __ASM_OUTERCACHE_H #define __ASM_OUTERCACHE_H
#include <linux/types.h>
struct outer_cache_fns { struct outer_cache_fns {
void (*inv_range)(unsigned long, unsigned long); void (*inv_range)(unsigned long, unsigned long);
void (*clean_range)(unsigned long, unsigned long); void (*clean_range)(unsigned long, unsigned long);
...@@ -38,17 +40,17 @@ struct outer_cache_fns { ...@@ -38,17 +40,17 @@ struct outer_cache_fns {
extern struct outer_cache_fns outer_cache; extern struct outer_cache_fns outer_cache;
static inline void outer_inv_range(unsigned long start, unsigned long end) static inline void outer_inv_range(phys_addr_t start, phys_addr_t end)
{ {
if (outer_cache.inv_range) if (outer_cache.inv_range)
outer_cache.inv_range(start, end); outer_cache.inv_range(start, end);
} }
static inline void outer_clean_range(unsigned long start, unsigned long end) static inline void outer_clean_range(phys_addr_t start, phys_addr_t end)
{ {
if (outer_cache.clean_range) if (outer_cache.clean_range)
outer_cache.clean_range(start, end); outer_cache.clean_range(start, end);
} }
static inline void outer_flush_range(unsigned long start, unsigned long end) static inline void outer_flush_range(phys_addr_t start, phys_addr_t end)
{ {
if (outer_cache.flush_range) if (outer_cache.flush_range)
outer_cache.flush_range(start, end); outer_cache.flush_range(start, end);
...@@ -74,11 +76,11 @@ static inline void outer_disable(void) ...@@ -74,11 +76,11 @@ static inline void outer_disable(void)
#else #else
static inline void outer_inv_range(unsigned long start, unsigned long end) static inline void outer_inv_range(phys_addr_t start, phys_addr_t end)
{ } { }
static inline void outer_clean_range(unsigned long start, unsigned long end) static inline void outer_clean_range(phys_addr_t start, phys_addr_t end)
{ } { }
static inline void outer_flush_range(unsigned long start, unsigned long end) static inline void outer_flush_range(phys_addr_t start, phys_addr_t end)
{ } { }
static inline void outer_flush_all(void) { } static inline void outer_flush_all(void) { }
static inline void outer_inv_all(void) { } static inline void outer_inv_all(void) { }
......
...@@ -301,6 +301,7 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; ...@@ -301,6 +301,7 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
#define pgd_present(pgd) (1) #define pgd_present(pgd) (1)
#define pgd_clear(pgdp) do { } while (0) #define pgd_clear(pgdp) do { } while (0)
#define set_pgd(pgd,pgdp) do { } while (0) #define set_pgd(pgd,pgdp) do { } while (0)
#define set_pud(pud,pudp) do { } while (0)
/* Find an entry in the second-level page table.. */ /* Find an entry in the second-level page table.. */
...@@ -351,7 +352,7 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd) ...@@ -351,7 +352,7 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd)
#define pte_unmap(pte) __pte_unmap(pte) #define pte_unmap(pte) __pte_unmap(pte)
#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT) #define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)
#define pfn_pte(pfn,prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) #define pfn_pte(pfn,prot) __pte(__pfn_to_phys(pfn) | pgprot_val(prot))
#define pte_page(pte) pfn_to_page(pte_pfn(pte)) #define pte_page(pte) pfn_to_page(pte_pfn(pte))
#define mk_pte(page,prot) pfn_pte(page_to_pfn(page), prot) #define mk_pte(page,prot) pfn_pte(page_to_pfn(page), prot)
......
...@@ -195,7 +195,7 @@ static struct tagtable __tagtable_##fn __tag = { tag, fn } ...@@ -195,7 +195,7 @@ static struct tagtable __tagtable_##fn __tag = { tag, fn }
#define NR_BANKS 8 #define NR_BANKS 8
struct membank { struct membank {
unsigned long start; phys_addr_t start;
unsigned long size; unsigned long size;
unsigned int highmem; unsigned int highmem;
}; };
......
...@@ -238,8 +238,8 @@ static int enable_monitor_mode(void) ...@@ -238,8 +238,8 @@ static int enable_monitor_mode(void)
ARM_DBG_READ(c1, 0, dscr); ARM_DBG_READ(c1, 0, dscr);
/* Ensure that halting mode is disabled. */ /* Ensure that halting mode is disabled. */
if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN, "halting debug mode enabled." if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN,
"Unable to access hardware resources.")) { "halting debug mode enabled. Unable to access hardware resources.\n")) {
ret = -EPERM; ret = -EPERM;
goto out; goto out;
} }
...@@ -377,7 +377,7 @@ int arch_install_hw_breakpoint(struct perf_event *bp) ...@@ -377,7 +377,7 @@ int arch_install_hw_breakpoint(struct perf_event *bp)
} }
} }
if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot")) { if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n")) {
ret = -EBUSY; ret = -EBUSY;
goto out; goto out;
} }
...@@ -423,7 +423,7 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp) ...@@ -423,7 +423,7 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp)
} }
} }
if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot")) if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n"))
return; return;
/* Reset the control register. */ /* Reset the control register. */
...@@ -635,7 +635,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp) ...@@ -635,7 +635,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
if (WARN_ONCE(!bp->overflow_handler && if (WARN_ONCE(!bp->overflow_handler &&
(arch_check_bp_in_kernelspace(bp) || !core_has_mismatch_brps() (arch_check_bp_in_kernelspace(bp) || !core_has_mismatch_brps()
|| !bp->hw.bp_target), || !bp->hw.bp_target),
"overflow handler required but none found")) { "overflow handler required but none found\n")) {
ret = -EINVAL; ret = -EINVAL;
} }
out: out:
...@@ -936,8 +936,8 @@ static int __init arch_hw_breakpoint_init(void) ...@@ -936,8 +936,8 @@ static int __init arch_hw_breakpoint_init(void)
ARM_DBG_READ(c1, 0, dscr); ARM_DBG_READ(c1, 0, dscr);
if (dscr & ARM_DSCR_HDBGEN) { if (dscr & ARM_DSCR_HDBGEN) {
max_watchpoint_len = 4; max_watchpoint_len = 4;
pr_warning("halting debug mode enabled. Assuming maximum " pr_warning("halting debug mode enabled. Assuming maximum watchpoint size of %u bytes.\n",
"watchpoint size of %u bytes.", max_watchpoint_len); max_watchpoint_len);
} else { } else {
/* Work out the maximum supported watchpoint length. */ /* Work out the maximum supported watchpoint length. */
max_watchpoint_len = get_max_wp_len(); max_watchpoint_len = get_max_wp_len();
......
...@@ -466,13 +466,13 @@ static struct machine_desc * __init setup_machine(unsigned int nr) ...@@ -466,13 +466,13 @@ static struct machine_desc * __init setup_machine(unsigned int nr)
/* can't use cpu_relax() here as it may require MMU setup */; /* can't use cpu_relax() here as it may require MMU setup */;
} }
static int __init arm_add_memory(unsigned long start, unsigned long size) static int __init arm_add_memory(phys_addr_t start, unsigned long size)
{ {
struct membank *bank = &meminfo.bank[meminfo.nr_banks]; struct membank *bank = &meminfo.bank[meminfo.nr_banks];
if (meminfo.nr_banks >= NR_BANKS) { if (meminfo.nr_banks >= NR_BANKS) {
printk(KERN_CRIT "NR_BANKS too low, " printk(KERN_CRIT "NR_BANKS too low, "
"ignoring memory at %#lx\n", start); "ignoring memory at 0x%08llx\n", (long long)start);
return -EINVAL; return -EINVAL;
} }
...@@ -502,7 +502,8 @@ static int __init arm_add_memory(unsigned long start, unsigned long size) ...@@ -502,7 +502,8 @@ static int __init arm_add_memory(unsigned long start, unsigned long size)
static int __init early_mem(char *p) static int __init early_mem(char *p)
{ {
static int usermem __initdata = 0; static int usermem __initdata = 0;
unsigned long size, start; unsigned long size;
phys_addr_t start;
char *endp; char *endp;
/* /*
......
...@@ -474,13 +474,12 @@ static void smp_timer_broadcast(const struct cpumask *mask) ...@@ -474,13 +474,12 @@ static void smp_timer_broadcast(const struct cpumask *mask)
#define smp_timer_broadcast NULL #define smp_timer_broadcast NULL
#endif #endif
#ifndef CONFIG_LOCAL_TIMERS
static void broadcast_timer_set_mode(enum clock_event_mode mode, static void broadcast_timer_set_mode(enum clock_event_mode mode,
struct clock_event_device *evt) struct clock_event_device *evt)
{ {
} }
static void local_timer_setup(struct clock_event_device *evt) static void broadcast_timer_setup(struct clock_event_device *evt)
{ {
evt->name = "dummy_timer"; evt->name = "dummy_timer";
evt->features = CLOCK_EVT_FEAT_ONESHOT | evt->features = CLOCK_EVT_FEAT_ONESHOT |
...@@ -492,7 +491,6 @@ static void local_timer_setup(struct clock_event_device *evt) ...@@ -492,7 +491,6 @@ static void local_timer_setup(struct clock_event_device *evt)
clockevents_register_device(evt); clockevents_register_device(evt);
} }
#endif
void __cpuinit percpu_timer_setup(void) void __cpuinit percpu_timer_setup(void)
{ {
...@@ -502,7 +500,8 @@ void __cpuinit percpu_timer_setup(void) ...@@ -502,7 +500,8 @@ void __cpuinit percpu_timer_setup(void)
evt->cpumask = cpumask_of(cpu); evt->cpumask = cpumask_of(cpu);
evt->broadcast = smp_timer_broadcast; evt->broadcast = smp_timer_broadcast;
local_timer_setup(evt); if (local_timer_setup(evt))
broadcast_timer_setup(evt);
} }
#ifdef CONFIG_HOTPLUG_CPU #ifdef CONFIG_HOTPLUG_CPU
......
...@@ -712,17 +712,17 @@ EXPORT_SYMBOL(__readwrite_bug); ...@@ -712,17 +712,17 @@ EXPORT_SYMBOL(__readwrite_bug);
void __pte_error(const char *file, int line, pte_t pte) void __pte_error(const char *file, int line, pte_t pte)
{ {
printk("%s:%d: bad pte %08lx.\n", file, line, pte_val(pte)); printk("%s:%d: bad pte %08llx.\n", file, line, (long long)pte_val(pte));
} }
void __pmd_error(const char *file, int line, pmd_t pmd) void __pmd_error(const char *file, int line, pmd_t pmd)
{ {
printk("%s:%d: bad pmd %08lx.\n", file, line, pmd_val(pmd)); printk("%s:%d: bad pmd %08llx.\n", file, line, (long long)pmd_val(pmd));
} }
void __pgd_error(const char *file, int line, pgd_t pgd) void __pgd_error(const char *file, int line, pgd_t pgd)
{ {
printk("%s:%d: bad pgd %08lx.\n", file, line, pgd_val(pgd)); printk("%s:%d: bad pgd %08llx.\n", file, line, (long long)pgd_val(pgd));
} }
asmlinkage void __div0(void) asmlinkage void __div0(void)
......
...@@ -27,13 +27,18 @@ pin_page_for_write(const void __user *_addr, pte_t **ptep, spinlock_t **ptlp) ...@@ -27,13 +27,18 @@ pin_page_for_write(const void __user *_addr, pte_t **ptep, spinlock_t **ptlp)
pgd_t *pgd; pgd_t *pgd;
pmd_t *pmd; pmd_t *pmd;
pte_t *pte; pte_t *pte;
pud_t *pud;
spinlock_t *ptl; spinlock_t *ptl;
pgd = pgd_offset(current->mm, addr); pgd = pgd_offset(current->mm, addr);
if (unlikely(pgd_none(*pgd) || pgd_bad(*pgd))) if (unlikely(pgd_none(*pgd) || pgd_bad(*pgd)))
return 0; return 0;
pmd = pmd_offset(pgd, addr); pud = pud_offset(pgd, addr);
if (unlikely(pud_none(*pud) || pud_bad(*pud)))
return 0;
pmd = pmd_offset(pud, addr);
if (unlikely(pmd_none(*pmd) || pmd_bad(*pmd))) if (unlikely(pmd_none(*pmd) || pmd_bad(*pmd)))
return 0; return 0;
......
...@@ -18,8 +18,9 @@ ...@@ -18,8 +18,9 @@
/* /*
* Setup the local clock events for a CPU. * Setup the local clock events for a CPU.
*/ */
void __cpuinit local_timer_setup(struct clock_event_device *evt) int __cpuinit local_timer_setup(struct clock_event_device *evt)
{ {
evt->irq = IRQ_LOCALTIMER; evt->irq = IRQ_LOCALTIMER;
twd_timer_setup(evt); twd_timer_setup(evt);
return 0;
} }
...@@ -13,6 +13,7 @@ config ARCH_INTEGRATOR_CP ...@@ -13,6 +13,7 @@ config ARCH_INTEGRATOR_CP
bool "Support Integrator/CP platform" bool "Support Integrator/CP platform"
select ARCH_CINTEGRATOR select ARCH_CINTEGRATOR
select ARM_TIMER_SP804 select ARM_TIMER_SP804
select PLAT_VERSATILE_CLCD
help help
Include support for the ARM(R) Integrator CP platform. Include support for the ARM(R) Integrator CP platform.
......
void integrator_init_early(void);
void integrator_reserve(void); void integrator_reserve(void);
...@@ -144,12 +144,15 @@ static struct clk_lookup lookups[] = { ...@@ -144,12 +144,15 @@ static struct clk_lookup lookups[] = {
} }
}; };
void __init integrator_init_early(void)
{
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
}
static int __init integrator_init(void) static int __init integrator_init(void)
{ {
int i; int i;
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
struct amba_device *d = amba_devs[i]; struct amba_device *d = amba_devs[i];
amba_device_register(d, &iomem_resource); amba_device_register(d, &iomem_resource);
......
...@@ -121,6 +121,7 @@ static struct clcd_panel vga = { ...@@ -121,6 +121,7 @@ static struct clcd_panel vga = {
.height = -1, .height = -1,
.tim2 = TIM2_BCD | TIM2_IPC, .tim2 = TIM2_BCD | TIM2_IPC,
.cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1), .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
.caps = CLCD_CAP_5551,
.connector = IMPD1_CTRL_DISP_VGA, .connector = IMPD1_CTRL_DISP_VGA,
.bpp = 16, .bpp = 16,
.grayscale = 0, .grayscale = 0,
...@@ -149,6 +150,7 @@ static struct clcd_panel svga = { ...@@ -149,6 +150,7 @@ static struct clcd_panel svga = {
.tim2 = TIM2_BCD, .tim2 = TIM2_BCD,
.cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1), .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
.connector = IMPD1_CTRL_DISP_VGA, .connector = IMPD1_CTRL_DISP_VGA,
.caps = CLCD_CAP_5551,
.bpp = 16, .bpp = 16,
.grayscale = 0, .grayscale = 0,
}; };
...@@ -175,6 +177,7 @@ static struct clcd_panel prospector = { ...@@ -175,6 +177,7 @@ static struct clcd_panel prospector = {
.height = -1, .height = -1,
.tim2 = TIM2_BCD, .tim2 = TIM2_BCD,
.cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1), .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
.caps = CLCD_CAP_5551,
.fixedtimings = 1, .fixedtimings = 1,
.connector = IMPD1_CTRL_DISP_LCD, .connector = IMPD1_CTRL_DISP_LCD,
.bpp = 16, .bpp = 16,
...@@ -206,6 +209,7 @@ static struct clcd_panel ltm10c209 = { ...@@ -206,6 +209,7 @@ static struct clcd_panel ltm10c209 = {
.height = -1, .height = -1,
.tim2 = TIM2_BCD, .tim2 = TIM2_BCD,
.cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1), .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
.caps = CLCD_CAP_5551,
.fixedtimings = 1, .fixedtimings = 1,
.connector = IMPD1_CTRL_DISP_LCD, .connector = IMPD1_CTRL_DISP_LCD,
.bpp = 16, .bpp = 16,
...@@ -279,6 +283,7 @@ static void impd1fb_clcd_remove(struct clcd_fb *fb) ...@@ -279,6 +283,7 @@ static void impd1fb_clcd_remove(struct clcd_fb *fb)
static struct clcd_board impd1_clcd_data = { static struct clcd_board impd1_clcd_data = {
.name = "IM-PD/1", .name = "IM-PD/1",
.caps = CLCD_CAP_5551 | CLCD_CAP_888,
.check = clcdfb_check, .check = clcdfb_check,
.decode = clcdfb_decode, .decode = clcdfb_decode,
.disable = impd1fb_clcd_disable, .disable = impd1fb_clcd_disable,
......
...@@ -24,9 +24,9 @@ void cm_control(u32, u32); ...@@ -24,9 +24,9 @@ void cm_control(u32, u32);
#define CM_CTRL_LCDBIASDN (1 << 10) #define CM_CTRL_LCDBIASDN (1 << 10)
#define CM_CTRL_LCDMUXSEL_MASK (7 << 11) #define CM_CTRL_LCDMUXSEL_MASK (7 << 11)
#define CM_CTRL_LCDMUXSEL_GENLCD (1 << 11) #define CM_CTRL_LCDMUXSEL_GENLCD (1 << 11)
#define CM_CTRL_LCDMUXSEL_VGA_16BPP (2 << 11) #define CM_CTRL_LCDMUXSEL_VGA565_TFT555 (2 << 11)
#define CM_CTRL_LCDMUXSEL_SHARPLCD (3 << 11) #define CM_CTRL_LCDMUXSEL_SHARPLCD (3 << 11)
#define CM_CTRL_LCDMUXSEL_VGA_8421BPP (4 << 11) #define CM_CTRL_LCDMUXSEL_VGA555_TFT555 (4 << 11)
#define CM_CTRL_LCDEN0 (1 << 14) #define CM_CTRL_LCDEN0 (1 << 14)
#define CM_CTRL_LCDEN1 (1 << 15) #define CM_CTRL_LCDEN1 (1 << 15)
#define CM_CTRL_STATIC1 (1 << 16) #define CM_CTRL_STATIC1 (1 << 16)
......
...@@ -48,6 +48,8 @@ ...@@ -48,6 +48,8 @@
#include <asm/mach/map.h> #include <asm/mach/map.h>
#include <asm/mach/time.h> #include <asm/mach/time.h>
#include <plat/fpga-irq.h>
#include "common.h" #include "common.h"
/* /*
...@@ -57,10 +59,10 @@ ...@@ -57,10 +59,10 @@
* Setup a VA for the Integrator interrupt controller (for header #0, * Setup a VA for the Integrator interrupt controller (for header #0,
* just for now). * just for now).
*/ */
#define VA_IC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE) #define VA_IC_BASE __io_address(INTEGRATOR_IC_BASE)
#define VA_SC_BASE IO_ADDRESS(INTEGRATOR_SC_BASE) #define VA_SC_BASE __io_address(INTEGRATOR_SC_BASE)
#define VA_EBI_BASE IO_ADDRESS(INTEGRATOR_EBI_BASE) #define VA_EBI_BASE __io_address(INTEGRATOR_EBI_BASE)
#define VA_CMIC_BASE IO_ADDRESS(INTEGRATOR_HDR_IC) #define VA_CMIC_BASE __io_address(INTEGRATOR_HDR_IC)
/* /*
* Logical Physical * Logical Physical
...@@ -156,27 +158,14 @@ static void __init ap_map_io(void) ...@@ -156,27 +158,14 @@ static void __init ap_map_io(void)
#define INTEGRATOR_SC_VALID_INT 0x003fffff #define INTEGRATOR_SC_VALID_INT 0x003fffff
static void sc_mask_irq(struct irq_data *d) static struct fpga_irq_data sc_irq_data = {
{ .base = VA_IC_BASE,
writel(1 << d->irq, VA_IC_BASE + IRQ_ENABLE_CLEAR); .irq_start = 0,
} .chip.name = "SC",
static void sc_unmask_irq(struct irq_data *d)
{
writel(1 << d->irq, VA_IC_BASE + IRQ_ENABLE_SET);
}
static struct irq_chip sc_chip = {
.name = "SC",
.irq_ack = sc_mask_irq,
.irq_mask = sc_mask_irq,
.irq_unmask = sc_unmask_irq,
}; };
static void __init ap_init_irq(void) static void __init ap_init_irq(void)
{ {
unsigned int i;
/* Disable all interrupts initially. */ /* Disable all interrupts initially. */
/* Do the core module ones */ /* Do the core module ones */
writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR); writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
...@@ -185,13 +174,7 @@ static void __init ap_init_irq(void) ...@@ -185,13 +174,7 @@ static void __init ap_init_irq(void)
writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR); writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR); writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
for (i = 0; i < NR_IRQS; i++) { fpga_irq_init(-1, INTEGRATOR_SC_VALID_INT, &sc_irq_data);
if (((1 << i) & INTEGRATOR_SC_VALID_INT) != 0) {
set_irq_chip(i, &sc_chip);
set_irq_handler(i, handle_level_irq);
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
}
}
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM
...@@ -282,7 +265,7 @@ static void ap_flash_exit(void) ...@@ -282,7 +265,7 @@ static void ap_flash_exit(void)
static void ap_flash_set_vpp(int on) static void ap_flash_set_vpp(int on)
{ {
unsigned long reg = on ? SC_CTRLS : SC_CTRLC; void __iomem *reg = on ? SC_CTRLS : SC_CTRLC;
writel(INTEGRATOR_SC_CTRL_nFLVPPEN, reg); writel(INTEGRATOR_SC_CTRL_nFLVPPEN, reg);
} }
...@@ -499,8 +482,9 @@ static struct sys_timer ap_timer = { ...@@ -499,8 +482,9 @@ static struct sys_timer ap_timer = {
MACHINE_START(INTEGRATOR, "ARM-Integrator") MACHINE_START(INTEGRATOR, "ARM-Integrator")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
.boot_params = 0x00000100, .boot_params = 0x00000100,
.map_io = ap_map_io,
.reserve = integrator_reserve, .reserve = integrator_reserve,
.map_io = ap_map_io,
.init_early = integrator_init_early,
.init_irq = ap_init_irq, .init_irq = ap_init_irq,
.timer = &ap_timer, .timer = &ap_timer,
.init_machine = ap_init, .init_machine = ap_init,
......
...@@ -42,6 +42,10 @@ ...@@ -42,6 +42,10 @@
#include <asm/hardware/timer-sp.h> #include <asm/hardware/timer-sp.h>
#include <plat/clcd.h>
#include <plat/fpga-irq.h>
#include <plat/sched_clock.h>
#include "common.h" #include "common.h"
#define INTCP_PA_FLASH_BASE 0x24000000 #define INTCP_PA_FLASH_BASE 0x24000000
...@@ -49,9 +53,9 @@ ...@@ -49,9 +53,9 @@
#define INTCP_PA_CLCD_BASE 0xc0000000 #define INTCP_PA_CLCD_BASE 0xc0000000
#define INTCP_VA_CIC_BASE IO_ADDRESS(INTEGRATOR_HDR_BASE + 0x40) #define INTCP_VA_CIC_BASE __io_address(INTEGRATOR_HDR_BASE + 0x40)
#define INTCP_VA_PIC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE) #define INTCP_VA_PIC_BASE __io_address(INTEGRATOR_IC_BASE)
#define INTCP_VA_SIC_BASE IO_ADDRESS(INTEGRATOR_CP_SIC_BASE) #define INTCP_VA_SIC_BASE __io_address(INTEGRATOR_CP_SIC_BASE)
#define INTCP_ETH_SIZE 0x10 #define INTCP_ETH_SIZE 0x10
...@@ -139,129 +143,48 @@ static void __init intcp_map_io(void) ...@@ -139,129 +143,48 @@ static void __init intcp_map_io(void)
iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc)); iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc));
} }
#define cic_writel __raw_writel static struct fpga_irq_data cic_irq_data = {
#define cic_readl __raw_readl .base = INTCP_VA_CIC_BASE,
#define pic_writel __raw_writel .irq_start = IRQ_CIC_START,
#define pic_readl __raw_readl .chip.name = "CIC",
#define sic_writel __raw_writel
#define sic_readl __raw_readl
static void cic_mask_irq(struct irq_data *d)
{
unsigned int irq = d->irq - IRQ_CIC_START;
cic_writel(1 << irq, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR);
}
static void cic_unmask_irq(struct irq_data *d)
{
unsigned int irq = d->irq - IRQ_CIC_START;
cic_writel(1 << irq, INTCP_VA_CIC_BASE + IRQ_ENABLE_SET);
}
static struct irq_chip cic_chip = {
.name = "CIC",
.irq_ack = cic_mask_irq,
.irq_mask = cic_mask_irq,
.irq_unmask = cic_unmask_irq,
}; };
static void pic_mask_irq(struct irq_data *d) static struct fpga_irq_data pic_irq_data = {
{ .base = INTCP_VA_PIC_BASE,
unsigned int irq = d->irq - IRQ_PIC_START; .irq_start = IRQ_PIC_START,
pic_writel(1 << irq, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR); .chip.name = "PIC",
}
static void pic_unmask_irq(struct irq_data *d)
{
unsigned int irq = d->irq - IRQ_PIC_START;
pic_writel(1 << irq, INTCP_VA_PIC_BASE + IRQ_ENABLE_SET);
}
static struct irq_chip pic_chip = {
.name = "PIC",
.irq_ack = pic_mask_irq,
.irq_mask = pic_mask_irq,
.irq_unmask = pic_unmask_irq,
}; };
static void sic_mask_irq(struct irq_data *d) static struct fpga_irq_data sic_irq_data = {
{ .base = INTCP_VA_SIC_BASE,
unsigned int irq = d->irq - IRQ_SIC_START; .irq_start = IRQ_SIC_START,
sic_writel(1 << irq, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR); .chip.name = "SIC",
}
static void sic_unmask_irq(struct irq_data *d)
{
unsigned int irq = d->irq - IRQ_SIC_START;
sic_writel(1 << irq, INTCP_VA_SIC_BASE + IRQ_ENABLE_SET);
}
static struct irq_chip sic_chip = {
.name = "SIC",
.irq_ack = sic_mask_irq,
.irq_mask = sic_mask_irq,
.irq_unmask = sic_unmask_irq,
}; };
static void
sic_handle_irq(unsigned int irq, struct irq_desc *desc)
{
unsigned long status = sic_readl(INTCP_VA_SIC_BASE + IRQ_STATUS);
if (status == 0) {
do_bad_IRQ(irq, desc);
return;
}
do {
irq = ffs(status) - 1;
status &= ~(1 << irq);
irq += IRQ_SIC_START;
generic_handle_irq(irq);
} while (status);
}
static void __init intcp_init_irq(void) static void __init intcp_init_irq(void)
{ {
unsigned int i; u32 pic_mask, sic_mask;
pic_mask = ~((~0u) << (11 - IRQ_PIC_START));
pic_mask |= (~((~0u) << (29 - 22))) << 22;
sic_mask = ~((~0u) << (1 + IRQ_SIC_END - IRQ_SIC_START));
/* /*
* Disable all interrupt sources * Disable all interrupt sources
*/ */
pic_writel(0xffffffff, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR); writel(0xffffffff, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR);
pic_writel(0xffffffff, INTCP_VA_PIC_BASE + FIQ_ENABLE_CLEAR); writel(0xffffffff, INTCP_VA_PIC_BASE + FIQ_ENABLE_CLEAR);
writel(0xffffffff, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR);
for (i = IRQ_PIC_START; i <= IRQ_PIC_END; i++) { writel(0xffffffff, INTCP_VA_CIC_BASE + FIQ_ENABLE_CLEAR);
if (i == 11) writel(sic_mask, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR);
i = 22; writel(sic_mask, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR);
if (i == 29)
break;
set_irq_chip(i, &pic_chip);
set_irq_handler(i, handle_level_irq);
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
}
cic_writel(0xffffffff, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR); fpga_irq_init(-1, pic_mask, &pic_irq_data);
cic_writel(0xffffffff, INTCP_VA_CIC_BASE + FIQ_ENABLE_CLEAR);
for (i = IRQ_CIC_START; i <= IRQ_CIC_END; i++) { fpga_irq_init(-1, ~((~0u) << (1 + IRQ_CIC_END - IRQ_CIC_START)),
set_irq_chip(i, &cic_chip); &cic_irq_data);
set_irq_handler(i, handle_level_irq);
set_irq_flags(i, IRQF_VALID);
}
sic_writel(0x00000fff, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR);
sic_writel(0x00000fff, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR);
for (i = IRQ_SIC_START; i <= IRQ_SIC_END; i++) {
set_irq_chip(i, &sic_chip);
set_irq_handler(i, handle_level_irq);
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
}
set_irq_chained_handler(IRQ_CP_CPPLDINT, sic_handle_irq); fpga_irq_init(IRQ_CP_CPPLDINT, sic_mask, &sic_irq_data);
} }
/* /*
...@@ -449,43 +372,21 @@ static struct amba_device aaci_device = { ...@@ -449,43 +372,21 @@ static struct amba_device aaci_device = {
/* /*
* CLCD support * CLCD support
*/ */
static struct clcd_panel vga = {
.mode = {
.name = "VGA",
.refresh = 60,
.xres = 640,
.yres = 480,
.pixclock = 39721,
.left_margin = 40,
.right_margin = 24,
.upper_margin = 32,
.lower_margin = 11,
.hsync_len = 96,
.vsync_len = 2,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_BCD | TIM2_IPC,
.cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
.bpp = 16,
.grayscale = 0,
};
/* /*
* Ensure VGA is selected. * Ensure VGA is selected.
*/ */
static void cp_clcd_enable(struct clcd_fb *fb) static void cp_clcd_enable(struct clcd_fb *fb)
{ {
u32 val; struct fb_var_screeninfo *var = &fb->fb.var;
u32 val = CM_CTRL_STATIC1 | CM_CTRL_STATIC2;
if (fb->fb.var.bits_per_pixel <= 8) if (var->bits_per_pixel <= 8 ||
val = CM_CTRL_LCDMUXSEL_VGA_8421BPP; (var->bits_per_pixel == 16 && var->green.length == 5))
/* Pseudocolor, RGB555, BGR555 */
val |= CM_CTRL_LCDMUXSEL_VGA555_TFT555;
else if (fb->fb.var.bits_per_pixel <= 16) else if (fb->fb.var.bits_per_pixel <= 16)
val = CM_CTRL_LCDMUXSEL_VGA_16BPP /* truecolor RGB565 */
| CM_CTRL_LCDEN0 | CM_CTRL_LCDEN1 val |= CM_CTRL_LCDMUXSEL_VGA565_TFT555;
| CM_CTRL_STATIC1 | CM_CTRL_STATIC2;
else else
val = 0; /* no idea for this, don't trust the docs */ val = 0; /* no idea for this, don't trust the docs */
...@@ -498,49 +399,24 @@ static void cp_clcd_enable(struct clcd_fb *fb) ...@@ -498,49 +399,24 @@ static void cp_clcd_enable(struct clcd_fb *fb)
CM_CTRL_n24BITEN, val); CM_CTRL_n24BITEN, val);
} }
static unsigned long framesize = SZ_1M;
static int cp_clcd_setup(struct clcd_fb *fb) static int cp_clcd_setup(struct clcd_fb *fb)
{ {
dma_addr_t dma; fb->panel = versatile_clcd_get_panel("VGA");
if (!fb->panel)
fb->panel = &vga; return -EINVAL;
fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize,
&dma, GFP_KERNEL);
if (!fb->fb.screen_base) {
printk(KERN_ERR "CLCD: unable to map framebuffer\n");
return -ENOMEM;
}
fb->fb.fix.smem_start = dma;
fb->fb.fix.smem_len = framesize;
return 0;
}
static int cp_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
{
return dma_mmap_writecombine(&fb->dev->dev, vma,
fb->fb.screen_base,
fb->fb.fix.smem_start,
fb->fb.fix.smem_len);
}
static void cp_clcd_remove(struct clcd_fb *fb) return versatile_clcd_setup_dma(fb, SZ_1M);
{
dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
fb->fb.screen_base, fb->fb.fix.smem_start);
} }
static struct clcd_board clcd_data = { static struct clcd_board clcd_data = {
.name = "Integrator/CP", .name = "Integrator/CP",
.caps = CLCD_CAP_5551 | CLCD_CAP_RGB565 | CLCD_CAP_888,
.check = clcdfb_check, .check = clcdfb_check,
.decode = clcdfb_decode, .decode = clcdfb_decode,
.enable = cp_clcd_enable, .enable = cp_clcd_enable,
.setup = cp_clcd_setup, .setup = cp_clcd_setup,
.mmap = cp_clcd_mmap, .mmap = versatile_clcd_mmap_dma,
.remove = cp_clcd_remove, .remove = versatile_clcd_remove_dma,
}; };
static struct amba_device clcd_device = { static struct amba_device clcd_device = {
...@@ -565,11 +441,23 @@ static struct amba_device *amba_devs[] __initdata = { ...@@ -565,11 +441,23 @@ static struct amba_device *amba_devs[] __initdata = {
&clcd_device, &clcd_device,
}; };
#define REFCOUNTER (__io_address(INTEGRATOR_HDR_BASE) + 0x28)
static void __init intcp_init_early(void)
{
clkdev_add_table(cp_lookups, ARRAY_SIZE(cp_lookups));
integrator_init_early();
#ifdef CONFIG_PLAT_VERSATILE_SCHED_CLOCK
versatile_sched_clock_init(REFCOUNTER, 24000000);
#endif
}
static void __init intcp_init(void) static void __init intcp_init(void)
{ {
int i; int i;
clkdev_add_table(cp_lookups, ARRAY_SIZE(cp_lookups));
platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs)); platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs));
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
...@@ -599,8 +487,9 @@ static struct sys_timer cp_timer = { ...@@ -599,8 +487,9 @@ static struct sys_timer cp_timer = {
MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP") MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
.boot_params = 0x00000100, .boot_params = 0x00000100,
.map_io = intcp_map_io,
.reserve = integrator_reserve, .reserve = integrator_reserve,
.map_io = intcp_map_io,
.init_early = intcp_init_early,
.init_irq = intcp_init_irq, .init_irq = intcp_init_irq,
.timer = &cp_timer, .timer = &cp_timer,
.init_machine = intcp_init, .init_machine = intcp_init,
......
...@@ -263,7 +263,7 @@ static void __init msm_timer_init(void) ...@@ -263,7 +263,7 @@ static void __init msm_timer_init(void)
} }
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
void __cpuinit local_timer_setup(struct clock_event_device *evt) int __cpuinit local_timer_setup(struct clock_event_device *evt)
{ {
struct msm_clock *clock = &msm_clocks[MSM_GLOBAL_TIMER]; struct msm_clock *clock = &msm_clocks[MSM_GLOBAL_TIMER];
...@@ -295,6 +295,7 @@ void __cpuinit local_timer_setup(struct clock_event_device *evt) ...@@ -295,6 +295,7 @@ void __cpuinit local_timer_setup(struct clock_event_device *evt)
gic_enable_ppi(clock->irq.irq); gic_enable_ppi(clock->irq.irq);
clockevents_register_device(evt); clockevents_register_device(evt);
return 0;
} }
inline int local_timer_ack(void) inline int local_timer_ack(void)
......
...@@ -44,6 +44,7 @@ config ARCH_OMAP4 ...@@ -44,6 +44,7 @@ config ARCH_OMAP4
depends on ARCH_OMAP2PLUS depends on ARCH_OMAP2PLUS
select CPU_V7 select CPU_V7
select ARM_GIC select ARM_GIC
select LOCAL_TIMERS if SMP
select PL310_ERRATA_588369 select PL310_ERRATA_588369
select PL310_ERRATA_727915 select PL310_ERRATA_727915
select ARM_ERRATA_720789 select ARM_ERRATA_720789
......
...@@ -26,9 +26,14 @@ ...@@ -26,9 +26,14 @@
/* /*
* Setup the local clock events for a CPU. * Setup the local clock events for a CPU.
*/ */
void __cpuinit local_timer_setup(struct clock_event_device *evt) int __cpuinit local_timer_setup(struct clock_event_device *evt)
{ {
/* Local timers are not supprted on OMAP4430 ES1.0 */
if (omap_rev() == OMAP4430_REV_ES1_0)
return -ENXIO;
evt->irq = OMAP44XX_IRQ_LOCALTIMER; evt->irq = OMAP44XX_IRQ_LOCALTIMER;
twd_timer_setup(evt); twd_timer_setup(evt);
return 0;
} }
...@@ -8,6 +8,5 @@ obj-$(CONFIG_MACH_REALVIEW_PB11MP) += realview_pb11mp.o ...@@ -8,6 +8,5 @@ obj-$(CONFIG_MACH_REALVIEW_PB11MP) += realview_pb11mp.o
obj-$(CONFIG_MACH_REALVIEW_PB1176) += realview_pb1176.o obj-$(CONFIG_MACH_REALVIEW_PB1176) += realview_pb1176.o
obj-$(CONFIG_MACH_REALVIEW_PBA8) += realview_pba8.o obj-$(CONFIG_MACH_REALVIEW_PBA8) += realview_pba8.o
obj-$(CONFIG_MACH_REALVIEW_PBX) += realview_pbx.o obj-$(CONFIG_MACH_REALVIEW_PBX) += realview_pbx.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o obj-$(CONFIG_SMP) += platsmp.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
#include <mach/irqs.h> #include <mach/irqs.h>
#include <asm/hardware/timer-sp.h> #include <asm/hardware/timer-sp.h>
#include <plat/clcd.h>
#include <plat/sched_clock.h> #include <plat/sched_clock.h>
#include "core.h" #include "core.h"
...@@ -359,18 +360,19 @@ static struct clk_lookup lookups[] = { ...@@ -359,18 +360,19 @@ static struct clk_lookup lookups[] = {
} }
}; };
static int __init clk_init(void) void __init realview_init_early(void)
{ {
void __iomem *sys = __io_address(REALVIEW_SYS_BASE);
if (machine_is_realview_pb1176()) if (machine_is_realview_pb1176())
oscvco_clk.vcoreg = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC0_OFFSET; oscvco_clk.vcoreg = sys + REALVIEW_SYS_OSC0_OFFSET;
else else
oscvco_clk.vcoreg = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC4_OFFSET; oscvco_clk.vcoreg = sys + REALVIEW_SYS_OSC4_OFFSET;
clkdev_add_table(lookups, ARRAY_SIZE(lookups)); clkdev_add_table(lookups, ARRAY_SIZE(lookups));
return 0; versatile_sched_clock_init(sys + REALVIEW_SYS_24MHz_OFFSET, 24000000);
} }
core_initcall(clk_init);
/* /*
* CLCD support. * CLCD support.
...@@ -385,157 +387,6 @@ core_initcall(clk_init); ...@@ -385,157 +387,6 @@ core_initcall(clk_init);
#define SYS_CLCD_ID_SANYO_2_5 (0x07 << 8) #define SYS_CLCD_ID_SANYO_2_5 (0x07 << 8)
#define SYS_CLCD_ID_VGA (0x1f << 8) #define SYS_CLCD_ID_VGA (0x1f << 8)
static struct clcd_panel vga = {
.mode = {
.name = "VGA",
.refresh = 60,
.xres = 640,
.yres = 480,
.pixclock = 39721,
.left_margin = 40,
.right_margin = 24,
.upper_margin = 32,
.lower_margin = 11,
.hsync_len = 96,
.vsync_len = 2,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_BCD | TIM2_IPC,
.cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
.bpp = 16,
};
static struct clcd_panel xvga = {
.mode = {
.name = "XVGA",
.refresh = 60,
.xres = 1024,
.yres = 768,
.pixclock = 15748,
.left_margin = 152,
.right_margin = 48,
.upper_margin = 23,
.lower_margin = 3,
.hsync_len = 104,
.vsync_len = 4,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_BCD | TIM2_IPC,
.cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
.bpp = 16,
};
static struct clcd_panel sanyo_3_8_in = {
.mode = {
.name = "Sanyo QVGA",
.refresh = 116,
.xres = 320,
.yres = 240,
.pixclock = 100000,
.left_margin = 6,
.right_margin = 6,
.upper_margin = 5,
.lower_margin = 5,
.hsync_len = 6,
.vsync_len = 6,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_BCD,
.cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
.bpp = 16,
};
static struct clcd_panel sanyo_2_5_in = {
.mode = {
.name = "Sanyo QVGA Portrait",
.refresh = 116,
.xres = 240,
.yres = 320,
.pixclock = 100000,
.left_margin = 20,
.right_margin = 10,
.upper_margin = 2,
.lower_margin = 2,
.hsync_len = 10,
.vsync_len = 2,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_IVS | TIM2_IHS | TIM2_IPC,
.cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
.bpp = 16,
};
static struct clcd_panel epson_2_2_in = {
.mode = {
.name = "Epson QCIF",
.refresh = 390,
.xres = 176,
.yres = 220,
.pixclock = 62500,
.left_margin = 3,
.right_margin = 2,
.upper_margin = 1,
.lower_margin = 0,
.hsync_len = 3,
.vsync_len = 2,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_BCD | TIM2_IPC,
.cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
.bpp = 16,
};
/*
* Detect which LCD panel is connected, and return the appropriate
* clcd_panel structure. Note: we do not have any information on
* the required timings for the 8.4in panel, so we presently assume
* VGA timings.
*/
static struct clcd_panel *realview_clcd_panel(void)
{
void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET;
struct clcd_panel *vga_panel;
struct clcd_panel *panel;
u32 val;
if (machine_is_realview_eb())
vga_panel = &vga;
else
vga_panel = &xvga;
val = readl(sys_clcd) & SYS_CLCD_ID_MASK;
if (val == SYS_CLCD_ID_SANYO_3_8)
panel = &sanyo_3_8_in;
else if (val == SYS_CLCD_ID_SANYO_2_5)
panel = &sanyo_2_5_in;
else if (val == SYS_CLCD_ID_EPSON_2_2)
panel = &epson_2_2_in;
else if (val == SYS_CLCD_ID_VGA)
panel = vga_panel;
else {
printk(KERN_ERR "CLCD: unknown LCD panel ID 0x%08x, using VGA\n",
val);
panel = vga_panel;
}
return panel;
}
/* /*
* Disable all display connectors on the interface module. * Disable all display connectors on the interface module.
*/ */
...@@ -565,56 +416,60 @@ static void realview_clcd_enable(struct clcd_fb *fb) ...@@ -565,56 +416,60 @@ static void realview_clcd_enable(struct clcd_fb *fb)
writel(val, sys_clcd); writel(val, sys_clcd);
} }
/*
* Detect which LCD panel is connected, and return the appropriate
* clcd_panel structure. Note: we do not have any information on
* the required timings for the 8.4in panel, so we presently assume
* VGA timings.
*/
static int realview_clcd_setup(struct clcd_fb *fb) static int realview_clcd_setup(struct clcd_fb *fb)
{ {
void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET;
const char *panel_name, *vga_panel_name;
unsigned long framesize; unsigned long framesize;
dma_addr_t dma; u32 val;
if (machine_is_realview_eb()) if (machine_is_realview_eb()) {
/* VGA, 16bpp */ /* VGA, 16bpp */
framesize = 640 * 480 * 2; framesize = 640 * 480 * 2;
else vga_panel_name = "VGA";
} else {
/* XVGA, 16bpp */ /* XVGA, 16bpp */
framesize = 1024 * 768 * 2; framesize = 1024 * 768 * 2;
vga_panel_name = "XVGA";
fb->panel = realview_clcd_panel();
fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize,
&dma, GFP_KERNEL | GFP_DMA);
if (!fb->fb.screen_base) {
printk(KERN_ERR "CLCD: unable to map framebuffer\n");
return -ENOMEM;
} }
fb->fb.fix.smem_start = dma; val = readl(sys_clcd) & SYS_CLCD_ID_MASK;
fb->fb.fix.smem_len = framesize; if (val == SYS_CLCD_ID_SANYO_3_8)
panel_name = "Sanyo TM38QV67A02A";
return 0; else if (val == SYS_CLCD_ID_SANYO_2_5)
} panel_name = "Sanyo QVGA Portrait";
else if (val == SYS_CLCD_ID_EPSON_2_2)
panel_name = "Epson L2F50113T00";
else if (val == SYS_CLCD_ID_VGA)
panel_name = vga_panel_name;
else {
pr_err("CLCD: unknown LCD panel ID 0x%08x, using VGA\n", val);
panel_name = vga_panel_name;
}
static int realview_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma) fb->panel = versatile_clcd_get_panel(panel_name);
{ if (!fb->panel)
return dma_mmap_writecombine(&fb->dev->dev, vma, return -EINVAL;
fb->fb.screen_base,
fb->fb.fix.smem_start,
fb->fb.fix.smem_len);
}
static void realview_clcd_remove(struct clcd_fb *fb) return versatile_clcd_setup_dma(fb, framesize);
{
dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
fb->fb.screen_base, fb->fb.fix.smem_start);
} }
struct clcd_board clcd_plat_data = { struct clcd_board clcd_plat_data = {
.name = "RealView", .name = "RealView",
.caps = CLCD_CAP_ALL,
.check = clcdfb_check, .check = clcdfb_check,
.decode = clcdfb_decode, .decode = clcdfb_decode,
.disable = realview_clcd_disable, .disable = realview_clcd_disable,
.enable = realview_clcd_enable, .enable = realview_clcd_enable,
.setup = realview_clcd_setup, .setup = realview_clcd_setup,
.mmap = realview_clcd_mmap, .mmap = versatile_clcd_mmap_dma,
.remove = realview_clcd_remove, .remove = versatile_clcd_remove_dma,
}; };
#ifdef CONFIG_LEDS #ifdef CONFIG_LEDS
...@@ -655,12 +510,6 @@ void realview_leds_event(led_event_t ledevt) ...@@ -655,12 +510,6 @@ void realview_leds_event(led_event_t ledevt)
} }
#endif /* CONFIG_LEDS */ #endif /* CONFIG_LEDS */
/*
* The sched_clock counter
*/
#define REFCOUNTER (__io_address(REALVIEW_SYS_BASE) + \
REALVIEW_SYS_24MHz_OFFSET)
/* /*
* Where is the timer (VA)? * Where is the timer (VA)?
*/ */
...@@ -676,8 +525,6 @@ void __init realview_timer_init(unsigned int timer_irq) ...@@ -676,8 +525,6 @@ void __init realview_timer_init(unsigned int timer_irq)
{ {
u32 val; u32 val;
versatile_sched_clock_init(REFCOUNTER, 24000000);
/* /*
* set clock frequency: * set clock frequency:
* REALVIEW_REFCLK is 32KHz * REALVIEW_REFCLK is 32KHz
......
...@@ -42,7 +42,6 @@ static struct amba_device name##_device = { \ ...@@ -42,7 +42,6 @@ static struct amba_device name##_device = { \
}, \ }, \
.dma_mask = ~0, \ .dma_mask = ~0, \
.irq = base##_IRQ, \ .irq = base##_IRQ, \
/* .dma = base##_DMA,*/ \
} }
struct machine_desc; struct machine_desc;
...@@ -63,6 +62,7 @@ extern void realview_timer_init(unsigned int timer_irq); ...@@ -63,6 +62,7 @@ extern void realview_timer_init(unsigned int timer_irq);
extern int realview_flash_register(struct resource *res, u32 num); extern int realview_flash_register(struct resource *res, u32 num);
extern int realview_eth_register(const char *name, struct resource *res); extern int realview_eth_register(const char *name, struct resource *res);
extern int realview_usb_register(struct resource *res); extern int realview_usb_register(struct resource *res);
extern void realview_init_early(void);
extern void realview_fixup(struct machine_desc *mdesc, struct tag *tags, extern void realview_fixup(struct machine_desc *mdesc, struct tag *tags,
char **from, struct meminfo *meminfo); char **from, struct meminfo *meminfo);
extern void (*realview_reset)(char); extern void (*realview_reset)(char);
......
/*
* linux/arch/arm/mach-realview/headsmp.S
*
* Copyright (c) 2003 ARM Limited
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/linkage.h>
#include <linux/init.h>
__INIT
/*
* Realview specific entry point for secondary CPUs. This provides
* a "holding pen" into which all secondary cores are held until we're
* ready for them to initialise.
*/
ENTRY(realview_secondary_startup)
mrc p15, 0, r0, c0, c0, 5
and r0, r0, #15
adr r4, 1f
ldmia r4, {r5, r6}
sub r4, r4, r5
add r6, r6, r4
pen: ldr r7, [r6]
cmp r7, r0
bne pen
/*
* we've been released from the holding pen: secondary_stack
* should now contain the SVC stack for this core
*/
b secondary_startup
.align
1: .long .
.long pen_release
/*
* linux/arch/arm/mach-realview/localtimer.c
*
* Copyright (C) 2002 ARM Ltd.
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/smp.h>
#include <linux/clockchips.h>
#include <asm/irq.h>
#include <asm/smp_twd.h>
#include <asm/localtimer.h>
/*
* Setup the local clock events for a CPU.
*/
void __cpuinit local_timer_setup(struct clock_event_device *evt)
{
evt->irq = IRQ_LOCALTIMER;
twd_timer_setup(evt);
}
...@@ -10,44 +10,21 @@ ...@@ -10,44 +10,21 @@
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/jiffies.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/io.h> #include <linux/io.h>
#include <asm/cacheflush.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/smp_scu.h>
#include <asm/unified.h> #include <asm/unified.h>
#include <mach/board-eb.h> #include <mach/board-eb.h>
#include <mach/board-pb11mp.h> #include <mach/board-pb11mp.h>
#include <mach/board-pbx.h> #include <mach/board-pbx.h>
#include <asm/smp_scu.h>
#include "core.h" #include "core.h"
extern void realview_secondary_startup(void); extern void versatile_secondary_startup(void);
/*
* control for which core is the next to come out of the secondary
* boot "holding pen"
*/
volatile int __cpuinitdata pen_release = -1;
/*
* Write pen_release in a way that is guaranteed to be visible to all
* observers, irrespective of whether they're taking part in coherency
* or not. This is necessary for the hotplug code to work reliably.
*/
static void __cpuinit write_pen_release(int val)
{
pen_release = val;
smp_wmb();
__cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
}
static void __iomem *scu_base_addr(void) static void __iomem *scu_base_addr(void)
{ {
...@@ -62,75 +39,6 @@ static void __iomem *scu_base_addr(void) ...@@ -62,75 +39,6 @@ static void __iomem *scu_base_addr(void)
return (void __iomem *)0; return (void __iomem *)0;
} }
static DEFINE_SPINLOCK(boot_lock);
void __cpuinit platform_secondary_init(unsigned int cpu)
{
/*
* if any interrupts are already enabled for the primary
* core (e.g. timer irq), then they will not have been enabled
* for us: do so
*/
gic_secondary_init(0);
/*
* let the primary processor know we're out of the
* pen, then head off into the C entry point
*/
write_pen_release(-1);
/*
* Synchronise with the boot thread.
*/
spin_lock(&boot_lock);
spin_unlock(&boot_lock);
}
int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
{
unsigned long timeout;
/*
* set synchronisation state between this boot processor
* and the secondary one
*/
spin_lock(&boot_lock);
/*
* The secondary processor is waiting to be released from
* the holding pen - release it, then wait for it to flag
* that it has been released by resetting pen_release.
*
* Note that "pen_release" is the hardware CPU ID, whereas
* "cpu" is Linux's internal ID.
*/
write_pen_release(cpu);
/*
* Send the secondary CPU a soft interrupt, thereby causing
* the boot monitor to read the system wide flags register,
* and branch to the address found there.
*/
smp_cross_call(cpumask_of(cpu), 1);
timeout = jiffies + (1 * HZ);
while (time_before(jiffies, timeout)) {
smp_rmb();
if (pen_release == -1)
break;
udelay(10);
}
/*
* now the secondary core is starting up let it run its
* calibrations, then wait for it to finish
*/
spin_unlock(&boot_lock);
return pen_release != -1 ? -ENOSYS : 0;
}
/* /*
* Initialise the CPU possible map early - this describes the CPUs * Initialise the CPU possible map early - this describes the CPUs
* which may be present or become present in the system. * which may be present or become present in the system.
...@@ -174,6 +82,6 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus) ...@@ -174,6 +82,6 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
* until it receives a soft interrupt, and then the * until it receives a soft interrupt, and then the
* secondary CPU branches to this address. * secondary CPU branches to this address.
*/ */
__raw_writel(BSYM(virt_to_phys(realview_secondary_startup)), __raw_writel(BSYM(virt_to_phys(versatile_secondary_startup)),
__io_address(REALVIEW_SYS_FLAGSSET)); __io_address(REALVIEW_SYS_FLAGSSET));
} }
...@@ -144,60 +144,39 @@ static struct pl022_ssp_controller ssp0_plat_data = { ...@@ -144,60 +144,39 @@ static struct pl022_ssp_controller ssp0_plat_data = {
* These devices are connected via the core APB bridge * These devices are connected via the core APB bridge
*/ */
#define GPIO2_IRQ { IRQ_EB_GPIO2, NO_IRQ } #define GPIO2_IRQ { IRQ_EB_GPIO2, NO_IRQ }
#define GPIO2_DMA { 0, 0 }
#define GPIO3_IRQ { IRQ_EB_GPIO3, NO_IRQ } #define GPIO3_IRQ { IRQ_EB_GPIO3, NO_IRQ }
#define GPIO3_DMA { 0, 0 }
#define AACI_IRQ { IRQ_EB_AACI, NO_IRQ } #define AACI_IRQ { IRQ_EB_AACI, NO_IRQ }
#define AACI_DMA { 0x80, 0x81 }
#define MMCI0_IRQ { IRQ_EB_MMCI0A, IRQ_EB_MMCI0B } #define MMCI0_IRQ { IRQ_EB_MMCI0A, IRQ_EB_MMCI0B }
#define MMCI0_DMA { 0x84, 0 }
#define KMI0_IRQ { IRQ_EB_KMI0, NO_IRQ } #define KMI0_IRQ { IRQ_EB_KMI0, NO_IRQ }
#define KMI0_DMA { 0, 0 }
#define KMI1_IRQ { IRQ_EB_KMI1, NO_IRQ } #define KMI1_IRQ { IRQ_EB_KMI1, NO_IRQ }
#define KMI1_DMA { 0, 0 }
/* /*
* These devices are connected directly to the multi-layer AHB switch * These devices are connected directly to the multi-layer AHB switch
*/ */
#define EB_SMC_IRQ { NO_IRQ, NO_IRQ } #define EB_SMC_IRQ { NO_IRQ, NO_IRQ }
#define EB_SMC_DMA { 0, 0 }
#define MPMC_IRQ { NO_IRQ, NO_IRQ } #define MPMC_IRQ { NO_IRQ, NO_IRQ }
#define MPMC_DMA { 0, 0 }
#define EB_CLCD_IRQ { IRQ_EB_CLCD, NO_IRQ } #define EB_CLCD_IRQ { IRQ_EB_CLCD, NO_IRQ }
#define EB_CLCD_DMA { 0, 0 }
#define DMAC_IRQ { IRQ_EB_DMA, NO_IRQ } #define DMAC_IRQ { IRQ_EB_DMA, NO_IRQ }
#define DMAC_DMA { 0, 0 }
/* /*
* These devices are connected via the core APB bridge * These devices are connected via the core APB bridge
*/ */
#define SCTL_IRQ { NO_IRQ, NO_IRQ } #define SCTL_IRQ { NO_IRQ, NO_IRQ }
#define SCTL_DMA { 0, 0 }
#define EB_WATCHDOG_IRQ { IRQ_EB_WDOG, NO_IRQ } #define EB_WATCHDOG_IRQ { IRQ_EB_WDOG, NO_IRQ }
#define EB_WATCHDOG_DMA { 0, 0 }
#define EB_GPIO0_IRQ { IRQ_EB_GPIO0, NO_IRQ } #define EB_GPIO0_IRQ { IRQ_EB_GPIO0, NO_IRQ }
#define EB_GPIO0_DMA { 0, 0 }
#define GPIO1_IRQ { IRQ_EB_GPIO1, NO_IRQ } #define GPIO1_IRQ { IRQ_EB_GPIO1, NO_IRQ }
#define GPIO1_DMA { 0, 0 }
#define EB_RTC_IRQ { IRQ_EB_RTC, NO_IRQ } #define EB_RTC_IRQ { IRQ_EB_RTC, NO_IRQ }
#define EB_RTC_DMA { 0, 0 }
/* /*
* These devices are connected via the DMA APB bridge * These devices are connected via the DMA APB bridge
*/ */
#define SCI_IRQ { IRQ_EB_SCI, NO_IRQ } #define SCI_IRQ { IRQ_EB_SCI, NO_IRQ }
#define SCI_DMA { 7, 6 }
#define EB_UART0_IRQ { IRQ_EB_UART0, NO_IRQ } #define EB_UART0_IRQ { IRQ_EB_UART0, NO_IRQ }
#define EB_UART0_DMA { 15, 14 }
#define EB_UART1_IRQ { IRQ_EB_UART1, NO_IRQ } #define EB_UART1_IRQ { IRQ_EB_UART1, NO_IRQ }
#define EB_UART1_DMA { 13, 12 }
#define EB_UART2_IRQ { IRQ_EB_UART2, NO_IRQ } #define EB_UART2_IRQ { IRQ_EB_UART2, NO_IRQ }
#define EB_UART2_DMA { 11, 10 }
#define EB_UART3_IRQ { IRQ_EB_UART3, NO_IRQ } #define EB_UART3_IRQ { IRQ_EB_UART3, NO_IRQ }
#define EB_UART3_DMA { 0x86, 0x87 }
#define EB_SSP_IRQ { IRQ_EB_SSP, NO_IRQ } #define EB_SSP_IRQ { IRQ_EB_SSP, NO_IRQ }
#define EB_SSP_DMA { 9, 8 }
/* FPGA Primecells */ /* FPGA Primecells */
AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL); AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL);
...@@ -487,6 +466,7 @@ MACHINE_START(REALVIEW_EB, "ARM-RealView EB") ...@@ -487,6 +466,7 @@ MACHINE_START(REALVIEW_EB, "ARM-RealView EB")
.boot_params = PLAT_PHYS_OFFSET + 0x00000100, .boot_params = PLAT_PHYS_OFFSET + 0x00000100,
.fixup = realview_fixup, .fixup = realview_fixup,
.map_io = realview_eb_map_io, .map_io = realview_eb_map_io,
.init_early = realview_init_early,
.init_irq = gic_init_irq, .init_irq = gic_init_irq,
.timer = &realview_eb_timer, .timer = &realview_eb_timer,
.init_machine = realview_eb_init, .init_machine = realview_eb_init,
......
...@@ -134,47 +134,26 @@ static struct pl022_ssp_controller ssp0_plat_data = { ...@@ -134,47 +134,26 @@ static struct pl022_ssp_controller ssp0_plat_data = {
* RealView PB1176 AMBA devices * RealView PB1176 AMBA devices
*/ */
#define GPIO2_IRQ { IRQ_PB1176_GPIO2, NO_IRQ } #define GPIO2_IRQ { IRQ_PB1176_GPIO2, NO_IRQ }
#define GPIO2_DMA { 0, 0 }
#define GPIO3_IRQ { IRQ_PB1176_GPIO3, NO_IRQ } #define GPIO3_IRQ { IRQ_PB1176_GPIO3, NO_IRQ }
#define GPIO3_DMA { 0, 0 }
#define AACI_IRQ { IRQ_PB1176_AACI, NO_IRQ } #define AACI_IRQ { IRQ_PB1176_AACI, NO_IRQ }
#define AACI_DMA { 0x80, 0x81 }
#define MMCI0_IRQ { IRQ_PB1176_MMCI0A, IRQ_PB1176_MMCI0B } #define MMCI0_IRQ { IRQ_PB1176_MMCI0A, IRQ_PB1176_MMCI0B }
#define MMCI0_DMA { 0x84, 0 }
#define KMI0_IRQ { IRQ_PB1176_KMI0, NO_IRQ } #define KMI0_IRQ { IRQ_PB1176_KMI0, NO_IRQ }
#define KMI0_DMA { 0, 0 }
#define KMI1_IRQ { IRQ_PB1176_KMI1, NO_IRQ } #define KMI1_IRQ { IRQ_PB1176_KMI1, NO_IRQ }
#define KMI1_DMA { 0, 0 }
#define PB1176_SMC_IRQ { NO_IRQ, NO_IRQ } #define PB1176_SMC_IRQ { NO_IRQ, NO_IRQ }
#define PB1176_SMC_DMA { 0, 0 }
#define MPMC_IRQ { NO_IRQ, NO_IRQ } #define MPMC_IRQ { NO_IRQ, NO_IRQ }
#define MPMC_DMA { 0, 0 }
#define PB1176_CLCD_IRQ { IRQ_DC1176_CLCD, NO_IRQ } #define PB1176_CLCD_IRQ { IRQ_DC1176_CLCD, NO_IRQ }
#define PB1176_CLCD_DMA { 0, 0 }
#define SCTL_IRQ { NO_IRQ, NO_IRQ } #define SCTL_IRQ { NO_IRQ, NO_IRQ }
#define SCTL_DMA { 0, 0 }
#define PB1176_WATCHDOG_IRQ { IRQ_DC1176_WATCHDOG, NO_IRQ } #define PB1176_WATCHDOG_IRQ { IRQ_DC1176_WATCHDOG, NO_IRQ }
#define PB1176_WATCHDOG_DMA { 0, 0 }
#define PB1176_GPIO0_IRQ { IRQ_PB1176_GPIO0, NO_IRQ } #define PB1176_GPIO0_IRQ { IRQ_PB1176_GPIO0, NO_IRQ }
#define PB1176_GPIO0_DMA { 0, 0 }
#define GPIO1_IRQ { IRQ_PB1176_GPIO1, NO_IRQ } #define GPIO1_IRQ { IRQ_PB1176_GPIO1, NO_IRQ }
#define GPIO1_DMA { 0, 0 }
#define PB1176_RTC_IRQ { IRQ_DC1176_RTC, NO_IRQ } #define PB1176_RTC_IRQ { IRQ_DC1176_RTC, NO_IRQ }
#define PB1176_RTC_DMA { 0, 0 }
#define SCI_IRQ { IRQ_PB1176_SCI, NO_IRQ } #define SCI_IRQ { IRQ_PB1176_SCI, NO_IRQ }
#define SCI_DMA { 7, 6 }
#define PB1176_UART0_IRQ { IRQ_DC1176_UART0, NO_IRQ } #define PB1176_UART0_IRQ { IRQ_DC1176_UART0, NO_IRQ }
#define PB1176_UART0_DMA { 15, 14 }
#define PB1176_UART1_IRQ { IRQ_DC1176_UART1, NO_IRQ } #define PB1176_UART1_IRQ { IRQ_DC1176_UART1, NO_IRQ }
#define PB1176_UART1_DMA { 13, 12 }
#define PB1176_UART2_IRQ { IRQ_DC1176_UART2, NO_IRQ } #define PB1176_UART2_IRQ { IRQ_DC1176_UART2, NO_IRQ }
#define PB1176_UART2_DMA { 11, 10 }
#define PB1176_UART3_IRQ { IRQ_DC1176_UART3, NO_IRQ } #define PB1176_UART3_IRQ { IRQ_DC1176_UART3, NO_IRQ }
#define PB1176_UART3_DMA { 0x86, 0x87 }
#define PB1176_UART4_IRQ { IRQ_PB1176_UART4, NO_IRQ } #define PB1176_UART4_IRQ { IRQ_PB1176_UART4, NO_IRQ }
#define PB1176_UART4_DMA { 0, 0 }
#define PB1176_SSP_IRQ { IRQ_DC1176_SSP, NO_IRQ } #define PB1176_SSP_IRQ { IRQ_DC1176_SSP, NO_IRQ }
#define PB1176_SSP_DMA { 9, 8 }
/* FPGA Primecells */ /* FPGA Primecells */
AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL); AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL);
...@@ -382,6 +361,7 @@ MACHINE_START(REALVIEW_PB1176, "ARM-RealView PB1176") ...@@ -382,6 +361,7 @@ MACHINE_START(REALVIEW_PB1176, "ARM-RealView PB1176")
.boot_params = PLAT_PHYS_OFFSET + 0x00000100, .boot_params = PLAT_PHYS_OFFSET + 0x00000100,
.fixup = realview_pb1176_fixup, .fixup = realview_pb1176_fixup,
.map_io = realview_pb1176_map_io, .map_io = realview_pb1176_map_io,
.init_early = realview_init_early,
.init_irq = gic_init_irq, .init_irq = gic_init_irq,
.timer = &realview_pb1176_timer, .timer = &realview_pb1176_timer,
.init_machine = realview_pb1176_init, .init_machine = realview_pb1176_init,
......
...@@ -136,47 +136,26 @@ static struct pl022_ssp_controller ssp0_plat_data = { ...@@ -136,47 +136,26 @@ static struct pl022_ssp_controller ssp0_plat_data = {
*/ */
#define GPIO2_IRQ { IRQ_PB11MP_GPIO2, NO_IRQ } #define GPIO2_IRQ { IRQ_PB11MP_GPIO2, NO_IRQ }
#define GPIO2_DMA { 0, 0 }
#define GPIO3_IRQ { IRQ_PB11MP_GPIO3, NO_IRQ } #define GPIO3_IRQ { IRQ_PB11MP_GPIO3, NO_IRQ }
#define GPIO3_DMA { 0, 0 }
#define AACI_IRQ { IRQ_TC11MP_AACI, NO_IRQ } #define AACI_IRQ { IRQ_TC11MP_AACI, NO_IRQ }
#define AACI_DMA { 0x80, 0x81 }
#define MMCI0_IRQ { IRQ_TC11MP_MMCI0A, IRQ_TC11MP_MMCI0B } #define MMCI0_IRQ { IRQ_TC11MP_MMCI0A, IRQ_TC11MP_MMCI0B }
#define MMCI0_DMA { 0x84, 0 }
#define KMI0_IRQ { IRQ_TC11MP_KMI0, NO_IRQ } #define KMI0_IRQ { IRQ_TC11MP_KMI0, NO_IRQ }
#define KMI0_DMA { 0, 0 }
#define KMI1_IRQ { IRQ_TC11MP_KMI1, NO_IRQ } #define KMI1_IRQ { IRQ_TC11MP_KMI1, NO_IRQ }
#define KMI1_DMA { 0, 0 }
#define PB11MP_SMC_IRQ { NO_IRQ, NO_IRQ } #define PB11MP_SMC_IRQ { NO_IRQ, NO_IRQ }
#define PB11MP_SMC_DMA { 0, 0 }
#define MPMC_IRQ { NO_IRQ, NO_IRQ } #define MPMC_IRQ { NO_IRQ, NO_IRQ }
#define MPMC_DMA { 0, 0 }
#define PB11MP_CLCD_IRQ { IRQ_PB11MP_CLCD, NO_IRQ } #define PB11MP_CLCD_IRQ { IRQ_PB11MP_CLCD, NO_IRQ }
#define PB11MP_CLCD_DMA { 0, 0 }
#define DMAC_IRQ { IRQ_PB11MP_DMAC, NO_IRQ } #define DMAC_IRQ { IRQ_PB11MP_DMAC, NO_IRQ }
#define DMAC_DMA { 0, 0 }
#define SCTL_IRQ { NO_IRQ, NO_IRQ } #define SCTL_IRQ { NO_IRQ, NO_IRQ }
#define SCTL_DMA { 0, 0 }
#define PB11MP_WATCHDOG_IRQ { IRQ_PB11MP_WATCHDOG, NO_IRQ } #define PB11MP_WATCHDOG_IRQ { IRQ_PB11MP_WATCHDOG, NO_IRQ }
#define PB11MP_WATCHDOG_DMA { 0, 0 }
#define PB11MP_GPIO0_IRQ { IRQ_PB11MP_GPIO0, NO_IRQ } #define PB11MP_GPIO0_IRQ { IRQ_PB11MP_GPIO0, NO_IRQ }
#define PB11MP_GPIO0_DMA { 0, 0 }
#define GPIO1_IRQ { IRQ_PB11MP_GPIO1, NO_IRQ } #define GPIO1_IRQ { IRQ_PB11MP_GPIO1, NO_IRQ }
#define GPIO1_DMA { 0, 0 }
#define PB11MP_RTC_IRQ { IRQ_TC11MP_RTC, NO_IRQ } #define PB11MP_RTC_IRQ { IRQ_TC11MP_RTC, NO_IRQ }
#define PB11MP_RTC_DMA { 0, 0 }
#define SCI_IRQ { IRQ_PB11MP_SCI, NO_IRQ } #define SCI_IRQ { IRQ_PB11MP_SCI, NO_IRQ }
#define SCI_DMA { 7, 6 }
#define PB11MP_UART0_IRQ { IRQ_TC11MP_UART0, NO_IRQ } #define PB11MP_UART0_IRQ { IRQ_TC11MP_UART0, NO_IRQ }
#define PB11MP_UART0_DMA { 15, 14 }
#define PB11MP_UART1_IRQ { IRQ_TC11MP_UART1, NO_IRQ } #define PB11MP_UART1_IRQ { IRQ_TC11MP_UART1, NO_IRQ }
#define PB11MP_UART1_DMA { 13, 12 }
#define PB11MP_UART2_IRQ { IRQ_PB11MP_UART2, NO_IRQ } #define PB11MP_UART2_IRQ { IRQ_PB11MP_UART2, NO_IRQ }
#define PB11MP_UART2_DMA { 11, 10 }
#define PB11MP_UART3_IRQ { IRQ_PB11MP_UART3, NO_IRQ } #define PB11MP_UART3_IRQ { IRQ_PB11MP_UART3, NO_IRQ }
#define PB11MP_UART3_DMA { 0x86, 0x87 }
#define PB11MP_SSP_IRQ { IRQ_PB11MP_SSP, NO_IRQ } #define PB11MP_SSP_IRQ { IRQ_PB11MP_SSP, NO_IRQ }
#define PB11MP_SSP_DMA { 9, 8 }
/* FPGA Primecells */ /* FPGA Primecells */
AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL); AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL);
...@@ -384,6 +363,7 @@ MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore") ...@@ -384,6 +363,7 @@ MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore")
.boot_params = PLAT_PHYS_OFFSET + 0x00000100, .boot_params = PLAT_PHYS_OFFSET + 0x00000100,
.fixup = realview_fixup, .fixup = realview_fixup,
.map_io = realview_pb11mp_map_io, .map_io = realview_pb11mp_map_io,
.init_early = realview_init_early,
.init_irq = gic_init_irq, .init_irq = gic_init_irq,
.timer = &realview_pb11mp_timer, .timer = &realview_pb11mp_timer,
.init_machine = realview_pb11mp_init, .init_machine = realview_pb11mp_init,
......
...@@ -126,47 +126,26 @@ static struct pl022_ssp_controller ssp0_plat_data = { ...@@ -126,47 +126,26 @@ static struct pl022_ssp_controller ssp0_plat_data = {
*/ */
#define GPIO2_IRQ { IRQ_PBA8_GPIO2, NO_IRQ } #define GPIO2_IRQ { IRQ_PBA8_GPIO2, NO_IRQ }
#define GPIO2_DMA { 0, 0 }
#define GPIO3_IRQ { IRQ_PBA8_GPIO3, NO_IRQ } #define GPIO3_IRQ { IRQ_PBA8_GPIO3, NO_IRQ }
#define GPIO3_DMA { 0, 0 }
#define AACI_IRQ { IRQ_PBA8_AACI, NO_IRQ } #define AACI_IRQ { IRQ_PBA8_AACI, NO_IRQ }
#define AACI_DMA { 0x80, 0x81 }
#define MMCI0_IRQ { IRQ_PBA8_MMCI0A, IRQ_PBA8_MMCI0B } #define MMCI0_IRQ { IRQ_PBA8_MMCI0A, IRQ_PBA8_MMCI0B }
#define MMCI0_DMA { 0x84, 0 }
#define KMI0_IRQ { IRQ_PBA8_KMI0, NO_IRQ } #define KMI0_IRQ { IRQ_PBA8_KMI0, NO_IRQ }
#define KMI0_DMA { 0, 0 }
#define KMI1_IRQ { IRQ_PBA8_KMI1, NO_IRQ } #define KMI1_IRQ { IRQ_PBA8_KMI1, NO_IRQ }
#define KMI1_DMA { 0, 0 }
#define PBA8_SMC_IRQ { NO_IRQ, NO_IRQ } #define PBA8_SMC_IRQ { NO_IRQ, NO_IRQ }
#define PBA8_SMC_DMA { 0, 0 }
#define MPMC_IRQ { NO_IRQ, NO_IRQ } #define MPMC_IRQ { NO_IRQ, NO_IRQ }
#define MPMC_DMA { 0, 0 }
#define PBA8_CLCD_IRQ { IRQ_PBA8_CLCD, NO_IRQ } #define PBA8_CLCD_IRQ { IRQ_PBA8_CLCD, NO_IRQ }
#define PBA8_CLCD_DMA { 0, 0 }
#define DMAC_IRQ { IRQ_PBA8_DMAC, NO_IRQ } #define DMAC_IRQ { IRQ_PBA8_DMAC, NO_IRQ }
#define DMAC_DMA { 0, 0 }
#define SCTL_IRQ { NO_IRQ, NO_IRQ } #define SCTL_IRQ { NO_IRQ, NO_IRQ }
#define SCTL_DMA { 0, 0 }
#define PBA8_WATCHDOG_IRQ { IRQ_PBA8_WATCHDOG, NO_IRQ } #define PBA8_WATCHDOG_IRQ { IRQ_PBA8_WATCHDOG, NO_IRQ }
#define PBA8_WATCHDOG_DMA { 0, 0 }
#define PBA8_GPIO0_IRQ { IRQ_PBA8_GPIO0, NO_IRQ } #define PBA8_GPIO0_IRQ { IRQ_PBA8_GPIO0, NO_IRQ }
#define PBA8_GPIO0_DMA { 0, 0 }
#define GPIO1_IRQ { IRQ_PBA8_GPIO1, NO_IRQ } #define GPIO1_IRQ { IRQ_PBA8_GPIO1, NO_IRQ }
#define GPIO1_DMA { 0, 0 }
#define PBA8_RTC_IRQ { IRQ_PBA8_RTC, NO_IRQ } #define PBA8_RTC_IRQ { IRQ_PBA8_RTC, NO_IRQ }
#define PBA8_RTC_DMA { 0, 0 }
#define SCI_IRQ { IRQ_PBA8_SCI, NO_IRQ } #define SCI_IRQ { IRQ_PBA8_SCI, NO_IRQ }
#define SCI_DMA { 7, 6 }
#define PBA8_UART0_IRQ { IRQ_PBA8_UART0, NO_IRQ } #define PBA8_UART0_IRQ { IRQ_PBA8_UART0, NO_IRQ }
#define PBA8_UART0_DMA { 15, 14 }
#define PBA8_UART1_IRQ { IRQ_PBA8_UART1, NO_IRQ } #define PBA8_UART1_IRQ { IRQ_PBA8_UART1, NO_IRQ }
#define PBA8_UART1_DMA { 13, 12 }
#define PBA8_UART2_IRQ { IRQ_PBA8_UART2, NO_IRQ } #define PBA8_UART2_IRQ { IRQ_PBA8_UART2, NO_IRQ }
#define PBA8_UART2_DMA { 11, 10 }
#define PBA8_UART3_IRQ { IRQ_PBA8_UART3, NO_IRQ } #define PBA8_UART3_IRQ { IRQ_PBA8_UART3, NO_IRQ }
#define PBA8_UART3_DMA { 0x86, 0x87 }
#define PBA8_SSP_IRQ { IRQ_PBA8_SSP, NO_IRQ } #define PBA8_SSP_IRQ { IRQ_PBA8_SSP, NO_IRQ }
#define PBA8_SSP_DMA { 9, 8 }
/* FPGA Primecells */ /* FPGA Primecells */
AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL); AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL);
...@@ -334,6 +313,7 @@ MACHINE_START(REALVIEW_PBA8, "ARM-RealView PB-A8") ...@@ -334,6 +313,7 @@ MACHINE_START(REALVIEW_PBA8, "ARM-RealView PB-A8")
.boot_params = PLAT_PHYS_OFFSET + 0x00000100, .boot_params = PLAT_PHYS_OFFSET + 0x00000100,
.fixup = realview_fixup, .fixup = realview_fixup,
.map_io = realview_pba8_map_io, .map_io = realview_pba8_map_io,
.init_early = realview_init_early,
.init_irq = gic_init_irq, .init_irq = gic_init_irq,
.timer = &realview_pba8_timer, .timer = &realview_pba8_timer,
.init_machine = realview_pba8_init, .init_machine = realview_pba8_init,
......
...@@ -148,47 +148,26 @@ static struct pl022_ssp_controller ssp0_plat_data = { ...@@ -148,47 +148,26 @@ static struct pl022_ssp_controller ssp0_plat_data = {
*/ */
#define GPIO2_IRQ { IRQ_PBX_GPIO2, NO_IRQ } #define GPIO2_IRQ { IRQ_PBX_GPIO2, NO_IRQ }
#define GPIO2_DMA { 0, 0 }
#define GPIO3_IRQ { IRQ_PBX_GPIO3, NO_IRQ } #define GPIO3_IRQ { IRQ_PBX_GPIO3, NO_IRQ }
#define GPIO3_DMA { 0, 0 }
#define AACI_IRQ { IRQ_PBX_AACI, NO_IRQ } #define AACI_IRQ { IRQ_PBX_AACI, NO_IRQ }
#define AACI_DMA { 0x80, 0x81 }
#define MMCI0_IRQ { IRQ_PBX_MMCI0A, IRQ_PBX_MMCI0B } #define MMCI0_IRQ { IRQ_PBX_MMCI0A, IRQ_PBX_MMCI0B }
#define MMCI0_DMA { 0x84, 0 }
#define KMI0_IRQ { IRQ_PBX_KMI0, NO_IRQ } #define KMI0_IRQ { IRQ_PBX_KMI0, NO_IRQ }
#define KMI0_DMA { 0, 0 }
#define KMI1_IRQ { IRQ_PBX_KMI1, NO_IRQ } #define KMI1_IRQ { IRQ_PBX_KMI1, NO_IRQ }
#define KMI1_DMA { 0, 0 }
#define PBX_SMC_IRQ { NO_IRQ, NO_IRQ } #define PBX_SMC_IRQ { NO_IRQ, NO_IRQ }
#define PBX_SMC_DMA { 0, 0 }
#define MPMC_IRQ { NO_IRQ, NO_IRQ } #define MPMC_IRQ { NO_IRQ, NO_IRQ }
#define MPMC_DMA { 0, 0 }
#define PBX_CLCD_IRQ { IRQ_PBX_CLCD, NO_IRQ } #define PBX_CLCD_IRQ { IRQ_PBX_CLCD, NO_IRQ }
#define PBX_CLCD_DMA { 0, 0 }
#define DMAC_IRQ { IRQ_PBX_DMAC, NO_IRQ } #define DMAC_IRQ { IRQ_PBX_DMAC, NO_IRQ }
#define DMAC_DMA { 0, 0 }
#define SCTL_IRQ { NO_IRQ, NO_IRQ } #define SCTL_IRQ { NO_IRQ, NO_IRQ }
#define SCTL_DMA { 0, 0 }
#define PBX_WATCHDOG_IRQ { IRQ_PBX_WATCHDOG, NO_IRQ } #define PBX_WATCHDOG_IRQ { IRQ_PBX_WATCHDOG, NO_IRQ }
#define PBX_WATCHDOG_DMA { 0, 0 }
#define PBX_GPIO0_IRQ { IRQ_PBX_GPIO0, NO_IRQ } #define PBX_GPIO0_IRQ { IRQ_PBX_GPIO0, NO_IRQ }
#define PBX_GPIO0_DMA { 0, 0 }
#define GPIO1_IRQ { IRQ_PBX_GPIO1, NO_IRQ } #define GPIO1_IRQ { IRQ_PBX_GPIO1, NO_IRQ }
#define GPIO1_DMA { 0, 0 }
#define PBX_RTC_IRQ { IRQ_PBX_RTC, NO_IRQ } #define PBX_RTC_IRQ { IRQ_PBX_RTC, NO_IRQ }
#define PBX_RTC_DMA { 0, 0 }
#define SCI_IRQ { IRQ_PBX_SCI, NO_IRQ } #define SCI_IRQ { IRQ_PBX_SCI, NO_IRQ }
#define SCI_DMA { 7, 6 }
#define PBX_UART0_IRQ { IRQ_PBX_UART0, NO_IRQ } #define PBX_UART0_IRQ { IRQ_PBX_UART0, NO_IRQ }
#define PBX_UART0_DMA { 15, 14 }
#define PBX_UART1_IRQ { IRQ_PBX_UART1, NO_IRQ } #define PBX_UART1_IRQ { IRQ_PBX_UART1, NO_IRQ }
#define PBX_UART1_DMA { 13, 12 }
#define PBX_UART2_IRQ { IRQ_PBX_UART2, NO_IRQ } #define PBX_UART2_IRQ { IRQ_PBX_UART2, NO_IRQ }
#define PBX_UART2_DMA { 11, 10 }
#define PBX_UART3_IRQ { IRQ_PBX_UART3, NO_IRQ } #define PBX_UART3_IRQ { IRQ_PBX_UART3, NO_IRQ }
#define PBX_UART3_DMA { 0x86, 0x87 }
#define PBX_SSP_IRQ { IRQ_PBX_SSP, NO_IRQ } #define PBX_SSP_IRQ { IRQ_PBX_SSP, NO_IRQ }
#define PBX_SSP_DMA { 9, 8 }
/* FPGA Primecells */ /* FPGA Primecells */
AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL); AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL);
...@@ -417,6 +396,7 @@ MACHINE_START(REALVIEW_PBX, "ARM-RealView PBX") ...@@ -417,6 +396,7 @@ MACHINE_START(REALVIEW_PBX, "ARM-RealView PBX")
.boot_params = PLAT_PHYS_OFFSET + 0x00000100, .boot_params = PLAT_PHYS_OFFSET + 0x00000100,
.fixup = realview_pbx_fixup, .fixup = realview_pbx_fixup,
.map_io = realview_pbx_map_io, .map_io = realview_pbx_map_io,
.init_early = realview_init_early,
.init_irq = gic_init_irq, .init_irq = gic_init_irq,
.timer = &realview_pbx_timer, .timer = &realview_pbx_timer,
.init_machine = realview_pbx_init, .init_machine = realview_pbx_init,
......
...@@ -18,8 +18,9 @@ ...@@ -18,8 +18,9 @@
/* /*
* Setup the local clock events for a CPU. * Setup the local clock events for a CPU.
*/ */
void __cpuinit local_timer_setup(struct clock_event_device *evt) int __cpuinit local_timer_setup(struct clock_event_device *evt)
{ {
evt->irq = 29; evt->irq = 29;
twd_timer_setup(evt); twd_timer_setup(evt);
return 0;
} }
...@@ -18,8 +18,9 @@ ...@@ -18,8 +18,9 @@
/* /*
* Setup the local clock events for a CPU. * Setup the local clock events for a CPU.
*/ */
void __cpuinit local_timer_setup(struct clock_event_device *evt) int __cpuinit local_timer_setup(struct clock_event_device *evt)
{ {
evt->irq = IRQ_LOCALTIMER; evt->irq = IRQ_LOCALTIMER;
twd_timer_setup(evt); twd_timer_setup(evt);
return 0;
} }
...@@ -21,8 +21,9 @@ ...@@ -21,8 +21,9 @@
/* /*
* Setup the local clock events for a CPU. * Setup the local clock events for a CPU.
*/ */
void __cpuinit local_timer_setup(struct clock_event_device *evt) int __cpuinit local_timer_setup(struct clock_event_device *evt)
{ {
evt->irq = IRQ_LOCALTIMER; evt->irq = IRQ_LOCALTIMER;
twd_timer_setup(evt); twd_timer_setup(evt);
return 0;
} }
...@@ -50,6 +50,8 @@ ...@@ -50,6 +50,8 @@
#include <mach/platform.h> #include <mach/platform.h>
#include <asm/hardware/timer-sp.h> #include <asm/hardware/timer-sp.h>
#include <plat/clcd.h>
#include <plat/fpga-irq.h>
#include <plat/sched_clock.h> #include <plat/sched_clock.h>
#include "core.h" #include "core.h"
...@@ -63,47 +65,12 @@ ...@@ -63,47 +65,12 @@
#define VA_VIC_BASE __io_address(VERSATILE_VIC_BASE) #define VA_VIC_BASE __io_address(VERSATILE_VIC_BASE)
#define VA_SIC_BASE __io_address(VERSATILE_SIC_BASE) #define VA_SIC_BASE __io_address(VERSATILE_SIC_BASE)
static void sic_mask_irq(struct irq_data *d) static struct fpga_irq_data sic_irq = {
{ .base = VA_SIC_BASE,
unsigned int irq = d->irq - IRQ_SIC_START; .irq_start = IRQ_SIC_START,
.chip.name = "SIC",
writel(1 << irq, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);
}
static void sic_unmask_irq(struct irq_data *d)
{
unsigned int irq = d->irq - IRQ_SIC_START;
writel(1 << irq, VA_SIC_BASE + SIC_IRQ_ENABLE_SET);
}
static struct irq_chip sic_chip = {
.name = "SIC",
.irq_ack = sic_mask_irq,
.irq_mask = sic_mask_irq,
.irq_unmask = sic_unmask_irq,
}; };
static void
sic_handle_irq(unsigned int irq, struct irq_desc *desc)
{
unsigned long status = readl(VA_SIC_BASE + SIC_IRQ_STATUS);
if (status == 0) {
do_bad_IRQ(irq, desc);
return;
}
do {
irq = ffs(status) - 1;
status &= ~(1 << irq);
irq += IRQ_SIC_START;
generic_handle_irq(irq);
} while (status);
}
#if 1 #if 1
#define IRQ_MMCI0A IRQ_VICSOURCE22 #define IRQ_MMCI0A IRQ_VICSOURCE22
#define IRQ_AACI IRQ_VICSOURCE24 #define IRQ_AACI IRQ_VICSOURCE24
...@@ -118,22 +85,11 @@ sic_handle_irq(unsigned int irq, struct irq_desc *desc) ...@@ -118,22 +85,11 @@ sic_handle_irq(unsigned int irq, struct irq_desc *desc)
void __init versatile_init_irq(void) void __init versatile_init_irq(void)
{ {
unsigned int i;
vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0, 0); vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0, 0);
set_irq_chained_handler(IRQ_VICSOURCE31, sic_handle_irq);
/* Do second interrupt controller */
writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR); writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);
for (i = IRQ_SIC_START; i <= IRQ_SIC_END; i++) { fpga_irq_init(IRQ_VICSOURCE31, ~PIC_MASK, &sic_irq);
if ((PIC_MASK & (1 << (i - IRQ_SIC_START))) == 0) {
set_irq_chip(i, &sic_chip);
set_irq_handler(i, handle_level_irq);
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
}
}
/* /*
* Interrupts on secondary controller from 0 to 8 are routed to * Interrupts on secondary controller from 0 to 8 are routed to
...@@ -476,127 +432,7 @@ static struct clk_lookup lookups[] = { ...@@ -476,127 +432,7 @@ static struct clk_lookup lookups[] = {
#define SYS_CLCD_ID_SANYO_2_5 (0x07 << 8) #define SYS_CLCD_ID_SANYO_2_5 (0x07 << 8)
#define SYS_CLCD_ID_VGA (0x1f << 8) #define SYS_CLCD_ID_VGA (0x1f << 8)
static struct clcd_panel vga = { static bool is_sanyo_2_5_lcd;
.mode = {
.name = "VGA",
.refresh = 60,
.xres = 640,
.yres = 480,
.pixclock = 39721,
.left_margin = 40,
.right_margin = 24,
.upper_margin = 32,
.lower_margin = 11,
.hsync_len = 96,
.vsync_len = 2,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_BCD | TIM2_IPC,
.cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
.bpp = 16,
};
static struct clcd_panel sanyo_3_8_in = {
.mode = {
.name = "Sanyo QVGA",
.refresh = 116,
.xres = 320,
.yres = 240,
.pixclock = 100000,
.left_margin = 6,
.right_margin = 6,
.upper_margin = 5,
.lower_margin = 5,
.hsync_len = 6,
.vsync_len = 6,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_BCD,
.cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
.bpp = 16,
};
static struct clcd_panel sanyo_2_5_in = {
.mode = {
.name = "Sanyo QVGA Portrait",
.refresh = 116,
.xres = 240,
.yres = 320,
.pixclock = 100000,
.left_margin = 20,
.right_margin = 10,
.upper_margin = 2,
.lower_margin = 2,
.hsync_len = 10,
.vsync_len = 2,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_IVS | TIM2_IHS | TIM2_IPC,
.cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
.bpp = 16,
};
static struct clcd_panel epson_2_2_in = {
.mode = {
.name = "Epson QCIF",
.refresh = 390,
.xres = 176,
.yres = 220,
.pixclock = 62500,
.left_margin = 3,
.right_margin = 2,
.upper_margin = 1,
.lower_margin = 0,
.hsync_len = 3,
.vsync_len = 2,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_BCD | TIM2_IPC,
.cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
.bpp = 16,
};
/*
* Detect which LCD panel is connected, and return the appropriate
* clcd_panel structure. Note: we do not have any information on
* the required timings for the 8.4in panel, so we presently assume
* VGA timings.
*/
static struct clcd_panel *versatile_clcd_panel(void)
{
void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
struct clcd_panel *panel = &vga;
u32 val;
val = readl(sys_clcd) & SYS_CLCD_ID_MASK;
if (val == SYS_CLCD_ID_SANYO_3_8)
panel = &sanyo_3_8_in;
else if (val == SYS_CLCD_ID_SANYO_2_5)
panel = &sanyo_2_5_in;
else if (val == SYS_CLCD_ID_EPSON_2_2)
panel = &epson_2_2_in;
else if (val == SYS_CLCD_ID_VGA)
panel = &vga;
else {
printk(KERN_ERR "CLCD: unknown LCD panel ID 0x%08x, using VGA\n",
val);
panel = &vga;
}
return panel;
}
/* /*
* Disable all display connectors on the interface module. * Disable all display connectors on the interface module.
...@@ -614,7 +450,7 @@ static void versatile_clcd_disable(struct clcd_fb *fb) ...@@ -614,7 +450,7 @@ static void versatile_clcd_disable(struct clcd_fb *fb)
/* /*
* If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light off * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light off
*/ */
if (machine_is_versatile_ab() && fb->panel == &sanyo_2_5_in) { if (machine_is_versatile_ab() && is_sanyo_2_5_lcd) {
void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL); void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL);
unsigned long ctrl; unsigned long ctrl;
...@@ -630,18 +466,22 @@ static void versatile_clcd_disable(struct clcd_fb *fb) ...@@ -630,18 +466,22 @@ static void versatile_clcd_disable(struct clcd_fb *fb)
*/ */
static void versatile_clcd_enable(struct clcd_fb *fb) static void versatile_clcd_enable(struct clcd_fb *fb)
{ {
struct fb_var_screeninfo *var = &fb->fb.var;
void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET; void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
u32 val; u32 val;
val = readl(sys_clcd); val = readl(sys_clcd);
val &= ~SYS_CLCD_MODE_MASK; val &= ~SYS_CLCD_MODE_MASK;
switch (fb->fb.var.green.length) { switch (var->green.length) {
case 5: case 5:
val |= SYS_CLCD_MODE_5551; val |= SYS_CLCD_MODE_5551;
break; break;
case 6: case 6:
val |= SYS_CLCD_MODE_565_RLSB; if (var->red.offset == 0)
val |= SYS_CLCD_MODE_565_RLSB;
else
val |= SYS_CLCD_MODE_565_BLSB;
break; break;
case 8: case 8:
val |= SYS_CLCD_MODE_888; val |= SYS_CLCD_MODE_888;
...@@ -663,7 +503,7 @@ static void versatile_clcd_enable(struct clcd_fb *fb) ...@@ -663,7 +503,7 @@ static void versatile_clcd_enable(struct clcd_fb *fb)
/* /*
* If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light on * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light on
*/ */
if (machine_is_versatile_ab() && fb->panel == &sanyo_2_5_in) { if (machine_is_versatile_ab() && is_sanyo_2_5_lcd) {
void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL); void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL);
unsigned long ctrl; unsigned long ctrl;
...@@ -674,50 +514,62 @@ static void versatile_clcd_enable(struct clcd_fb *fb) ...@@ -674,50 +514,62 @@ static void versatile_clcd_enable(struct clcd_fb *fb)
#endif #endif
} }
static unsigned long framesize = SZ_1M; /*
* Detect which LCD panel is connected, and return the appropriate
* clcd_panel structure. Note: we do not have any information on
* the required timings for the 8.4in panel, so we presently assume
* VGA timings.
*/
static int versatile_clcd_setup(struct clcd_fb *fb) static int versatile_clcd_setup(struct clcd_fb *fb)
{ {
dma_addr_t dma; void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
const char *panel_name;
u32 val;
fb->panel = versatile_clcd_panel(); is_sanyo_2_5_lcd = false;
fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize, val = readl(sys_clcd) & SYS_CLCD_ID_MASK;
&dma, GFP_KERNEL); if (val == SYS_CLCD_ID_SANYO_3_8)
if (!fb->fb.screen_base) { panel_name = "Sanyo TM38QV67A02A";
printk(KERN_ERR "CLCD: unable to map framebuffer\n"); else if (val == SYS_CLCD_ID_SANYO_2_5) {
return -ENOMEM; panel_name = "Sanyo QVGA Portrait";
is_sanyo_2_5_lcd = true;
} else if (val == SYS_CLCD_ID_EPSON_2_2)
panel_name = "Epson L2F50113T00";
else if (val == SYS_CLCD_ID_VGA)
panel_name = "VGA";
else {
printk(KERN_ERR "CLCD: unknown LCD panel ID 0x%08x, using VGA\n",
val);
panel_name = "VGA";
} }
fb->fb.fix.smem_start = dma; fb->panel = versatile_clcd_get_panel(panel_name);
fb->fb.fix.smem_len = framesize; if (!fb->panel)
return -EINVAL;
return 0; return versatile_clcd_setup_dma(fb, SZ_1M);
} }
static int versatile_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma) static void versatile_clcd_decode(struct clcd_fb *fb, struct clcd_regs *regs)
{ {
return dma_mmap_writecombine(&fb->dev->dev, vma, clcdfb_decode(fb, regs);
fb->fb.screen_base,
fb->fb.fix.smem_start,
fb->fb.fix.smem_len);
}
static void versatile_clcd_remove(struct clcd_fb *fb) /* Always clear BGR for RGB565: we do the routing externally */
{ if (fb->fb.var.green.length == 6)
dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len, regs->cntl &= ~CNTL_BGR;
fb->fb.screen_base, fb->fb.fix.smem_start);
} }
static struct clcd_board clcd_plat_data = { static struct clcd_board clcd_plat_data = {
.name = "Versatile", .name = "Versatile",
.caps = CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888,
.check = clcdfb_check, .check = clcdfb_check,
.decode = clcdfb_decode, .decode = versatile_clcd_decode,
.disable = versatile_clcd_disable, .disable = versatile_clcd_disable,
.enable = versatile_clcd_enable, .enable = versatile_clcd_enable,
.setup = versatile_clcd_setup, .setup = versatile_clcd_setup,
.mmap = versatile_clcd_mmap, .mmap = versatile_clcd_mmap_dma,
.remove = versatile_clcd_remove, .remove = versatile_clcd_remove_dma,
}; };
static struct pl061_platform_data gpio0_plat_data = { static struct pl061_platform_data gpio0_plat_data = {
...@@ -737,53 +589,35 @@ static struct pl022_ssp_controller ssp0_plat_data = { ...@@ -737,53 +589,35 @@ static struct pl022_ssp_controller ssp0_plat_data = {
}; };
#define AACI_IRQ { IRQ_AACI, NO_IRQ } #define AACI_IRQ { IRQ_AACI, NO_IRQ }
#define AACI_DMA { 0x80, 0x81 }
#define MMCI0_IRQ { IRQ_MMCI0A,IRQ_SIC_MMCI0B } #define MMCI0_IRQ { IRQ_MMCI0A,IRQ_SIC_MMCI0B }
#define MMCI0_DMA { 0x84, 0 }
#define KMI0_IRQ { IRQ_SIC_KMI0, NO_IRQ } #define KMI0_IRQ { IRQ_SIC_KMI0, NO_IRQ }
#define KMI0_DMA { 0, 0 }
#define KMI1_IRQ { IRQ_SIC_KMI1, NO_IRQ } #define KMI1_IRQ { IRQ_SIC_KMI1, NO_IRQ }
#define KMI1_DMA { 0, 0 }
/* /*
* These devices are connected directly to the multi-layer AHB switch * These devices are connected directly to the multi-layer AHB switch
*/ */
#define SMC_IRQ { NO_IRQ, NO_IRQ } #define SMC_IRQ { NO_IRQ, NO_IRQ }
#define SMC_DMA { 0, 0 }
#define MPMC_IRQ { NO_IRQ, NO_IRQ } #define MPMC_IRQ { NO_IRQ, NO_IRQ }
#define MPMC_DMA { 0, 0 }
#define CLCD_IRQ { IRQ_CLCDINT, NO_IRQ } #define CLCD_IRQ { IRQ_CLCDINT, NO_IRQ }
#define CLCD_DMA { 0, 0 }
#define DMAC_IRQ { IRQ_DMAINT, NO_IRQ } #define DMAC_IRQ { IRQ_DMAINT, NO_IRQ }
#define DMAC_DMA { 0, 0 }
/* /*
* These devices are connected via the core APB bridge * These devices are connected via the core APB bridge
*/ */
#define SCTL_IRQ { NO_IRQ, NO_IRQ } #define SCTL_IRQ { NO_IRQ, NO_IRQ }
#define SCTL_DMA { 0, 0 }
#define WATCHDOG_IRQ { IRQ_WDOGINT, NO_IRQ } #define WATCHDOG_IRQ { IRQ_WDOGINT, NO_IRQ }
#define WATCHDOG_DMA { 0, 0 }
#define GPIO0_IRQ { IRQ_GPIOINT0, NO_IRQ } #define GPIO0_IRQ { IRQ_GPIOINT0, NO_IRQ }
#define GPIO0_DMA { 0, 0 }
#define GPIO1_IRQ { IRQ_GPIOINT1, NO_IRQ } #define GPIO1_IRQ { IRQ_GPIOINT1, NO_IRQ }
#define GPIO1_DMA { 0, 0 }
#define RTC_IRQ { IRQ_RTCINT, NO_IRQ } #define RTC_IRQ { IRQ_RTCINT, NO_IRQ }
#define RTC_DMA { 0, 0 }
/* /*
* These devices are connected via the DMA APB bridge * These devices are connected via the DMA APB bridge
*/ */
#define SCI_IRQ { IRQ_SCIINT, NO_IRQ } #define SCI_IRQ { IRQ_SCIINT, NO_IRQ }
#define SCI_DMA { 7, 6 }
#define UART0_IRQ { IRQ_UARTINT0, NO_IRQ } #define UART0_IRQ { IRQ_UARTINT0, NO_IRQ }
#define UART0_DMA { 15, 14 }
#define UART1_IRQ { IRQ_UARTINT1, NO_IRQ } #define UART1_IRQ { IRQ_UARTINT1, NO_IRQ }
#define UART1_DMA { 13, 12 }
#define UART2_IRQ { IRQ_UARTINT2, NO_IRQ } #define UART2_IRQ { IRQ_UARTINT2, NO_IRQ }
#define UART2_DMA { 11, 10 }
#define SSP_IRQ { IRQ_SSPINT, NO_IRQ } #define SSP_IRQ { IRQ_SSPINT, NO_IRQ }
#define SSP_DMA { 9, 8 }
/* FPGA Primecells */ /* FPGA Primecells */
AMBA_DEVICE(aaci, "fpga:04", AACI, NULL); AMBA_DEVICE(aaci, "fpga:04", AACI, NULL);
...@@ -865,14 +699,21 @@ static void versatile_leds_event(led_event_t ledevt) ...@@ -865,14 +699,21 @@ static void versatile_leds_event(led_event_t ledevt)
} }
#endif /* CONFIG_LEDS */ #endif /* CONFIG_LEDS */
void __init versatile_init(void) /* Early initializations */
void __init versatile_init_early(void)
{ {
int i; void __iomem *sys = __io_address(VERSATILE_SYS_BASE);
osc4_clk.vcoreg = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_OSCCLCD_OFFSET;
osc4_clk.vcoreg = sys + VERSATILE_SYS_OSCCLCD_OFFSET;
clkdev_add_table(lookups, ARRAY_SIZE(lookups)); clkdev_add_table(lookups, ARRAY_SIZE(lookups));
versatile_sched_clock_init(sys + VERSATILE_SYS_24MHz_OFFSET, 24000000);
}
void __init versatile_init(void)
{
int i;
platform_device_register(&versatile_flash_device); platform_device_register(&versatile_flash_device);
platform_device_register(&versatile_i2c_device); platform_device_register(&versatile_i2c_device);
platform_device_register(&smc91x_device); platform_device_register(&smc91x_device);
...@@ -888,12 +729,6 @@ void __init versatile_init(void) ...@@ -888,12 +729,6 @@ void __init versatile_init(void)
#endif #endif
} }
/*
* The sched_clock counter
*/
#define REFCOUNTER (__io_address(VERSATILE_SYS_BASE) + \
VERSATILE_SYS_24MHz_OFFSET)
/* /*
* Where is the timer (VA)? * Where is the timer (VA)?
*/ */
...@@ -909,8 +744,6 @@ static void __init versatile_timer_init(void) ...@@ -909,8 +744,6 @@ static void __init versatile_timer_init(void)
{ {
u32 val; u32 val;
versatile_sched_clock_init(REFCOUNTER, 24000000);
/* /*
* set clock frequency: * set clock frequency:
* VERSATILE_REFCLK is 32KHz * VERSATILE_REFCLK is 32KHz
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/amba/bus.h> #include <linux/amba/bus.h>
extern void __init versatile_init(void); extern void __init versatile_init(void);
extern void __init versatile_init_early(void);
extern void __init versatile_init_irq(void); extern void __init versatile_init_irq(void);
extern void __init versatile_map_io(void); extern void __init versatile_map_io(void);
extern struct sys_timer versatile_timer; extern struct sys_timer versatile_timer;
...@@ -44,7 +45,6 @@ static struct amba_device name##_device = { \ ...@@ -44,7 +45,6 @@ static struct amba_device name##_device = { \
}, \ }, \
.dma_mask = ~0, \ .dma_mask = ~0, \
.irq = base##_IRQ, \ .irq = base##_IRQ, \
/* .dma = base##_DMA,*/ \
} }
#endif #endif
...@@ -39,6 +39,6 @@ ...@@ -39,6 +39,6 @@
/* macro to get at IO space when running virtually */ /* macro to get at IO space when running virtually */
#define IO_ADDRESS(x) (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000) #define IO_ADDRESS(x) (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000)
#define __io_address(n) __io(IO_ADDRESS(n)) #define __io_address(n) ((void __iomem __force *)IO_ADDRESS(n))
#endif #endif
...@@ -37,6 +37,7 @@ MACHINE_START(VERSATILE_AB, "ARM-Versatile AB") ...@@ -37,6 +37,7 @@ MACHINE_START(VERSATILE_AB, "ARM-Versatile AB")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
.boot_params = 0x00000100, .boot_params = 0x00000100,
.map_io = versatile_map_io, .map_io = versatile_map_io,
.init_early = versatile_init_early,
.init_irq = versatile_init_irq, .init_irq = versatile_init_irq,
.timer = &versatile_timer, .timer = &versatile_timer,
.init_machine = versatile_init, .init_machine = versatile_init,
......
...@@ -59,19 +59,14 @@ static struct pl061_platform_data gpio3_plat_data = { ...@@ -59,19 +59,14 @@ static struct pl061_platform_data gpio3_plat_data = {
}; };
#define UART3_IRQ { IRQ_SIC_UART3, NO_IRQ } #define UART3_IRQ { IRQ_SIC_UART3, NO_IRQ }
#define UART3_DMA { 0x86, 0x87 }
#define SCI1_IRQ { IRQ_SIC_SCI3, NO_IRQ } #define SCI1_IRQ { IRQ_SIC_SCI3, NO_IRQ }
#define SCI1_DMA { 0x88, 0x89 }
#define MMCI1_IRQ { IRQ_MMCI1A, IRQ_SIC_MMCI1B } #define MMCI1_IRQ { IRQ_MMCI1A, IRQ_SIC_MMCI1B }
#define MMCI1_DMA { 0x85, 0 }
/* /*
* These devices are connected via the core APB bridge * These devices are connected via the core APB bridge
*/ */
#define GPIO2_IRQ { IRQ_GPIOINT2, NO_IRQ } #define GPIO2_IRQ { IRQ_GPIOINT2, NO_IRQ }
#define GPIO2_DMA { 0, 0 }
#define GPIO3_IRQ { IRQ_GPIOINT3, NO_IRQ } #define GPIO3_IRQ { IRQ_GPIOINT3, NO_IRQ }
#define GPIO3_DMA { 0, 0 }
/* /*
* These devices are connected via the DMA APB bridge * These devices are connected via the DMA APB bridge
...@@ -110,6 +105,7 @@ MACHINE_START(VERSATILE_PB, "ARM-Versatile PB") ...@@ -110,6 +105,7 @@ MACHINE_START(VERSATILE_PB, "ARM-Versatile PB")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
.boot_params = 0x00000100, .boot_params = 0x00000100,
.map_io = versatile_map_io, .map_io = versatile_map_io,
.init_early = versatile_init_early,
.init_irq = versatile_init_irq, .init_irq = versatile_init_irq,
.timer = &versatile_timer, .timer = &versatile_timer,
.init_machine = versatile_pb_init, .init_machine = versatile_pb_init,
......
...@@ -5,5 +5,8 @@ config ARCH_VEXPRESS_CA9X4 ...@@ -5,5 +5,8 @@ config ARCH_VEXPRESS_CA9X4
bool "Versatile Express Cortex-A9x4 tile" bool "Versatile Express Cortex-A9x4 tile"
select CPU_V7 select CPU_V7
select ARM_GIC select ARM_GIC
select ARM_ERRATA_720789
select ARM_ERRATA_751472
select ARM_ERRATA_753970
endmenu endmenu
...@@ -4,6 +4,5 @@ ...@@ -4,6 +4,5 @@
obj-y := v2m.o obj-y := v2m.o
obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o obj-$(CONFIG_SMP) += platsmp.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
...@@ -17,8 +17,3 @@ struct amba_device name##_device = { \ ...@@ -17,8 +17,3 @@ struct amba_device name##_device = { \
.irq = IRQ_##base, \ .irq = IRQ_##base, \
/* .dma = DMA_##base,*/ \ /* .dma = DMA_##base,*/ \
} }
struct map_desc;
void v2m_map_io(struct map_desc *tile, size_t num);
extern struct sys_timer v2m_timer;
...@@ -10,19 +10,17 @@ ...@@ -10,19 +10,17 @@
#include <linux/amba/clcd.h> #include <linux/amba/clcd.h>
#include <linux/clkdev.h> #include <linux/clkdev.h>
#include <asm/pgtable.h>
#include <asm/hardware/arm_timer.h> #include <asm/hardware/arm_timer.h>
#include <asm/hardware/cache-l2x0.h> #include <asm/hardware/cache-l2x0.h>
#include <asm/hardware/gic.h> #include <asm/hardware/gic.h>
#include <asm/mach-types.h>
#include <asm/pmu.h> #include <asm/pmu.h>
#include <asm/smp_scu.h>
#include <asm/smp_twd.h> #include <asm/smp_twd.h>
#include <mach/ct-ca9x4.h> #include <mach/ct-ca9x4.h>
#include <asm/hardware/timer-sp.h> #include <asm/hardware/timer-sp.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
#include <asm/mach/time.h> #include <asm/mach/time.h>
...@@ -30,6 +28,8 @@ ...@@ -30,6 +28,8 @@
#include <mach/motherboard.h> #include <mach/motherboard.h>
#include <plat/clcd.h>
#define V2M_PA_CS7 0x10000000 #define V2M_PA_CS7 0x10000000
static struct map_desc ct_ca9x4_io_desc[] __initdata = { static struct map_desc ct_ca9x4_io_desc[] __initdata = {
...@@ -56,7 +56,7 @@ static void __init ct_ca9x4_map_io(void) ...@@ -56,7 +56,7 @@ static void __init ct_ca9x4_map_io(void)
#ifdef CONFIG_LOCAL_TIMERS #ifdef CONFIG_LOCAL_TIMERS
twd_base = MMIO_P2V(A9_MPCORE_TWD); twd_base = MMIO_P2V(A9_MPCORE_TWD);
#endif #endif
v2m_map_io(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc)); iotable_init(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc));
} }
static void __init ct_ca9x4_init_irq(void) static void __init ct_ca9x4_init_irq(void)
...@@ -80,29 +80,6 @@ static struct sys_timer ct_ca9x4_timer = { ...@@ -80,29 +80,6 @@ static struct sys_timer ct_ca9x4_timer = {
}; };
#endif #endif
static struct clcd_panel xvga_panel = {
.mode = {
.name = "XVGA",
.refresh = 60,
.xres = 1024,
.yres = 768,
.pixclock = 15384,
.left_margin = 168,
.right_margin = 8,
.upper_margin = 29,
.lower_margin = 3,
.hsync_len = 144,
.vsync_len = 6,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_BCD | TIM2_IPC,
.cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
.bpp = 16,
};
static void ct_ca9x4_clcd_enable(struct clcd_fb *fb) static void ct_ca9x4_clcd_enable(struct clcd_fb *fb)
{ {
v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE_DB1, 0); v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE_DB1, 0);
...@@ -112,42 +89,23 @@ static void ct_ca9x4_clcd_enable(struct clcd_fb *fb) ...@@ -112,42 +89,23 @@ static void ct_ca9x4_clcd_enable(struct clcd_fb *fb)
static int ct_ca9x4_clcd_setup(struct clcd_fb *fb) static int ct_ca9x4_clcd_setup(struct clcd_fb *fb)
{ {
unsigned long framesize = 1024 * 768 * 2; unsigned long framesize = 1024 * 768 * 2;
dma_addr_t dma;
fb->panel = &xvga_panel; fb->panel = versatile_clcd_get_panel("XVGA");
if (!fb->panel)
return -EINVAL;
fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize, return versatile_clcd_setup_dma(fb, framesize);
&dma, GFP_KERNEL);
if (!fb->fb.screen_base) {
printk(KERN_ERR "CLCD: unable to map frame buffer\n");
return -ENOMEM;
}
fb->fb.fix.smem_start = dma;
fb->fb.fix.smem_len = framesize;
return 0;
}
static int ct_ca9x4_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
{
return dma_mmap_writecombine(&fb->dev->dev, vma, fb->fb.screen_base,
fb->fb.fix.smem_start, fb->fb.fix.smem_len);
}
static void ct_ca9x4_clcd_remove(struct clcd_fb *fb)
{
dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
fb->fb.screen_base, fb->fb.fix.smem_start);
} }
static struct clcd_board ct_ca9x4_clcd_data = { static struct clcd_board ct_ca9x4_clcd_data = {
.name = "CT-CA9X4", .name = "CT-CA9X4",
.caps = CLCD_CAP_5551 | CLCD_CAP_565,
.check = clcdfb_check, .check = clcdfb_check,
.decode = clcdfb_decode, .decode = clcdfb_decode,
.enable = ct_ca9x4_clcd_enable, .enable = ct_ca9x4_clcd_enable,
.setup = ct_ca9x4_clcd_setup, .setup = ct_ca9x4_clcd_setup,
.mmap = ct_ca9x4_clcd_mmap, .mmap = versatile_clcd_mmap_dma,
.remove = ct_ca9x4_clcd_remove, .remove = versatile_clcd_remove_dma,
}; };
static AMBA_DEVICE(clcd, "ct:clcd", CT_CA9X4_CLCDC, &ct_ca9x4_clcd_data); static AMBA_DEVICE(clcd, "ct:clcd", CT_CA9X4_CLCDC, &ct_ca9x4_clcd_data);
...@@ -220,6 +178,11 @@ static struct platform_device pmu_device = { ...@@ -220,6 +178,11 @@ static struct platform_device pmu_device = {
.resource = pmu_resources, .resource = pmu_resources,
}; };
static void __init ct_ca9x4_init_early(void)
{
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
}
static void __init ct_ca9x4_init(void) static void __init ct_ca9x4_init(void)
{ {
int i; int i;
...@@ -234,22 +197,40 @@ static void __init ct_ca9x4_init(void) ...@@ -234,22 +197,40 @@ static void __init ct_ca9x4_init(void)
l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff); l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff);
#endif #endif
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
for (i = 0; i < ARRAY_SIZE(ct_ca9x4_amba_devs); i++) for (i = 0; i < ARRAY_SIZE(ct_ca9x4_amba_devs); i++)
amba_device_register(ct_ca9x4_amba_devs[i], &iomem_resource); amba_device_register(ct_ca9x4_amba_devs[i], &iomem_resource);
platform_device_register(&pmu_device); platform_device_register(&pmu_device);
} }
MACHINE_START(VEXPRESS, "ARM-Versatile Express CA9x4") #ifdef CONFIG_SMP
.boot_params = PLAT_PHYS_OFFSET + 0x00000100, static void ct_ca9x4_init_cpu_map(void)
{
int i, ncores = scu_get_core_count(MMIO_P2V(A9_MPCORE_SCU));
for (i = 0; i < ncores; ++i)
set_cpu_possible(i, true);
}
static void ct_ca9x4_smp_enable(unsigned int max_cpus)
{
int i;
for (i = 0; i < max_cpus; i++)
set_cpu_present(i, true);
scu_enable(MMIO_P2V(A9_MPCORE_SCU));
}
#endif
struct ct_desc ct_ca9x4_desc __initdata = {
.id = V2M_CT_ID_CA9,
.name = "CA9x4",
.map_io = ct_ca9x4_map_io, .map_io = ct_ca9x4_map_io,
.init_early = ct_ca9x4_init_early,
.init_irq = ct_ca9x4_init_irq, .init_irq = ct_ca9x4_init_irq,
#if 0 .init_tile = ct_ca9x4_init,
.timer = &ct_ca9x4_timer, #ifdef CONFIG_SMP
#else .init_cpu_map = ct_ca9x4_init_cpu_map,
.timer = &v2m_timer, .smp_enable = ct_ca9x4_smp_enable,
#endif #endif
.init_machine = ct_ca9x4_init, };
MACHINE_END
...@@ -45,4 +45,6 @@ ...@@ -45,4 +45,6 @@
#define IRQ_CT_CA9X4_PMU_CPU2 94 #define IRQ_CT_CA9X4_PMU_CPU2 94
#define IRQ_CT_CA9X4_PMU_CPU3 95 #define IRQ_CT_CA9X4_PMU_CPU3 95
extern struct ct_desc ct_ca9x4_desc;
#endif #endif
...@@ -118,4 +118,26 @@ ...@@ -118,4 +118,26 @@
int v2m_cfg_write(u32 devfn, u32 data); int v2m_cfg_write(u32 devfn, u32 data);
int v2m_cfg_read(u32 devfn, u32 *data); int v2m_cfg_read(u32 devfn, u32 *data);
/*
* Core tile IDs
*/
#define V2M_CT_ID_CA9 0x0c000191
#define V2M_CT_ID_UNSUPPORTED 0xff000191
#define V2M_CT_ID_MASK 0xff000fff
struct ct_desc {
u32 id;
const char *name;
void (*map_io)(void);
void (*init_early)(void);
void (*init_irq)(void);
void (*init_tile)(void);
#ifdef CONFIG_SMP
void (*init_cpu_map)(void);
void (*smp_enable)(unsigned int);
#endif
};
extern struct ct_desc *ct_desc;
#endif #endif
...@@ -10,114 +10,17 @@ ...@@ -10,114 +10,17 @@
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/jiffies.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/io.h> #include <linux/io.h>
#include <asm/cacheflush.h>
#include <asm/smp_scu.h>
#include <asm/unified.h> #include <asm/unified.h>
#include <mach/ct-ca9x4.h>
#include <mach/motherboard.h> #include <mach/motherboard.h>
#define V2M_PA_CS7 0x10000000 #define V2M_PA_CS7 0x10000000
#include "core.h" #include "core.h"
extern void vexpress_secondary_startup(void); extern void versatile_secondary_startup(void);
/*
* control for which core is the next to come out of the secondary
* boot "holding pen"
*/
volatile int __cpuinitdata pen_release = -1;
/*
* Write pen_release in a way that is guaranteed to be visible to all
* observers, irrespective of whether they're taking part in coherency
* or not. This is necessary for the hotplug code to work reliably.
*/
static void __cpuinit write_pen_release(int val)
{
pen_release = val;
smp_wmb();
__cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
}
static void __iomem *scu_base_addr(void)
{
return MMIO_P2V(A9_MPCORE_SCU);
}
static DEFINE_SPINLOCK(boot_lock);
void __cpuinit platform_secondary_init(unsigned int cpu)
{
/*
* if any interrupts are already enabled for the primary
* core (e.g. timer irq), then they will not have been enabled
* for us: do so
*/
gic_secondary_init(0);
/*
* let the primary processor know we're out of the
* pen, then head off into the C entry point
*/
write_pen_release(-1);
/*
* Synchronise with the boot thread.
*/
spin_lock(&boot_lock);
spin_unlock(&boot_lock);
}
int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
{
unsigned long timeout;
/*
* Set synchronisation state between this boot processor
* and the secondary one
*/
spin_lock(&boot_lock);
/*
* This is really belt and braces; we hold unintended secondary
* CPUs in the holding pen until we're ready for them. However,
* since we haven't sent them a soft interrupt, they shouldn't
* be there.
*/
write_pen_release(cpu);
/*
* Send the secondary CPU a soft interrupt, thereby causing
* the boot monitor to read the system wide flags register,
* and branch to the address found there.
*/
smp_cross_call(cpumask_of(cpu), 1);
timeout = jiffies + (1 * HZ);
while (time_before(jiffies, timeout)) {
smp_rmb();
if (pen_release == -1)
break;
udelay(10);
}
/*
* now the secondary core is starting up let it run its
* calibrations, then wait for it to finish
*/
spin_unlock(&boot_lock);
return pen_release != -1 ? -ENOSYS : 0;
}
/* /*
* Initialise the CPU possible map early - this describes the CPUs * Initialise the CPU possible map early - this describes the CPUs
...@@ -125,36 +28,16 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) ...@@ -125,36 +28,16 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
*/ */
void __init smp_init_cpus(void) void __init smp_init_cpus(void)
{ {
void __iomem *scu_base = scu_base_addr(); ct_desc->init_cpu_map();
unsigned int i, ncores;
ncores = scu_base ? scu_get_core_count(scu_base) : 1;
/* sanity check */
if (ncores > NR_CPUS) {
printk(KERN_WARNING
"vexpress: no. of cores (%d) greater than configured "
"maximum of %d - clipping\n",
ncores, NR_CPUS);
ncores = NR_CPUS;
}
for (i = 0; i < ncores; i++)
set_cpu_possible(i, true);
} }
void __init platform_smp_prepare_cpus(unsigned int max_cpus) void __init platform_smp_prepare_cpus(unsigned int max_cpus)
{ {
int i;
/* /*
* Initialise the present map, which describes the set of CPUs * Initialise the present map, which describes the set of CPUs
* actually populated at the present time. * actually populated at the present time.
*/ */
for (i = 0; i < max_cpus; i++) ct_desc->smp_enable(max_cpus);
set_cpu_present(i, true);
scu_enable(scu_base_addr());
/* /*
* Write the address of secondary startup into the * Write the address of secondary startup into the
...@@ -163,6 +46,6 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus) ...@@ -163,6 +46,6 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
* secondary CPU branches to this address. * secondary CPU branches to this address.
*/ */
writel(~0, MMIO_P2V(V2M_SYS_FLAGSCLR)); writel(~0, MMIO_P2V(V2M_SYS_FLAGSCLR));
writel(BSYM(virt_to_phys(vexpress_secondary_startup)), writel(BSYM(virt_to_phys(versatile_secondary_startup)),
MMIO_P2V(V2M_SYS_FLAGSSET)); MMIO_P2V(V2M_SYS_FLAGSSET));
} }
...@@ -7,13 +7,16 @@ ...@@ -7,13 +7,16 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/ata_platform.h>
#include <linux/smsc911x.h> #include <linux/smsc911x.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/sysdev.h> #include <linux/sysdev.h>
#include <linux/usb/isp1760.h> #include <linux/usb/isp1760.h>
#include <linux/clkdev.h> #include <linux/clkdev.h>
#include <asm/mach-types.h>
#include <asm/sizes.h> #include <asm/sizes.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h> #include <asm/mach/flash.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
#include <asm/mach/time.h> #include <asm/mach/time.h>
...@@ -21,6 +24,7 @@ ...@@ -21,6 +24,7 @@
#include <asm/hardware/timer-sp.h> #include <asm/hardware/timer-sp.h>
#include <asm/hardware/sp810.h> #include <asm/hardware/sp810.h>
#include <mach/ct-ca9x4.h>
#include <mach/motherboard.h> #include <mach/motherboard.h>
#include <plat/sched_clock.h> #include <plat/sched_clock.h>
...@@ -42,19 +46,16 @@ static struct map_desc v2m_io_desc[] __initdata = { ...@@ -42,19 +46,16 @@ static struct map_desc v2m_io_desc[] __initdata = {
}, },
}; };
void __init v2m_map_io(struct map_desc *tile, size_t num) static void __init v2m_init_early(void)
{ {
iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc)); ct_desc->init_early();
iotable_init(tile, num); versatile_sched_clock_init(MMIO_P2V(V2M_SYS_24MHZ), 24000000);
} }
static void __init v2m_timer_init(void) static void __init v2m_timer_init(void)
{ {
u32 scctrl; u32 scctrl;
versatile_sched_clock_init(MMIO_P2V(V2M_SYS_24MHZ), 24000000);
/* Select 1MHz TIMCLK as the reference clock for SP804 timers */ /* Select 1MHz TIMCLK as the reference clock for SP804 timers */
scctrl = readl(MMIO_P2V(V2M_SYSCTL + SCCTRL)); scctrl = readl(MMIO_P2V(V2M_SYSCTL + SCCTRL));
scctrl |= SCCTRL_TIMEREN0SEL_TIMCLK; scctrl |= SCCTRL_TIMEREN0SEL_TIMCLK;
...@@ -68,7 +69,7 @@ static void __init v2m_timer_init(void) ...@@ -68,7 +69,7 @@ static void __init v2m_timer_init(void)
sp804_clockevents_init(MMIO_P2V(V2M_TIMER0), IRQ_V2M_TIMER0); sp804_clockevents_init(MMIO_P2V(V2M_TIMER0), IRQ_V2M_TIMER0);
} }
struct sys_timer v2m_timer = { static struct sys_timer v2m_timer = {
.init = v2m_timer_init, .init = v2m_timer_init,
}; };
...@@ -249,6 +250,29 @@ static struct platform_device v2m_flash_device = { ...@@ -249,6 +250,29 @@ static struct platform_device v2m_flash_device = {
.dev.platform_data = &v2m_flash_data, .dev.platform_data = &v2m_flash_data,
}; };
static struct pata_platform_info v2m_pata_data = {
.ioport_shift = 2,
};
static struct resource v2m_pata_resources[] = {
{
.start = V2M_CF,
.end = V2M_CF + 0xff,
.flags = IORESOURCE_MEM,
}, {
.start = V2M_CF + 0x100,
.end = V2M_CF + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device v2m_cf_device = {
.name = "pata_platform",
.id = -1,
.resource = v2m_pata_resources,
.num_resources = ARRAY_SIZE(v2m_pata_resources),
.dev.platform_data = &v2m_pata_data,
};
static unsigned int v2m_mmci_status(struct device *dev) static unsigned int v2m_mmci_status(struct device *dev)
{ {
...@@ -354,7 +378,44 @@ static void v2m_restart(char str, const char *cmd) ...@@ -354,7 +378,44 @@ static void v2m_restart(char str, const char *cmd)
printk(KERN_EMERG "Unable to reboot\n"); printk(KERN_EMERG "Unable to reboot\n");
} }
static int __init v2m_init(void) struct ct_desc *ct_desc;
static struct ct_desc *ct_descs[] __initdata = {
#ifdef CONFIG_ARCH_VEXPRESS_CA9X4
&ct_ca9x4_desc,
#endif
};
static void __init v2m_populate_ct_desc(void)
{
int i;
u32 current_tile_id;
ct_desc = NULL;
current_tile_id = readl(MMIO_P2V(V2M_SYS_PROCID0)) & V2M_CT_ID_MASK;
for (i = 0; i < ARRAY_SIZE(ct_descs) && !ct_desc; ++i)
if (ct_descs[i]->id == current_tile_id)
ct_desc = ct_descs[i];
if (!ct_desc)
panic("vexpress: failed to populate core tile description "
"for tile ID 0x%8x\n", current_tile_id);
}
static void __init v2m_map_io(void)
{
iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc));
v2m_populate_ct_desc();
ct_desc->map_io();
}
static void __init v2m_init_irq(void)
{
ct_desc->init_irq();
}
static void __init v2m_init(void)
{ {
int i; int i;
...@@ -363,6 +424,7 @@ static int __init v2m_init(void) ...@@ -363,6 +424,7 @@ static int __init v2m_init(void)
platform_device_register(&v2m_pcie_i2c_device); platform_device_register(&v2m_pcie_i2c_device);
platform_device_register(&v2m_ddc_i2c_device); platform_device_register(&v2m_ddc_i2c_device);
platform_device_register(&v2m_flash_device); platform_device_register(&v2m_flash_device);
platform_device_register(&v2m_cf_device);
platform_device_register(&v2m_eth_device); platform_device_register(&v2m_eth_device);
platform_device_register(&v2m_usb_device); platform_device_register(&v2m_usb_device);
...@@ -372,6 +434,14 @@ static int __init v2m_init(void) ...@@ -372,6 +434,14 @@ static int __init v2m_init(void)
pm_power_off = v2m_power_off; pm_power_off = v2m_power_off;
arm_pm_restart = v2m_restart; arm_pm_restart = v2m_restart;
return 0; ct_desc->init_tile();
} }
arch_initcall(v2m_init);
MACHINE_START(VEXPRESS, "ARM-Versatile Express")
.boot_params = PLAT_PHYS_OFFSET + 0x00000100,
.map_io = v2m_map_io,
.init_early = v2m_init_early,
.init_irq = v2m_init_irq,
.timer = &v2m_timer,
.init_machine = v2m_init,
MACHINE_END
...@@ -149,6 +149,7 @@ static int __init consistent_init(void) ...@@ -149,6 +149,7 @@ static int __init consistent_init(void)
{ {
int ret = 0; int ret = 0;
pgd_t *pgd; pgd_t *pgd;
pud_t *pud;
pmd_t *pmd; pmd_t *pmd;
pte_t *pte; pte_t *pte;
int i = 0; int i = 0;
...@@ -156,7 +157,15 @@ static int __init consistent_init(void) ...@@ -156,7 +157,15 @@ static int __init consistent_init(void)
do { do {
pgd = pgd_offset(&init_mm, base); pgd = pgd_offset(&init_mm, base);
pmd = pmd_alloc(&init_mm, pgd, base);
pud = pud_alloc(&init_mm, pgd, base);
if (!pud) {
printk(KERN_ERR "%s: no pud tables\n", __func__);
ret = -ENOMEM;
break;
}
pmd = pmd_alloc(&init_mm, pud, base);
if (!pmd) { if (!pmd) {
printk(KERN_ERR "%s: no pmd tables\n", __func__); printk(KERN_ERR "%s: no pmd tables\n", __func__);
ret = -ENOMEM; ret = -ENOMEM;
......
...@@ -95,6 +95,7 @@ static int adjust_pte(struct vm_area_struct *vma, unsigned long address, ...@@ -95,6 +95,7 @@ static int adjust_pte(struct vm_area_struct *vma, unsigned long address,
{ {
spinlock_t *ptl; spinlock_t *ptl;
pgd_t *pgd; pgd_t *pgd;
pud_t *pud;
pmd_t *pmd; pmd_t *pmd;
pte_t *pte; pte_t *pte;
int ret; int ret;
...@@ -103,7 +104,11 @@ static int adjust_pte(struct vm_area_struct *vma, unsigned long address, ...@@ -103,7 +104,11 @@ static int adjust_pte(struct vm_area_struct *vma, unsigned long address,
if (pgd_none_or_clear_bad(pgd)) if (pgd_none_or_clear_bad(pgd))
return 0; return 0;
pmd = pmd_offset(pgd, address); pud = pud_offset(pgd, address);
if (pud_none_or_clear_bad(pud))
return 0;
pmd = pmd_offset(pud, address);
if (pmd_none_or_clear_bad(pmd)) if (pmd_none_or_clear_bad(pmd))
return 0; return 0;
......
...@@ -76,9 +76,11 @@ void show_pte(struct mm_struct *mm, unsigned long addr) ...@@ -76,9 +76,11 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
printk(KERN_ALERT "pgd = %p\n", mm->pgd); printk(KERN_ALERT "pgd = %p\n", mm->pgd);
pgd = pgd_offset(mm, addr); pgd = pgd_offset(mm, addr);
printk(KERN_ALERT "[%08lx] *pgd=%08lx", addr, pgd_val(*pgd)); printk(KERN_ALERT "[%08lx] *pgd=%08llx",
addr, (long long)pgd_val(*pgd));
do { do {
pud_t *pud;
pmd_t *pmd; pmd_t *pmd;
pte_t *pte; pte_t *pte;
...@@ -90,9 +92,21 @@ void show_pte(struct mm_struct *mm, unsigned long addr) ...@@ -90,9 +92,21 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
break; break;
} }
pmd = pmd_offset(pgd, addr); pud = pud_offset(pgd, addr);
if (PTRS_PER_PUD != 1)
printk(", *pud=%08lx", pud_val(*pud));
if (pud_none(*pud))
break;
if (pud_bad(*pud)) {
printk("(bad)");
break;
}
pmd = pmd_offset(pud, addr);
if (PTRS_PER_PMD != 1) if (PTRS_PER_PMD != 1)
printk(", *pmd=%08lx", pmd_val(*pmd)); printk(", *pmd=%08llx", (long long)pmd_val(*pmd));
if (pmd_none(*pmd)) if (pmd_none(*pmd))
break; break;
...@@ -107,8 +121,9 @@ void show_pte(struct mm_struct *mm, unsigned long addr) ...@@ -107,8 +121,9 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
break; break;
pte = pte_offset_map(pmd, addr); pte = pte_offset_map(pmd, addr);
printk(", *pte=%08lx", pte_val(*pte)); printk(", *pte=%08llx", (long long)pte_val(*pte));
printk(", *ppte=%08lx", pte_val(pte[PTE_HWTABLE_PTRS])); printk(", *ppte=%08llx",
(long long)pte_val(pte[PTE_HWTABLE_PTRS]));
pte_unmap(pte); pte_unmap(pte);
} while(0); } while(0);
...@@ -388,6 +403,7 @@ do_translation_fault(unsigned long addr, unsigned int fsr, ...@@ -388,6 +403,7 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
{ {
unsigned int index; unsigned int index;
pgd_t *pgd, *pgd_k; pgd_t *pgd, *pgd_k;
pud_t *pud, *pud_k;
pmd_t *pmd, *pmd_k; pmd_t *pmd, *pmd_k;
if (addr < TASK_SIZE) if (addr < TASK_SIZE)
...@@ -406,12 +422,19 @@ do_translation_fault(unsigned long addr, unsigned int fsr, ...@@ -406,12 +422,19 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
if (pgd_none(*pgd_k)) if (pgd_none(*pgd_k))
goto bad_area; goto bad_area;
if (!pgd_present(*pgd)) if (!pgd_present(*pgd))
set_pgd(pgd, *pgd_k); set_pgd(pgd, *pgd_k);
pmd_k = pmd_offset(pgd_k, addr); pud = pud_offset(pgd, addr);
pmd = pmd_offset(pgd, addr); pud_k = pud_offset(pgd_k, addr);
if (pud_none(*pud_k))
goto bad_area;
if (!pud_present(*pud))
set_pud(pud, *pud_k);
pmd = pmd_offset(pud, addr);
pmd_k = pmd_offset(pud_k, addr);
/* /*
* On ARM one Linux PGD entry contains two hardware entries (see page * On ARM one Linux PGD entry contains two hardware entries (see page
......
...@@ -4,10 +4,10 @@ ...@@ -4,10 +4,10 @@
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
static void idmap_add_pmd(pgd_t *pgd, unsigned long addr, unsigned long end, static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end,
unsigned long prot) unsigned long prot)
{ {
pmd_t *pmd = pmd_offset(pgd, addr); pmd_t *pmd = pmd_offset(pud, addr);
addr = (addr & PMD_MASK) | prot; addr = (addr & PMD_MASK) | prot;
pmd[0] = __pmd(addr); pmd[0] = __pmd(addr);
...@@ -16,6 +16,18 @@ static void idmap_add_pmd(pgd_t *pgd, unsigned long addr, unsigned long end, ...@@ -16,6 +16,18 @@ static void idmap_add_pmd(pgd_t *pgd, unsigned long addr, unsigned long end,
flush_pmd_entry(pmd); flush_pmd_entry(pmd);
} }
static void idmap_add_pud(pgd_t *pgd, unsigned long addr, unsigned long end,
unsigned long prot)
{
pud_t *pud = pud_offset(pgd, addr);
unsigned long next;
do {
next = pud_addr_end(addr, end);
idmap_add_pmd(pud, addr, next, prot);
} while (pud++, addr = next, addr != end);
}
void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end) void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end)
{ {
unsigned long prot, next; unsigned long prot, next;
...@@ -27,17 +39,28 @@ void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end) ...@@ -27,17 +39,28 @@ void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end)
pgd += pgd_index(addr); pgd += pgd_index(addr);
do { do {
next = pgd_addr_end(addr, end); next = pgd_addr_end(addr, end);
idmap_add_pmd(pgd, addr, next, prot); idmap_add_pud(pgd, addr, next, prot);
} while (pgd++, addr = next, addr != end); } while (pgd++, addr = next, addr != end);
} }
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
static void idmap_del_pmd(pgd_t *pgd, unsigned long addr, unsigned long end) static void idmap_del_pmd(pud_t *pud, unsigned long addr, unsigned long end)
{ {
pmd_t *pmd = pmd_offset(pgd, addr); pmd_t *pmd = pmd_offset(pud, addr);
pmd_clear(pmd); pmd_clear(pmd);
} }
static void idmap_del_pud(pgd_t *pgd, unsigned long addr, unsigned long end)
{
pud_t *pud = pud_offset(pgd, addr);
unsigned long next;
do {
next = pud_addr_end(addr, end);
idmap_del_pmd(pud, addr, next);
} while (pud++, addr = next, addr != end);
}
void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end) void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end)
{ {
unsigned long next; unsigned long next;
...@@ -45,7 +68,7 @@ void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end) ...@@ -45,7 +68,7 @@ void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end)
pgd += pgd_index(addr); pgd += pgd_index(addr);
do { do {
next = pgd_addr_end(addr, end); next = pgd_addr_end(addr, end);
idmap_del_pmd(pgd, addr, next); idmap_del_pud(pgd, addr, next);
} while (pgd++, addr = next, addr != end); } while (pgd++, addr = next, addr != end);
} }
#endif #endif
......
...@@ -350,7 +350,7 @@ void __init bootmem_init(void) ...@@ -350,7 +350,7 @@ void __init bootmem_init(void)
*/ */
arm_bootmem_free(min, max_low, max_high); arm_bootmem_free(min, max_low, max_high);
high_memory = __va((max_low << PAGE_SHIFT) - 1) + 1; high_memory = __va(((phys_addr_t)max_low << PAGE_SHIFT) - 1) + 1;
/* /*
* This doesn't seem to be used by the Linux memory manager any * This doesn't seem to be used by the Linux memory manager any
...@@ -398,8 +398,8 @@ free_memmap(unsigned long start_pfn, unsigned long end_pfn) ...@@ -398,8 +398,8 @@ free_memmap(unsigned long start_pfn, unsigned long end_pfn)
* Convert to physical addresses, and * Convert to physical addresses, and
* round start upwards and end downwards. * round start upwards and end downwards.
*/ */
pg = PAGE_ALIGN(__pa(start_pg)); pg = (unsigned long)PAGE_ALIGN(__pa(start_pg));
pgend = __pa(end_pg) & PAGE_MASK; pgend = (unsigned long)__pa(end_pg) & PAGE_MASK;
/* /*
* If there are free pages between these, * If there are free pages between these,
......
...@@ -7,7 +7,7 @@ extern pmd_t *top_pmd; ...@@ -7,7 +7,7 @@ extern pmd_t *top_pmd;
static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt) static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt)
{ {
return pmd_offset(pgd, virt); return pmd_offset(pud_offset(pgd, virt), virt);
} }
static inline pmd_t *pmd_off_k(unsigned long virt) static inline pmd_t *pmd_off_k(unsigned long virt)
......
...@@ -533,7 +533,7 @@ static void __init *early_alloc(unsigned long sz) ...@@ -533,7 +533,7 @@ static void __init *early_alloc(unsigned long sz)
static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr, unsigned long prot) static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr, unsigned long prot)
{ {
if (pmd_none(*pmd)) { if (pmd_none(*pmd)) {
pte_t *pte = early_alloc(2 * PTRS_PER_PTE * sizeof(pte_t)); pte_t *pte = early_alloc(PTE_HWTABLE_OFF + PTE_HWTABLE_SIZE);
__pmd_populate(pmd, __pa(pte), prot); __pmd_populate(pmd, __pa(pte), prot);
} }
BUG_ON(pmd_bad(*pmd)); BUG_ON(pmd_bad(*pmd));
...@@ -551,11 +551,11 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr, ...@@ -551,11 +551,11 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
} while (pte++, addr += PAGE_SIZE, addr != end); } while (pte++, addr += PAGE_SIZE, addr != end);
} }
static void __init alloc_init_section(pgd_t *pgd, unsigned long addr, static void __init alloc_init_section(pud_t *pud, unsigned long addr,
unsigned long end, phys_addr_t phys, unsigned long end, phys_addr_t phys,
const struct mem_type *type) const struct mem_type *type)
{ {
pmd_t *pmd = pmd_offset(pgd, addr); pmd_t *pmd = pmd_offset(pud, addr);
/* /*
* Try a section mapping - end, addr and phys must all be aligned * Try a section mapping - end, addr and phys must all be aligned
...@@ -584,6 +584,19 @@ static void __init alloc_init_section(pgd_t *pgd, unsigned long addr, ...@@ -584,6 +584,19 @@ static void __init alloc_init_section(pgd_t *pgd, unsigned long addr,
} }
} }
static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end,
unsigned long phys, const struct mem_type *type)
{
pud_t *pud = pud_offset(pgd, addr);
unsigned long next;
do {
next = pud_addr_end(addr, end);
alloc_init_section(pud, addr, next, phys, type);
phys += next - addr;
} while (pud++, addr = next, addr != end);
}
static void __init create_36bit_mapping(struct map_desc *md, static void __init create_36bit_mapping(struct map_desc *md,
const struct mem_type *type) const struct mem_type *type)
{ {
...@@ -592,13 +605,13 @@ static void __init create_36bit_mapping(struct map_desc *md, ...@@ -592,13 +605,13 @@ static void __init create_36bit_mapping(struct map_desc *md,
pgd_t *pgd; pgd_t *pgd;
addr = md->virtual; addr = md->virtual;
phys = (unsigned long)__pfn_to_phys(md->pfn); phys = __pfn_to_phys(md->pfn);
length = PAGE_ALIGN(md->length); length = PAGE_ALIGN(md->length);
if (!(cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3())) { if (!(cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3())) {
printk(KERN_ERR "MM: CPU does not support supersection " printk(KERN_ERR "MM: CPU does not support supersection "
"mapping for 0x%08llx at 0x%08lx\n", "mapping for 0x%08llx at 0x%08lx\n",
__pfn_to_phys((u64)md->pfn), addr); (long long)__pfn_to_phys((u64)md->pfn), addr);
return; return;
} }
...@@ -611,14 +624,14 @@ static void __init create_36bit_mapping(struct map_desc *md, ...@@ -611,14 +624,14 @@ static void __init create_36bit_mapping(struct map_desc *md,
if (type->domain) { if (type->domain) {
printk(KERN_ERR "MM: invalid domain in supersection " printk(KERN_ERR "MM: invalid domain in supersection "
"mapping for 0x%08llx at 0x%08lx\n", "mapping for 0x%08llx at 0x%08lx\n",
__pfn_to_phys((u64)md->pfn), addr); (long long)__pfn_to_phys((u64)md->pfn), addr);
return; return;
} }
if ((addr | length | __pfn_to_phys(md->pfn)) & ~SUPERSECTION_MASK) { if ((addr | length | __pfn_to_phys(md->pfn)) & ~SUPERSECTION_MASK) {
printk(KERN_ERR "MM: cannot create mapping for " printk(KERN_ERR "MM: cannot create mapping for 0x%08llx"
"0x%08llx at 0x%08lx invalid alignment\n", " at 0x%08lx invalid alignment\n",
__pfn_to_phys((u64)md->pfn), addr); (long long)__pfn_to_phys((u64)md->pfn), addr);
return; return;
} }
...@@ -631,7 +644,8 @@ static void __init create_36bit_mapping(struct map_desc *md, ...@@ -631,7 +644,8 @@ static void __init create_36bit_mapping(struct map_desc *md,
pgd = pgd_offset_k(addr); pgd = pgd_offset_k(addr);
end = addr + length; end = addr + length;
do { do {
pmd_t *pmd = pmd_offset(pgd, addr); pud_t *pud = pud_offset(pgd, addr);
pmd_t *pmd = pmd_offset(pud, addr);
int i; int i;
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
...@@ -652,22 +666,23 @@ static void __init create_36bit_mapping(struct map_desc *md, ...@@ -652,22 +666,23 @@ static void __init create_36bit_mapping(struct map_desc *md,
*/ */
static void __init create_mapping(struct map_desc *md) static void __init create_mapping(struct map_desc *md)
{ {
unsigned long phys, addr, length, end; unsigned long addr, length, end;
phys_addr_t phys;
const struct mem_type *type; const struct mem_type *type;
pgd_t *pgd; pgd_t *pgd;
if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) { if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) {
printk(KERN_WARNING "BUG: not creating mapping for " printk(KERN_WARNING "BUG: not creating mapping for 0x%08llx"
"0x%08llx at 0x%08lx in user region\n", " at 0x%08lx in user region\n",
__pfn_to_phys((u64)md->pfn), md->virtual); (long long)__pfn_to_phys((u64)md->pfn), md->virtual);
return; return;
} }
if ((md->type == MT_DEVICE || md->type == MT_ROM) && if ((md->type == MT_DEVICE || md->type == MT_ROM) &&
md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) { md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) {
printk(KERN_WARNING "BUG: mapping for 0x%08llx at 0x%08lx " printk(KERN_WARNING "BUG: mapping for 0x%08llx"
"overlaps vmalloc space\n", " at 0x%08lx overlaps vmalloc space\n",
__pfn_to_phys((u64)md->pfn), md->virtual); (long long)__pfn_to_phys((u64)md->pfn), md->virtual);
} }
type = &mem_types[md->type]; type = &mem_types[md->type];
...@@ -681,13 +696,13 @@ static void __init create_mapping(struct map_desc *md) ...@@ -681,13 +696,13 @@ static void __init create_mapping(struct map_desc *md)
} }
addr = md->virtual & PAGE_MASK; addr = md->virtual & PAGE_MASK;
phys = (unsigned long)__pfn_to_phys(md->pfn); phys = __pfn_to_phys(md->pfn);
length = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK)); length = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK));
if (type->prot_l1 == 0 && ((addr | phys | length) & ~SECTION_MASK)) { if (type->prot_l1 == 0 && ((addr | phys | length) & ~SECTION_MASK)) {
printk(KERN_WARNING "BUG: map for 0x%08lx at 0x%08lx can not " printk(KERN_WARNING "BUG: map for 0x%08llx at 0x%08lx can not "
"be mapped using pages, ignoring.\n", "be mapped using pages, ignoring.\n",
__pfn_to_phys(md->pfn), addr); (long long)__pfn_to_phys(md->pfn), addr);
return; return;
} }
...@@ -696,7 +711,7 @@ static void __init create_mapping(struct map_desc *md) ...@@ -696,7 +711,7 @@ static void __init create_mapping(struct map_desc *md)
do { do {
unsigned long next = pgd_addr_end(addr, end); unsigned long next = pgd_addr_end(addr, end);
alloc_init_section(pgd, addr, next, phys, type); alloc_init_pud(pgd, addr, next, phys, type);
phys += next - addr; phys += next - addr;
addr = next; addr = next;
...@@ -794,9 +809,10 @@ static void __init sanity_check_meminfo(void) ...@@ -794,9 +809,10 @@ static void __init sanity_check_meminfo(void)
*/ */
if (__va(bank->start) >= vmalloc_min || if (__va(bank->start) >= vmalloc_min ||
__va(bank->start) < (void *)PAGE_OFFSET) { __va(bank->start) < (void *)PAGE_OFFSET) {
printk(KERN_NOTICE "Ignoring RAM at %.8lx-%.8lx " printk(KERN_NOTICE "Ignoring RAM at %.8llx-%.8llx "
"(vmalloc region overlap).\n", "(vmalloc region overlap).\n",
bank->start, bank->start + bank->size - 1); (unsigned long long)bank->start,
(unsigned long long)bank->start + bank->size - 1);
continue; continue;
} }
...@@ -807,10 +823,11 @@ static void __init sanity_check_meminfo(void) ...@@ -807,10 +823,11 @@ static void __init sanity_check_meminfo(void)
if (__va(bank->start + bank->size) > vmalloc_min || if (__va(bank->start + bank->size) > vmalloc_min ||
__va(bank->start + bank->size) < __va(bank->start)) { __va(bank->start + bank->size) < __va(bank->start)) {
unsigned long newsize = vmalloc_min - __va(bank->start); unsigned long newsize = vmalloc_min - __va(bank->start);
printk(KERN_NOTICE "Truncating RAM at %.8lx-%.8lx " printk(KERN_NOTICE "Truncating RAM at %.8llx-%.8llx "
"to -%.8lx (vmalloc region overlap).\n", "to -%.8llx (vmalloc region overlap).\n",
bank->start, bank->start + bank->size - 1, (unsigned long long)bank->start,
bank->start + newsize - 1); (unsigned long long)bank->start + bank->size - 1,
(unsigned long long)bank->start + newsize - 1);
bank->size = newsize; bank->size = newsize;
} }
#endif #endif
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
pgd_t *pgd_alloc(struct mm_struct *mm) pgd_t *pgd_alloc(struct mm_struct *mm)
{ {
pgd_t *new_pgd, *init_pgd; pgd_t *new_pgd, *init_pgd;
pud_t *new_pud, *init_pud;
pmd_t *new_pmd, *init_pmd; pmd_t *new_pmd, *init_pmd;
pte_t *new_pte, *init_pte; pte_t *new_pte, *init_pte;
...@@ -46,7 +47,11 @@ pgd_t *pgd_alloc(struct mm_struct *mm) ...@@ -46,7 +47,11 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
* On ARM, first page must always be allocated since it * On ARM, first page must always be allocated since it
* contains the machine vectors. * contains the machine vectors.
*/ */
new_pmd = pmd_alloc(mm, new_pgd, 0); new_pud = pud_alloc(mm, new_pgd, 0);
if (!new_pud)
goto no_pud;
new_pmd = pmd_alloc(mm, new_pud, 0);
if (!new_pmd) if (!new_pmd)
goto no_pmd; goto no_pmd;
...@@ -54,7 +59,8 @@ pgd_t *pgd_alloc(struct mm_struct *mm) ...@@ -54,7 +59,8 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
if (!new_pte) if (!new_pte)
goto no_pte; goto no_pte;
init_pmd = pmd_offset(init_pgd, 0); init_pud = pud_offset(init_pgd, 0);
init_pmd = pmd_offset(init_pud, 0);
init_pte = pte_offset_map(init_pmd, 0); init_pte = pte_offset_map(init_pmd, 0);
set_pte_ext(new_pte, *init_pte, 0); set_pte_ext(new_pte, *init_pte, 0);
pte_unmap(init_pte); pte_unmap(init_pte);
...@@ -66,6 +72,8 @@ pgd_t *pgd_alloc(struct mm_struct *mm) ...@@ -66,6 +72,8 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
no_pte: no_pte:
pmd_free(mm, new_pmd); pmd_free(mm, new_pmd);
no_pmd: no_pmd:
pud_free(mm, new_pud);
no_pud:
free_pages((unsigned long)new_pgd, 2); free_pages((unsigned long)new_pgd, 2);
no_pgd: no_pgd:
return NULL; return NULL;
...@@ -74,6 +82,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm) ...@@ -74,6 +82,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
void pgd_free(struct mm_struct *mm, pgd_t *pgd_base) void pgd_free(struct mm_struct *mm, pgd_t *pgd_base)
{ {
pgd_t *pgd; pgd_t *pgd;
pud_t *pud;
pmd_t *pmd; pmd_t *pmd;
pgtable_t pte; pgtable_t pte;
...@@ -84,7 +93,11 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd_base) ...@@ -84,7 +93,11 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd_base)
if (pgd_none_or_clear_bad(pgd)) if (pgd_none_or_clear_bad(pgd))
goto no_pgd; goto no_pgd;
pmd = pmd_offset(pgd, 0); pud = pud_offset(pgd, 0);
if (pud_none_or_clear_bad(pud))
goto no_pud;
pmd = pmd_offset(pud, 0);
if (pmd_none_or_clear_bad(pmd)) if (pmd_none_or_clear_bad(pmd))
goto no_pmd; goto no_pmd;
...@@ -92,8 +105,11 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd_base) ...@@ -92,8 +105,11 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd_base)
pmd_clear(pmd); pmd_clear(pmd);
pte_free(mm, pte); pte_free(mm, pte);
no_pmd: no_pmd:
pgd_clear(pgd); pud_clear(pud);
pmd_free(mm, pmd); pmd_free(mm, pmd);
no_pud:
pgd_clear(pgd);
pud_free(mm, pud);
no_pgd: no_pgd:
free_pages((unsigned long) pgd_base, 2); free_pages((unsigned long) pgd_base, 2);
} }
if PLAT_VERSATILE
config PLAT_VERSATILE_CLCD
bool
config PLAT_VERSATILE_FPGA_IRQ
bool
config PLAT_VERSATILE_LEDS
def_bool y if LEDS_CLASS
depends on ARCH_REALVIEW || ARCH_VERSATILE
config PLAT_VERSATILE_SCHED_CLOCK
def_bool y if !ARCH_INTEGRATOR_AP
select HAVE_SCHED_CLOCK
endif
obj-y := clock.o obj-y := clock.o
ifneq ($(CONFIG_ARCH_INTEGRATOR),y) obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
obj-y += sched-clock.o obj-$(CONFIG_PLAT_VERSATILE_CLCD) += clcd.o
endif obj-$(CONFIG_PLAT_VERSATILE_FPGA_IRQ) += fpga-irq.o
ifeq ($(CONFIG_LEDS_CLASS),y) obj-$(CONFIG_PLAT_VERSATILE_LEDS) += leds.o
obj-$(CONFIG_ARCH_REALVIEW) += leds.o obj-$(CONFIG_PLAT_VERSATILE_SCHED_CLOCK) += sched-clock.o
obj-$(CONFIG_ARCH_VERSATILE) += leds.o obj-$(CONFIG_SMP) += headsmp.o platsmp.o
endif
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/amba/bus.h>
#include <linux/amba/clcd.h>
#include <plat/clcd.h>
static struct clcd_panel vga = {
.mode = {
.name = "VGA",
.refresh = 60,
.xres = 640,
.yres = 480,
.pixclock = 39721,
.left_margin = 40,
.right_margin = 24,
.upper_margin = 32,
.lower_margin = 11,
.hsync_len = 96,
.vsync_len = 2,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_BCD | TIM2_IPC,
.cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
.caps = CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888,
.bpp = 16,
};
static struct clcd_panel xvga = {
.mode = {
.name = "XVGA",
.refresh = 60,
.xres = 1024,
.yres = 768,
.pixclock = 15748,
.left_margin = 152,
.right_margin = 48,
.upper_margin = 23,
.lower_margin = 3,
.hsync_len = 104,
.vsync_len = 4,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_BCD | TIM2_IPC,
.cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
.caps = CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888,
.bpp = 16,
};
/* Sanyo TM38QV67A02A - 3.8 inch QVGA (320x240) Color TFT */
static struct clcd_panel sanyo_tm38qv67a02a = {
.mode = {
.name = "Sanyo TM38QV67A02A",
.refresh = 116,
.xres = 320,
.yres = 240,
.pixclock = 100000,
.left_margin = 6,
.right_margin = 6,
.upper_margin = 5,
.lower_margin = 5,
.hsync_len = 6,
.vsync_len = 6,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_BCD,
.cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
.caps = CLCD_CAP_5551,
.bpp = 16,
};
static struct clcd_panel sanyo_2_5_in = {
.mode = {
.name = "Sanyo QVGA Portrait",
.refresh = 116,
.xres = 240,
.yres = 320,
.pixclock = 100000,
.left_margin = 20,
.right_margin = 10,
.upper_margin = 2,
.lower_margin = 2,
.hsync_len = 10,
.vsync_len = 2,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_IVS | TIM2_IHS | TIM2_IPC,
.cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
.caps = CLCD_CAP_5551,
.bpp = 16,
};
/* Epson L2F50113T00 - 2.2 inch 176x220 Color TFT */
static struct clcd_panel epson_l2f50113t00 = {
.mode = {
.name = "Epson L2F50113T00",
.refresh = 390,
.xres = 176,
.yres = 220,
.pixclock = 62500,
.left_margin = 3,
.right_margin = 2,
.upper_margin = 1,
.lower_margin = 0,
.hsync_len = 3,
.vsync_len = 2,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = TIM2_BCD | TIM2_IPC,
.cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
.caps = CLCD_CAP_5551,
.bpp = 16,
};
static struct clcd_panel *panels[] = {
&vga,
&xvga,
&sanyo_tm38qv67a02a,
&sanyo_2_5_in,
&epson_l2f50113t00,
};
struct clcd_panel *versatile_clcd_get_panel(const char *name)
{
int i;
for (i = 0; i < ARRAY_SIZE(panels); i++)
if (strcmp(panels[i]->mode.name, name) == 0)
break;
if (i < ARRAY_SIZE(panels))
return panels[i];
pr_err("CLCD: couldn't get parameters for panel %s\n", name);
return NULL;
}
int versatile_clcd_setup_dma(struct clcd_fb *fb, unsigned long framesize)
{
dma_addr_t dma;
fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize,
&dma, GFP_KERNEL);
if (!fb->fb.screen_base) {
pr_err("CLCD: unable to map framebuffer\n");
return -ENOMEM;
}
fb->fb.fix.smem_start = dma;
fb->fb.fix.smem_len = framesize;
return 0;
}
int versatile_clcd_mmap_dma(struct clcd_fb *fb, struct vm_area_struct *vma)
{
return dma_mmap_writecombine(&fb->dev->dev, vma,
fb->fb.screen_base,
fb->fb.fix.smem_start,
fb->fb.fix.smem_len);
}
void versatile_clcd_remove_dma(struct clcd_fb *fb)
{
dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
fb->fb.screen_base, fb->fb.fix.smem_start);
}
/*
* Support for Versatile FPGA-based IRQ controllers
*/
#include <linux/irq.h>
#include <linux/io.h>
#include <asm/mach/irq.h>
#include <plat/fpga-irq.h>
#define IRQ_STATUS 0x00
#define IRQ_RAW_STATUS 0x04
#define IRQ_ENABLE_SET 0x08
#define IRQ_ENABLE_CLEAR 0x0c
static void fpga_irq_mask(struct irq_data *d)
{
struct fpga_irq_data *f = irq_data_get_irq_chip_data(d);
u32 mask = 1 << (d->irq - f->irq_start);
writel(mask, f->base + IRQ_ENABLE_CLEAR);
}
static void fpga_irq_unmask(struct irq_data *d)
{
struct fpga_irq_data *f = irq_data_get_irq_chip_data(d);
u32 mask = 1 << (d->irq - f->irq_start);
writel(mask, f->base + IRQ_ENABLE_SET);
}
static void fpga_irq_handle(unsigned int irq, struct irq_desc *desc)
{
struct fpga_irq_data *f = get_irq_desc_data(desc);
u32 status = readl(f->base + IRQ_STATUS);
if (status == 0) {
do_bad_IRQ(irq, desc);
return;
}
do {
irq = ffs(status) - 1;
status &= ~(1 << irq);
generic_handle_irq(irq + f->irq_start);
} while (status);
}
void __init fpga_irq_init(int parent_irq, u32 valid, struct fpga_irq_data *f)
{
unsigned int i;
f->chip.irq_ack = fpga_irq_mask;
f->chip.irq_mask = fpga_irq_mask;
f->chip.irq_unmask = fpga_irq_unmask;
if (parent_irq != -1) {
set_irq_data(parent_irq, f);
set_irq_chained_handler(parent_irq, fpga_irq_handle);
}
for (i = 0; i < 32; i++) {
if (valid & (1 << i)) {
unsigned int irq = f->irq_start + i;
set_irq_chip_data(irq, f);
set_irq_chip(irq, &f->chip);
set_irq_handler(irq, handle_level_irq);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
}
}
/* /*
* linux/arch/arm/mach-vexpress/headsmp.S * linux/arch/arm/plat-versatile/headsmp.S
* *
* Copyright (c) 2003 ARM Limited * Copyright (c) 2003 ARM Limited
* All Rights Reserved * All Rights Reserved
...@@ -14,11 +14,11 @@ ...@@ -14,11 +14,11 @@
__INIT __INIT
/* /*
* Versatile Express specific entry point for secondary CPUs. This * Realview/Versatile Express specific entry point for secondary CPUs.
* provides a "holding pen" into which all secondary cores are held * This provides a "holding pen" into which all secondary cores are held
* until we're ready for them to initialise. * until we're ready for them to initialise.
*/ */
ENTRY(vexpress_secondary_startup) ENTRY(versatile_secondary_startup)
mrc p15, 0, r0, c0, c0, 5 mrc p15, 0, r0, c0, c0, 5
and r0, r0, #15 and r0, r0, #15
adr r4, 1f adr r4, 1f
......
#ifndef PLAT_CLCD_H
#define PLAT_CLCD_H
struct clcd_panel *versatile_clcd_get_panel(const char *);
int versatile_clcd_setup_dma(struct clcd_fb *, unsigned long);
int versatile_clcd_mmap_dma(struct clcd_fb *, struct vm_area_struct *);
void versatile_clcd_remove_dma(struct clcd_fb *);
#endif
#ifndef PLAT_FPGA_IRQ_H
#define PLAT_FPGA_IRQ_H
struct fpga_irq_data {
void __iomem *base;
unsigned int irq_start;
struct irq_chip chip;
};
void fpga_irq_init(int, u32, struct fpga_irq_data *);
#endif
/* /*
* linux/arch/arm/mach-vexpress/localtimer.c * linux/arch/arm/plat-versatile/localtimer.c
* *
* Copyright (C) 2002 ARM Ltd. * Copyright (C) 2002 ARM Ltd.
* All Rights Reserved * All Rights Reserved
...@@ -19,8 +19,9 @@ ...@@ -19,8 +19,9 @@
/* /*
* Setup the local clock events for a CPU. * Setup the local clock events for a CPU.
*/ */
void __cpuinit local_timer_setup(struct clock_event_device *evt) int __cpuinit local_timer_setup(struct clock_event_device *evt)
{ {
evt->irq = IRQ_LOCALTIMER; evt->irq = IRQ_LOCALTIMER;
twd_timer_setup(evt); twd_timer_setup(evt);
return 0;
} }
/*
* linux/arch/arm/plat-versatile/platsmp.c
*
* Copyright (C) 2002 ARM Ltd.
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/jiffies.h>
#include <linux/smp.h>
#include <asm/cacheflush.h>
/*
* control for which core is the next to come out of the secondary
* boot "holding pen"
*/
volatile int __cpuinitdata pen_release = -1;
/*
* Write pen_release in a way that is guaranteed to be visible to all
* observers, irrespective of whether they're taking part in coherency
* or not. This is necessary for the hotplug code to work reliably.
*/
static void __cpuinit write_pen_release(int val)
{
pen_release = val;
smp_wmb();
__cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
}
static DEFINE_SPINLOCK(boot_lock);
void __cpuinit platform_secondary_init(unsigned int cpu)
{
/*
* if any interrupts are already enabled for the primary
* core (e.g. timer irq), then they will not have been enabled
* for us: do so
*/
gic_secondary_init(0);
/*
* let the primary processor know we're out of the
* pen, then head off into the C entry point
*/
write_pen_release(-1);
/*
* Synchronise with the boot thread.
*/
spin_lock(&boot_lock);
spin_unlock(&boot_lock);
}
int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
{
unsigned long timeout;
/*
* Set synchronisation state between this boot processor
* and the secondary one
*/
spin_lock(&boot_lock);
/*
* This is really belt and braces; we hold unintended secondary
* CPUs in the holding pen until we're ready for them. However,
* since we haven't sent them a soft interrupt, they shouldn't
* be there.
*/
write_pen_release(cpu);
/*
* Send the secondary CPU a soft interrupt, thereby causing
* the boot monitor to read the system wide flags register,
* and branch to the address found there.
*/
smp_cross_call(cpumask_of(cpu), 1);
timeout = jiffies + (1 * HZ);
while (time_before(jiffies, timeout)) {
smp_rmb();
if (pen_release == -1)
break;
udelay(10);
}
/*
* now the secondary core is starting up let it run its
* calibrations, then wait for it to finish
*/
spin_unlock(&boot_lock);
return pen_release != -1 ? -ENOSYS : 0;
}
此差异已折叠。
...@@ -120,8 +120,23 @@ static void clcdfb_enable(struct clcd_fb *fb, u32 cntl) ...@@ -120,8 +120,23 @@ static void clcdfb_enable(struct clcd_fb *fb, u32 cntl)
static int static int
clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var) clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var)
{ {
u32 caps;
int ret = 0; int ret = 0;
if (fb->panel->caps && fb->board->caps)
caps = fb->panel->caps & fb->board->caps;
else {
/* Old way of specifying what can be used */
caps = fb->panel->cntl & CNTL_BGR ?
CLCD_CAP_BGR : CLCD_CAP_RGB;
/* But mask out 444 modes as they weren't supported */
caps &= ~CLCD_CAP_444;
}
/* Only TFT panels can do RGB888/BGR888 */
if (!(fb->panel->cntl & CNTL_LCDTFT))
caps &= ~CLCD_CAP_888;
memset(&var->transp, 0, sizeof(var->transp)); memset(&var->transp, 0, sizeof(var->transp));
var->red.msb_right = 0; var->red.msb_right = 0;
...@@ -133,6 +148,13 @@ clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var) ...@@ -133,6 +148,13 @@ clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var)
case 2: case 2:
case 4: case 4:
case 8: case 8:
/* If we can't do 5551, reject */
caps &= CLCD_CAP_5551;
if (!caps) {
ret = -EINVAL;
break;
}
var->red.length = var->bits_per_pixel; var->red.length = var->bits_per_pixel;
var->red.offset = 0; var->red.offset = 0;
var->green.length = var->bits_per_pixel; var->green.length = var->bits_per_pixel;
...@@ -140,23 +162,61 @@ clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var) ...@@ -140,23 +162,61 @@ clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var)
var->blue.length = var->bits_per_pixel; var->blue.length = var->bits_per_pixel;
var->blue.offset = 0; var->blue.offset = 0;
break; break;
case 16: case 16:
var->red.length = 5; /* If we can't do 444, 5551 or 565, reject */
var->blue.length = 5; if (!(caps & (CLCD_CAP_444 | CLCD_CAP_5551 | CLCD_CAP_565))) {
ret = -EINVAL;
break;
}
/* /*
* Green length can be 5 or 6 depending whether * Green length can be 4, 5 or 6 depending whether
* we're operating in RGB555 or RGB565 mode. * we're operating in 444, 5551 or 565 mode.
*/ */
if (var->green.length != 5 && var->green.length != 6) if (var->green.length == 4 && caps & CLCD_CAP_444)
var->green.length = 6; caps &= CLCD_CAP_444;
if (var->green.length == 5 && caps & CLCD_CAP_5551)
caps &= CLCD_CAP_5551;
else if (var->green.length == 6 && caps & CLCD_CAP_565)
caps &= CLCD_CAP_565;
else {
/*
* PL110 officially only supports RGB555,
* but may be wired up to allow RGB565.
*/
if (caps & CLCD_CAP_565) {
var->green.length = 6;
caps &= CLCD_CAP_565;
} else if (caps & CLCD_CAP_5551) {
var->green.length = 5;
caps &= CLCD_CAP_5551;
} else {
var->green.length = 4;
caps &= CLCD_CAP_444;
}
}
if (var->green.length >= 5) {
var->red.length = 5;
var->blue.length = 5;
} else {
var->red.length = 4;
var->blue.length = 4;
}
break; break;
case 32: case 32:
if (fb->panel->cntl & CNTL_LCDTFT) { /* If we can't do 888, reject */
var->red.length = 8; caps &= CLCD_CAP_888;
var->green.length = 8; if (!caps) {
var->blue.length = 8; ret = -EINVAL;
break; break;
} }
var->red.length = 8;
var->green.length = 8;
var->blue.length = 8;
break;
default: default:
ret = -EINVAL; ret = -EINVAL;
break; break;
...@@ -168,7 +228,20 @@ clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var) ...@@ -168,7 +228,20 @@ clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var)
* the bitfield length defined above. * the bitfield length defined above.
*/ */
if (ret == 0 && var->bits_per_pixel >= 16) { if (ret == 0 && var->bits_per_pixel >= 16) {
if (fb->panel->cntl & CNTL_BGR) { bool bgr, rgb;
bgr = caps & CLCD_CAP_BGR && var->blue.offset == 0;
rgb = caps & CLCD_CAP_RGB && var->red.offset == 0;
if (!bgr && !rgb)
/*
* The requested format was not possible, try just
* our capabilities. One of BGR or RGB must be
* supported.
*/
bgr = caps & CLCD_CAP_BGR;
if (bgr) {
var->blue.offset = 0; var->blue.offset = 0;
var->green.offset = var->blue.offset + var->blue.length; var->green.offset = var->blue.offset + var->blue.length;
var->red.offset = var->green.offset + var->green.length; var->red.offset = var->green.offset + var->green.length;
...@@ -443,8 +516,8 @@ static int clcdfb_register(struct clcd_fb *fb) ...@@ -443,8 +516,8 @@ static int clcdfb_register(struct clcd_fb *fb)
fb_set_var(&fb->fb, &fb->fb.var); fb_set_var(&fb->fb, &fb->fb.var);
printk(KERN_INFO "CLCD: %s hardware, %s display\n", dev_info(&fb->dev->dev, "%s hardware, %s display\n",
fb->board->name, fb->panel->mode.name); fb->board->name, fb->panel->mode.name);
ret = register_framebuffer(&fb->fb); ret = register_framebuffer(&fb->fb);
if (ret == 0) if (ret == 0)
...@@ -486,6 +559,10 @@ static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id) ...@@ -486,6 +559,10 @@ static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id)
fb->dev = dev; fb->dev = dev;
fb->board = board; fb->board = board;
dev_info(&fb->dev->dev, "PL%03x rev%u at 0x%08llx\n",
amba_part(dev), amba_rev(dev),
(unsigned long long)dev->res.start);
ret = fb->board->setup(fb); ret = fb->board->setup(fb);
if (ret) if (ret)
goto free_fb; goto free_fb;
......
...@@ -53,6 +53,7 @@ ...@@ -53,6 +53,7 @@
#define CNTL_LCDBPP8 (3 << 1) #define CNTL_LCDBPP8 (3 << 1)
#define CNTL_LCDBPP16 (4 << 1) #define CNTL_LCDBPP16 (4 << 1)
#define CNTL_LCDBPP16_565 (6 << 1) #define CNTL_LCDBPP16_565 (6 << 1)
#define CNTL_LCDBPP16_444 (7 << 1)
#define CNTL_LCDBPP24 (5 << 1) #define CNTL_LCDBPP24 (5 << 1)
#define CNTL_LCDBW (1 << 4) #define CNTL_LCDBW (1 << 4)
#define CNTL_LCDTFT (1 << 5) #define CNTL_LCDTFT (1 << 5)
...@@ -66,6 +67,32 @@ ...@@ -66,6 +67,32 @@
#define CNTL_LDMAFIFOTIME (1 << 15) #define CNTL_LDMAFIFOTIME (1 << 15)
#define CNTL_WATERMARK (1 << 16) #define CNTL_WATERMARK (1 << 16)
enum {
/* individual formats */
CLCD_CAP_RGB444 = (1 << 0),
CLCD_CAP_RGB5551 = (1 << 1),
CLCD_CAP_RGB565 = (1 << 2),
CLCD_CAP_RGB888 = (1 << 3),
CLCD_CAP_BGR444 = (1 << 4),
CLCD_CAP_BGR5551 = (1 << 5),
CLCD_CAP_BGR565 = (1 << 6),
CLCD_CAP_BGR888 = (1 << 7),
/* connection layouts */
CLCD_CAP_444 = CLCD_CAP_RGB444 | CLCD_CAP_BGR444,
CLCD_CAP_5551 = CLCD_CAP_RGB5551 | CLCD_CAP_BGR5551,
CLCD_CAP_565 = CLCD_CAP_RGB565 | CLCD_CAP_BGR565,
CLCD_CAP_888 = CLCD_CAP_RGB888 | CLCD_CAP_BGR888,
/* red/blue ordering */
CLCD_CAP_RGB = CLCD_CAP_RGB444 | CLCD_CAP_RGB5551 |
CLCD_CAP_RGB565 | CLCD_CAP_RGB888,
CLCD_CAP_BGR = CLCD_CAP_BGR444 | CLCD_CAP_BGR5551 |
CLCD_CAP_BGR565 | CLCD_CAP_BGR888,
CLCD_CAP_ALL = CLCD_CAP_BGR | CLCD_CAP_RGB,
};
struct clcd_panel { struct clcd_panel {
struct fb_videomode mode; struct fb_videomode mode;
signed short width; /* width in mm */ signed short width; /* width in mm */
...@@ -73,6 +100,7 @@ struct clcd_panel { ...@@ -73,6 +100,7 @@ struct clcd_panel {
u32 tim2; u32 tim2;
u32 tim3; u32 tim3;
u32 cntl; u32 cntl;
u32 caps;
unsigned int bpp:8, unsigned int bpp:8,
fixedtimings:1, fixedtimings:1,
grayscale:1; grayscale:1;
...@@ -96,6 +124,11 @@ struct clcd_fb; ...@@ -96,6 +124,11 @@ struct clcd_fb;
struct clcd_board { struct clcd_board {
const char *name; const char *name;
/*
* Optional. Hardware capability flags.
*/
u32 caps;
/* /*
* Optional. Check whether the var structure is acceptable * Optional. Check whether the var structure is acceptable
* for this display. * for this display.
...@@ -155,34 +188,35 @@ struct clcd_fb { ...@@ -155,34 +188,35 @@ struct clcd_fb {
static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs) static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs)
{ {
struct fb_var_screeninfo *var = &fb->fb.var;
u32 val, cpl; u32 val, cpl;
/* /*
* Program the CLCD controller registers and start the CLCD * Program the CLCD controller registers and start the CLCD
*/ */
val = ((fb->fb.var.xres / 16) - 1) << 2; val = ((var->xres / 16) - 1) << 2;
val |= (fb->fb.var.hsync_len - 1) << 8; val |= (var->hsync_len - 1) << 8;
val |= (fb->fb.var.right_margin - 1) << 16; val |= (var->right_margin - 1) << 16;
val |= (fb->fb.var.left_margin - 1) << 24; val |= (var->left_margin - 1) << 24;
regs->tim0 = val; regs->tim0 = val;
val = fb->fb.var.yres; val = var->yres;
if (fb->panel->cntl & CNTL_LCDDUAL) if (fb->panel->cntl & CNTL_LCDDUAL)
val /= 2; val /= 2;
val -= 1; val -= 1;
val |= (fb->fb.var.vsync_len - 1) << 10; val |= (var->vsync_len - 1) << 10;
val |= fb->fb.var.lower_margin << 16; val |= var->lower_margin << 16;
val |= fb->fb.var.upper_margin << 24; val |= var->upper_margin << 24;
regs->tim1 = val; regs->tim1 = val;
val = fb->panel->tim2; val = fb->panel->tim2;
val |= fb->fb.var.sync & FB_SYNC_HOR_HIGH_ACT ? 0 : TIM2_IHS; val |= var->sync & FB_SYNC_HOR_HIGH_ACT ? 0 : TIM2_IHS;
val |= fb->fb.var.sync & FB_SYNC_VERT_HIGH_ACT ? 0 : TIM2_IVS; val |= var->sync & FB_SYNC_VERT_HIGH_ACT ? 0 : TIM2_IVS;
cpl = fb->fb.var.xres_virtual; cpl = var->xres_virtual;
if (fb->panel->cntl & CNTL_LCDTFT) /* TFT */ if (fb->panel->cntl & CNTL_LCDTFT) /* TFT */
/* / 1 */; /* / 1 */;
else if (!fb->fb.var.grayscale) /* STN color */ else if (!var->grayscale) /* STN color */
cpl = cpl * 8 / 3; cpl = cpl * 8 / 3;
else if (fb->panel->cntl & CNTL_LCDMONO8) /* STN monochrome, 8bit */ else if (fb->panel->cntl & CNTL_LCDMONO8) /* STN monochrome, 8bit */
cpl /= 8; cpl /= 8;
...@@ -194,10 +228,22 @@ static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs) ...@@ -194,10 +228,22 @@ static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs)
regs->tim3 = fb->panel->tim3; regs->tim3 = fb->panel->tim3;
val = fb->panel->cntl; val = fb->panel->cntl;
if (fb->fb.var.grayscale) if (var->grayscale)
val |= CNTL_LCDBW; val |= CNTL_LCDBW;
switch (fb->fb.var.bits_per_pixel) { if (fb->panel->caps && fb->board->caps &&
var->bits_per_pixel >= 16) {
/*
* if board and panel supply capabilities, we can support
* changing BGR/RGB depending on supplied parameters
*/
if (var->red.offset == 0)
val &= ~CNTL_BGR;
else
val |= CNTL_BGR;
}
switch (var->bits_per_pixel) {
case 1: case 1:
val |= CNTL_LCDBPP1; val |= CNTL_LCDBPP1;
break; break;
...@@ -212,15 +258,17 @@ static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs) ...@@ -212,15 +258,17 @@ static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs)
break; break;
case 16: case 16:
/* /*
* PL110 cannot choose between 5551 and 565 modes in * PL110 cannot choose between 5551 and 565 modes in its
* its control register * control register. It is possible to use 565 with
* custom external wiring.
*/ */
if ((fb->dev->periphid & 0x000fffff) == 0x00041110) if (amba_part(fb->dev) == 0x110 ||
var->green.length == 5)
val |= CNTL_LCDBPP16; val |= CNTL_LCDBPP16;
else if (fb->fb.var.green.length == 5) else if (var->green.length == 6)
val |= CNTL_LCDBPP16;
else
val |= CNTL_LCDBPP16_565; val |= CNTL_LCDBPP16_565;
else
val |= CNTL_LCDBPP16_444;
break; break;
case 32: case 32:
val |= CNTL_LCDBPP24; val |= CNTL_LCDBPP24;
...@@ -228,7 +276,7 @@ static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs) ...@@ -228,7 +276,7 @@ static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs)
} }
regs->cntl = val; regs->cntl = val;
regs->pixclock = fb->fb.var.pixclock; regs->pixclock = var->pixclock;
} }
static inline int clcdfb_check(struct clcd_fb *fb, struct fb_var_screeninfo *var) static inline int clcdfb_check(struct clcd_fb *fb, struct fb_var_screeninfo *var)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册