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 ...
This commit is contained in:
commit
2f284c8463
|
@ -235,6 +235,7 @@ config ARCH_INTEGRATOR
|
|||
select ICST
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select PLAT_VERSATILE
|
||||
select PLAT_VERSATILE_FPGA_IRQ
|
||||
help
|
||||
Support for ARM's Integrator platform.
|
||||
|
||||
|
@ -242,11 +243,11 @@ config ARCH_REALVIEW
|
|||
bool "ARM Ltd. RealView family"
|
||||
select ARM_AMBA
|
||||
select CLKDEV_LOOKUP
|
||||
select HAVE_SCHED_CLOCK
|
||||
select ICST
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select ARCH_WANT_OPTIONAL_GPIOLIB
|
||||
select PLAT_VERSATILE
|
||||
select PLAT_VERSATILE_CLCD
|
||||
select ARM_TIMER_SP804
|
||||
select GPIO_PL061 if GPIOLIB
|
||||
help
|
||||
|
@ -257,11 +258,12 @@ config ARCH_VERSATILE
|
|||
select ARM_AMBA
|
||||
select ARM_VIC
|
||||
select CLKDEV_LOOKUP
|
||||
select HAVE_SCHED_CLOCK
|
||||
select ICST
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select ARCH_WANT_OPTIONAL_GPIOLIB
|
||||
select PLAT_VERSATILE
|
||||
select PLAT_VERSATILE_CLCD
|
||||
select PLAT_VERSATILE_FPGA_IRQ
|
||||
select ARM_TIMER_SP804
|
||||
help
|
||||
This enables support for ARM Ltd Versatile board.
|
||||
|
@ -274,9 +276,10 @@ config ARCH_VEXPRESS
|
|||
select CLKDEV_LOOKUP
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select HAVE_CLK
|
||||
select HAVE_SCHED_CLOCK
|
||||
select HAVE_PATA_PLATFORM
|
||||
select ICST
|
||||
select PLAT_VERSATILE
|
||||
select PLAT_VERSATILE_CLCD
|
||||
help
|
||||
This enables support for the ARM Ltd Versatile Express boards.
|
||||
|
||||
|
@ -1011,6 +1014,7 @@ source "arch/arm/mach-ux500/Kconfig"
|
|||
source "arch/arm/mach-versatile/Kconfig"
|
||||
|
||||
source "arch/arm/mach-vexpress/Kconfig"
|
||||
source "arch/arm/plat-versatile/Kconfig"
|
||||
|
||||
source "arch/arm/mach-vt8500/Kconfig"
|
||||
|
||||
|
|
|
@ -44,8 +44,14 @@ int local_timer_ack(void);
|
|||
/*
|
||||
* 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
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#ifndef __ASM_OUTERCACHE_H
|
||||
#define __ASM_OUTERCACHE_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct outer_cache_fns {
|
||||
void (*inv_range)(unsigned long, unsigned long);
|
||||
void (*clean_range)(unsigned long, unsigned long);
|
||||
|
@ -38,17 +40,17 @@ struct outer_cache_fns {
|
|||
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
outer_cache.flush_range(start, end);
|
||||
|
@ -74,11 +76,11 @@ static inline void outer_disable(void)
|
|||
|
||||
#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_inv_all(void) { }
|
||||
|
|
|
@ -301,6 +301,7 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
|
|||
#define pgd_present(pgd) (1)
|
||||
#define pgd_clear(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.. */
|
||||
|
@ -351,7 +352,7 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd)
|
|||
#define pte_unmap(pte) __pte_unmap(pte)
|
||||
|
||||
#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 mk_pte(page,prot) pfn_pte(page_to_pfn(page), prot)
|
||||
|
|
|
@ -195,7 +195,7 @@ static struct tagtable __tagtable_##fn __tag = { tag, fn }
|
|||
#define NR_BANKS 8
|
||||
|
||||
struct membank {
|
||||
unsigned long start;
|
||||
phys_addr_t start;
|
||||
unsigned long size;
|
||||
unsigned int highmem;
|
||||
};
|
||||
|
|
|
@ -238,8 +238,8 @@ static int enable_monitor_mode(void)
|
|||
ARM_DBG_READ(c1, 0, dscr);
|
||||
|
||||
/* Ensure that halting mode is disabled. */
|
||||
if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN, "halting debug mode enabled."
|
||||
"Unable to access hardware resources.")) {
|
||||
if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN,
|
||||
"halting debug mode enabled. Unable to access hardware resources.\n")) {
|
||||
ret = -EPERM;
|
||||
goto out;
|
||||
}
|
||||
|
@ -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;
|
||||
goto out;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
/* Reset the control register. */
|
||||
|
@ -635,7 +635,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
|
|||
if (WARN_ONCE(!bp->overflow_handler &&
|
||||
(arch_check_bp_in_kernelspace(bp) || !core_has_mismatch_brps()
|
||||
|| !bp->hw.bp_target),
|
||||
"overflow handler required but none found")) {
|
||||
"overflow handler required but none found\n")) {
|
||||
ret = -EINVAL;
|
||||
}
|
||||
out:
|
||||
|
@ -936,8 +936,8 @@ static int __init arch_hw_breakpoint_init(void)
|
|||
ARM_DBG_READ(c1, 0, dscr);
|
||||
if (dscr & ARM_DSCR_HDBGEN) {
|
||||
max_watchpoint_len = 4;
|
||||
pr_warning("halting debug mode enabled. Assuming maximum "
|
||||
"watchpoint size of %u bytes.", max_watchpoint_len);
|
||||
pr_warning("halting debug mode enabled. Assuming maximum watchpoint size of %u bytes.\n",
|
||||
max_watchpoint_len);
|
||||
} else {
|
||||
/* Work out the maximum supported watchpoint length. */
|
||||
max_watchpoint_len = get_max_wp_len();
|
||||
|
|
|
@ -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 */;
|
||||
}
|
||||
|
||||
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];
|
||||
|
||||
if (meminfo.nr_banks >= NR_BANKS) {
|
||||
printk(KERN_CRIT "NR_BANKS too low, "
|
||||
"ignoring memory at %#lx\n", start);
|
||||
"ignoring memory at 0x%08llx\n", (long long)start);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -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 usermem __initdata = 0;
|
||||
unsigned long size, start;
|
||||
unsigned long size;
|
||||
phys_addr_t start;
|
||||
char *endp;
|
||||
|
||||
/*
|
||||
|
|
|
@ -474,13 +474,12 @@ static void smp_timer_broadcast(const struct cpumask *mask)
|
|||
#define smp_timer_broadcast NULL
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_LOCAL_TIMERS
|
||||
static void broadcast_timer_set_mode(enum clock_event_mode mode,
|
||||
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->features = CLOCK_EVT_FEAT_ONESHOT |
|
||||
|
@ -492,7 +491,6 @@ static void local_timer_setup(struct clock_event_device *evt)
|
|||
|
||||
clockevents_register_device(evt);
|
||||
}
|
||||
#endif
|
||||
|
||||
void __cpuinit percpu_timer_setup(void)
|
||||
{
|
||||
|
@ -502,7 +500,8 @@ void __cpuinit percpu_timer_setup(void)
|
|||
evt->cpumask = cpumask_of(cpu);
|
||||
evt->broadcast = smp_timer_broadcast;
|
||||
|
||||
local_timer_setup(evt);
|
||||
if (local_timer_setup(evt))
|
||||
broadcast_timer_setup(evt);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
|
|
|
@ -712,17 +712,17 @@ EXPORT_SYMBOL(__readwrite_bug);
|
|||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
|
|
|
@ -27,13 +27,18 @@ pin_page_for_write(const void __user *_addr, pte_t **ptep, spinlock_t **ptlp)
|
|||
pgd_t *pgd;
|
||||
pmd_t *pmd;
|
||||
pte_t *pte;
|
||||
pud_t *pud;
|
||||
spinlock_t *ptl;
|
||||
|
||||
pgd = pgd_offset(current->mm, addr);
|
||||
if (unlikely(pgd_none(*pgd) || pgd_bad(*pgd)))
|
||||
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)))
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -18,8 +18,9 @@
|
|||
/*
|
||||
* 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;
|
||||
twd_timer_setup(evt);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ config ARCH_INTEGRATOR_CP
|
|||
bool "Support Integrator/CP platform"
|
||||
select ARCH_CINTEGRATOR
|
||||
select ARM_TIMER_SP804
|
||||
select PLAT_VERSATILE_CLCD
|
||||
help
|
||||
Include support for the ARM(R) Integrator CP platform.
|
||||
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
void integrator_init_early(void);
|
||||
void integrator_reserve(void);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
int i;
|
||||
|
||||
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
|
||||
struct amba_device *d = amba_devs[i];
|
||||
amba_device_register(d, &iomem_resource);
|
||||
|
|
|
@ -121,6 +121,7 @@ static struct clcd_panel vga = {
|
|||
.height = -1,
|
||||
.tim2 = TIM2_BCD | TIM2_IPC,
|
||||
.cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
|
||||
.caps = CLCD_CAP_5551,
|
||||
.connector = IMPD1_CTRL_DISP_VGA,
|
||||
.bpp = 16,
|
||||
.grayscale = 0,
|
||||
|
@ -149,6 +150,7 @@ static struct clcd_panel svga = {
|
|||
.tim2 = TIM2_BCD,
|
||||
.cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
|
||||
.connector = IMPD1_CTRL_DISP_VGA,
|
||||
.caps = CLCD_CAP_5551,
|
||||
.bpp = 16,
|
||||
.grayscale = 0,
|
||||
};
|
||||
|
@ -175,6 +177,7 @@ static struct clcd_panel prospector = {
|
|||
.height = -1,
|
||||
.tim2 = TIM2_BCD,
|
||||
.cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
|
||||
.caps = CLCD_CAP_5551,
|
||||
.fixedtimings = 1,
|
||||
.connector = IMPD1_CTRL_DISP_LCD,
|
||||
.bpp = 16,
|
||||
|
@ -206,6 +209,7 @@ static struct clcd_panel ltm10c209 = {
|
|||
.height = -1,
|
||||
.tim2 = TIM2_BCD,
|
||||
.cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
|
||||
.caps = CLCD_CAP_5551,
|
||||
.fixedtimings = 1,
|
||||
.connector = IMPD1_CTRL_DISP_LCD,
|
||||
.bpp = 16,
|
||||
|
@ -279,6 +283,7 @@ static void impd1fb_clcd_remove(struct clcd_fb *fb)
|
|||
|
||||
static struct clcd_board impd1_clcd_data = {
|
||||
.name = "IM-PD/1",
|
||||
.caps = CLCD_CAP_5551 | CLCD_CAP_888,
|
||||
.check = clcdfb_check,
|
||||
.decode = clcdfb_decode,
|
||||
.disable = impd1fb_clcd_disable,
|
||||
|
|
|
@ -24,9 +24,9 @@ void cm_control(u32, u32);
|
|||
#define CM_CTRL_LCDBIASDN (1 << 10)
|
||||
#define CM_CTRL_LCDMUXSEL_MASK (7 << 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_VGA_8421BPP (4 << 11)
|
||||
#define CM_CTRL_LCDMUXSEL_VGA555_TFT555 (4 << 11)
|
||||
#define CM_CTRL_LCDEN0 (1 << 14)
|
||||
#define CM_CTRL_LCDEN1 (1 << 15)
|
||||
#define CM_CTRL_STATIC1 (1 << 16)
|
||||
|
|
|
@ -48,6 +48,8 @@
|
|||
#include <asm/mach/map.h>
|
||||
#include <asm/mach/time.h>
|
||||
|
||||
#include <plat/fpga-irq.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/*
|
||||
|
@ -57,10 +59,10 @@
|
|||
* Setup a VA for the Integrator interrupt controller (for header #0,
|
||||
* just for now).
|
||||
*/
|
||||
#define VA_IC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE)
|
||||
#define VA_SC_BASE IO_ADDRESS(INTEGRATOR_SC_BASE)
|
||||
#define VA_EBI_BASE IO_ADDRESS(INTEGRATOR_EBI_BASE)
|
||||
#define VA_CMIC_BASE IO_ADDRESS(INTEGRATOR_HDR_IC)
|
||||
#define VA_IC_BASE __io_address(INTEGRATOR_IC_BASE)
|
||||
#define VA_SC_BASE __io_address(INTEGRATOR_SC_BASE)
|
||||
#define VA_EBI_BASE __io_address(INTEGRATOR_EBI_BASE)
|
||||
#define VA_CMIC_BASE __io_address(INTEGRATOR_HDR_IC)
|
||||
|
||||
/*
|
||||
* Logical Physical
|
||||
|
@ -156,27 +158,14 @@ static void __init ap_map_io(void)
|
|||
|
||||
#define INTEGRATOR_SC_VALID_INT 0x003fffff
|
||||
|
||||
static void sc_mask_irq(struct irq_data *d)
|
||||
{
|
||||
writel(1 << d->irq, VA_IC_BASE + IRQ_ENABLE_CLEAR);
|
||||
}
|
||||
|
||||
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 struct fpga_irq_data sc_irq_data = {
|
||||
.base = VA_IC_BASE,
|
||||
.irq_start = 0,
|
||||
.chip.name = "SC",
|
||||
};
|
||||
|
||||
static void __init ap_init_irq(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
/* Disable all interrupts initially. */
|
||||
/* Do the core module ones */
|
||||
writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
|
||||
|
@ -185,13 +174,7 @@ static void __init ap_init_irq(void)
|
|||
writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
|
||||
writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
|
||||
|
||||
for (i = 0; i < NR_IRQS; i++) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
fpga_irq_init(-1, INTEGRATOR_SC_VALID_INT, &sc_irq_data);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
@ -282,7 +265,7 @@ static void ap_flash_exit(void)
|
|||
|
||||
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);
|
||||
}
|
||||
|
@ -499,8 +482,9 @@ static struct sys_timer ap_timer = {
|
|||
MACHINE_START(INTEGRATOR, "ARM-Integrator")
|
||||
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
|
||||
.boot_params = 0x00000100,
|
||||
.map_io = ap_map_io,
|
||||
.reserve = integrator_reserve,
|
||||
.map_io = ap_map_io,
|
||||
.init_early = integrator_init_early,
|
||||
.init_irq = ap_init_irq,
|
||||
.timer = &ap_timer,
|
||||
.init_machine = ap_init,
|
||||
|
|
|
@ -42,6 +42,10 @@
|
|||
|
||||
#include <asm/hardware/timer-sp.h>
|
||||
|
||||
#include <plat/clcd.h>
|
||||
#include <plat/fpga-irq.h>
|
||||
#include <plat/sched_clock.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#define INTCP_PA_FLASH_BASE 0x24000000
|
||||
|
@ -49,9 +53,9 @@
|
|||
|
||||
#define INTCP_PA_CLCD_BASE 0xc0000000
|
||||
|
||||
#define INTCP_VA_CIC_BASE IO_ADDRESS(INTEGRATOR_HDR_BASE + 0x40)
|
||||
#define INTCP_VA_PIC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE)
|
||||
#define INTCP_VA_SIC_BASE IO_ADDRESS(INTEGRATOR_CP_SIC_BASE)
|
||||
#define INTCP_VA_CIC_BASE __io_address(INTEGRATOR_HDR_BASE + 0x40)
|
||||
#define INTCP_VA_PIC_BASE __io_address(INTEGRATOR_IC_BASE)
|
||||
#define INTCP_VA_SIC_BASE __io_address(INTEGRATOR_CP_SIC_BASE)
|
||||
|
||||
#define INTCP_ETH_SIZE 0x10
|
||||
|
||||
|
@ -139,129 +143,48 @@ static void __init intcp_map_io(void)
|
|||
iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc));
|
||||
}
|
||||
|
||||
#define cic_writel __raw_writel
|
||||
#define cic_readl __raw_readl
|
||||
#define pic_writel __raw_writel
|
||||
#define pic_readl __raw_readl
|
||||
#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 struct fpga_irq_data cic_irq_data = {
|
||||
.base = INTCP_VA_CIC_BASE,
|
||||
.irq_start = IRQ_CIC_START,
|
||||
.chip.name = "CIC",
|
||||
};
|
||||
|
||||
static void pic_mask_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq - IRQ_PIC_START;
|
||||
pic_writel(1 << irq, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR);
|
||||
}
|
||||
|
||||
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 struct fpga_irq_data pic_irq_data = {
|
||||
.base = INTCP_VA_PIC_BASE,
|
||||
.irq_start = IRQ_PIC_START,
|
||||
.chip.name = "PIC",
|
||||
};
|
||||
|
||||
static void sic_mask_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq - IRQ_SIC_START;
|
||||
sic_writel(1 << irq, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR);
|
||||
}
|
||||
|
||||
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 struct fpga_irq_data sic_irq_data = {
|
||||
.base = INTCP_VA_SIC_BASE,
|
||||
.irq_start = IRQ_SIC_START,
|
||||
.chip.name = "SIC",
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
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
|
||||
*/
|
||||
pic_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 + IRQ_ENABLE_CLEAR);
|
||||
writel(0xffffffff, INTCP_VA_PIC_BASE + FIQ_ENABLE_CLEAR);
|
||||
writel(0xffffffff, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR);
|
||||
writel(0xffffffff, INTCP_VA_CIC_BASE + FIQ_ENABLE_CLEAR);
|
||||
writel(sic_mask, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR);
|
||||
writel(sic_mask, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR);
|
||||
|
||||
for (i = IRQ_PIC_START; i <= IRQ_PIC_END; i++) {
|
||||
if (i == 11)
|
||||
i = 22;
|
||||
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);
|
||||
}
|
||||
fpga_irq_init(-1, pic_mask, &pic_irq_data);
|
||||
|
||||
cic_writel(0xffffffff, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR);
|
||||
cic_writel(0xffffffff, INTCP_VA_CIC_BASE + FIQ_ENABLE_CLEAR);
|
||||
fpga_irq_init(-1, ~((~0u) << (1 + IRQ_CIC_END - IRQ_CIC_START)),
|
||||
&cic_irq_data);
|
||||
|
||||
for (i = IRQ_CIC_START; i <= IRQ_CIC_END; i++) {
|
||||
set_irq_chip(i, &cic_chip);
|
||||
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 = {
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
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)
|
||||
val = CM_CTRL_LCDMUXSEL_VGA_8421BPP;
|
||||
if (var->bits_per_pixel <= 8 ||
|
||||
(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)
|
||||
val = CM_CTRL_LCDMUXSEL_VGA_16BPP
|
||||
| CM_CTRL_LCDEN0 | CM_CTRL_LCDEN1
|
||||
| CM_CTRL_STATIC1 | CM_CTRL_STATIC2;
|
||||
/* truecolor RGB565 */
|
||||
val |= CM_CTRL_LCDMUXSEL_VGA565_TFT555;
|
||||
else
|
||||
val = 0; /* no idea for this, don't trust the docs */
|
||||
|
||||
|
@ -498,49 +399,24 @@ static void cp_clcd_enable(struct clcd_fb *fb)
|
|||
CM_CTRL_n24BITEN, val);
|
||||
}
|
||||
|
||||
static unsigned long framesize = SZ_1M;
|
||||
|
||||
static int cp_clcd_setup(struct clcd_fb *fb)
|
||||
{
|
||||
dma_addr_t dma;
|
||||
fb->panel = versatile_clcd_get_panel("VGA");
|
||||
if (!fb->panel)
|
||||
return -EINVAL;
|
||||
|
||||
fb->panel = &vga;
|
||||
|
||||
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)
|
||||
{
|
||||
dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
|
||||
fb->fb.screen_base, fb->fb.fix.smem_start);
|
||||
return versatile_clcd_setup_dma(fb, SZ_1M);
|
||||
}
|
||||
|
||||
static struct clcd_board clcd_data = {
|
||||
.name = "Integrator/CP",
|
||||
.caps = CLCD_CAP_5551 | CLCD_CAP_RGB565 | CLCD_CAP_888,
|
||||
.check = clcdfb_check,
|
||||
.decode = clcdfb_decode,
|
||||
.enable = cp_clcd_enable,
|
||||
.setup = cp_clcd_setup,
|
||||
.mmap = cp_clcd_mmap,
|
||||
.remove = cp_clcd_remove,
|
||||
.mmap = versatile_clcd_mmap_dma,
|
||||
.remove = versatile_clcd_remove_dma,
|
||||
};
|
||||
|
||||
static struct amba_device clcd_device = {
|
||||
|
@ -565,11 +441,23 @@ static struct amba_device *amba_devs[] __initdata = {
|
|||
&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)
|
||||
{
|
||||
int i;
|
||||
|
||||
clkdev_add_table(cp_lookups, ARRAY_SIZE(cp_lookups));
|
||||
platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs));
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
|
||||
|
@ -599,8 +487,9 @@ static struct sys_timer cp_timer = {
|
|||
MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
|
||||
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
|
||||
.boot_params = 0x00000100,
|
||||
.map_io = intcp_map_io,
|
||||
.reserve = integrator_reserve,
|
||||
.map_io = intcp_map_io,
|
||||
.init_early = intcp_init_early,
|
||||
.init_irq = intcp_init_irq,
|
||||
.timer = &cp_timer,
|
||||
.init_machine = intcp_init,
|
||||
|
|
|
@ -263,7 +263,7 @@ static void __init msm_timer_init(void)
|
|||
}
|
||||
|
||||
#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];
|
||||
|
||||
|
@ -295,6 +295,7 @@ void __cpuinit local_timer_setup(struct clock_event_device *evt)
|
|||
gic_enable_ppi(clock->irq.irq);
|
||||
|
||||
clockevents_register_device(evt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int local_timer_ack(void)
|
||||
|
|
|
@ -44,6 +44,7 @@ config ARCH_OMAP4
|
|||
depends on ARCH_OMAP2PLUS
|
||||
select CPU_V7
|
||||
select ARM_GIC
|
||||
select LOCAL_TIMERS if SMP
|
||||
select PL310_ERRATA_588369
|
||||
select PL310_ERRATA_727915
|
||||
select ARM_ERRATA_720789
|
||||
|
|
|
@ -26,9 +26,14 @@
|
|||
/*
|
||||
* 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;
|
||||
twd_timer_setup(evt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,5 @@ obj-$(CONFIG_MACH_REALVIEW_PB11MP) += realview_pb11mp.o
|
|||
obj-$(CONFIG_MACH_REALVIEW_PB1176) += realview_pb1176.o
|
||||
obj-$(CONFIG_MACH_REALVIEW_PBA8) += realview_pba8.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_LOCAL_TIMERS) += localtimer.o
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include <mach/irqs.h>
|
||||
#include <asm/hardware/timer-sp.h>
|
||||
|
||||
#include <plat/clcd.h>
|
||||
#include <plat/sched_clock.h>
|
||||
|
||||
#include "core.h"
|
||||
|
@ -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())
|
||||
oscvco_clk.vcoreg = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC0_OFFSET;
|
||||
oscvco_clk.vcoreg = sys + REALVIEW_SYS_OSC0_OFFSET;
|
||||
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));
|
||||
|
||||
return 0;
|
||||
versatile_sched_clock_init(sys + REALVIEW_SYS_24MHz_OFFSET, 24000000);
|
||||
}
|
||||
core_initcall(clk_init);
|
||||
|
||||
/*
|
||||
* CLCD support.
|
||||
|
@ -385,157 +387,6 @@ core_initcall(clk_init);
|
|||
#define SYS_CLCD_ID_SANYO_2_5 (0x07 << 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.
|
||||
*/
|
||||
|
@ -565,56 +416,60 @@ static void realview_clcd_enable(struct clcd_fb *fb)
|
|||
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)
|
||||
{
|
||||
void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET;
|
||||
const char *panel_name, *vga_panel_name;
|
||||
unsigned long framesize;
|
||||
dma_addr_t dma;
|
||||
u32 val;
|
||||
|
||||
if (machine_is_realview_eb())
|
||||
if (machine_is_realview_eb()) {
|
||||
/* VGA, 16bpp */
|
||||
framesize = 640 * 480 * 2;
|
||||
else
|
||||
vga_panel_name = "VGA";
|
||||
} else {
|
||||
/* XVGA, 16bpp */
|
||||
framesize = 1024 * 768 * 2;
|
||||
|
||||
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;
|
||||
vga_panel_name = "XVGA";
|
||||
}
|
||||
|
||||
fb->fb.fix.smem_start = dma;
|
||||
fb->fb.fix.smem_len = framesize;
|
||||
val = readl(sys_clcd) & SYS_CLCD_ID_MASK;
|
||||
if (val == SYS_CLCD_ID_SANYO_3_8)
|
||||
panel_name = "Sanyo TM38QV67A02A";
|
||||
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;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
fb->panel = versatile_clcd_get_panel(panel_name);
|
||||
if (!fb->panel)
|
||||
return -EINVAL;
|
||||
|
||||
static int realview_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 realview_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);
|
||||
return versatile_clcd_setup_dma(fb, framesize);
|
||||
}
|
||||
|
||||
struct clcd_board clcd_plat_data = {
|
||||
.name = "RealView",
|
||||
.caps = CLCD_CAP_ALL,
|
||||
.check = clcdfb_check,
|
||||
.decode = clcdfb_decode,
|
||||
.disable = realview_clcd_disable,
|
||||
.enable = realview_clcd_enable,
|
||||
.setup = realview_clcd_setup,
|
||||
.mmap = realview_clcd_mmap,
|
||||
.remove = realview_clcd_remove,
|
||||
.mmap = versatile_clcd_mmap_dma,
|
||||
.remove = versatile_clcd_remove_dma,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_LEDS
|
||||
|
@ -655,12 +510,6 @@ void realview_leds_event(led_event_t ledevt)
|
|||
}
|
||||
#endif /* CONFIG_LEDS */
|
||||
|
||||
/*
|
||||
* The sched_clock counter
|
||||
*/
|
||||
#define REFCOUNTER (__io_address(REALVIEW_SYS_BASE) + \
|
||||
REALVIEW_SYS_24MHz_OFFSET)
|
||||
|
||||
/*
|
||||
* Where is the timer (VA)?
|
||||
*/
|
||||
|
@ -676,8 +525,6 @@ void __init realview_timer_init(unsigned int timer_irq)
|
|||
{
|
||||
u32 val;
|
||||
|
||||
versatile_sched_clock_init(REFCOUNTER, 24000000);
|
||||
|
||||
/*
|
||||
* set clock frequency:
|
||||
* REALVIEW_REFCLK is 32KHz
|
||||
|
|
|
@ -42,7 +42,6 @@ static struct amba_device name##_device = { \
|
|||
}, \
|
||||
.dma_mask = ~0, \
|
||||
.irq = base##_IRQ, \
|
||||
/* .dma = base##_DMA,*/ \
|
||||
}
|
||||
|
||||
struct machine_desc;
|
||||
|
@ -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_eth_register(const char *name, 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,
|
||||
char **from, struct meminfo *meminfo);
|
||||
extern void (*realview_reset)(char);
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
* 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
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* 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 @@
|
|||
*/
|
||||
#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 <linux/io.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/smp_scu.h>
|
||||
#include <asm/unified.h>
|
||||
|
||||
#include <mach/board-eb.h>
|
||||
#include <mach/board-pb11mp.h>
|
||||
#include <mach/board-pbx.h>
|
||||
#include <asm/smp_scu.h>
|
||||
|
||||
#include "core.h"
|
||||
|
||||
extern void realview_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));
|
||||
}
|
||||
extern void versatile_secondary_startup(void);
|
||||
|
||||
static void __iomem *scu_base_addr(void)
|
||||
{
|
||||
|
@ -62,75 +39,6 @@ static void __iomem *scu_base_addr(void)
|
|||
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
|
||||
* which may be present or become present in the system.
|
||||
|
@ -174,6 +82,6 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
|
|||
* until it receives a soft interrupt, and then the
|
||||
* 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));
|
||||
}
|
||||
|
|
|
@ -144,60 +144,39 @@ static struct pl022_ssp_controller ssp0_plat_data = {
|
|||
* These devices are connected via the core APB bridge
|
||||
*/
|
||||
#define GPIO2_IRQ { IRQ_EB_GPIO2, NO_IRQ }
|
||||
#define GPIO2_DMA { 0, 0 }
|
||||
#define GPIO3_IRQ { IRQ_EB_GPIO3, NO_IRQ }
|
||||
#define GPIO3_DMA { 0, 0 }
|
||||
|
||||
#define AACI_IRQ { IRQ_EB_AACI, NO_IRQ }
|
||||
#define AACI_DMA { 0x80, 0x81 }
|
||||
#define MMCI0_IRQ { IRQ_EB_MMCI0A, IRQ_EB_MMCI0B }
|
||||
#define MMCI0_DMA { 0x84, 0 }
|
||||
#define KMI0_IRQ { IRQ_EB_KMI0, NO_IRQ }
|
||||
#define KMI0_DMA { 0, 0 }
|
||||
#define KMI1_IRQ { IRQ_EB_KMI1, NO_IRQ }
|
||||
#define KMI1_DMA { 0, 0 }
|
||||
|
||||
/*
|
||||
* These devices are connected directly to the multi-layer AHB switch
|
||||
*/
|
||||
#define EB_SMC_IRQ { NO_IRQ, NO_IRQ }
|
||||
#define EB_SMC_DMA { 0, 0 }
|
||||
#define MPMC_IRQ { NO_IRQ, NO_IRQ }
|
||||
#define MPMC_DMA { 0, 0 }
|
||||
#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_DMA { 0, 0 }
|
||||
|
||||
/*
|
||||
* These devices are connected via the core APB bridge
|
||||
*/
|
||||
#define SCTL_IRQ { NO_IRQ, NO_IRQ }
|
||||
#define SCTL_DMA { 0, 0 }
|
||||
#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_DMA { 0, 0 }
|
||||
#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_DMA { 0, 0 }
|
||||
|
||||
/*
|
||||
* These devices are connected via the DMA APB bridge
|
||||
*/
|
||||
#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_DMA { 15, 14 }
|
||||
#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_DMA { 11, 10 }
|
||||
#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_DMA { 9, 8 }
|
||||
|
||||
/* FPGA Primecells */
|
||||
AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL);
|
||||
|
@ -487,6 +466,7 @@ MACHINE_START(REALVIEW_EB, "ARM-RealView EB")
|
|||
.boot_params = PLAT_PHYS_OFFSET + 0x00000100,
|
||||
.fixup = realview_fixup,
|
||||
.map_io = realview_eb_map_io,
|
||||
.init_early = realview_init_early,
|
||||
.init_irq = gic_init_irq,
|
||||
.timer = &realview_eb_timer,
|
||||
.init_machine = realview_eb_init,
|
||||
|
|
|
@ -134,47 +134,26 @@ static struct pl022_ssp_controller ssp0_plat_data = {
|
|||
* RealView PB1176 AMBA devices
|
||||
*/
|
||||
#define GPIO2_IRQ { IRQ_PB1176_GPIO2, NO_IRQ }
|
||||
#define GPIO2_DMA { 0, 0 }
|
||||
#define GPIO3_IRQ { IRQ_PB1176_GPIO3, NO_IRQ }
|
||||
#define GPIO3_DMA { 0, 0 }
|
||||
#define AACI_IRQ { IRQ_PB1176_AACI, NO_IRQ }
|
||||
#define AACI_DMA { 0x80, 0x81 }
|
||||
#define MMCI0_IRQ { IRQ_PB1176_MMCI0A, IRQ_PB1176_MMCI0B }
|
||||
#define MMCI0_DMA { 0x84, 0 }
|
||||
#define KMI0_IRQ { IRQ_PB1176_KMI0, NO_IRQ }
|
||||
#define KMI0_DMA { 0, 0 }
|
||||
#define KMI1_IRQ { IRQ_PB1176_KMI1, NO_IRQ }
|
||||
#define KMI1_DMA { 0, 0 }
|
||||
#define PB1176_SMC_IRQ { NO_IRQ, NO_IRQ }
|
||||
#define PB1176_SMC_DMA { 0, 0 }
|
||||
#define MPMC_IRQ { NO_IRQ, NO_IRQ }
|
||||
#define MPMC_DMA { 0, 0 }
|
||||
#define PB1176_CLCD_IRQ { IRQ_DC1176_CLCD, NO_IRQ }
|
||||
#define PB1176_CLCD_DMA { 0, 0 }
|
||||
#define SCTL_IRQ { NO_IRQ, NO_IRQ }
|
||||
#define SCTL_DMA { 0, 0 }
|
||||
#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_DMA { 0, 0 }
|
||||
#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_DMA { 0, 0 }
|
||||
#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_DMA { 15, 14 }
|
||||
#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_DMA { 11, 10 }
|
||||
#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_DMA { 0, 0 }
|
||||
#define PB1176_SSP_IRQ { IRQ_DC1176_SSP, NO_IRQ }
|
||||
#define PB1176_SSP_DMA { 9, 8 }
|
||||
|
||||
/* FPGA Primecells */
|
||||
AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL);
|
||||
|
@ -382,6 +361,7 @@ MACHINE_START(REALVIEW_PB1176, "ARM-RealView PB1176")
|
|||
.boot_params = PLAT_PHYS_OFFSET + 0x00000100,
|
||||
.fixup = realview_pb1176_fixup,
|
||||
.map_io = realview_pb1176_map_io,
|
||||
.init_early = realview_init_early,
|
||||
.init_irq = gic_init_irq,
|
||||
.timer = &realview_pb1176_timer,
|
||||
.init_machine = realview_pb1176_init,
|
||||
|
|
|
@ -136,47 +136,26 @@ static struct pl022_ssp_controller ssp0_plat_data = {
|
|||
*/
|
||||
|
||||
#define GPIO2_IRQ { IRQ_PB11MP_GPIO2, NO_IRQ }
|
||||
#define GPIO2_DMA { 0, 0 }
|
||||
#define GPIO3_IRQ { IRQ_PB11MP_GPIO3, NO_IRQ }
|
||||
#define GPIO3_DMA { 0, 0 }
|
||||
#define AACI_IRQ { IRQ_TC11MP_AACI, NO_IRQ }
|
||||
#define AACI_DMA { 0x80, 0x81 }
|
||||
#define MMCI0_IRQ { IRQ_TC11MP_MMCI0A, IRQ_TC11MP_MMCI0B }
|
||||
#define MMCI0_DMA { 0x84, 0 }
|
||||
#define KMI0_IRQ { IRQ_TC11MP_KMI0, NO_IRQ }
|
||||
#define KMI0_DMA { 0, 0 }
|
||||
#define KMI1_IRQ { IRQ_TC11MP_KMI1, NO_IRQ }
|
||||
#define KMI1_DMA { 0, 0 }
|
||||
#define PB11MP_SMC_IRQ { NO_IRQ, NO_IRQ }
|
||||
#define PB11MP_SMC_DMA { 0, 0 }
|
||||
#define MPMC_IRQ { NO_IRQ, NO_IRQ }
|
||||
#define MPMC_DMA { 0, 0 }
|
||||
#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_DMA { 0, 0 }
|
||||
#define SCTL_IRQ { NO_IRQ, NO_IRQ }
|
||||
#define SCTL_DMA { 0, 0 }
|
||||
#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_DMA { 0, 0 }
|
||||
#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_DMA { 0, 0 }
|
||||
#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_DMA { 15, 14 }
|
||||
#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_DMA { 11, 10 }
|
||||
#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_DMA { 9, 8 }
|
||||
|
||||
/* FPGA Primecells */
|
||||
AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL);
|
||||
|
@ -384,6 +363,7 @@ MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore")
|
|||
.boot_params = PLAT_PHYS_OFFSET + 0x00000100,
|
||||
.fixup = realview_fixup,
|
||||
.map_io = realview_pb11mp_map_io,
|
||||
.init_early = realview_init_early,
|
||||
.init_irq = gic_init_irq,
|
||||
.timer = &realview_pb11mp_timer,
|
||||
.init_machine = realview_pb11mp_init,
|
||||
|
|
|
@ -126,47 +126,26 @@ static struct pl022_ssp_controller ssp0_plat_data = {
|
|||
*/
|
||||
|
||||
#define GPIO2_IRQ { IRQ_PBA8_GPIO2, NO_IRQ }
|
||||
#define GPIO2_DMA { 0, 0 }
|
||||
#define GPIO3_IRQ { IRQ_PBA8_GPIO3, NO_IRQ }
|
||||
#define GPIO3_DMA { 0, 0 }
|
||||
#define AACI_IRQ { IRQ_PBA8_AACI, NO_IRQ }
|
||||
#define AACI_DMA { 0x80, 0x81 }
|
||||
#define MMCI0_IRQ { IRQ_PBA8_MMCI0A, IRQ_PBA8_MMCI0B }
|
||||
#define MMCI0_DMA { 0x84, 0 }
|
||||
#define KMI0_IRQ { IRQ_PBA8_KMI0, NO_IRQ }
|
||||
#define KMI0_DMA { 0, 0 }
|
||||
#define KMI1_IRQ { IRQ_PBA8_KMI1, NO_IRQ }
|
||||
#define KMI1_DMA { 0, 0 }
|
||||
#define PBA8_SMC_IRQ { NO_IRQ, NO_IRQ }
|
||||
#define PBA8_SMC_DMA { 0, 0 }
|
||||
#define MPMC_IRQ { NO_IRQ, NO_IRQ }
|
||||
#define MPMC_DMA { 0, 0 }
|
||||
#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_DMA { 0, 0 }
|
||||
#define SCTL_IRQ { NO_IRQ, NO_IRQ }
|
||||
#define SCTL_DMA { 0, 0 }
|
||||
#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_DMA { 0, 0 }
|
||||
#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_DMA { 0, 0 }
|
||||
#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_DMA { 15, 14 }
|
||||
#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_DMA { 11, 10 }
|
||||
#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_DMA { 9, 8 }
|
||||
|
||||
/* FPGA Primecells */
|
||||
AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL);
|
||||
|
@ -334,6 +313,7 @@ MACHINE_START(REALVIEW_PBA8, "ARM-RealView PB-A8")
|
|||
.boot_params = PLAT_PHYS_OFFSET + 0x00000100,
|
||||
.fixup = realview_fixup,
|
||||
.map_io = realview_pba8_map_io,
|
||||
.init_early = realview_init_early,
|
||||
.init_irq = gic_init_irq,
|
||||
.timer = &realview_pba8_timer,
|
||||
.init_machine = realview_pba8_init,
|
||||
|
|
|
@ -148,47 +148,26 @@ static struct pl022_ssp_controller ssp0_plat_data = {
|
|||
*/
|
||||
|
||||
#define GPIO2_IRQ { IRQ_PBX_GPIO2, NO_IRQ }
|
||||
#define GPIO2_DMA { 0, 0 }
|
||||
#define GPIO3_IRQ { IRQ_PBX_GPIO3, NO_IRQ }
|
||||
#define GPIO3_DMA { 0, 0 }
|
||||
#define AACI_IRQ { IRQ_PBX_AACI, NO_IRQ }
|
||||
#define AACI_DMA { 0x80, 0x81 }
|
||||
#define MMCI0_IRQ { IRQ_PBX_MMCI0A, IRQ_PBX_MMCI0B }
|
||||
#define MMCI0_DMA { 0x84, 0 }
|
||||
#define KMI0_IRQ { IRQ_PBX_KMI0, NO_IRQ }
|
||||
#define KMI0_DMA { 0, 0 }
|
||||
#define KMI1_IRQ { IRQ_PBX_KMI1, NO_IRQ }
|
||||
#define KMI1_DMA { 0, 0 }
|
||||
#define PBX_SMC_IRQ { NO_IRQ, NO_IRQ }
|
||||
#define PBX_SMC_DMA { 0, 0 }
|
||||
#define MPMC_IRQ { NO_IRQ, NO_IRQ }
|
||||
#define MPMC_DMA { 0, 0 }
|
||||
#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_DMA { 0, 0 }
|
||||
#define SCTL_IRQ { NO_IRQ, NO_IRQ }
|
||||
#define SCTL_DMA { 0, 0 }
|
||||
#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_DMA { 0, 0 }
|
||||
#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_DMA { 0, 0 }
|
||||
#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_DMA { 15, 14 }
|
||||
#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_DMA { 11, 10 }
|
||||
#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_DMA { 9, 8 }
|
||||
|
||||
/* FPGA Primecells */
|
||||
AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL);
|
||||
|
@ -417,6 +396,7 @@ MACHINE_START(REALVIEW_PBX, "ARM-RealView PBX")
|
|||
.boot_params = PLAT_PHYS_OFFSET + 0x00000100,
|
||||
.fixup = realview_pbx_fixup,
|
||||
.map_io = realview_pbx_map_io,
|
||||
.init_early = realview_init_early,
|
||||
.init_irq = gic_init_irq,
|
||||
.timer = &realview_pbx_timer,
|
||||
.init_machine = realview_pbx_init,
|
||||
|
|
|
@ -18,8 +18,9 @@
|
|||
/*
|
||||
* 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;
|
||||
twd_timer_setup(evt);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -18,8 +18,9 @@
|
|||
/*
|
||||
* 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;
|
||||
twd_timer_setup(evt);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -21,8 +21,9 @@
|
|||
/*
|
||||
* 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;
|
||||
twd_timer_setup(evt);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -50,6 +50,8 @@
|
|||
#include <mach/platform.h>
|
||||
#include <asm/hardware/timer-sp.h>
|
||||
|
||||
#include <plat/clcd.h>
|
||||
#include <plat/fpga-irq.h>
|
||||
#include <plat/sched_clock.h>
|
||||
|
||||
#include "core.h"
|
||||
|
@ -63,47 +65,12 @@
|
|||
#define VA_VIC_BASE __io_address(VERSATILE_VIC_BASE)
|
||||
#define VA_SIC_BASE __io_address(VERSATILE_SIC_BASE)
|
||||
|
||||
static void sic_mask_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq - IRQ_SIC_START;
|
||||
|
||||
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 struct fpga_irq_data sic_irq = {
|
||||
.base = VA_SIC_BASE,
|
||||
.irq_start = IRQ_SIC_START,
|
||||
.chip.name = "SIC",
|
||||
};
|
||||
|
||||
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
|
||||
#define IRQ_MMCI0A IRQ_VICSOURCE22
|
||||
#define IRQ_AACI IRQ_VICSOURCE24
|
||||
|
@ -118,22 +85,11 @@ sic_handle_irq(unsigned int irq, struct irq_desc *desc)
|
|||
|
||||
void __init versatile_init_irq(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
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);
|
||||
|
||||
for (i = IRQ_SIC_START; i <= IRQ_SIC_END; i++) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
fpga_irq_init(IRQ_VICSOURCE31, ~PIC_MASK, &sic_irq);
|
||||
|
||||
/*
|
||||
* Interrupts on secondary controller from 0 to 8 are routed to
|
||||
|
@ -476,127 +432,7 @@ static struct clk_lookup lookups[] = {
|
|||
#define SYS_CLCD_ID_SANYO_2_5 (0x07 << 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_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;
|
||||
}
|
||||
static bool is_sanyo_2_5_lcd;
|
||||
|
||||
/*
|
||||
* Disable all display connectors on the interface module.
|
||||
|
@ -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 (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);
|
||||
unsigned long ctrl;
|
||||
|
||||
|
@ -630,18 +466,22 @@ static void versatile_clcd_disable(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;
|
||||
u32 val;
|
||||
|
||||
val = readl(sys_clcd);
|
||||
val &= ~SYS_CLCD_MODE_MASK;
|
||||
|
||||
switch (fb->fb.var.green.length) {
|
||||
switch (var->green.length) {
|
||||
case 5:
|
||||
val |= SYS_CLCD_MODE_5551;
|
||||
break;
|
||||
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;
|
||||
case 8:
|
||||
val |= SYS_CLCD_MODE_888;
|
||||
|
@ -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 (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);
|
||||
unsigned long ctrl;
|
||||
|
||||
|
@ -674,50 +514,62 @@ static void versatile_clcd_enable(struct clcd_fb *fb)
|
|||
#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)
|
||||
{
|
||||
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,
|
||||
&dma, GFP_KERNEL);
|
||||
if (!fb->fb.screen_base) {
|
||||
printk(KERN_ERR "CLCD: unable to map framebuffer\n");
|
||||
return -ENOMEM;
|
||||
val = readl(sys_clcd) & SYS_CLCD_ID_MASK;
|
||||
if (val == SYS_CLCD_ID_SANYO_3_8)
|
||||
panel_name = "Sanyo TM38QV67A02A";
|
||||
else if (val == SYS_CLCD_ID_SANYO_2_5) {
|
||||
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->fb.fix.smem_len = framesize;
|
||||
fb->panel = versatile_clcd_get_panel(panel_name);
|
||||
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,
|
||||
fb->fb.screen_base,
|
||||
fb->fb.fix.smem_start,
|
||||
fb->fb.fix.smem_len);
|
||||
}
|
||||
clcdfb_decode(fb, regs);
|
||||
|
||||
static void versatile_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);
|
||||
/* Always clear BGR for RGB565: we do the routing externally */
|
||||
if (fb->fb.var.green.length == 6)
|
||||
regs->cntl &= ~CNTL_BGR;
|
||||
}
|
||||
|
||||
static struct clcd_board clcd_plat_data = {
|
||||
.name = "Versatile",
|
||||
.caps = CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888,
|
||||
.check = clcdfb_check,
|
||||
.decode = clcdfb_decode,
|
||||
.decode = versatile_clcd_decode,
|
||||
.disable = versatile_clcd_disable,
|
||||
.enable = versatile_clcd_enable,
|
||||
.setup = versatile_clcd_setup,
|
||||
.mmap = versatile_clcd_mmap,
|
||||
.remove = versatile_clcd_remove,
|
||||
.mmap = versatile_clcd_mmap_dma,
|
||||
.remove = versatile_clcd_remove_dma,
|
||||
};
|
||||
|
||||
static struct pl061_platform_data gpio0_plat_data = {
|
||||
|
@ -737,53 +589,35 @@ static struct pl022_ssp_controller ssp0_plat_data = {
|
|||
};
|
||||
|
||||
#define AACI_IRQ { IRQ_AACI, NO_IRQ }
|
||||
#define AACI_DMA { 0x80, 0x81 }
|
||||
#define MMCI0_IRQ { IRQ_MMCI0A,IRQ_SIC_MMCI0B }
|
||||
#define MMCI0_DMA { 0x84, 0 }
|
||||
#define KMI0_IRQ { IRQ_SIC_KMI0, NO_IRQ }
|
||||
#define KMI0_DMA { 0, 0 }
|
||||
#define KMI1_IRQ { IRQ_SIC_KMI1, NO_IRQ }
|
||||
#define KMI1_DMA { 0, 0 }
|
||||
|
||||
/*
|
||||
* These devices are connected directly to the multi-layer AHB switch
|
||||
*/
|
||||
#define SMC_IRQ { NO_IRQ, NO_IRQ }
|
||||
#define SMC_DMA { 0, 0 }
|
||||
#define MPMC_IRQ { NO_IRQ, NO_IRQ }
|
||||
#define MPMC_DMA { 0, 0 }
|
||||
#define CLCD_IRQ { IRQ_CLCDINT, NO_IRQ }
|
||||
#define CLCD_DMA { 0, 0 }
|
||||
#define DMAC_IRQ { IRQ_DMAINT, NO_IRQ }
|
||||
#define DMAC_DMA { 0, 0 }
|
||||
|
||||
/*
|
||||
* These devices are connected via the core APB bridge
|
||||
*/
|
||||
#define SCTL_IRQ { NO_IRQ, NO_IRQ }
|
||||
#define SCTL_DMA { 0, 0 }
|
||||
#define WATCHDOG_IRQ { IRQ_WDOGINT, NO_IRQ }
|
||||
#define WATCHDOG_DMA { 0, 0 }
|
||||
#define GPIO0_IRQ { IRQ_GPIOINT0, NO_IRQ }
|
||||
#define GPIO0_DMA { 0, 0 }
|
||||
#define GPIO1_IRQ { IRQ_GPIOINT1, NO_IRQ }
|
||||
#define GPIO1_DMA { 0, 0 }
|
||||
#define RTC_IRQ { IRQ_RTCINT, NO_IRQ }
|
||||
#define RTC_DMA { 0, 0 }
|
||||
|
||||
/*
|
||||
* These devices are connected via the DMA APB bridge
|
||||
*/
|
||||
#define SCI_IRQ { IRQ_SCIINT, NO_IRQ }
|
||||
#define SCI_DMA { 7, 6 }
|
||||
#define UART0_IRQ { IRQ_UARTINT0, NO_IRQ }
|
||||
#define UART0_DMA { 15, 14 }
|
||||
#define UART1_IRQ { IRQ_UARTINT1, NO_IRQ }
|
||||
#define UART1_DMA { 13, 12 }
|
||||
#define UART2_IRQ { IRQ_UARTINT2, NO_IRQ }
|
||||
#define UART2_DMA { 11, 10 }
|
||||
#define SSP_IRQ { IRQ_SSPINT, NO_IRQ }
|
||||
#define SSP_DMA { 9, 8 }
|
||||
|
||||
/* FPGA Primecells */
|
||||
AMBA_DEVICE(aaci, "fpga:04", AACI, NULL);
|
||||
|
@ -865,14 +699,21 @@ static void versatile_leds_event(led_event_t ledevt)
|
|||
}
|
||||
#endif /* CONFIG_LEDS */
|
||||
|
||||
/* Early initializations */
|
||||
void __init versatile_init_early(void)
|
||||
{
|
||||
void __iomem *sys = __io_address(VERSATILE_SYS_BASE);
|
||||
|
||||
osc4_clk.vcoreg = sys + VERSATILE_SYS_OSCCLCD_OFFSET;
|
||||
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
|
||||
|
||||
versatile_sched_clock_init(sys + VERSATILE_SYS_24MHz_OFFSET, 24000000);
|
||||
}
|
||||
|
||||
void __init versatile_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
osc4_clk.vcoreg = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_OSCCLCD_OFFSET;
|
||||
|
||||
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
|
||||
|
||||
platform_device_register(&versatile_flash_device);
|
||||
platform_device_register(&versatile_i2c_device);
|
||||
platform_device_register(&smc91x_device);
|
||||
|
@ -888,12 +729,6 @@ void __init versatile_init(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* The sched_clock counter
|
||||
*/
|
||||
#define REFCOUNTER (__io_address(VERSATILE_SYS_BASE) + \
|
||||
VERSATILE_SYS_24MHz_OFFSET)
|
||||
|
||||
/*
|
||||
* Where is the timer (VA)?
|
||||
*/
|
||||
|
@ -909,8 +744,6 @@ static void __init versatile_timer_init(void)
|
|||
{
|
||||
u32 val;
|
||||
|
||||
versatile_sched_clock_init(REFCOUNTER, 24000000);
|
||||
|
||||
/*
|
||||
* set clock frequency:
|
||||
* VERSATILE_REFCLK is 32KHz
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <linux/amba/bus.h>
|
||||
|
||||
extern void __init versatile_init(void);
|
||||
extern void __init versatile_init_early(void);
|
||||
extern void __init versatile_init_irq(void);
|
||||
extern void __init versatile_map_io(void);
|
||||
extern struct sys_timer versatile_timer;
|
||||
|
@ -44,7 +45,6 @@ static struct amba_device name##_device = { \
|
|||
}, \
|
||||
.dma_mask = ~0, \
|
||||
.irq = base##_IRQ, \
|
||||
/* .dma = base##_DMA,*/ \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -39,6 +39,6 @@
|
|||
/* macro to get at IO space when running virtually */
|
||||
#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
|
||||
|
|
|
@ -37,6 +37,7 @@ MACHINE_START(VERSATILE_AB, "ARM-Versatile AB")
|
|||
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
|
||||
.boot_params = 0x00000100,
|
||||
.map_io = versatile_map_io,
|
||||
.init_early = versatile_init_early,
|
||||
.init_irq = versatile_init_irq,
|
||||
.timer = &versatile_timer,
|
||||
.init_machine = versatile_init,
|
||||
|
|
|
@ -59,19 +59,14 @@ static struct pl061_platform_data gpio3_plat_data = {
|
|||
};
|
||||
|
||||
#define UART3_IRQ { IRQ_SIC_UART3, NO_IRQ }
|
||||
#define UART3_DMA { 0x86, 0x87 }
|
||||
#define SCI1_IRQ { IRQ_SIC_SCI3, NO_IRQ }
|
||||
#define SCI1_DMA { 0x88, 0x89 }
|
||||
#define MMCI1_IRQ { IRQ_MMCI1A, IRQ_SIC_MMCI1B }
|
||||
#define MMCI1_DMA { 0x85, 0 }
|
||||
|
||||
/*
|
||||
* These devices are connected via the core APB bridge
|
||||
*/
|
||||
#define GPIO2_IRQ { IRQ_GPIOINT2, NO_IRQ }
|
||||
#define GPIO2_DMA { 0, 0 }
|
||||
#define GPIO3_IRQ { IRQ_GPIOINT3, NO_IRQ }
|
||||
#define GPIO3_DMA { 0, 0 }
|
||||
|
||||
/*
|
||||
* These devices are connected via the DMA APB bridge
|
||||
|
@ -110,6 +105,7 @@ MACHINE_START(VERSATILE_PB, "ARM-Versatile PB")
|
|||
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
|
||||
.boot_params = 0x00000100,
|
||||
.map_io = versatile_map_io,
|
||||
.init_early = versatile_init_early,
|
||||
.init_irq = versatile_init_irq,
|
||||
.timer = &versatile_timer,
|
||||
.init_machine = versatile_pb_init,
|
||||
|
|
|
@ -5,5 +5,8 @@ config ARCH_VEXPRESS_CA9X4
|
|||
bool "Versatile Express Cortex-A9x4 tile"
|
||||
select CPU_V7
|
||||
select ARM_GIC
|
||||
select ARM_ERRATA_720789
|
||||
select ARM_ERRATA_751472
|
||||
select ARM_ERRATA_753970
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -4,6 +4,5 @@
|
|||
|
||||
obj-y := v2m.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_LOCAL_TIMERS) += localtimer.o
|
||||
|
|
|
@ -17,8 +17,3 @@ struct amba_device name##_device = { \
|
|||
.irq = IRQ_##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 @@
|
|||
#include <linux/amba/clcd.h>
|
||||
#include <linux/clkdev.h>
|
||||
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/hardware/arm_timer.h>
|
||||
#include <asm/hardware/cache-l2x0.h>
|
||||
#include <asm/hardware/gic.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/pmu.h>
|
||||
#include <asm/smp_scu.h>
|
||||
#include <asm/smp_twd.h>
|
||||
|
||||
#include <mach/ct-ca9x4.h>
|
||||
|
||||
#include <asm/hardware/timer-sp.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mach/time.h>
|
||||
|
||||
|
@ -30,6 +28,8 @@
|
|||
|
||||
#include <mach/motherboard.h>
|
||||
|
||||
#include <plat/clcd.h>
|
||||
|
||||
#define V2M_PA_CS7 0x10000000
|
||||
|
||||
static struct map_desc ct_ca9x4_io_desc[] __initdata = {
|
||||
|
@ -56,7 +56,7 @@ static void __init ct_ca9x4_map_io(void)
|
|||
#ifdef CONFIG_LOCAL_TIMERS
|
||||
twd_base = MMIO_P2V(A9_MPCORE_TWD);
|
||||
#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)
|
||||
|
@ -80,29 +80,6 @@ static struct sys_timer ct_ca9x4_timer = {
|
|||
};
|
||||
#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)
|
||||
{
|
||||
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)
|
|||
static int ct_ca9x4_clcd_setup(struct clcd_fb *fb)
|
||||
{
|
||||
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,
|
||||
&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);
|
||||
return versatile_clcd_setup_dma(fb, framesize);
|
||||
}
|
||||
|
||||
static struct clcd_board ct_ca9x4_clcd_data = {
|
||||
.name = "CT-CA9X4",
|
||||
.caps = CLCD_CAP_5551 | CLCD_CAP_565,
|
||||
.check = clcdfb_check,
|
||||
.decode = clcdfb_decode,
|
||||
.enable = ct_ca9x4_clcd_enable,
|
||||
.setup = ct_ca9x4_clcd_setup,
|
||||
.mmap = ct_ca9x4_clcd_mmap,
|
||||
.remove = ct_ca9x4_clcd_remove,
|
||||
.mmap = versatile_clcd_mmap_dma,
|
||||
.remove = versatile_clcd_remove_dma,
|
||||
};
|
||||
|
||||
static AMBA_DEVICE(clcd, "ct:clcd", CT_CA9X4_CLCDC, &ct_ca9x4_clcd_data);
|
||||
|
@ -220,6 +178,11 @@ static struct platform_device pmu_device = {
|
|||
.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)
|
||||
{
|
||||
int i;
|
||||
|
@ -234,22 +197,40 @@ static void __init ct_ca9x4_init(void)
|
|||
l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff);
|
||||
#endif
|
||||
|
||||
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ct_ca9x4_amba_devs); i++)
|
||||
amba_device_register(ct_ca9x4_amba_devs[i], &iomem_resource);
|
||||
|
||||
platform_device_register(&pmu_device);
|
||||
}
|
||||
|
||||
MACHINE_START(VEXPRESS, "ARM-Versatile Express CA9x4")
|
||||
.boot_params = PLAT_PHYS_OFFSET + 0x00000100,
|
||||
.map_io = ct_ca9x4_map_io,
|
||||
.init_irq = ct_ca9x4_init_irq,
|
||||
#if 0
|
||||
.timer = &ct_ca9x4_timer,
|
||||
#else
|
||||
.timer = &v2m_timer,
|
||||
#ifdef CONFIG_SMP
|
||||
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
|
||||
.init_machine = ct_ca9x4_init,
|
||||
MACHINE_END
|
||||
|
||||
struct ct_desc ct_ca9x4_desc __initdata = {
|
||||
.id = V2M_CT_ID_CA9,
|
||||
.name = "CA9x4",
|
||||
.map_io = ct_ca9x4_map_io,
|
||||
.init_early = ct_ca9x4_init_early,
|
||||
.init_irq = ct_ca9x4_init_irq,
|
||||
.init_tile = ct_ca9x4_init,
|
||||
#ifdef CONFIG_SMP
|
||||
.init_cpu_map = ct_ca9x4_init_cpu_map,
|
||||
.smp_enable = ct_ca9x4_smp_enable,
|
||||
#endif
|
||||
};
|
||||
|
|
|
@ -45,4 +45,6 @@
|
|||
#define IRQ_CT_CA9X4_PMU_CPU2 94
|
||||
#define IRQ_CT_CA9X4_PMU_CPU3 95
|
||||
|
||||
extern struct ct_desc ct_ca9x4_desc;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -118,4 +118,26 @@
|
|||
int v2m_cfg_write(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
|
||||
|
|
|
@ -10,114 +10,17 @@
|
|||
*/
|
||||
#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 <linux/io.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/smp_scu.h>
|
||||
#include <asm/unified.h>
|
||||
|
||||
#include <mach/ct-ca9x4.h>
|
||||
#include <mach/motherboard.h>
|
||||
#define V2M_PA_CS7 0x10000000
|
||||
|
||||
#include "core.h"
|
||||
|
||||
extern void vexpress_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;
|
||||
}
|
||||
extern void versatile_secondary_startup(void);
|
||||
|
||||
/*
|
||||
* 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)
|
|||
*/
|
||||
void __init smp_init_cpus(void)
|
||||
{
|
||||
void __iomem *scu_base = scu_base_addr();
|
||||
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);
|
||||
ct_desc->init_cpu_map();
|
||||
}
|
||||
|
||||
void __init platform_smp_prepare_cpus(unsigned int max_cpus)
|
||||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Initialise the present map, which describes the set of CPUs
|
||||
* actually populated at the present time.
|
||||
*/
|
||||
for (i = 0; i < max_cpus; i++)
|
||||
set_cpu_present(i, true);
|
||||
|
||||
scu_enable(scu_base_addr());
|
||||
ct_desc->smp_enable(max_cpus);
|
||||
|
||||
/*
|
||||
* Write the address of secondary startup into the
|
||||
|
@ -163,6 +46,6 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
|
|||
* secondary CPU branches to this address.
|
||||
*/
|
||||
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));
|
||||
}
|
||||
|
|
|
@ -7,13 +7,16 @@
|
|||
#include <linux/io.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/ata_platform.h>
|
||||
#include <linux/smsc911x.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/sysdev.h>
|
||||
#include <linux/usb/isp1760.h>
|
||||
#include <linux/clkdev.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/sizes.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/flash.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mach/time.h>
|
||||
|
@ -21,6 +24,7 @@
|
|||
#include <asm/hardware/timer-sp.h>
|
||||
#include <asm/hardware/sp810.h>
|
||||
|
||||
#include <mach/ct-ca9x4.h>
|
||||
#include <mach/motherboard.h>
|
||||
|
||||
#include <plat/sched_clock.h>
|
||||
|
@ -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));
|
||||
iotable_init(tile, num);
|
||||
ct_desc->init_early();
|
||||
versatile_sched_clock_init(MMIO_P2V(V2M_SYS_24MHZ), 24000000);
|
||||
}
|
||||
|
||||
|
||||
static void __init v2m_timer_init(void)
|
||||
{
|
||||
u32 scctrl;
|
||||
|
||||
versatile_sched_clock_init(MMIO_P2V(V2M_SYS_24MHZ), 24000000);
|
||||
|
||||
/* Select 1MHz TIMCLK as the reference clock for SP804 timers */
|
||||
scctrl = readl(MMIO_P2V(V2M_SYSCTL + SCCTRL));
|
||||
scctrl |= SCCTRL_TIMEREN0SEL_TIMCLK;
|
||||
|
@ -68,7 +69,7 @@ static void __init v2m_timer_init(void)
|
|||
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,
|
||||
};
|
||||
|
||||
|
@ -249,6 +250,29 @@ static struct platform_device v2m_flash_device = {
|
|||
.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)
|
||||
{
|
||||
|
@ -354,7 +378,44 @@ static void v2m_restart(char str, const char *cmd)
|
|||
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;
|
||||
|
||||
|
@ -363,6 +424,7 @@ static int __init v2m_init(void)
|
|||
platform_device_register(&v2m_pcie_i2c_device);
|
||||
platform_device_register(&v2m_ddc_i2c_device);
|
||||
platform_device_register(&v2m_flash_device);
|
||||
platform_device_register(&v2m_cf_device);
|
||||
platform_device_register(&v2m_eth_device);
|
||||
platform_device_register(&v2m_usb_device);
|
||||
|
||||
|
@ -372,6 +434,14 @@ static int __init v2m_init(void)
|
|||
pm_power_off = v2m_power_off;
|
||||
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)
|
|||
{
|
||||
int ret = 0;
|
||||
pgd_t *pgd;
|
||||
pud_t *pud;
|
||||
pmd_t *pmd;
|
||||
pte_t *pte;
|
||||
int i = 0;
|
||||
|
@ -156,7 +157,15 @@ static int __init consistent_init(void)
|
|||
|
||||
do {
|
||||
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) {
|
||||
printk(KERN_ERR "%s: no pmd tables\n", __func__);
|
||||
ret = -ENOMEM;
|
||||
|
|
|
@ -95,6 +95,7 @@ static int adjust_pte(struct vm_area_struct *vma, unsigned long address,
|
|||
{
|
||||
spinlock_t *ptl;
|
||||
pgd_t *pgd;
|
||||
pud_t *pud;
|
||||
pmd_t *pmd;
|
||||
pte_t *pte;
|
||||
int ret;
|
||||
|
@ -103,7 +104,11 @@ static int adjust_pte(struct vm_area_struct *vma, unsigned long address,
|
|||
if (pgd_none_or_clear_bad(pgd))
|
||||
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))
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -76,9 +76,11 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
|
|||
|
||||
printk(KERN_ALERT "pgd = %p\n", mm->pgd);
|
||||
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 {
|
||||
pud_t *pud;
|
||||
pmd_t *pmd;
|
||||
pte_t *pte;
|
||||
|
||||
|
@ -90,9 +92,21 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
|
|||
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)
|
||||
printk(", *pmd=%08lx", pmd_val(*pmd));
|
||||
printk(", *pmd=%08llx", (long long)pmd_val(*pmd));
|
||||
|
||||
if (pmd_none(*pmd))
|
||||
break;
|
||||
|
@ -107,8 +121,9 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
|
|||
break;
|
||||
|
||||
pte = pte_offset_map(pmd, addr);
|
||||
printk(", *pte=%08lx", pte_val(*pte));
|
||||
printk(", *ppte=%08lx", pte_val(pte[PTE_HWTABLE_PTRS]));
|
||||
printk(", *pte=%08llx", (long long)pte_val(*pte));
|
||||
printk(", *ppte=%08llx",
|
||||
(long long)pte_val(pte[PTE_HWTABLE_PTRS]));
|
||||
pte_unmap(pte);
|
||||
} while(0);
|
||||
|
||||
|
@ -388,6 +403,7 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
|
|||
{
|
||||
unsigned int index;
|
||||
pgd_t *pgd, *pgd_k;
|
||||
pud_t *pud, *pud_k;
|
||||
pmd_t *pmd, *pmd_k;
|
||||
|
||||
if (addr < TASK_SIZE)
|
||||
|
@ -406,12 +422,19 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
|
|||
|
||||
if (pgd_none(*pgd_k))
|
||||
goto bad_area;
|
||||
|
||||
if (!pgd_present(*pgd))
|
||||
set_pgd(pgd, *pgd_k);
|
||||
|
||||
pmd_k = pmd_offset(pgd_k, addr);
|
||||
pmd = pmd_offset(pgd, addr);
|
||||
pud = pud_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
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
#include <asm/pgalloc.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)
|
||||
{
|
||||
pmd_t *pmd = pmd_offset(pgd, addr);
|
||||
pmd_t *pmd = pmd_offset(pud, addr);
|
||||
|
||||
addr = (addr & PMD_MASK) | prot;
|
||||
pmd[0] = __pmd(addr);
|
||||
|
@ -16,6 +16,18 @@ static void idmap_add_pmd(pgd_t *pgd, unsigned long addr, unsigned long end,
|
|||
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)
|
||||
{
|
||||
unsigned long prot, next;
|
||||
|
@ -27,17 +39,28 @@ void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end)
|
|||
pgd += pgd_index(addr);
|
||||
do {
|
||||
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);
|
||||
}
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
unsigned long next;
|
||||
|
@ -45,7 +68,7 @@ void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end)
|
|||
pgd += pgd_index(addr);
|
||||
do {
|
||||
next = pgd_addr_end(addr, end);
|
||||
idmap_del_pmd(pgd, addr, next);
|
||||
idmap_del_pud(pgd, addr, next);
|
||||
} while (pgd++, addr = next, addr != end);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -350,7 +350,7 @@ void __init bootmem_init(void)
|
|||
*/
|
||||
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
|
||||
|
@ -398,8 +398,8 @@ free_memmap(unsigned long start_pfn, unsigned long end_pfn)
|
|||
* Convert to physical addresses, and
|
||||
* round start upwards and end downwards.
|
||||
*/
|
||||
pg = PAGE_ALIGN(__pa(start_pg));
|
||||
pgend = __pa(end_pg) & PAGE_MASK;
|
||||
pg = (unsigned long)PAGE_ALIGN(__pa(start_pg));
|
||||
pgend = (unsigned long)__pa(end_pg) & PAGE_MASK;
|
||||
|
||||
/*
|
||||
* If there are free pages between these,
|
||||
|
|
|
@ -7,7 +7,7 @@ extern pmd_t *top_pmd;
|
|||
|
||||
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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
BUG_ON(pmd_bad(*pmd));
|
||||
|
@ -551,11 +551,11 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
|
|||
} 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,
|
||||
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
|
||||
|
@ -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,
|
||||
const struct mem_type *type)
|
||||
{
|
||||
|
@ -592,13 +605,13 @@ static void __init create_36bit_mapping(struct map_desc *md,
|
|||
pgd_t *pgd;
|
||||
|
||||
addr = md->virtual;
|
||||
phys = (unsigned long)__pfn_to_phys(md->pfn);
|
||||
phys = __pfn_to_phys(md->pfn);
|
||||
length = PAGE_ALIGN(md->length);
|
||||
|
||||
if (!(cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3())) {
|
||||
printk(KERN_ERR "MM: CPU does not support supersection "
|
||||
"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;
|
||||
}
|
||||
|
||||
|
@ -611,14 +624,14 @@ static void __init create_36bit_mapping(struct map_desc *md,
|
|||
if (type->domain) {
|
||||
printk(KERN_ERR "MM: invalid domain in supersection "
|
||||
"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;
|
||||
}
|
||||
|
||||
if ((addr | length | __pfn_to_phys(md->pfn)) & ~SUPERSECTION_MASK) {
|
||||
printk(KERN_ERR "MM: cannot create mapping for "
|
||||
"0x%08llx at 0x%08lx invalid alignment\n",
|
||||
__pfn_to_phys((u64)md->pfn), addr);
|
||||
printk(KERN_ERR "MM: cannot create mapping for 0x%08llx"
|
||||
" at 0x%08lx invalid alignment\n",
|
||||
(long long)__pfn_to_phys((u64)md->pfn), addr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -631,7 +644,8 @@ static void __init create_36bit_mapping(struct map_desc *md,
|
|||
pgd = pgd_offset_k(addr);
|
||||
end = addr + length;
|
||||
do {
|
||||
pmd_t *pmd = pmd_offset(pgd, addr);
|
||||
pud_t *pud = pud_offset(pgd, addr);
|
||||
pmd_t *pmd = pmd_offset(pud, addr);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
|
@ -652,22 +666,23 @@ static void __init create_36bit_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;
|
||||
pgd_t *pgd;
|
||||
|
||||
if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) {
|
||||
printk(KERN_WARNING "BUG: not creating mapping for "
|
||||
"0x%08llx at 0x%08lx in user region\n",
|
||||
__pfn_to_phys((u64)md->pfn), md->virtual);
|
||||
printk(KERN_WARNING "BUG: not creating mapping for 0x%08llx"
|
||||
" at 0x%08lx in user region\n",
|
||||
(long long)__pfn_to_phys((u64)md->pfn), md->virtual);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((md->type == MT_DEVICE || md->type == MT_ROM) &&
|
||||
md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) {
|
||||
printk(KERN_WARNING "BUG: mapping for 0x%08llx at 0x%08lx "
|
||||
"overlaps vmalloc space\n",
|
||||
__pfn_to_phys((u64)md->pfn), md->virtual);
|
||||
printk(KERN_WARNING "BUG: mapping for 0x%08llx"
|
||||
" at 0x%08lx overlaps vmalloc space\n",
|
||||
(long long)__pfn_to_phys((u64)md->pfn), md->virtual);
|
||||
}
|
||||
|
||||
type = &mem_types[md->type];
|
||||
|
@ -681,13 +696,13 @@ static void __init create_mapping(struct map_desc *md)
|
|||
}
|
||||
|
||||
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));
|
||||
|
||||
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",
|
||||
__pfn_to_phys(md->pfn), addr);
|
||||
(long long)__pfn_to_phys(md->pfn), addr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -696,7 +711,7 @@ static void __init create_mapping(struct map_desc *md)
|
|||
do {
|
||||
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;
|
||||
addr = next;
|
||||
|
@ -794,9 +809,10 @@ static void __init sanity_check_meminfo(void)
|
|||
*/
|
||||
if (__va(bank->start) >= vmalloc_min ||
|
||||
__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",
|
||||
bank->start, bank->start + bank->size - 1);
|
||||
(unsigned long long)bank->start,
|
||||
(unsigned long long)bank->start + bank->size - 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -807,10 +823,11 @@ static void __init sanity_check_meminfo(void)
|
|||
if (__va(bank->start + bank->size) > vmalloc_min ||
|
||||
__va(bank->start + bank->size) < __va(bank->start)) {
|
||||
unsigned long newsize = vmalloc_min - __va(bank->start);
|
||||
printk(KERN_NOTICE "Truncating RAM at %.8lx-%.8lx "
|
||||
"to -%.8lx (vmalloc region overlap).\n",
|
||||
bank->start, bank->start + bank->size - 1,
|
||||
bank->start + newsize - 1);
|
||||
printk(KERN_NOTICE "Truncating RAM at %.8llx-%.8llx "
|
||||
"to -%.8llx (vmalloc region overlap).\n",
|
||||
(unsigned long long)bank->start,
|
||||
(unsigned long long)bank->start + bank->size - 1,
|
||||
(unsigned long long)bank->start + newsize - 1);
|
||||
bank->size = newsize;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
pgd_t *pgd_alloc(struct mm_struct *mm)
|
||||
{
|
||||
pgd_t *new_pgd, *init_pgd;
|
||||
pud_t *new_pud, *init_pud;
|
||||
pmd_t *new_pmd, *init_pmd;
|
||||
pte_t *new_pte, *init_pte;
|
||||
|
||||
|
@ -46,7 +47,11 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
|
|||
* On ARM, first page must always be allocated since it
|
||||
* 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)
|
||||
goto no_pmd;
|
||||
|
||||
|
@ -54,7 +59,8 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
|
|||
if (!new_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);
|
||||
set_pte_ext(new_pte, *init_pte, 0);
|
||||
pte_unmap(init_pte);
|
||||
|
@ -66,6 +72,8 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
|
|||
no_pte:
|
||||
pmd_free(mm, new_pmd);
|
||||
no_pmd:
|
||||
pud_free(mm, new_pud);
|
||||
no_pud:
|
||||
free_pages((unsigned long)new_pgd, 2);
|
||||
no_pgd:
|
||||
return NULL;
|
||||
|
@ -74,6 +82,7 @@ no_pgd:
|
|||
void pgd_free(struct mm_struct *mm, pgd_t *pgd_base)
|
||||
{
|
||||
pgd_t *pgd;
|
||||
pud_t *pud;
|
||||
pmd_t *pmd;
|
||||
pgtable_t pte;
|
||||
|
||||
|
@ -84,7 +93,11 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd_base)
|
|||
if (pgd_none_or_clear_bad(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))
|
||||
goto no_pmd;
|
||||
|
||||
|
@ -92,8 +105,11 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd_base)
|
|||
pmd_clear(pmd);
|
||||
pte_free(mm, pte);
|
||||
no_pmd:
|
||||
pgd_clear(pgd);
|
||||
pud_clear(pud);
|
||||
pmd_free(mm, pmd);
|
||||
no_pud:
|
||||
pgd_clear(pgd);
|
||||
pud_free(mm, pud);
|
||||
no_pgd:
|
||||
free_pages((unsigned long) pgd_base, 2);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
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
|
|
@ -1,8 +1,7 @@
|
|||
obj-y := clock.o
|
||||
ifneq ($(CONFIG_ARCH_INTEGRATOR),y)
|
||||
obj-y += sched-clock.o
|
||||
endif
|
||||
ifeq ($(CONFIG_LEDS_CLASS),y)
|
||||
obj-$(CONFIG_ARCH_REALVIEW) += leds.o
|
||||
obj-$(CONFIG_ARCH_VERSATILE) += leds.o
|
||||
endif
|
||||
obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
|
||||
obj-$(CONFIG_PLAT_VERSATILE_CLCD) += clcd.o
|
||||
obj-$(CONFIG_PLAT_VERSATILE_FPGA_IRQ) += fpga-irq.o
|
||||
obj-$(CONFIG_PLAT_VERSATILE_LEDS) += leds.o
|
||||
obj-$(CONFIG_PLAT_VERSATILE_SCHED_CLOCK) += sched-clock.o
|
||||
obj-$(CONFIG_SMP) += headsmp.o platsmp.o
|
||||
|
|
|
@ -0,0 +1,182 @@
|
|||
#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);
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* linux/arch/arm/mach-vexpress/headsmp.S
|
||||
* linux/arch/arm/plat-versatile/headsmp.S
|
||||
*
|
||||
* Copyright (c) 2003 ARM Limited
|
||||
* All Rights Reserved
|
||||
|
@ -14,11 +14,11 @@
|
|||
__INIT
|
||||
|
||||
/*
|
||||
* Versatile Express specific entry point for secondary CPUs. This
|
||||
* provides a "holding pen" into which all secondary cores are held
|
||||
* Realview/Versatile Express 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(vexpress_secondary_startup)
|
||||
ENTRY(versatile_secondary_startup)
|
||||
mrc p15, 0, r0, c0, c0, 5
|
||||
and r0, r0, #15
|
||||
adr r4, 1f
|
|
@ -0,0 +1,9 @@
|
|||
#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
|
|
@ -0,0 +1,12 @@
|
|||
#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
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* linux/arch/arm/mach-vexpress/localtimer.c
|
||||
* linux/arch/arm/plat-versatile/localtimer.c
|
||||
*
|
||||
* Copyright (C) 2002 ARM Ltd.
|
||||
* All Rights Reserved
|
||||
|
@ -19,8 +19,9 @@
|
|||
/*
|
||||
* 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;
|
||||
twd_timer_setup(evt);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -120,8 +120,23 @@ static void clcdfb_enable(struct clcd_fb *fb, u32 cntl)
|
|||
static int
|
||||
clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var)
|
||||
{
|
||||
u32 caps;
|
||||
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));
|
||||
|
||||
var->red.msb_right = 0;
|
||||
|
@ -133,6 +148,13 @@ clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var)
|
|||
case 2:
|
||||
case 4:
|
||||
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.offset = 0;
|
||||
var->green.length = var->bits_per_pixel;
|
||||
|
@ -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.offset = 0;
|
||||
break;
|
||||
|
||||
case 16:
|
||||
var->red.length = 5;
|
||||
var->blue.length = 5;
|
||||
/*
|
||||
* Green length can be 5 or 6 depending whether
|
||||
* we're operating in RGB555 or RGB565 mode.
|
||||
*/
|
||||
if (var->green.length != 5 && var->green.length != 6)
|
||||
var->green.length = 6;
|
||||
break;
|
||||
case 32:
|
||||
if (fb->panel->cntl & CNTL_LCDTFT) {
|
||||
var->red.length = 8;
|
||||
var->green.length = 8;
|
||||
var->blue.length = 8;
|
||||
/* If we can't do 444, 5551 or 565, reject */
|
||||
if (!(caps & (CLCD_CAP_444 | CLCD_CAP_5551 | CLCD_CAP_565))) {
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Green length can be 4, 5 or 6 depending whether
|
||||
* we're operating in 444, 5551 or 565 mode.
|
||||
*/
|
||||
if (var->green.length == 4 && caps & CLCD_CAP_444)
|
||||
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;
|
||||
case 32:
|
||||
/* If we can't do 888, reject */
|
||||
caps &= CLCD_CAP_888;
|
||||
if (!caps) {
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
var->red.length = 8;
|
||||
var->green.length = 8;
|
||||
var->blue.length = 8;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
|
@ -168,7 +228,20 @@ clcdfb_set_bitfields(struct clcd_fb *fb, struct fb_var_screeninfo *var)
|
|||
* the bitfield length defined above.
|
||||
*/
|
||||
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->green.offset = var->blue.offset + var->blue.length;
|
||||
var->red.offset = var->green.offset + var->green.length;
|
||||
|
@ -443,8 +516,8 @@ static int clcdfb_register(struct clcd_fb *fb)
|
|||
|
||||
fb_set_var(&fb->fb, &fb->fb.var);
|
||||
|
||||
printk(KERN_INFO "CLCD: %s hardware, %s display\n",
|
||||
fb->board->name, fb->panel->mode.name);
|
||||
dev_info(&fb->dev->dev, "%s hardware, %s display\n",
|
||||
fb->board->name, fb->panel->mode.name);
|
||||
|
||||
ret = register_framebuffer(&fb->fb);
|
||||
if (ret == 0)
|
||||
|
@ -486,6 +559,10 @@ static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id)
|
|||
fb->dev = dev;
|
||||
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);
|
||||
if (ret)
|
||||
goto free_fb;
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#define CNTL_LCDBPP8 (3 << 1)
|
||||
#define CNTL_LCDBPP16 (4 << 1)
|
||||
#define CNTL_LCDBPP16_565 (6 << 1)
|
||||
#define CNTL_LCDBPP16_444 (7 << 1)
|
||||
#define CNTL_LCDBPP24 (5 << 1)
|
||||
#define CNTL_LCDBW (1 << 4)
|
||||
#define CNTL_LCDTFT (1 << 5)
|
||||
|
@ -66,6 +67,32 @@
|
|||
#define CNTL_LDMAFIFOTIME (1 << 15)
|
||||
#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 fb_videomode mode;
|
||||
signed short width; /* width in mm */
|
||||
|
@ -73,6 +100,7 @@ struct clcd_panel {
|
|||
u32 tim2;
|
||||
u32 tim3;
|
||||
u32 cntl;
|
||||
u32 caps;
|
||||
unsigned int bpp:8,
|
||||
fixedtimings:1,
|
||||
grayscale:1;
|
||||
|
@ -96,6 +124,11 @@ struct clcd_fb;
|
|||
struct clcd_board {
|
||||
const char *name;
|
||||
|
||||
/*
|
||||
* Optional. Hardware capability flags.
|
||||
*/
|
||||
u32 caps;
|
||||
|
||||
/*
|
||||
* Optional. Check whether the var structure is acceptable
|
||||
* for this display.
|
||||
|
@ -155,34 +188,35 @@ struct clcd_fb {
|
|||
|
||||
static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs)
|
||||
{
|
||||
struct fb_var_screeninfo *var = &fb->fb.var;
|
||||
u32 val, cpl;
|
||||
|
||||
/*
|
||||
* Program the CLCD controller registers and start the CLCD
|
||||
*/
|
||||
val = ((fb->fb.var.xres / 16) - 1) << 2;
|
||||
val |= (fb->fb.var.hsync_len - 1) << 8;
|
||||
val |= (fb->fb.var.right_margin - 1) << 16;
|
||||
val |= (fb->fb.var.left_margin - 1) << 24;
|
||||
val = ((var->xres / 16) - 1) << 2;
|
||||
val |= (var->hsync_len - 1) << 8;
|
||||
val |= (var->right_margin - 1) << 16;
|
||||
val |= (var->left_margin - 1) << 24;
|
||||
regs->tim0 = val;
|
||||
|
||||
val = fb->fb.var.yres;
|
||||
val = var->yres;
|
||||
if (fb->panel->cntl & CNTL_LCDDUAL)
|
||||
val /= 2;
|
||||
val -= 1;
|
||||
val |= (fb->fb.var.vsync_len - 1) << 10;
|
||||
val |= fb->fb.var.lower_margin << 16;
|
||||
val |= fb->fb.var.upper_margin << 24;
|
||||
val |= (var->vsync_len - 1) << 10;
|
||||
val |= var->lower_margin << 16;
|
||||
val |= var->upper_margin << 24;
|
||||
regs->tim1 = val;
|
||||
|
||||
val = fb->panel->tim2;
|
||||
val |= fb->fb.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_HOR_HIGH_ACT ? 0 : TIM2_IHS;
|
||||
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 */
|
||||
/* / 1 */;
|
||||
else if (!fb->fb.var.grayscale) /* STN color */
|
||||
else if (!var->grayscale) /* STN color */
|
||||
cpl = cpl * 8 / 3;
|
||||
else if (fb->panel->cntl & CNTL_LCDMONO8) /* STN monochrome, 8bit */
|
||||
cpl /= 8;
|
||||
|
@ -194,10 +228,22 @@ static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs)
|
|||
regs->tim3 = fb->panel->tim3;
|
||||
|
||||
val = fb->panel->cntl;
|
||||
if (fb->fb.var.grayscale)
|
||||
if (var->grayscale)
|
||||
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:
|
||||
val |= CNTL_LCDBPP1;
|
||||
break;
|
||||
|
@ -212,15 +258,17 @@ static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs)
|
|||
break;
|
||||
case 16:
|
||||
/*
|
||||
* PL110 cannot choose between 5551 and 565 modes in
|
||||
* its control register
|
||||
* PL110 cannot choose between 5551 and 565 modes in its
|
||||
* 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;
|
||||
else if (fb->fb.var.green.length == 5)
|
||||
val |= CNTL_LCDBPP16;
|
||||
else
|
||||
else if (var->green.length == 6)
|
||||
val |= CNTL_LCDBPP16_565;
|
||||
else
|
||||
val |= CNTL_LCDBPP16_444;
|
||||
break;
|
||||
case 32:
|
||||
val |= CNTL_LCDBPP24;
|
||||
|
@ -228,7 +276,7 @@ static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs)
|
|||
}
|
||||
|
||||
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)
|
||||
|
|
Loading…
Reference in New Issue