forked from Minki/linux
[ARM] Merge AT91 and devel branches
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
commit
e9ccb79927
@ -740,7 +740,7 @@ config XIP_PHYS_ADDR
|
||||
|
||||
endmenu
|
||||
|
||||
if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP)
|
||||
if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX )
|
||||
|
||||
menu "CPU Frequency scaling"
|
||||
|
||||
@ -767,6 +767,15 @@ config CPU_FREQ_INTEGRATOR
|
||||
|
||||
If in doubt, say Y.
|
||||
|
||||
config CPU_FREQ_IMX
|
||||
tristate "CPUfreq driver for i.MX CPUs"
|
||||
depends on ARCH_IMX && CPU_FREQ
|
||||
default n
|
||||
help
|
||||
This enables the CPUfreq driver for i.MX CPUs.
|
||||
|
||||
If in doubt, say N.
|
||||
|
||||
endmenu
|
||||
|
||||
endif
|
||||
@ -945,6 +954,8 @@ source "drivers/video/Kconfig"
|
||||
|
||||
source "sound/Kconfig"
|
||||
|
||||
source "drivers/hid/Kconfig"
|
||||
|
||||
source "drivers/usb/Kconfig"
|
||||
|
||||
source "drivers/mmc/Kconfig"
|
||||
|
@ -331,6 +331,19 @@
|
||||
CALL(sys_mbind)
|
||||
/* 320 */ CALL(sys_get_mempolicy)
|
||||
CALL(sys_set_mempolicy)
|
||||
CALL(sys_openat)
|
||||
CALL(sys_mkdirat)
|
||||
CALL(sys_mknodat)
|
||||
/* 325 */ CALL(sys_fchownat)
|
||||
CALL(sys_futimesat)
|
||||
CALL(sys_fstatat64)
|
||||
CALL(sys_unlinkat)
|
||||
CALL(sys_renameat)
|
||||
/* 330 */ CALL(sys_linkat)
|
||||
CALL(sys_symlinkat)
|
||||
CALL(sys_readlinkat)
|
||||
CALL(sys_fchmodat)
|
||||
CALL(sys_faccessat)
|
||||
#ifndef syscalls_counted
|
||||
.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
|
||||
#define syscalls_counted
|
||||
|
@ -22,30 +22,31 @@
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
#define KERNEL_RAM_ADDR (PAGE_OFFSET + TEXT_OFFSET)
|
||||
#define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET)
|
||||
#define KERNEL_RAM_PADDR (PHYS_OFFSET + TEXT_OFFSET)
|
||||
|
||||
/*
|
||||
* swapper_pg_dir is the virtual address of the initial page table.
|
||||
* We place the page tables 16K below KERNEL_RAM_ADDR. Therefore, we must
|
||||
* make sure that KERNEL_RAM_ADDR is correctly set. Currently, we expect
|
||||
* We place the page tables 16K below KERNEL_RAM_VADDR. Therefore, we must
|
||||
* make sure that KERNEL_RAM_VADDR is correctly set. Currently, we expect
|
||||
* the least significant 16 bits to be 0x8000, but we could probably
|
||||
* relax this restriction to KERNEL_RAM_ADDR >= PAGE_OFFSET + 0x4000.
|
||||
* relax this restriction to KERNEL_RAM_VADDR >= PAGE_OFFSET + 0x4000.
|
||||
*/
|
||||
#if (KERNEL_RAM_ADDR & 0xffff) != 0x8000
|
||||
#error KERNEL_RAM_ADDR must start at 0xXXXX8000
|
||||
#if (KERNEL_RAM_VADDR & 0xffff) != 0x8000
|
||||
#error KERNEL_RAM_VADDR must start at 0xXXXX8000
|
||||
#endif
|
||||
|
||||
.globl swapper_pg_dir
|
||||
.equ swapper_pg_dir, KERNEL_RAM_ADDR - 0x4000
|
||||
.equ swapper_pg_dir, KERNEL_RAM_VADDR - 0x4000
|
||||
|
||||
.macro pgtbl, rd
|
||||
ldr \rd, =(__virt_to_phys(KERNEL_RAM_ADDR - 0x4000))
|
||||
ldr \rd, =(KERNEL_RAM_PADDR - 0x4000)
|
||||
.endm
|
||||
|
||||
#ifdef CONFIG_XIP_KERNEL
|
||||
#define TEXTADDR XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
|
||||
#else
|
||||
#define TEXTADDR KERNEL_RAM_ADDR
|
||||
#define TEXTADDR KERNEL_RAM_VADDR
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -354,9 +354,6 @@ static void __init setup_processor(void)
|
||||
#ifndef CONFIG_ARM_THUMB
|
||||
elf_hwcap &= ~HWCAP_THUMB;
|
||||
#endif
|
||||
#ifndef CONFIG_VFP
|
||||
elf_hwcap &= ~HWCAP_VFP;
|
||||
#endif
|
||||
|
||||
cpu_proc_init();
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/arch/at91sam9260.h>
|
||||
#include <asm/arch/at91sam926x_mc.h>
|
||||
#include <asm/arch/at91sam9260_matrix.h>
|
||||
|
||||
#include "generic.h"
|
||||
|
||||
|
@ -119,6 +119,7 @@ static struct spi_board_info ek_spi_devices[] = {
|
||||
* MACB Ethernet device
|
||||
*/
|
||||
static struct __initdata eth_platform_data ek_macb_data = {
|
||||
.phy_irq_pin = AT91_PIN_PA7,
|
||||
.is_rmii = 1,
|
||||
};
|
||||
|
||||
|
@ -9,6 +9,8 @@
|
||||
|
||||
obj-y += irq.o time.o dma.o generic.o
|
||||
|
||||
obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o
|
||||
|
||||
# Specific board support
|
||||
obj-$(CONFIG_ARCH_MX1ADS) += mx1ads.o
|
||||
|
||||
|
287
arch/arm/mach-imx/cpufreq.c
Normal file
287
arch/arm/mach-imx/cpufreq.c
Normal file
@ -0,0 +1,287 @@
|
||||
/*
|
||||
* cpu.c: clock scaling for the iMX
|
||||
*
|
||||
* Copyright (C) 2000 2001, The Delft University of Technology
|
||||
* Copyright (c) 2004 Sascha Hauer <sascha@saschahauer.de>
|
||||
* Copyright (C) 2006 Inky Lung <ilung@cwlinux.com>
|
||||
* Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com>
|
||||
*
|
||||
* Based on SA1100 version written by:
|
||||
* - Johan Pouwelse (J.A.Pouwelse@its.tudelft.nl): initial version
|
||||
* - Erik Mouw (J.A.K.Mouw@its.tudelft.nl):
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/*#define DEBUG*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
|
||||
#include "generic.h"
|
||||
|
||||
#ifndef __val2mfld
|
||||
#define __val2mfld(mask,val) (((mask)&~((mask)<<1))*(val)&(mask))
|
||||
#endif
|
||||
#ifndef __mfld2val
|
||||
#define __mfld2val(mask,val) (((val)&(mask))/((mask)&~((mask)<<1)))
|
||||
#endif
|
||||
|
||||
#define CR_920T_CLOCK_MODE 0xC0000000
|
||||
#define CR_920T_FASTBUS_MODE 0x00000000
|
||||
#define CR_920T_ASYNC_MODE 0xC0000000
|
||||
|
||||
static u32 mpctl0_at_boot;
|
||||
|
||||
static void imx_set_async_mode(void)
|
||||
{
|
||||
adjust_cr(CR_920T_CLOCK_MODE, CR_920T_ASYNC_MODE);
|
||||
}
|
||||
|
||||
static void imx_set_fastbus_mode(void)
|
||||
{
|
||||
adjust_cr(CR_920T_CLOCK_MODE, CR_920T_FASTBUS_MODE);
|
||||
}
|
||||
|
||||
static void imx_set_mpctl0(u32 mpctl0)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (mpctl0 == 0) {
|
||||
local_irq_save(flags);
|
||||
CSCR &= ~CSCR_MPEN;
|
||||
local_irq_restore(flags);
|
||||
return;
|
||||
}
|
||||
|
||||
local_irq_save(flags);
|
||||
MPCTL0 = mpctl0;
|
||||
CSCR |= CSCR_MPEN;
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* imx_compute_mpctl - compute new PLL parameters
|
||||
* @new_mpctl: pointer to location assigned by new PLL control register value
|
||||
* @cur_mpctl: current PLL control register parameters
|
||||
* @freq: required frequency in Hz
|
||||
* @relation: is one of %CPUFREQ_RELATION_L (supremum)
|
||||
* and %CPUFREQ_RELATION_H (infimum)
|
||||
*/
|
||||
long imx_compute_mpctl(u32 *new_mpctl, u32 cur_mpctl, unsigned long freq, int relation)
|
||||
{
|
||||
u32 f_ref = (CSCR & CSCR_SYSTEM_SEL) ? 16000000 : (CLK32 * 512);
|
||||
u32 mfi;
|
||||
u32 mfn;
|
||||
u32 mfd;
|
||||
u32 pd;
|
||||
unsigned long long ll;
|
||||
long l;
|
||||
long quot;
|
||||
|
||||
/* Fdppl=2*Fref*(MFI+MFN/(MFD+1))/(PD+1) */
|
||||
/* PD=<0,15>, MFD=<1,1023>, MFI=<5,15> MFN=<0,1022> */
|
||||
|
||||
if (cur_mpctl) {
|
||||
mfd = ((cur_mpctl >> 16) & 0x3ff) + 1;
|
||||
pd = ((cur_mpctl >> 26) & 0xf) + 1;
|
||||
} else {
|
||||
pd=2; mfd=313;
|
||||
}
|
||||
|
||||
/* pd=2; mfd=313; mfi=8; mfn=183; */
|
||||
/* (MFI+MFN/(MFD)) = Fdppl / (2*Fref) * (PD); */
|
||||
|
||||
quot = (f_ref + (1 << 9)) >> 10;
|
||||
l = (freq * pd + quot) / (2 * quot);
|
||||
mfi = l >> 10;
|
||||
mfn = ((l & ((1 << 10) - 1)) * mfd + (1 << 9)) >> 10;
|
||||
|
||||
mfd -= 1;
|
||||
pd -= 1;
|
||||
|
||||
*new_mpctl = ((mfi & 0xf) << 10) | (mfn & 0x3ff) | ((mfd & 0x3ff) << 16)
|
||||
| ((pd & 0xf) << 26);
|
||||
|
||||
ll = 2 * (unsigned long long)f_ref * ( (mfi<<16) + (mfn<<16) / (mfd+1) );
|
||||
quot = (pd+1) * (1<<16);
|
||||
ll += quot / 2;
|
||||
do_div(ll, quot);
|
||||
freq = ll;
|
||||
|
||||
pr_debug(KERN_DEBUG "imx: new PLL parameters pd=%d mfd=%d mfi=%d mfn=%d, freq=%ld\n",
|
||||
pd, mfd, mfi, mfn, freq);
|
||||
|
||||
return freq;
|
||||
}
|
||||
|
||||
|
||||
static int imx_verify_speed(struct cpufreq_policy *policy)
|
||||
{
|
||||
if (policy->cpu != 0)
|
||||
return -EINVAL;
|
||||
|
||||
cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, policy->cpuinfo.max_freq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int imx_get_speed(unsigned int cpu)
|
||||
{
|
||||
unsigned int freq;
|
||||
unsigned int cr;
|
||||
unsigned int cscr;
|
||||
unsigned int bclk_div;
|
||||
|
||||
if (cpu)
|
||||
return 0;
|
||||
|
||||
cscr = CSCR;
|
||||
bclk_div = __mfld2val(CSCR_BCLK_DIV, cscr) + 1;
|
||||
cr = get_cr();
|
||||
|
||||
if((cr & CR_920T_CLOCK_MODE) == CR_920T_FASTBUS_MODE) {
|
||||
freq = imx_get_system_clk();
|
||||
freq = (freq + bclk_div/2) / bclk_div;
|
||||
} else {
|
||||
freq = imx_get_mcu_clk();
|
||||
if (cscr & CSCR_MPU_PRESC)
|
||||
freq /= 2;
|
||||
}
|
||||
|
||||
freq = (freq + 500) / 1000;
|
||||
|
||||
return freq;
|
||||
}
|
||||
|
||||
static int imx_set_target(struct cpufreq_policy *policy,
|
||||
unsigned int target_freq,
|
||||
unsigned int relation)
|
||||
{
|
||||
struct cpufreq_freqs freqs;
|
||||
u32 mpctl0 = 0;
|
||||
u32 cscr;
|
||||
unsigned long flags;
|
||||
long freq;
|
||||
long sysclk;
|
||||
unsigned int bclk_div = 1;
|
||||
|
||||
freq = target_freq * 1000;
|
||||
|
||||
pr_debug(KERN_DEBUG "imx: requested frequency %ld Hz, mpctl0 at boot 0x%08x\n",
|
||||
freq, mpctl0_at_boot);
|
||||
|
||||
sysclk = imx_get_system_clk();
|
||||
|
||||
if (freq > sysclk + 1000000) {
|
||||
freq = imx_compute_mpctl(&mpctl0, mpctl0_at_boot, freq, relation);
|
||||
if (freq < 0) {
|
||||
printk(KERN_WARNING "imx: target frequency %ld Hz cannot be set\n", freq);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
if(freq + 1000 < sysclk) {
|
||||
if (relation == CPUFREQ_RELATION_L)
|
||||
bclk_div = (sysclk - 1000) / freq;
|
||||
else
|
||||
bclk_div = (sysclk + freq + 1000) / freq;
|
||||
|
||||
if(bclk_div > 16)
|
||||
bclk_div = 16;
|
||||
}
|
||||
freq = (sysclk + bclk_div / 2) / bclk_div;
|
||||
}
|
||||
|
||||
freqs.old = imx_get_speed(0);
|
||||
freqs.new = (freq + 500) / 1000;
|
||||
freqs.cpu = 0;
|
||||
freqs.flags = 0;
|
||||
|
||||
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
imx_set_fastbus_mode();
|
||||
|
||||
imx_set_mpctl0(mpctl0);
|
||||
|
||||
cscr = CSCR;
|
||||
cscr &= ~CSCR_BCLK_DIV;
|
||||
cscr |= __val2mfld(CSCR_BCLK_DIV, bclk_div - 1);
|
||||
CSCR = cscr;
|
||||
|
||||
if(mpctl0) {
|
||||
CSCR |= CSCR_MPLL_RESTART;
|
||||
|
||||
/* Wait until MPLL is stablized */
|
||||
while( CSCR & CSCR_MPLL_RESTART );
|
||||
|
||||
imx_set_async_mode();
|
||||
}
|
||||
|
||||
local_irq_restore(flags);
|
||||
|
||||
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
|
||||
|
||||
pr_debug(KERN_INFO "imx: set frequency %ld Hz, running from %s\n",
|
||||
freq, mpctl0? "MPLL": "SPLL");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init imx_cpufreq_driver_init(struct cpufreq_policy *policy)
|
||||
{
|
||||
printk(KERN_INFO "i.MX cpu freq change driver v1.0\n");
|
||||
|
||||
if (policy->cpu != 0)
|
||||
return -EINVAL;
|
||||
|
||||
policy->cur = policy->min = policy->max = imx_get_speed(0);
|
||||
policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
|
||||
policy->cpuinfo.min_freq = 8000;
|
||||
policy->cpuinfo.max_freq = 200000;
|
||||
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cpufreq_driver imx_driver = {
|
||||
.flags = CPUFREQ_STICKY,
|
||||
.verify = imx_verify_speed,
|
||||
.target = imx_set_target,
|
||||
.get = imx_get_speed,
|
||||
.init = imx_cpufreq_driver_init,
|
||||
.name = "imx",
|
||||
};
|
||||
|
||||
static int __init imx_cpufreq_init(void)
|
||||
{
|
||||
|
||||
mpctl0_at_boot = 0;
|
||||
|
||||
if((CSCR & CSCR_MPEN) &&
|
||||
((get_cr() & CR_920T_CLOCK_MODE) != CR_920T_FASTBUS_MODE))
|
||||
mpctl0_at_boot = MPCTL0;
|
||||
|
||||
return cpufreq_register_driver(&imx_driver);
|
||||
}
|
||||
|
||||
arch_initcall(imx_cpufreq_init);
|
||||
|
@ -19,21 +19,14 @@
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/clocksource.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/mach/time.h>
|
||||
#include <asm/arch/netx-regs.h>
|
||||
|
||||
/*
|
||||
* Returns number of us since last clock interrupt. Note that interrupts
|
||||
* will have been disabled by do_gettimeoffset()
|
||||
*/
|
||||
static unsigned long netx_gettimeoffset(void)
|
||||
{
|
||||
return readl(NETX_GPIO_COUNTER_CURRENT(0)) / 100;
|
||||
}
|
||||
|
||||
/*
|
||||
* IRQ handler for the timer
|
||||
*/
|
||||
@ -43,6 +36,7 @@ netx_timer_interrupt(int irq, void *dev_id)
|
||||
write_seqlock(&xtime_lock);
|
||||
|
||||
timer_tick();
|
||||
|
||||
write_sequnlock(&xtime_lock);
|
||||
|
||||
/* acknowledge interrupt */
|
||||
@ -51,13 +45,26 @@ netx_timer_interrupt(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
||||
static struct irqaction netx_timer_irq = {
|
||||
.name = "NetX Timer Tick",
|
||||
.flags = IRQF_DISABLED | IRQF_TIMER,
|
||||
.handler = netx_timer_interrupt,
|
||||
};
|
||||
|
||||
cycle_t netx_get_cycles(void)
|
||||
{
|
||||
return readl(NETX_GPIO_COUNTER_CURRENT(1));
|
||||
}
|
||||
|
||||
static struct clocksource clocksource_netx = {
|
||||
.name = "netx_timer",
|
||||
.rating = 200,
|
||||
.read = netx_get_cycles,
|
||||
.mask = CLOCKSOURCE_MASK(32),
|
||||
.shift = 20,
|
||||
.is_continuous = 1,
|
||||
};
|
||||
|
||||
/*
|
||||
* Set up timer interrupt
|
||||
*/
|
||||
@ -80,9 +87,20 @@ static void __init netx_timer_init(void)
|
||||
NETX_GPIO_COUNTER_CTRL(0));
|
||||
|
||||
setup_irq(NETX_IRQ_TIMER0, &netx_timer_irq);
|
||||
|
||||
/* Setup timer one for clocksource */
|
||||
writel(0, NETX_GPIO_COUNTER_CTRL(1));
|
||||
writel(0, NETX_GPIO_COUNTER_CURRENT(1));
|
||||
writel(0xFFFFFFFF, NETX_GPIO_COUNTER_MAX(1));
|
||||
|
||||
writel(NETX_GPIO_COUNTER_CTRL_RUN,
|
||||
NETX_GPIO_COUNTER_CTRL(1));
|
||||
|
||||
clocksource_netx.mult =
|
||||
clocksource_hz2mult(CLOCK_TICK_RATE, clocksource_netx.shift);
|
||||
clocksource_register(&clocksource_netx);
|
||||
}
|
||||
|
||||
struct sys_timer netx_timer = {
|
||||
.init = netx_timer_init,
|
||||
.offset = netx_gettimeoffset,
|
||||
.init = netx_timer_init,
|
||||
};
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <linux/signal.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/clocksource.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/hardware.h>
|
||||
@ -48,27 +49,6 @@ static int pxa_set_rtc(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* IRQs are disabled before entering here from do_gettimeofday() */
|
||||
static unsigned long pxa_gettimeoffset (void)
|
||||
{
|
||||
long ticks_to_match, elapsed, usec;
|
||||
|
||||
/* Get ticks before next timer match */
|
||||
ticks_to_match = OSMR0 - OSCR;
|
||||
|
||||
/* We need elapsed ticks since last match */
|
||||
elapsed = LATCH - ticks_to_match;
|
||||
|
||||
/* don't get fooled by the workaround in pxa_timer_interrupt() */
|
||||
if (elapsed <= 0)
|
||||
return 0;
|
||||
|
||||
/* Now convert them to usec */
|
||||
usec = (unsigned long)(elapsed * (tick_nsec / 1000))/LATCH;
|
||||
|
||||
return usec;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NO_IDLE_HZ
|
||||
static unsigned long initial_match;
|
||||
static int match_posponed;
|
||||
@ -121,6 +101,20 @@ static struct irqaction pxa_timer_irq = {
|
||||
.handler = pxa_timer_interrupt,
|
||||
};
|
||||
|
||||
cycle_t pxa_get_cycles(void)
|
||||
{
|
||||
return OSCR;
|
||||
}
|
||||
|
||||
static struct clocksource clocksource_pxa = {
|
||||
.name = "pxa_timer",
|
||||
.rating = 200,
|
||||
.read = pxa_get_cycles,
|
||||
.mask = CLOCKSOURCE_MASK(32),
|
||||
.shift = 20,
|
||||
.is_continuous = 1,
|
||||
};
|
||||
|
||||
static void __init pxa_timer_init(void)
|
||||
{
|
||||
struct timespec tv;
|
||||
@ -139,6 +133,14 @@ static void __init pxa_timer_init(void)
|
||||
OIER = OIER_E0; /* enable match on timer 0 to cause interrupts */
|
||||
OSMR0 = OSCR + LATCH; /* set initial match */
|
||||
local_irq_restore(flags);
|
||||
|
||||
/* on PXA OSCR runs continiously and is not written to, so we can use it
|
||||
* as clock source directly.
|
||||
*/
|
||||
clocksource_pxa.mult =
|
||||
clocksource_hz2mult(CLOCK_TICK_RATE, clocksource_pxa.shift);
|
||||
clocksource_register(&clocksource_pxa);
|
||||
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NO_IDLE_HZ
|
||||
@ -211,7 +213,6 @@ struct sys_timer pxa_timer = {
|
||||
.init = pxa_timer_init,
|
||||
.suspend = pxa_timer_suspend,
|
||||
.resume = pxa_timer_resume,
|
||||
.offset = pxa_gettimeoffset,
|
||||
#ifdef CONFIG_NO_IDLE_HZ
|
||||
.dyn_tick = &pxa_dyn_tick,
|
||||
#endif
|
||||
|
@ -393,10 +393,6 @@ static struct pxafb_mach_info sharp_lcd = {
|
||||
.pxafb_backlight_power = board_backlight_power,
|
||||
};
|
||||
|
||||
static void __init trizeps4_fixup(struct machine_desc *desc, struct tag *tags, char **cmdline, struct meminfo *mi)
|
||||
{
|
||||
}
|
||||
|
||||
static void __init trizeps4_init(void)
|
||||
{
|
||||
platform_add_devices(trizeps4_devices, ARRAY_SIZE(trizeps4_devices));
|
||||
@ -469,7 +465,6 @@ MACHINE_START(TRIZEPS4, "Keith und Koep Trizeps IV module")
|
||||
.phys_io = 0x40000000,
|
||||
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
|
||||
.boot_params = TRIZEPS4_SDRAM_BASE + 0x100,
|
||||
.fixup = trizeps4_fixup,
|
||||
.init_machine = trizeps4_init,
|
||||
.map_io = trizeps4_map_io,
|
||||
.init_irq = pxa_init_irq,
|
||||
|
@ -1,5 +1,15 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-sa1100/jornada720.c
|
||||
*
|
||||
* HP Jornada720 init code
|
||||
*
|
||||
* Copyright (C) 2006 Filip Zyzniewski <filip.zyzniewski@tefnet.pl>
|
||||
* Copyright (C) 2005 Michael Gernoth <michael@gernoth.net>
|
||||
*
|
||||
* 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>
|
||||
@ -10,13 +20,13 @@
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <video/s1d13xxxfb.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/hardware/sa1111.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/setup.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/flash.h>
|
||||
#include <asm/mach/map.h>
|
||||
@ -24,13 +34,170 @@
|
||||
|
||||
#include "generic.h"
|
||||
|
||||
/*
|
||||
* HP Documentation referred in this file:
|
||||
* http://www.jlime.com/downloads/development/docs/jornada7xx/jornada720.txt
|
||||
*/
|
||||
|
||||
#define JORTUCR_VAL 0x20000400
|
||||
/* line 110 of HP's doc */
|
||||
#define TUCR_VAL 0x20000400
|
||||
|
||||
/* memory space (line 52 of HP's doc) */
|
||||
#define SA1111REGSTART 0x40000000
|
||||
#define SA1111REGLEN 0x00001fff
|
||||
#define EPSONREGSTART 0x48000000
|
||||
#define EPSONREGLEN 0x00100000
|
||||
#define EPSONFBSTART 0x48200000
|
||||
/* 512kB framebuffer */
|
||||
#define EPSONFBLEN 512*1024
|
||||
|
||||
static struct s1d13xxxfb_regval s1d13xxxfb_initregs[] = {
|
||||
/* line 344 of HP's doc */
|
||||
{0x0001,0x00}, // Miscellaneous Register
|
||||
{0x01FC,0x00}, // Display Mode Register
|
||||
{0x0004,0x00}, // General IO Pins Configuration Register 0
|
||||
{0x0005,0x00}, // General IO Pins Configuration Register 1
|
||||
{0x0008,0x00}, // General IO Pins Control Register 0
|
||||
{0x0009,0x00}, // General IO Pins Control Register 1
|
||||
{0x0010,0x01}, // Memory Clock Configuration Register
|
||||
{0x0014,0x11}, // LCD Pixel Clock Configuration Register
|
||||
{0x0018,0x01}, // CRT/TV Pixel Clock Configuration Register
|
||||
{0x001C,0x01}, // MediaPlug Clock Configuration Register
|
||||
{0x001E,0x01}, // CPU To Memory Wait State Select Register
|
||||
{0x0020,0x00}, // Memory Configuration Register
|
||||
{0x0021,0x45}, // DRAM Refresh Rate Register
|
||||
{0x002A,0x01}, // DRAM Timings Control Register 0
|
||||
{0x002B,0x03}, // DRAM Timings Control Register 1
|
||||
{0x0030,0x1c}, // Panel Type Register
|
||||
{0x0031,0x00}, // MOD Rate Register
|
||||
{0x0032,0x4F}, // LCD Horizontal Display Width Register
|
||||
{0x0034,0x07}, // LCD Horizontal Non-Display Period Register
|
||||
{0x0035,0x01}, // TFT FPLINE Start Position Register
|
||||
{0x0036,0x0B}, // TFT FPLINE Pulse Width Register
|
||||
{0x0038,0xEF}, // LCD Vertical Display Height Register 0
|
||||
{0x0039,0x00}, // LCD Vertical Display Height Register 1
|
||||
{0x003A,0x13}, // LCD Vertical Non-Display Period Register
|
||||
{0x003B,0x0B}, // TFT FPFRAME Start Position Register
|
||||
{0x003C,0x01}, // TFT FPFRAME Pulse Width Register
|
||||
{0x0040,0x05}, // LCD Display Mode Register (2:4bpp,3:8bpp,5:16bpp)
|
||||
{0x0041,0x00}, // LCD Miscellaneous Register
|
||||
{0x0042,0x00}, // LCD Display Start Address Register 0
|
||||
{0x0043,0x00}, // LCD Display Start Address Register 1
|
||||
{0x0044,0x00}, // LCD Display Start Address Register 2
|
||||
{0x0046,0x80}, // LCD Memory Address Offset Register 0
|
||||
{0x0047,0x02}, // LCD Memory Address Offset Register 1
|
||||
{0x0048,0x00}, // LCD Pixel Panning Register
|
||||
{0x004A,0x00}, // LCD Display FIFO High Threshold Control Register
|
||||
{0x004B,0x00}, // LCD Display FIFO Low Threshold Control Register
|
||||
{0x0050,0x4F}, // CRT/TV Horizontal Display Width Register
|
||||
{0x0052,0x13}, // CRT/TV Horizontal Non-Display Period Register
|
||||
{0x0053,0x01}, // CRT/TV HRTC Start Position Register
|
||||
{0x0054,0x0B}, // CRT/TV HRTC Pulse Width Register
|
||||
{0x0056,0xDF}, // CRT/TV Vertical Display Height Register 0
|
||||
{0x0057,0x01}, // CRT/TV Vertical Display Height Register 1
|
||||
{0x0058,0x2B}, // CRT/TV Vertical Non-Display Period Register
|
||||
{0x0059,0x09}, // CRT/TV VRTC Start Position Register
|
||||
{0x005A,0x01}, // CRT/TV VRTC Pulse Width Register
|
||||
{0x005B,0x10}, // TV Output Control Register
|
||||
{0x0060,0x03}, // CRT/TV Display Mode Register (2:4bpp,3:8bpp,5:16bpp)
|
||||
{0x0062,0x00}, // CRT/TV Display Start Address Register 0
|
||||
{0x0063,0x00}, // CRT/TV Display Start Address Register 1
|
||||
{0x0064,0x00}, // CRT/TV Display Start Address Register 2
|
||||
{0x0066,0x40}, // CRT/TV Memory Address Offset Register 0
|
||||
{0x0067,0x01}, // CRT/TV Memory Address Offset Register 1
|
||||
{0x0068,0x00}, // CRT/TV Pixel Panning Register
|
||||
{0x006A,0x00}, // CRT/TV Display FIFO High Threshold Control Register
|
||||
{0x006B,0x00}, // CRT/TV Display FIFO Low Threshold Control Register
|
||||
{0x0070,0x00}, // LCD Ink/Cursor Control Register
|
||||
{0x0071,0x01}, // LCD Ink/Cursor Start Address Register
|
||||
{0x0072,0x00}, // LCD Cursor X Position Register 0
|
||||
{0x0073,0x00}, // LCD Cursor X Position Register 1
|
||||
{0x0074,0x00}, // LCD Cursor Y Position Register 0
|
||||
{0x0075,0x00}, // LCD Cursor Y Position Register 1
|
||||
{0x0076,0x00}, // LCD Ink/Cursor Blue Color 0 Register
|
||||
{0x0077,0x00}, // LCD Ink/Cursor Green Color 0 Register
|
||||
{0x0078,0x00}, // LCD Ink/Cursor Red Color 0 Register
|
||||
{0x007A,0x1F}, // LCD Ink/Cursor Blue Color 1 Register
|
||||
{0x007B,0x3F}, // LCD Ink/Cursor Green Color 1 Register
|
||||
{0x007C,0x1F}, // LCD Ink/Cursor Red Color 1 Register
|
||||
{0x007E,0x00}, // LCD Ink/Cursor FIFO Threshold Register
|
||||
{0x0080,0x00}, // CRT/TV Ink/Cursor Control Register
|
||||
{0x0081,0x01}, // CRT/TV Ink/Cursor Start Address Register
|
||||
{0x0082,0x00}, // CRT/TV Cursor X Position Register 0
|
||||
{0x0083,0x00}, // CRT/TV Cursor X Position Register 1
|
||||
{0x0084,0x00}, // CRT/TV Cursor Y Position Register 0
|
||||
{0x0085,0x00}, // CRT/TV Cursor Y Position Register 1
|
||||
{0x0086,0x00}, // CRT/TV Ink/Cursor Blue Color 0 Register
|
||||
{0x0087,0x00}, // CRT/TV Ink/Cursor Green Color 0 Register
|
||||
{0x0088,0x00}, // CRT/TV Ink/Cursor Red Color 0 Register
|
||||
{0x008A,0x1F}, // CRT/TV Ink/Cursor Blue Color 1 Register
|
||||
{0x008B,0x3F}, // CRT/TV Ink/Cursor Green Color 1 Register
|
||||
{0x008C,0x1F}, // CRT/TV Ink/Cursor Red Color 1 Register
|
||||
{0x008E,0x00}, // CRT/TV Ink/Cursor FIFO Threshold Register
|
||||
{0x0100,0x00}, // BitBlt Control Register 0
|
||||
{0x0101,0x00}, // BitBlt Control Register 1
|
||||
{0x0102,0x00}, // BitBlt ROP Code/Color Expansion Register
|
||||
{0x0103,0x00}, // BitBlt Operation Register
|
||||
{0x0104,0x00}, // BitBlt Source Start Address Register 0
|
||||
{0x0105,0x00}, // BitBlt Source Start Address Register 1
|
||||
{0x0106,0x00}, // BitBlt Source Start Address Register 2
|
||||
{0x0108,0x00}, // BitBlt Destination Start Address Register 0
|
||||
{0x0109,0x00}, // BitBlt Destination Start Address Register 1
|
||||
{0x010A,0x00}, // BitBlt Destination Start Address Register 2
|
||||
{0x010C,0x00}, // BitBlt Memory Address Offset Register 0
|
||||
{0x010D,0x00}, // BitBlt Memory Address Offset Register 1
|
||||
{0x0110,0x00}, // BitBlt Width Register 0
|
||||
{0x0111,0x00}, // BitBlt Width Register 1
|
||||
{0x0112,0x00}, // BitBlt Height Register 0
|
||||
{0x0113,0x00}, // BitBlt Height Register 1
|
||||
{0x0114,0x00}, // BitBlt Background Color Register 0
|
||||
{0x0115,0x00}, // BitBlt Background Color Register 1
|
||||
{0x0118,0x00}, // BitBlt Foreground Color Register 0
|
||||
{0x0119,0x00}, // BitBlt Foreground Color Register 1
|
||||
{0x01E0,0x00}, // Look-Up Table Mode Register
|
||||
{0x01E2,0x00}, // Look-Up Table Address Register
|
||||
/* not sure, wouldn't like to mess with the driver */
|
||||
{0x01E4,0x00}, // Look-Up Table Data Register
|
||||
/* jornada doc says 0x00, but I trust the driver */
|
||||
{0x01F0,0x10}, // Power Save Configuration Register
|
||||
{0x01F1,0x00}, // Power Save Status Register
|
||||
{0x01F4,0x00}, // CPU-to-Memory Access Watchdog Timer Register
|
||||
{0x01FC,0x01}, // Display Mode Register(0x01:LCD, 0x02:CRT, 0x03:LCD&CRT)
|
||||
};
|
||||
|
||||
static struct s1d13xxxfb_pdata s1d13xxxfb_data = {
|
||||
.initregs = s1d13xxxfb_initregs,
|
||||
.initregssize = ARRAY_SIZE(s1d13xxxfb_initregs),
|
||||
.platform_init_video = NULL
|
||||
};
|
||||
|
||||
static struct resource s1d13xxxfb_resources[] = {
|
||||
[0] = {
|
||||
.start = EPSONFBSTART,
|
||||
.end = EPSONFBSTART + EPSONFBLEN,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = EPSONREGSTART,
|
||||
.end = EPSONREGSTART + EPSONREGLEN,
|
||||
.flags = IORESOURCE_MEM,
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device s1d13xxxfb_device = {
|
||||
.name = S1D_DEVICENAME,
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &s1d13xxxfb_data,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(s1d13xxxfb_resources),
|
||||
.resource = s1d13xxxfb_resources,
|
||||
};
|
||||
|
||||
static struct resource sa1111_resources[] = {
|
||||
[0] = {
|
||||
.start = 0x40000000,
|
||||
.end = 0x40001fff,
|
||||
.start = SA1111REGSTART,
|
||||
.end = SA1111REGSTART + SA1111REGLEN,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
@ -53,18 +220,32 @@ static struct platform_device sa1111_device = {
|
||||
.resource = sa1111_resources,
|
||||
};
|
||||
|
||||
static struct platform_device jornada720_mcu_device = {
|
||||
.name = "jornada720_mcu",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static struct platform_device *devices[] __initdata = {
|
||||
&sa1111_device,
|
||||
&jornada720_mcu_device,
|
||||
&s1d13xxxfb_device,
|
||||
};
|
||||
|
||||
/* a stub for now, we theoretically cannot suspend without a flashboard */
|
||||
int pm_suspend(suspend_state_t state)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int __init jornada720_init(void)
|
||||
{
|
||||
int ret = -ENODEV;
|
||||
|
||||
if (machine_is_jornada720()) {
|
||||
GPDR |= GPIO_GPIO20;
|
||||
TUCR = JORTUCR_VAL; /* set the oscillator out to the SA-1101 */
|
||||
|
||||
/* oscillator setup (line 116 of HP's doc) */
|
||||
TUCR = TUCR_VAL;
|
||||
/* resetting SA1111 (line 118 of HP's doc) */
|
||||
GPSR = GPIO_GPIO20;
|
||||
udelay(1);
|
||||
GPCR = GPIO_GPIO20;
|
||||
@ -72,10 +253,6 @@ static int __init jornada720_init(void)
|
||||
GPSR = GPIO_GPIO20;
|
||||
udelay(20);
|
||||
|
||||
/* LDD4 is speaker, LDD3 is microphone */
|
||||
PPSR &= ~(PPC_LDD3 | PPC_LDD4);
|
||||
PPDR |= PPC_LDD3 | PPC_LDD4;
|
||||
|
||||
ret = platform_add_devices(devices, ARRAY_SIZE(devices));
|
||||
}
|
||||
return ret;
|
||||
@ -85,19 +262,19 @@ arch_initcall(jornada720_init);
|
||||
|
||||
static struct map_desc jornada720_io_desc[] __initdata = {
|
||||
{ /* Epson registers */
|
||||
.virtual = 0xf0000000,
|
||||
.pfn = __phys_to_pfn(0x48000000),
|
||||
.length = 0x00100000,
|
||||
.virtual = 0xf0000000,
|
||||
.pfn = __phys_to_pfn(EPSONREGSTART),
|
||||
.length = EPSONREGLEN,
|
||||
.type = MT_DEVICE
|
||||
}, { /* Epson frame buffer */
|
||||
.virtual = 0xf1000000,
|
||||
.pfn = __phys_to_pfn(0x48200000),
|
||||
.length = 0x00100000,
|
||||
.virtual = 0xf1000000,
|
||||
.pfn = __phys_to_pfn(EPSONFBSTART),
|
||||
.length = EPSONFBLEN,
|
||||
.type = MT_DEVICE
|
||||
}, { /* SA-1111 */
|
||||
.virtual = 0xf4000000,
|
||||
.pfn = __phys_to_pfn(0x40000000),
|
||||
.length = 0x00100000,
|
||||
.virtual = 0xf4000000,
|
||||
.pfn = __phys_to_pfn(SA1111REGSTART),
|
||||
.length = SA1111REGLEN,
|
||||
.type = MT_DEVICE
|
||||
}
|
||||
};
|
||||
@ -116,7 +293,7 @@ static struct mtd_partition jornada720_partitions[] = {
|
||||
.name = "JORNADA720 boot firmware",
|
||||
.size = 0x00040000,
|
||||
.offset = 0,
|
||||
.mask_flags = MTD_WRITEABLE, /* force read-only */
|
||||
.mask_flags = MTD_WRITEABLE, /* force read-only */
|
||||
}, {
|
||||
.name = "JORNADA720 kernel",
|
||||
.size = 0x000c0000,
|
||||
@ -139,7 +316,7 @@ static struct mtd_partition jornada720_partitions[] = {
|
||||
.offset = 0x00540000,
|
||||
}, {
|
||||
.name = "JORNADA720 usr local",
|
||||
.size = 0, /* will expand to the end of the flash */
|
||||
.size = 0, /* will expand to the end of the flash */
|
||||
.offset = 0x00d00000,
|
||||
}
|
||||
};
|
||||
@ -147,10 +324,12 @@ static struct mtd_partition jornada720_partitions[] = {
|
||||
static void jornada720_set_vpp(int vpp)
|
||||
{
|
||||
if (vpp)
|
||||
PPSR |= 0x80;
|
||||
/* enabling flash write (line 470 of HP's doc) */
|
||||
PPSR |= PPC_LDD7;
|
||||
else
|
||||
PPSR &= ~0x80;
|
||||
PPDR |= 0x80;
|
||||
/* disabling flash write (line 470 of HP's doc) */
|
||||
PPSR &= ~PPC_LDD7;
|
||||
PPDR |= PPC_LDD7;
|
||||
}
|
||||
|
||||
static struct flash_platform_data jornada720_flash_data = {
|
||||
|
@ -238,7 +238,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
|
||||
* x86 does not mark the pages reserved...
|
||||
*/
|
||||
SetPageReserved(page);
|
||||
set_pte(pte, mk_pte(page, prot));
|
||||
set_pte_ext(pte, mk_pte(page, prot), 0);
|
||||
page++;
|
||||
pte++;
|
||||
off++;
|
||||
|
@ -71,7 +71,7 @@ void v4_mc_copy_user_page(void *kto, const void *kfrom, unsigned long vaddr)
|
||||
{
|
||||
spin_lock(&minicache_lock);
|
||||
|
||||
set_pte(TOP_PTE(0xffff8000), pfn_pte(__pa(kfrom) >> PAGE_SHIFT, minicache_pgprot));
|
||||
set_pte_ext(TOP_PTE(0xffff8000), pfn_pte(__pa(kfrom) >> PAGE_SHIFT, minicache_pgprot), 0);
|
||||
flush_tlb_kernel_page(0xffff8000);
|
||||
|
||||
mc_copy_user_page((void *)0xffff8000, kto);
|
||||
|
@ -70,8 +70,8 @@ static void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned lo
|
||||
*/
|
||||
spin_lock(&v6_lock);
|
||||
|
||||
set_pte(TOP_PTE(from_address) + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, PAGE_KERNEL));
|
||||
set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, PAGE_KERNEL));
|
||||
set_pte_ext(TOP_PTE(from_address) + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, PAGE_KERNEL), 0);
|
||||
set_pte_ext(TOP_PTE(to_address) + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, PAGE_KERNEL), 0);
|
||||
|
||||
from = from_address + (offset << PAGE_SHIFT);
|
||||
to = to_address + (offset << PAGE_SHIFT);
|
||||
@ -110,7 +110,7 @@ static void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr)
|
||||
*/
|
||||
spin_lock(&v6_lock);
|
||||
|
||||
set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, PAGE_KERNEL));
|
||||
set_pte_ext(TOP_PTE(to_address) + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, PAGE_KERNEL), 0);
|
||||
flush_tlb_kernel_page(to);
|
||||
clear_page((void *)to);
|
||||
|
||||
|
@ -93,7 +93,7 @@ void xscale_mc_copy_user_page(void *kto, const void *kfrom, unsigned long vaddr)
|
||||
{
|
||||
spin_lock(&minicache_lock);
|
||||
|
||||
set_pte(TOP_PTE(COPYPAGE_MINICACHE), pfn_pte(__pa(kfrom) >> PAGE_SHIFT, minicache_pgprot));
|
||||
set_pte_ext(TOP_PTE(COPYPAGE_MINICACHE), pfn_pte(__pa(kfrom) >> PAGE_SHIFT, minicache_pgprot), 0);
|
||||
flush_tlb_kernel_page(COPYPAGE_MINICACHE);
|
||||
|
||||
mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto);
|
||||
|
@ -61,7 +61,7 @@ static int adjust_pte(struct vm_area_struct *vma, unsigned long address)
|
||||
if (pte_present(entry) && pte_val(entry) & shared_pte_mask) {
|
||||
flush_cache_page(vma, address, pte_pfn(entry));
|
||||
pte_val(entry) &= ~shared_pte_mask;
|
||||
set_pte(pte, entry);
|
||||
set_pte_at(vma->vm_mm, address, pte, entry);
|
||||
flush_tlb_page(vma, address);
|
||||
ret = 1;
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)
|
||||
unsigned long to = ALIAS_FLUSH_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT);
|
||||
const int zero = 0;
|
||||
|
||||
set_pte(TOP_PTE(to), pfn_pte(pfn, PAGE_KERNEL));
|
||||
set_pte_ext(TOP_PTE(to), pfn_pte(pfn, PAGE_KERNEL), 0);
|
||||
flush_tlb_kernel_page(to);
|
||||
|
||||
asm( "mcrr p15, 0, %1, %0, c14\n"
|
||||
|
@ -38,89 +38,71 @@
|
||||
*/
|
||||
#define VM_ARM_SECTION_MAPPING 0x80000000
|
||||
|
||||
static inline void
|
||||
remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
|
||||
unsigned long phys_addr, pgprot_t pgprot)
|
||||
static int remap_area_pte(pmd_t *pmd, unsigned long addr, unsigned long end,
|
||||
unsigned long phys_addr, pgprot_t prot)
|
||||
{
|
||||
unsigned long end;
|
||||
pte_t *pte;
|
||||
|
||||
pte = pte_alloc_kernel(pmd, addr);
|
||||
if (!pte)
|
||||
return -ENOMEM;
|
||||
|
||||
address &= ~PMD_MASK;
|
||||
end = address + size;
|
||||
if (end > PMD_SIZE)
|
||||
end = PMD_SIZE;
|
||||
BUG_ON(address >= end);
|
||||
do {
|
||||
if (!pte_none(*pte))
|
||||
goto bad;
|
||||
|
||||
set_pte(pte, pfn_pte(phys_addr >> PAGE_SHIFT, pgprot));
|
||||
address += PAGE_SIZE;
|
||||
set_pte_ext(pte, pfn_pte(phys_addr >> PAGE_SHIFT, prot), 0);
|
||||
phys_addr += PAGE_SIZE;
|
||||
pte++;
|
||||
} while (address && (address < end));
|
||||
return;
|
||||
} while (pte++, addr += PAGE_SIZE, addr != end);
|
||||
return 0;
|
||||
|
||||
bad:
|
||||
printk("remap_area_pte: page already exists\n");
|
||||
printk(KERN_CRIT "remap_area_pte: page already exists\n");
|
||||
BUG();
|
||||
}
|
||||
|
||||
static inline int
|
||||
remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
|
||||
unsigned long phys_addr, unsigned long flags)
|
||||
static inline int remap_area_pmd(pgd_t *pgd, unsigned long addr,
|
||||
unsigned long end, unsigned long phys_addr,
|
||||
pgprot_t prot)
|
||||
{
|
||||
unsigned long end;
|
||||
pgprot_t pgprot;
|
||||
unsigned long next;
|
||||
pmd_t *pmd;
|
||||
int ret = 0;
|
||||
|
||||
address &= ~PGDIR_MASK;
|
||||
end = address + size;
|
||||
pmd = pmd_alloc(&init_mm, pgd, addr);
|
||||
if (!pmd)
|
||||
return -ENOMEM;
|
||||
|
||||
if (end > PGDIR_SIZE)
|
||||
end = PGDIR_SIZE;
|
||||
|
||||
phys_addr -= address;
|
||||
BUG_ON(address >= end);
|
||||
|
||||
pgprot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_WRITE | flags);
|
||||
do {
|
||||
pte_t * pte = pte_alloc_kernel(pmd, address);
|
||||
if (!pte)
|
||||
return -ENOMEM;
|
||||
remap_area_pte(pte, address, end - address, address + phys_addr, pgprot);
|
||||
address = (address + PMD_SIZE) & PMD_MASK;
|
||||
pmd++;
|
||||
} while (address && (address < end));
|
||||
return 0;
|
||||
next = pmd_addr_end(addr, end);
|
||||
ret = remap_area_pte(pmd, addr, next, phys_addr, prot);
|
||||
if (ret)
|
||||
return ret;
|
||||
phys_addr += next - addr;
|
||||
} while (pmd++, addr = next, addr != end);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
remap_area_pages(unsigned long start, unsigned long pfn,
|
||||
unsigned long size, unsigned long flags)
|
||||
static int remap_area_pages(unsigned long start, unsigned long pfn,
|
||||
unsigned long size, unsigned long flags)
|
||||
{
|
||||
unsigned long address = start;
|
||||
unsigned long end = start + size;
|
||||
unsigned long addr = start;
|
||||
unsigned long next, end = start + size;
|
||||
unsigned long phys_addr = __pfn_to_phys(pfn);
|
||||
pgprot_t prot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG |
|
||||
L_PTE_DIRTY | L_PTE_WRITE | flags);
|
||||
pgd_t *pgd;
|
||||
int err = 0;
|
||||
pgd_t * dir;
|
||||
|
||||
phys_addr -= address;
|
||||
dir = pgd_offset(&init_mm, address);
|
||||
BUG_ON(address >= end);
|
||||
BUG_ON(addr >= end);
|
||||
pgd = pgd_offset_k(addr);
|
||||
do {
|
||||
pmd_t *pmd = pmd_alloc(&init_mm, dir, address);
|
||||
if (!pmd) {
|
||||
err = -ENOMEM;
|
||||
next = pgd_addr_end(addr, end);
|
||||
err = remap_area_pmd(pgd, addr, next, phys_addr, prot);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
if (remap_area_pmd(pmd, address, end - address,
|
||||
phys_addr + address, flags)) {
|
||||
err = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
|
||||
address = (address + PGDIR_SIZE) & PGDIR_MASK;
|
||||
dir++;
|
||||
} while (address && (address < end));
|
||||
phys_addr += next - addr;
|
||||
} while (pgd++, addr = next, addr != end);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -294,12 +294,6 @@ static void __init build_mem_type_table(void)
|
||||
mem_types[MT_DEVICE].prot_pte |= L_PTE_BUFFERABLE;
|
||||
mem_types[MT_DEVICE].prot_sect |= PMD_SECT_BUFFERED;
|
||||
|
||||
/*
|
||||
* User pages need to be mapped with the ASID
|
||||
* (iow, non-global)
|
||||
*/
|
||||
user_pgprot |= L_PTE_ASID;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/*
|
||||
* Mark memory with the "shared" attribute for SMP systems
|
||||
@ -408,7 +402,7 @@ alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pg
|
||||
}
|
||||
ptep = pte_offset_kernel(pmdp, virt);
|
||||
|
||||
set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot));
|
||||
set_pte_ext(ptep, pfn_pte(phys >> PAGE_SHIFT, prot), 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -57,7 +57,7 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
|
||||
|
||||
init_pmd = pmd_offset(init_pgd, 0);
|
||||
init_pte = pte_offset_map_nested(init_pmd, 0);
|
||||
set_pte(new_pte, *init_pte);
|
||||
set_pte_ext(new_pte, *init_pte, 0);
|
||||
pte_unmap_nested(init_pte);
|
||||
pte_unmap(new_pte);
|
||||
}
|
||||
|
@ -397,7 +397,7 @@ ENTRY(cpu_arm1020_switch_mm)
|
||||
* Set a PTE and flush it out
|
||||
*/
|
||||
.align 5
|
||||
ENTRY(cpu_arm1020_set_pte)
|
||||
ENTRY(cpu_arm1020_set_pte_ext)
|
||||
#ifdef CONFIG_MMU
|
||||
str r1, [r0], #-2048 @ linux version
|
||||
|
||||
@ -477,7 +477,7 @@ arm1020_processor_functions:
|
||||
.word cpu_arm1020_do_idle
|
||||
.word cpu_arm1020_dcache_clean_area
|
||||
.word cpu_arm1020_switch_mm
|
||||
.word cpu_arm1020_set_pte
|
||||
.word cpu_arm1020_set_pte_ext
|
||||
.size arm1020_processor_functions, . - arm1020_processor_functions
|
||||
|
||||
.section ".rodata"
|
||||
|
@ -381,7 +381,7 @@ ENTRY(cpu_arm1020e_switch_mm)
|
||||
* Set a PTE and flush it out
|
||||
*/
|
||||
.align 5
|
||||
ENTRY(cpu_arm1020e_set_pte)
|
||||
ENTRY(cpu_arm1020e_set_pte_ext)
|
||||
#ifdef CONFIG_MMU
|
||||
str r1, [r0], #-2048 @ linux version
|
||||
|
||||
@ -458,7 +458,7 @@ arm1020e_processor_functions:
|
||||
.word cpu_arm1020e_do_idle
|
||||
.word cpu_arm1020e_dcache_clean_area
|
||||
.word cpu_arm1020e_switch_mm
|
||||
.word cpu_arm1020e_set_pte
|
||||
.word cpu_arm1020e_set_pte_ext
|
||||
.size arm1020e_processor_functions, . - arm1020e_processor_functions
|
||||
|
||||
.section ".rodata"
|
||||
|
@ -358,12 +358,12 @@ ENTRY(cpu_arm1022_switch_mm)
|
||||
mov pc, lr
|
||||
|
||||
/*
|
||||
* cpu_arm1022_set_pte(ptep, pte)
|
||||
* cpu_arm1022_set_pte_ext(ptep, pte, ext)
|
||||
*
|
||||
* Set a PTE and flush it out
|
||||
*/
|
||||
.align 5
|
||||
ENTRY(cpu_arm1022_set_pte)
|
||||
ENTRY(cpu_arm1022_set_pte_ext)
|
||||
#ifdef CONFIG_MMU
|
||||
str r1, [r0], #-2048 @ linux version
|
||||
|
||||
@ -441,7 +441,7 @@ arm1022_processor_functions:
|
||||
.word cpu_arm1022_do_idle
|
||||
.word cpu_arm1022_dcache_clean_area
|
||||
.word cpu_arm1022_switch_mm
|
||||
.word cpu_arm1022_set_pte
|
||||
.word cpu_arm1022_set_pte_ext
|
||||
.size arm1022_processor_functions, . - arm1022_processor_functions
|
||||
|
||||
.section ".rodata"
|
||||
|
@ -347,12 +347,12 @@ ENTRY(cpu_arm1026_switch_mm)
|
||||
mov pc, lr
|
||||
|
||||
/*
|
||||
* cpu_arm1026_set_pte(ptep, pte)
|
||||
* cpu_arm1026_set_pte_ext(ptep, pte, ext)
|
||||
*
|
||||
* Set a PTE and flush it out
|
||||
*/
|
||||
.align 5
|
||||
ENTRY(cpu_arm1026_set_pte)
|
||||
ENTRY(cpu_arm1026_set_pte_ext)
|
||||
#ifdef CONFIG_MMU
|
||||
str r1, [r0], #-2048 @ linux version
|
||||
|
||||
@ -436,7 +436,7 @@ arm1026_processor_functions:
|
||||
.word cpu_arm1026_do_idle
|
||||
.word cpu_arm1026_dcache_clean_area
|
||||
.word cpu_arm1026_switch_mm
|
||||
.word cpu_arm1026_set_pte
|
||||
.word cpu_arm1026_set_pte_ext
|
||||
.size arm1026_processor_functions, . - arm1026_processor_functions
|
||||
|
||||
.section .rodata
|
||||
|
@ -209,14 +209,14 @@ ENTRY(cpu_arm7_switch_mm)
|
||||
mov pc, lr
|
||||
|
||||
/*
|
||||
* Function: arm6_7_set_pte(pte_t *ptep, pte_t pte)
|
||||
* Function: arm6_7_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext)
|
||||
* Params : r0 = Address to set
|
||||
* : r1 = value to set
|
||||
* Purpose : Set a PTE and flush it out of any WB cache
|
||||
*/
|
||||
.align 5
|
||||
ENTRY(cpu_arm6_set_pte)
|
||||
ENTRY(cpu_arm7_set_pte)
|
||||
ENTRY(cpu_arm6_set_pte_ext)
|
||||
ENTRY(cpu_arm7_set_pte_ext)
|
||||
#ifdef CONFIG_MMU
|
||||
str r1, [r0], #-2048 @ linux version
|
||||
|
||||
@ -299,7 +299,7 @@ ENTRY(arm6_processor_functions)
|
||||
.word cpu_arm6_do_idle
|
||||
.word cpu_arm6_dcache_clean_area
|
||||
.word cpu_arm6_switch_mm
|
||||
.word cpu_arm6_set_pte
|
||||
.word cpu_arm6_set_pte_ext
|
||||
.size arm6_processor_functions, . - arm6_processor_functions
|
||||
|
||||
/*
|
||||
@ -315,7 +315,7 @@ ENTRY(arm7_processor_functions)
|
||||
.word cpu_arm7_do_idle
|
||||
.word cpu_arm7_dcache_clean_area
|
||||
.word cpu_arm7_switch_mm
|
||||
.word cpu_arm7_set_pte
|
||||
.word cpu_arm7_set_pte_ext
|
||||
.size arm7_processor_functions, . - arm7_processor_functions
|
||||
|
||||
.section ".rodata"
|
||||
|
@ -88,13 +88,13 @@ ENTRY(cpu_arm720_switch_mm)
|
||||
mov pc, lr
|
||||
|
||||
/*
|
||||
* Function: arm720_set_pte(pte_t *ptep, pte_t pte)
|
||||
* Function: arm720_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext)
|
||||
* Params : r0 = Address to set
|
||||
* : r1 = value to set
|
||||
* Purpose : Set a PTE and flush it out of any WB cache
|
||||
*/
|
||||
.align 5
|
||||
ENTRY(cpu_arm720_set_pte)
|
||||
ENTRY(cpu_arm720_set_pte_ext)
|
||||
#ifdef CONFIG_MMU
|
||||
str r1, [r0], #-2048 @ linux version
|
||||
|
||||
@ -204,7 +204,7 @@ ENTRY(arm720_processor_functions)
|
||||
.word cpu_arm720_do_idle
|
||||
.word cpu_arm720_dcache_clean_area
|
||||
.word cpu_arm720_switch_mm
|
||||
.word cpu_arm720_set_pte
|
||||
.word cpu_arm720_set_pte_ext
|
||||
.size arm720_processor_functions, . - arm720_processor_functions
|
||||
|
||||
.section ".rodata"
|
||||
|
@ -344,12 +344,12 @@ ENTRY(cpu_arm920_switch_mm)
|
||||
mov pc, lr
|
||||
|
||||
/*
|
||||
* cpu_arm920_set_pte(ptep, pte)
|
||||
* cpu_arm920_set_pte(ptep, pte, ext)
|
||||
*
|
||||
* Set a PTE and flush it out
|
||||
*/
|
||||
.align 5
|
||||
ENTRY(cpu_arm920_set_pte)
|
||||
ENTRY(cpu_arm920_set_pte_ext)
|
||||
#ifdef CONFIG_MMU
|
||||
str r1, [r0], #-2048 @ linux version
|
||||
|
||||
@ -423,7 +423,7 @@ arm920_processor_functions:
|
||||
.word cpu_arm920_do_idle
|
||||
.word cpu_arm920_dcache_clean_area
|
||||
.word cpu_arm920_switch_mm
|
||||
.word cpu_arm920_set_pte
|
||||
.word cpu_arm920_set_pte_ext
|
||||
.size arm920_processor_functions, . - arm920_processor_functions
|
||||
|
||||
.section ".rodata"
|
||||
|
@ -348,12 +348,12 @@ ENTRY(cpu_arm922_switch_mm)
|
||||
mov pc, lr
|
||||
|
||||
/*
|
||||
* cpu_arm922_set_pte(ptep, pte)
|
||||
* cpu_arm922_set_pte_ext(ptep, pte, ext)
|
||||
*
|
||||
* Set a PTE and flush it out
|
||||
*/
|
||||
.align 5
|
||||
ENTRY(cpu_arm922_set_pte)
|
||||
ENTRY(cpu_arm922_set_pte_ext)
|
||||
#ifdef CONFIG_MMU
|
||||
str r1, [r0], #-2048 @ linux version
|
||||
|
||||
@ -427,7 +427,7 @@ arm922_processor_functions:
|
||||
.word cpu_arm922_do_idle
|
||||
.word cpu_arm922_dcache_clean_area
|
||||
.word cpu_arm922_switch_mm
|
||||
.word cpu_arm922_set_pte
|
||||
.word cpu_arm922_set_pte_ext
|
||||
.size arm922_processor_functions, . - arm922_processor_functions
|
||||
|
||||
.section ".rodata"
|
||||
|
@ -391,12 +391,12 @@ ENTRY(cpu_arm925_switch_mm)
|
||||
mov pc, lr
|
||||
|
||||
/*
|
||||
* cpu_arm925_set_pte(ptep, pte)
|
||||
* cpu_arm925_set_pte_ext(ptep, pte, ext)
|
||||
*
|
||||
* Set a PTE and flush it out
|
||||
*/
|
||||
.align 5
|
||||
ENTRY(cpu_arm925_set_pte)
|
||||
ENTRY(cpu_arm925_set_pte_ext)
|
||||
#ifdef CONFIG_MMU
|
||||
str r1, [r0], #-2048 @ linux version
|
||||
|
||||
@ -490,7 +490,7 @@ arm925_processor_functions:
|
||||
.word cpu_arm925_do_idle
|
||||
.word cpu_arm925_dcache_clean_area
|
||||
.word cpu_arm925_switch_mm
|
||||
.word cpu_arm925_set_pte
|
||||
.word cpu_arm925_set_pte_ext
|
||||
.size arm925_processor_functions, . - arm925_processor_functions
|
||||
|
||||
.section ".rodata"
|
||||
|
@ -348,12 +348,12 @@ ENTRY(cpu_arm926_switch_mm)
|
||||
mov pc, lr
|
||||
|
||||
/*
|
||||
* cpu_arm926_set_pte(ptep, pte)
|
||||
* cpu_arm926_set_pte_ext(ptep, pte, ext)
|
||||
*
|
||||
* Set a PTE and flush it out
|
||||
*/
|
||||
.align 5
|
||||
ENTRY(cpu_arm926_set_pte)
|
||||
ENTRY(cpu_arm926_set_pte_ext)
|
||||
#ifdef CONFIG_MMU
|
||||
str r1, [r0], #-2048 @ linux version
|
||||
|
||||
@ -439,7 +439,7 @@ arm926_processor_functions:
|
||||
.word cpu_arm926_do_idle
|
||||
.word cpu_arm926_dcache_clean_area
|
||||
.word cpu_arm926_switch_mm
|
||||
.word cpu_arm926_set_pte
|
||||
.word cpu_arm926_set_pte_ext
|
||||
.size arm926_processor_functions, . - arm926_processor_functions
|
||||
|
||||
.section ".rodata"
|
||||
@ -480,7 +480,7 @@ __arm926_proc_info:
|
||||
b __arm926_setup
|
||||
.long cpu_arch_name
|
||||
.long cpu_elf_name
|
||||
.long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_VFP|HWCAP_EDSP|HWCAP_JAVA
|
||||
.long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_JAVA
|
||||
.long cpu_arm926_name
|
||||
.long arm926_processor_functions
|
||||
.long v4wbi_tlb_fns
|
||||
|
@ -146,12 +146,12 @@ ENTRY(cpu_sa110_switch_mm)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* cpu_sa110_set_pte(ptep, pte)
|
||||
* cpu_sa110_set_pte_ext(ptep, pte, ext)
|
||||
*
|
||||
* Set a PTE and flush it out
|
||||
*/
|
||||
.align 5
|
||||
ENTRY(cpu_sa110_set_pte)
|
||||
ENTRY(cpu_sa110_set_pte_ext)
|
||||
#ifdef CONFIG_MMU
|
||||
str r1, [r0], #-2048 @ linux version
|
||||
|
||||
@ -222,7 +222,7 @@ ENTRY(sa110_processor_functions)
|
||||
.word cpu_sa110_do_idle
|
||||
.word cpu_sa110_dcache_clean_area
|
||||
.word cpu_sa110_switch_mm
|
||||
.word cpu_sa110_set_pte
|
||||
.word cpu_sa110_set_pte_ext
|
||||
.size sa110_processor_functions, . - sa110_processor_functions
|
||||
|
||||
.section ".rodata"
|
||||
|
@ -159,12 +159,12 @@ ENTRY(cpu_sa1100_switch_mm)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* cpu_sa1100_set_pte(ptep, pte)
|
||||
* cpu_sa1100_set_pte_ext(ptep, pte, ext)
|
||||
*
|
||||
* Set a PTE and flush it out
|
||||
*/
|
||||
.align 5
|
||||
ENTRY(cpu_sa1100_set_pte)
|
||||
ENTRY(cpu_sa1100_set_pte_ext)
|
||||
#ifdef CONFIG_MMU
|
||||
str r1, [r0], #-2048 @ linux version
|
||||
|
||||
@ -237,7 +237,7 @@ ENTRY(sa1100_processor_functions)
|
||||
.word cpu_sa1100_do_idle
|
||||
.word cpu_sa1100_dcache_clean_area
|
||||
.word cpu_sa1100_switch_mm
|
||||
.word cpu_sa1100_set_pte
|
||||
.word cpu_sa1100_set_pte_ext
|
||||
.size sa1100_processor_functions, . - sa1100_processor_functions
|
||||
|
||||
.section ".rodata"
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
#ifndef MULTI_CPU
|
||||
EXPORT_SYMBOL(cpu_dcache_clean_area);
|
||||
EXPORT_SYMBOL(cpu_set_pte);
|
||||
EXPORT_SYMBOL(cpu_set_pte_ext);
|
||||
#else
|
||||
EXPORT_SYMBOL(processor);
|
||||
#endif
|
||||
|
@ -103,13 +103,14 @@ ENTRY(cpu_v6_switch_mm)
|
||||
mov pc, lr
|
||||
|
||||
/*
|
||||
* cpu_v6_set_pte(ptep, pte)
|
||||
* cpu_v6_set_pte_ext(ptep, pte, ext)
|
||||
*
|
||||
* Set a level 2 translation table entry.
|
||||
*
|
||||
* - ptep - pointer to level 2 translation table entry
|
||||
* (hardware version is stored at -1024 bytes)
|
||||
* - pte - PTE value to store
|
||||
* - ext - value for extended PTE bits
|
||||
*
|
||||
* Permissions:
|
||||
* YUWD APX AP1 AP0 SVC User
|
||||
@ -121,33 +122,34 @@ ENTRY(cpu_v6_switch_mm)
|
||||
* 11x0 0 1 0 r/w r/o
|
||||
* 1111 0 1 1 r/w r/w
|
||||
*/
|
||||
ENTRY(cpu_v6_set_pte)
|
||||
ENTRY(cpu_v6_set_pte_ext)
|
||||
#ifdef CONFIG_MMU
|
||||
str r1, [r0], #-2048 @ linux version
|
||||
|
||||
bic r2, r1, #0x000003f0
|
||||
bic r2, r2, #0x00000003
|
||||
orr r2, r2, #PTE_EXT_AP0 | 2
|
||||
bic r3, r1, #0x000003f0
|
||||
bic r3, r3, #0x00000003
|
||||
orr r3, r3, r2
|
||||
orr r3, r3, #PTE_EXT_AP0 | 2
|
||||
|
||||
tst r1, #L_PTE_WRITE
|
||||
tstne r1, #L_PTE_DIRTY
|
||||
orreq r2, r2, #PTE_EXT_APX
|
||||
orreq r3, r3, #PTE_EXT_APX
|
||||
|
||||
tst r1, #L_PTE_USER
|
||||
orrne r2, r2, #PTE_EXT_AP1
|
||||
tstne r2, #PTE_EXT_APX
|
||||
bicne r2, r2, #PTE_EXT_APX | PTE_EXT_AP0
|
||||
orrne r3, r3, #PTE_EXT_AP1
|
||||
tstne r3, #PTE_EXT_APX
|
||||
bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0
|
||||
|
||||
tst r1, #L_PTE_YOUNG
|
||||
biceq r2, r2, #PTE_EXT_APX | PTE_EXT_AP_MASK
|
||||
biceq r3, r3, #PTE_EXT_APX | PTE_EXT_AP_MASK
|
||||
|
||||
tst r1, #L_PTE_EXEC
|
||||
orreq r2, r2, #PTE_EXT_XN
|
||||
orreq r3, r3, #PTE_EXT_XN
|
||||
|
||||
tst r1, #L_PTE_PRESENT
|
||||
moveq r2, #0
|
||||
moveq r3, #0
|
||||
|
||||
str r2, [r0]
|
||||
str r3, [r0]
|
||||
mcr p15, 0, r0, c7, c10, 1 @ flush_pte
|
||||
#endif
|
||||
mov pc, lr
|
||||
@ -156,7 +158,7 @@ ENTRY(cpu_v6_set_pte)
|
||||
|
||||
|
||||
cpu_v6_name:
|
||||
.asciz "Some Random V6 Processor"
|
||||
.asciz "ARMv6-compatible processor"
|
||||
.align
|
||||
|
||||
.section ".text.init", #alloc, #execinstr
|
||||
@ -207,11 +209,6 @@ __v6_setup:
|
||||
#endif
|
||||
mcr p15, 0, r4, c2, c0, 1 @ load TTB1
|
||||
#endif /* CONFIG_MMU */
|
||||
#ifdef CONFIG_VFP
|
||||
mrc p15, 0, r0, c1, c0, 2
|
||||
orr r0, r0, #(0xf << 20)
|
||||
mcr p15, 0, r0, c1, c0, 2 @ Enable full access to VFP
|
||||
#endif
|
||||
adr r5, v6_crval
|
||||
ldmia r5, {r5, r6}
|
||||
mrc p15, 0, r0, c1, c0, 0 @ read control register
|
||||
@ -238,7 +235,7 @@ ENTRY(v6_processor_functions)
|
||||
.word cpu_v6_do_idle
|
||||
.word cpu_v6_dcache_clean_area
|
||||
.word cpu_v6_switch_mm
|
||||
.word cpu_v6_set_pte
|
||||
.word cpu_v6_set_pte_ext
|
||||
.size v6_processor_functions, . - v6_processor_functions
|
||||
|
||||
.type cpu_arch_name, #object
|
||||
@ -273,7 +270,7 @@ __v6_proc_info:
|
||||
b __v6_setup
|
||||
.long cpu_arch_name
|
||||
.long cpu_elf_name
|
||||
.long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_VFP|HWCAP_EDSP|HWCAP_JAVA
|
||||
.long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_JAVA
|
||||
.long cpu_v6_name
|
||||
.long v6_processor_functions
|
||||
.long v6wbi_tlb_fns
|
||||
|
@ -357,13 +357,13 @@ ENTRY(cpu_xsc3_switch_mm)
|
||||
cpwait_ret lr, ip
|
||||
|
||||
/*
|
||||
* cpu_xsc3_set_pte(ptep, pte)
|
||||
* cpu_xsc3_set_pte_ext(ptep, pte, ext)
|
||||
*
|
||||
* Set a PTE and flush it out
|
||||
*
|
||||
*/
|
||||
.align 5
|
||||
ENTRY(cpu_xsc3_set_pte)
|
||||
ENTRY(cpu_xsc3_set_pte_ext)
|
||||
str r1, [r0], #-2048 @ linux version
|
||||
|
||||
bic r2, r1, #0xff0 @ Keep C, B bits
|
||||
@ -457,7 +457,7 @@ ENTRY(xsc3_processor_functions)
|
||||
.word cpu_xsc3_do_idle
|
||||
.word cpu_xsc3_dcache_clean_area
|
||||
.word cpu_xsc3_switch_mm
|
||||
.word cpu_xsc3_set_pte
|
||||
.word cpu_xsc3_set_pte_ext
|
||||
.size xsc3_processor_functions, . - xsc3_processor_functions
|
||||
|
||||
.section ".rodata"
|
||||
|
@ -421,14 +421,14 @@ ENTRY(cpu_xscale_switch_mm)
|
||||
cpwait_ret lr, ip
|
||||
|
||||
/*
|
||||
* cpu_xscale_set_pte(ptep, pte)
|
||||
* cpu_xscale_set_pte_ext(ptep, pte, ext)
|
||||
*
|
||||
* Set a PTE and flush it out
|
||||
*
|
||||
* Errata 40: must set memory to write-through for user read-only pages.
|
||||
*/
|
||||
.align 5
|
||||
ENTRY(cpu_xscale_set_pte)
|
||||
ENTRY(cpu_xscale_set_pte_ext)
|
||||
str r1, [r0], #-2048 @ linux version
|
||||
|
||||
bic r2, r1, #0xff0
|
||||
@ -529,7 +529,7 @@ ENTRY(xscale_processor_functions)
|
||||
.word cpu_xscale_do_idle
|
||||
.word cpu_xscale_dcache_clean_area
|
||||
.word cpu_xscale_switch_mm
|
||||
.word cpu_xscale_set_pte
|
||||
.word cpu_xscale_set_pte_ext
|
||||
.size xscale_processor_functions, . - xscale_processor_functions
|
||||
|
||||
.section ".rodata"
|
||||
|
@ -270,6 +270,17 @@ void VFP9_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
|
||||
static int __init vfp_init(void)
|
||||
{
|
||||
unsigned int vfpsid;
|
||||
unsigned int cpu_arch = cpu_architecture();
|
||||
u32 access = 0;
|
||||
|
||||
if (cpu_arch >= CPU_ARCH_ARMv6) {
|
||||
access = get_copro_access();
|
||||
|
||||
/*
|
||||
* Enable full access to VFP (cp10 and cp11)
|
||||
*/
|
||||
set_copro_access(access | CPACC_FULL(10) | CPACC_FULL(11));
|
||||
}
|
||||
|
||||
/*
|
||||
* First check that there is a VFP that we can use.
|
||||
@ -281,6 +292,12 @@ static int __init vfp_init(void)
|
||||
printk(KERN_INFO "VFP support v0.3: ");
|
||||
if (VFP_arch) {
|
||||
printk("not present\n");
|
||||
|
||||
/*
|
||||
* Restore the copro access register.
|
||||
*/
|
||||
if (cpu_arch >= CPU_ARCH_ARMv6)
|
||||
set_copro_access(access);
|
||||
} else if (vfpsid & FPSID_NODOUBLE) {
|
||||
printk("no double precision support\n");
|
||||
} else {
|
||||
@ -291,9 +308,16 @@ static int __init vfp_init(void)
|
||||
(vfpsid & FPSID_PART_MASK) >> FPSID_PART_BIT,
|
||||
(vfpsid & FPSID_VARIANT_MASK) >> FPSID_VARIANT_BIT,
|
||||
(vfpsid & FPSID_REV_MASK) >> FPSID_REV_BIT);
|
||||
|
||||
vfp_vector = vfp_support_entry;
|
||||
|
||||
thread_register_notifier(&vfp_notifier_block);
|
||||
|
||||
/*
|
||||
* We detected VFP, and the support code is
|
||||
* in place; report VFP support to userspace.
|
||||
*/
|
||||
elf_hwcap |= HWCAP_VFP;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -41,7 +41,13 @@
|
||||
|
||||
/* PLL registers */
|
||||
#define CSCR __REG(IMX_PLL_BASE) /* Clock Source Control Register */
|
||||
#define CSCR_SYSTEM_SEL (1<<16)
|
||||
#define CSCR_SPLL_RESTART (1<<22)
|
||||
#define CSCR_MPLL_RESTART (1<<21)
|
||||
#define CSCR_SYSTEM_SEL (1<<16)
|
||||
#define CSCR_BCLK_DIV (0xf<<10)
|
||||
#define CSCR_MPU_PRESC (1<<15)
|
||||
#define CSCR_SPEN (1<<1)
|
||||
#define CSCR_MPEN (1<<0)
|
||||
|
||||
#define MPCTL0 __REG(IMX_PLL_BASE + 0x4) /* MCU PLL Control Register 0 */
|
||||
#define MPCTL1 __REG(IMX_PLL_BASE + 0x8) /* MCU PLL and System Clock Register 1 */
|
||||
@ -49,8 +55,6 @@
|
||||
#define SPCTL1 __REG(IMX_PLL_BASE + 0x10) /* System PLL Control Register 1 */
|
||||
#define PCDR __REG(IMX_PLL_BASE + 0x20) /* Peripheral Clock Divider Register */
|
||||
|
||||
#define CSCR_MPLL_RESTART (1<<21)
|
||||
|
||||
/*
|
||||
* GPIO Module and I/O Multiplexer
|
||||
* x = 0..3 for reg_A, reg_B, reg_C, reg_D
|
||||
|
@ -11,8 +11,7 @@
|
||||
#ifndef __ASM_ARCH_REGS_UDC_H
|
||||
#define __ASM_ARCH_REGS_UDC_H
|
||||
|
||||
|
||||
#define S3C2410_USBDREG(x) ((x) + S3C24XX_VA_USBDEV)
|
||||
#define S3C2410_USBDREG(x) (x)
|
||||
|
||||
#define S3C2410_UDC_FUNC_ADDR_REG S3C2410_USBDREG(0x0140)
|
||||
#define S3C2410_UDC_PWR_REG S3C2410_USBDREG(0x0144)
|
||||
@ -136,8 +135,8 @@
|
||||
#define S3C2410_UDC_OCSR2_ISO (1<<6) // R/W
|
||||
#define S3C2410_UDC_OCSR2_DMAIEN (1<<5) // R/W
|
||||
|
||||
#define S3C2410_UDC_SETIX(x) \
|
||||
__raw_writel(S3C2410_UDC_INDEX_ ## x, S3C2410_UDC_INDEX_REG);
|
||||
#define S3C2410_UDC_SETIX(base,x) \
|
||||
writel(S3C2410_UDC_INDEX_ ## x, base+S3C2410_UDC_INDEX_REG);
|
||||
|
||||
|
||||
#define S3C2410_UDC_EP0_CSR_OPKRDY (1<<0)
|
||||
|
@ -50,9 +50,10 @@ extern struct processor {
|
||||
*/
|
||||
void (*switch_mm)(unsigned long pgd_phys, struct mm_struct *mm);
|
||||
/*
|
||||
* Set a PTE
|
||||
* Set a possibly extended PTE. Non-extended PTEs should
|
||||
* ignore 'ext'.
|
||||
*/
|
||||
void (*set_pte)(pte_t *ptep, pte_t pte);
|
||||
void (*set_pte_ext)(pte_t *ptep, pte_t pte, unsigned int ext);
|
||||
} processor;
|
||||
|
||||
#define cpu_proc_init() processor._proc_init()
|
||||
@ -60,5 +61,5 @@ extern struct processor {
|
||||
#define cpu_reset(addr) processor.reset(addr)
|
||||
#define cpu_do_idle() processor._do_idle()
|
||||
#define cpu_dcache_clean_area(addr,sz) processor.dcache_clean_area(addr,sz)
|
||||
#define cpu_set_pte(ptep, pte) processor.set_pte(ptep, pte)
|
||||
#define cpu_set_pte_ext(ptep,pte,ext) processor.set_pte_ext(ptep,pte,ext)
|
||||
#define cpu_do_switch_mm(pgd,mm) processor.switch_mm(pgd,mm)
|
||||
|
@ -28,7 +28,7 @@
|
||||
#define cpu_do_idle __cpu_fn(CPU_NAME,_do_idle)
|
||||
#define cpu_dcache_clean_area __cpu_fn(CPU_NAME,_dcache_clean_area)
|
||||
#define cpu_do_switch_mm __cpu_fn(CPU_NAME,_switch_mm)
|
||||
#define cpu_set_pte __cpu_fn(CPU_NAME,_set_pte)
|
||||
#define cpu_set_pte_ext __cpu_fn(CPU_NAME,_set_pte_ext)
|
||||
|
||||
#include <asm/page.h>
|
||||
|
||||
@ -40,5 +40,5 @@ extern void cpu_proc_fin(void);
|
||||
extern int cpu_do_idle(void);
|
||||
extern void cpu_dcache_clean_area(void *, int);
|
||||
extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
|
||||
extern void cpu_set_pte(pte_t *ptep, pte_t pte);
|
||||
extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
|
||||
extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include <asm/memory.h>
|
||||
#include <asm/arch/vmalloc.h>
|
||||
#include <asm/pgtable-hwdef.h>
|
||||
|
||||
/*
|
||||
* Just any arbitrary offset to the start of the vmalloc VM area: the
|
||||
@ -170,7 +171,6 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
|
||||
#define L_PTE_EXEC (1 << 6)
|
||||
#define L_PTE_DIRTY (1 << 7)
|
||||
#define L_PTE_SHARED (1 << 10) /* shared(v6), coherent(xsc3) */
|
||||
#define L_PTE_ASID (1 << 11) /* non-global (use ASID, v6) */
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
@ -228,7 +228,7 @@ extern struct page *empty_zero_page;
|
||||
#define pfn_pte(pfn,prot) (__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)))
|
||||
|
||||
#define pte_none(pte) (!pte_val(pte))
|
||||
#define pte_clear(mm,addr,ptep) set_pte_at((mm),(addr),(ptep), __pte(0))
|
||||
#define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0)
|
||||
#define pte_page(pte) (pfn_to_page(pte_pfn(pte)))
|
||||
#define pte_offset_kernel(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr))
|
||||
#define pte_offset_map(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr))
|
||||
@ -236,8 +236,11 @@ extern struct page *empty_zero_page;
|
||||
#define pte_unmap(pte) do { } while (0)
|
||||
#define pte_unmap_nested(pte) do { } while (0)
|
||||
|
||||
#define set_pte(ptep, pte) cpu_set_pte(ptep,pte)
|
||||
#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
|
||||
#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
|
||||
|
||||
#define set_pte_at(mm,addr,ptep,pteval) do { \
|
||||
set_pte_ext(ptep, pteval, (addr) >= PAGE_OFFSET ? 0 : PTE_EXT_NG); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* The following only work if pte_present() is true.
|
||||
|
@ -103,14 +103,14 @@ extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
|
||||
#if __LINUX_ARM_ARCH__ >= 5
|
||||
|
||||
#define ARCH_HAS_PREFETCH
|
||||
#define prefetch(ptr) \
|
||||
({ \
|
||||
__asm__ __volatile__( \
|
||||
"pld\t%0" \
|
||||
: \
|
||||
: "o" (*(char *)(ptr)) \
|
||||
: "cc"); \
|
||||
})
|
||||
static inline void prefetch(const void *ptr)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"pld\t%0"
|
||||
:
|
||||
: "o" (*(char *)ptr)
|
||||
: "cc");
|
||||
}
|
||||
|
||||
#define ARCH_HAS_PREFETCHW
|
||||
#define prefetchw(ptr) prefetch(ptr)
|
||||
|
@ -139,23 +139,60 @@ static inline int cpu_is_xsc3(void)
|
||||
#define cpu_is_xscale() 1
|
||||
#endif
|
||||
|
||||
#define set_cr(x) \
|
||||
__asm__ __volatile__( \
|
||||
"mcr p15, 0, %0, c1, c0, 0 @ set CR" \
|
||||
: : "r" (x) : "cc")
|
||||
static inline unsigned int get_cr(void)
|
||||
{
|
||||
unsigned int val;
|
||||
asm("mrc p15, 0, %0, c1, c0, 0 @ get CR" : "=r" (val) : : "cc");
|
||||
return val;
|
||||
}
|
||||
|
||||
#define get_cr() \
|
||||
({ \
|
||||
unsigned int __val; \
|
||||
__asm__ __volatile__( \
|
||||
"mrc p15, 0, %0, c1, c0, 0 @ get CR" \
|
||||
: "=r" (__val) : : "cc"); \
|
||||
__val; \
|
||||
})
|
||||
static inline void set_cr(unsigned int val)
|
||||
{
|
||||
asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR"
|
||||
: : "r" (val) : "cc");
|
||||
}
|
||||
|
||||
#define CPACC_FULL(n) (3 << (n * 2))
|
||||
#define CPACC_SVC(n) (1 << (n * 2))
|
||||
#define CPACC_DISABLE(n) (0 << (n * 2))
|
||||
|
||||
static inline unsigned int get_copro_access(void)
|
||||
{
|
||||
unsigned int val;
|
||||
asm("mrc p15, 0, %0, c1, c0, 2 @ get copro access"
|
||||
: "=r" (val) : : "cc");
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline void set_copro_access(unsigned int val)
|
||||
{
|
||||
asm volatile("mcr p15, 0, %0, c1, c0, 2 @ set copro access"
|
||||
: : "r" (val) : "cc");
|
||||
}
|
||||
|
||||
extern unsigned long cr_no_alignment; /* defined in entry-armv.S */
|
||||
extern unsigned long cr_alignment; /* defined in entry-armv.S */
|
||||
|
||||
#ifndef CONFIG_SMP
|
||||
static inline void adjust_cr(unsigned long mask, unsigned long set)
|
||||
{
|
||||
unsigned long flags, cr;
|
||||
|
||||
mask &= ~CR_A;
|
||||
|
||||
set &= mask;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
cr_no_alignment = (cr_no_alignment & ~mask) | set;
|
||||
cr_alignment = (cr_alignment & ~mask) | set;
|
||||
|
||||
set_cr((get_cr() & ~mask) | set);
|
||||
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define UDBG_UNDEFINED (1 << 0)
|
||||
#define UDBG_SYSCALL (1 << 1)
|
||||
#define UDBG_BADABORT (1 << 2)
|
||||
|
@ -347,6 +347,19 @@
|
||||
#define __NR_mbind (__NR_SYSCALL_BASE+319)
|
||||
#define __NR_get_mempolicy (__NR_SYSCALL_BASE+320)
|
||||
#define __NR_set_mempolicy (__NR_SYSCALL_BASE+321)
|
||||
#define __NR_openat (__NR_SYSCALL_BASE+322)
|
||||
#define __NR_mkdirat (__NR_SYSCALL_BASE+323)
|
||||
#define __NR_mknodat (__NR_SYSCALL_BASE+324)
|
||||
#define __NR_fchownat (__NR_SYSCALL_BASE+325)
|
||||
#define __NR_futimesat (__NR_SYSCALL_BASE+326)
|
||||
#define __NR_fstatat64 (__NR_SYSCALL_BASE+327)
|
||||
#define __NR_unlinkat (__NR_SYSCALL_BASE+328)
|
||||
#define __NR_renameat (__NR_SYSCALL_BASE+329)
|
||||
#define __NR_linkat (__NR_SYSCALL_BASE+330)
|
||||
#define __NR_symlinkat (__NR_SYSCALL_BASE+331)
|
||||
#define __NR_readlinkat (__NR_SYSCALL_BASE+332)
|
||||
#define __NR_fchmodat (__NR_SYSCALL_BASE+333)
|
||||
#define __NR_faccessat (__NR_SYSCALL_BASE+334)
|
||||
|
||||
/*
|
||||
* The following SWIs are ARM private.
|
||||
|
Loading…
Reference in New Issue
Block a user