Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts: drivers/net/wireless/iwlwifi/iwl-4965-rs.c drivers/net/wireless/rt2x00/rt61pci.c
This commit is contained in:
commit
63fe46da9c
980 changed files with 25435 additions and 13014 deletions
|
@ -72,7 +72,7 @@
|
|||
kgdb is a source level debugger for linux kernel. It is used along
|
||||
with gdb to debug a linux kernel. The expectation is that gdb can
|
||||
be used to "break in" to the kernel to inspect memory, variables
|
||||
and look through a cal stack information similar to what an
|
||||
and look through call stack information similar to what an
|
||||
application developer would use gdb for. It is possible to place
|
||||
breakpoints in kernel code and perform some limited execution
|
||||
stepping.
|
||||
|
@ -93,8 +93,10 @@
|
|||
<chapter id="CompilingAKernel">
|
||||
<title>Compiling a kernel</title>
|
||||
<para>
|
||||
To enable <symbol>CONFIG_KGDB</symbol>, look under the "Kernel debugging"
|
||||
and then select "KGDB: kernel debugging with remote gdb".
|
||||
To enable <symbol>CONFIG_KGDB</symbol> you should first turn on
|
||||
"Prompt for development and/or incomplete code/drivers"
|
||||
(CONFIG_EXPERIMENTAL) in "General setup", then under the
|
||||
"Kernel debugging" select "KGDB: kernel debugging with remote gdb".
|
||||
</para>
|
||||
<para>
|
||||
Next you should choose one of more I/O drivers to interconnect debugging
|
||||
|
|
|
@ -310,8 +310,8 @@ and then start a subshell 'sh' in that cgroup:
|
|||
cd /dev/cgroup
|
||||
mkdir Charlie
|
||||
cd Charlie
|
||||
/bin/echo 2-3 > cpus
|
||||
/bin/echo 1 > mems
|
||||
/bin/echo 2-3 > cpuset.cpus
|
||||
/bin/echo 1 > cpuset.mems
|
||||
/bin/echo $$ > tasks
|
||||
sh
|
||||
# The subshell 'sh' is now running in cgroup Charlie
|
||||
|
|
|
@ -289,6 +289,14 @@ Who: Glauber Costa <gcosta@redhat.com>
|
|||
|
||||
---------------------------
|
||||
|
||||
What: old style serial driver for ColdFire (CONFIG_SERIAL_COLDFIRE)
|
||||
When: 2.6.28
|
||||
Why: This driver still uses the old interface and has been replaced
|
||||
by CONFIG_SERIAL_MCF.
|
||||
Who: Sebastian Siewior <sebastian@breakpoint.cc>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: /sys/o2cb symlink
|
||||
When: January 2010
|
||||
Why: /sys/fs/o2cb is the proper location for this information - /sys/o2cb
|
||||
|
|
|
@ -92,7 +92,6 @@ prototypes:
|
|||
void (*destroy_inode)(struct inode *);
|
||||
void (*dirty_inode) (struct inode *);
|
||||
int (*write_inode) (struct inode *, int);
|
||||
void (*put_inode) (struct inode *);
|
||||
void (*drop_inode) (struct inode *);
|
||||
void (*delete_inode) (struct inode *);
|
||||
void (*put_super) (struct super_block *);
|
||||
|
@ -115,7 +114,6 @@ alloc_inode: no no no
|
|||
destroy_inode: no
|
||||
dirty_inode: no (must not sleep)
|
||||
write_inode: no
|
||||
put_inode: no
|
||||
drop_inode: no !!!inode_lock!!!
|
||||
delete_inode: no
|
||||
put_super: yes yes no
|
||||
|
|
|
@ -205,7 +205,6 @@ struct super_operations {
|
|||
|
||||
void (*dirty_inode) (struct inode *);
|
||||
int (*write_inode) (struct inode *, int);
|
||||
void (*put_inode) (struct inode *);
|
||||
void (*drop_inode) (struct inode *);
|
||||
void (*delete_inode) (struct inode *);
|
||||
void (*put_super) (struct super_block *);
|
||||
|
@ -246,9 +245,6 @@ or bottom half).
|
|||
inode to disc. The second parameter indicates whether the write
|
||||
should be synchronous or not, not all filesystems check this flag.
|
||||
|
||||
put_inode: called when the VFS inode is removed from the inode
|
||||
cache.
|
||||
|
||||
drop_inode: called when the last access to the inode is dropped,
|
||||
with the inode_lock spinlock held.
|
||||
|
||||
|
|
|
@ -69,7 +69,8 @@ point2: Set the pwm speed at a higher temperature bound.
|
|||
|
||||
The ADT7473 will scale the pwm between the lower and higher pwm speed when
|
||||
the temperature is between the two temperature boundaries. PWM values range
|
||||
from 0 (off) to 255 (full speed).
|
||||
from 0 (off) to 255 (full speed). Fan speed will be set to maximum when the
|
||||
temperature sensor associated with the PWM control exceeds temp#_max.
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
|
|
@ -51,26 +51,38 @@ A few combinations of the above flags are also defined for your convenience:
|
|||
the transparent emulation layer)
|
||||
|
||||
|
||||
ALGORITHM/ADAPTER IMPLEMENTATION
|
||||
--------------------------------
|
||||
ADAPTER IMPLEMENTATION
|
||||
----------------------
|
||||
|
||||
When you write a new algorithm driver, you will have to implement a
|
||||
function callback `functionality', that gets an i2c_adapter structure
|
||||
pointer as its only parameter:
|
||||
When you write a new adapter driver, you will have to implement a
|
||||
function callback `functionality'. Typical implementations are given
|
||||
below.
|
||||
|
||||
struct i2c_algorithm {
|
||||
/* Many other things of course; check <linux/i2c.h>! */
|
||||
u32 (*functionality) (struct i2c_adapter *);
|
||||
}
|
||||
A typical SMBus-only adapter would list all the SMBus transactions it
|
||||
supports. This example comes from the i2c-piix4 driver:
|
||||
|
||||
A typically implementation is given below, from i2c-algo-bit.c:
|
||||
|
||||
static u32 bit_func(struct i2c_adapter *adap)
|
||||
static u32 piix4_func(struct i2c_adapter *adapter)
|
||||
{
|
||||
return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
|
||||
I2C_FUNC_PROTOCOL_MANGLING;
|
||||
return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
|
||||
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
|
||||
I2C_FUNC_SMBUS_BLOCK_DATA;
|
||||
}
|
||||
|
||||
A typical full-I2C adapter would use the following (from the i2c-pxa
|
||||
driver):
|
||||
|
||||
static u32 i2c_pxa_functionality(struct i2c_adapter *adap)
|
||||
{
|
||||
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
|
||||
}
|
||||
|
||||
I2C_FUNC_SMBUS_EMUL includes all the SMBus transactions (with the
|
||||
addition of I2C block transactions) which i2c-core can emulate using
|
||||
I2C_FUNC_I2C without any help from the adapter driver. The idea is
|
||||
to let the client drivers check for the support of SMBus functions
|
||||
without having to care whether the said functions are implemented in
|
||||
hardware by the adapter, or emulated in software by i2c-core on top
|
||||
of an I2C adapter.
|
||||
|
||||
|
||||
CLIENT CHECKING
|
||||
|
@ -78,36 +90,33 @@ CLIENT CHECKING
|
|||
|
||||
Before a client tries to attach to an adapter, or even do tests to check
|
||||
whether one of the devices it supports is present on an adapter, it should
|
||||
check whether the needed functionality is present. There are two functions
|
||||
defined which should be used instead of calling the functionality hook
|
||||
in the algorithm structure directly:
|
||||
check whether the needed functionality is present. The typical way to do
|
||||
this is (from the lm75 driver):
|
||||
|
||||
/* Return the functionality mask */
|
||||
extern u32 i2c_get_functionality (struct i2c_adapter *adap);
|
||||
|
||||
/* Return 1 if adapter supports everything we need, 0 if not. */
|
||||
extern int i2c_check_functionality (struct i2c_adapter *adap, u32 func);
|
||||
|
||||
This is a typical way to use these functions (from the writing-clients
|
||||
document):
|
||||
int foo_detect_client(struct i2c_adapter *adapter, int address,
|
||||
unsigned short flags, int kind)
|
||||
static int lm75_detect(...)
|
||||
{
|
||||
/* Define needed variables */
|
||||
|
||||
/* As the very first action, we check whether the adapter has the
|
||||
needed functionality: we need the SMBus read_word_data,
|
||||
write_word_data and write_byte functions in this example. */
|
||||
if (!i2c_check_functionality(adapter,I2C_FUNC_SMBUS_WORD_DATA |
|
||||
I2C_FUNC_SMBUS_WRITE_BYTE))
|
||||
goto ERROR0;
|
||||
|
||||
/* Now we can do the real detection */
|
||||
|
||||
ERROR0:
|
||||
/* Return an error */
|
||||
(...)
|
||||
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
|
||||
I2C_FUNC_SMBUS_WORD_DATA))
|
||||
goto exit;
|
||||
(...)
|
||||
}
|
||||
|
||||
Here, the lm75 driver checks if the adapter can do both SMBus byte data
|
||||
and SMBus word data transactions. If not, then the driver won't work on
|
||||
this adapter and there's no point in going on. If the check above is
|
||||
successful, then the driver knows that it can call the following
|
||||
functions: i2c_smbus_read_byte_data(), i2c_smbus_write_byte_data(),
|
||||
i2c_smbus_read_word_data() and i2c_smbus_write_word_data(). As a rule of
|
||||
thumb, the functionality constants you test for with
|
||||
i2c_check_functionality() should match exactly the i2c_smbus_* functions
|
||||
which you driver is calling.
|
||||
|
||||
Note that the check above doesn't tell whether the functionalities are
|
||||
implemented in hardware by the underlying adapter or emulated in
|
||||
software by i2c-core. Client drivers don't have to care about this, as
|
||||
i2c-core will transparently implement SMBus transactions on top of I2C
|
||||
adapters.
|
||||
|
||||
|
||||
CHECKING THROUGH /DEV
|
||||
|
@ -116,19 +125,19 @@ CHECKING THROUGH /DEV
|
|||
If you try to access an adapter from a userspace program, you will have
|
||||
to use the /dev interface. You will still have to check whether the
|
||||
functionality you need is supported, of course. This is done using
|
||||
the I2C_FUNCS ioctl. An example, adapted from the lm_sensors i2cdetect
|
||||
program, is below:
|
||||
the I2C_FUNCS ioctl. An example, adapted from the i2cdetect program, is
|
||||
below:
|
||||
|
||||
int file;
|
||||
if (file = open("/dev/i2c-0",O_RDWR) < 0) {
|
||||
if (file = open("/dev/i2c-0", O_RDWR) < 0) {
|
||||
/* Some kind of error handling */
|
||||
exit(1);
|
||||
}
|
||||
if (ioctl(file,I2C_FUNCS,&funcs) < 0) {
|
||||
if (ioctl(file, I2C_FUNCS, &funcs) < 0) {
|
||||
/* Some kind of error handling */
|
||||
exit(1);
|
||||
}
|
||||
if (! (funcs & I2C_FUNC_SMBUS_QUICK)) {
|
||||
if (!(funcs & I2C_FUNC_SMBUS_QUICK)) {
|
||||
/* Oops, the needed functionality (SMBus write_quick function) is
|
||||
not available! */
|
||||
exit(1);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
SMBus Protocol Summary
|
||||
======================
|
||||
|
||||
The following is a summary of the SMBus protocol. It applies to
|
||||
all revisions of the protocol (1.0, 1.1, and 2.0).
|
||||
Certain protocol features which are not supported by
|
||||
|
@ -8,6 +9,7 @@ this package are briefly described at the end of this document.
|
|||
Some adapters understand only the SMBus (System Management Bus) protocol,
|
||||
which is a subset from the I2C protocol. Fortunately, many devices use
|
||||
only the same subset, which makes it possible to put them on an SMBus.
|
||||
|
||||
If you write a driver for some I2C device, please try to use the SMBus
|
||||
commands if at all possible (if the device uses only that subset of the
|
||||
I2C protocol). This makes it possible to use the device driver on both
|
||||
|
@ -15,7 +17,12 @@ SMBus adapters and I2C adapters (the SMBus command set is automatically
|
|||
translated to I2C on I2C adapters, but plain I2C commands can not be
|
||||
handled at all on most pure SMBus adapters).
|
||||
|
||||
Below is a list of SMBus commands.
|
||||
Below is a list of SMBus protocol operations, and the functions executing
|
||||
them. Note that the names used in the SMBus protocol specifications usually
|
||||
don't match these function names. For some of the operations which pass a
|
||||
single data byte, the functions using SMBus protocol operation names execute
|
||||
a different protocol operation entirely.
|
||||
|
||||
|
||||
Key to symbols
|
||||
==============
|
||||
|
@ -35,17 +42,16 @@ Count (8 bits): A data byte containing the length of a block operation.
|
|||
[..]: Data sent by I2C device, as opposed to data sent by the host adapter.
|
||||
|
||||
|
||||
SMBus Write Quick
|
||||
=================
|
||||
SMBus Quick Command: i2c_smbus_write_quick()
|
||||
=============================================
|
||||
|
||||
This sends a single bit to the device, at the place of the Rd/Wr bit.
|
||||
There is no equivalent Read Quick command.
|
||||
|
||||
A Addr Rd/Wr [A] P
|
||||
|
||||
|
||||
SMBus Read Byte
|
||||
===============
|
||||
SMBus Receive Byte: i2c_smbus_read_byte()
|
||||
==========================================
|
||||
|
||||
This reads a single byte from a device, without specifying a device
|
||||
register. Some devices are so simple that this interface is enough; for
|
||||
|
@ -55,17 +61,17 @@ the previous SMBus command.
|
|||
S Addr Rd [A] [Data] NA P
|
||||
|
||||
|
||||
SMBus Write Byte
|
||||
================
|
||||
SMBus Send Byte: i2c_smbus_write_byte()
|
||||
========================================
|
||||
|
||||
This is the reverse of Read Byte: it sends a single byte to a device.
|
||||
See Read Byte for more information.
|
||||
This operation is the reverse of Receive Byte: it sends a single byte
|
||||
to a device. See Receive Byte for more information.
|
||||
|
||||
S Addr Wr [A] Data [A] P
|
||||
|
||||
|
||||
SMBus Read Byte Data
|
||||
====================
|
||||
SMBus Read Byte: i2c_smbus_read_byte_data()
|
||||
============================================
|
||||
|
||||
This reads a single byte from a device, from a designated register.
|
||||
The register is specified through the Comm byte.
|
||||
|
@ -73,30 +79,30 @@ The register is specified through the Comm byte.
|
|||
S Addr Wr [A] Comm [A] S Addr Rd [A] [Data] NA P
|
||||
|
||||
|
||||
SMBus Read Word Data
|
||||
====================
|
||||
SMBus Read Word: i2c_smbus_read_word_data()
|
||||
============================================
|
||||
|
||||
This command is very like Read Byte Data; again, data is read from a
|
||||
This operation is very like Read Byte; again, data is read from a
|
||||
device, from a designated register that is specified through the Comm
|
||||
byte. But this time, the data is a complete word (16 bits).
|
||||
|
||||
S Addr Wr [A] Comm [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P
|
||||
|
||||
|
||||
SMBus Write Byte Data
|
||||
=====================
|
||||
SMBus Write Byte: i2c_smbus_write_byte_data()
|
||||
==============================================
|
||||
|
||||
This writes a single byte to a device, to a designated register. The
|
||||
register is specified through the Comm byte. This is the opposite of
|
||||
the Read Byte Data command.
|
||||
the Read Byte operation.
|
||||
|
||||
S Addr Wr [A] Comm [A] Data [A] P
|
||||
|
||||
|
||||
SMBus Write Word Data
|
||||
=====================
|
||||
SMBus Write Word: i2c_smbus_write_word_data()
|
||||
==============================================
|
||||
|
||||
This is the opposite operation of the Read Word Data command. 16 bits
|
||||
This is the opposite of the Read Word operation. 16 bits
|
||||
of data is written to a device, to the designated register that is
|
||||
specified through the Comm byte.
|
||||
|
||||
|
@ -113,8 +119,8 @@ S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A]
|
|||
S Addr Rd [A] [DataLow] A [DataHigh] NA P
|
||||
|
||||
|
||||
SMBus Block Read
|
||||
================
|
||||
SMBus Block Read: i2c_smbus_read_block_data()
|
||||
==============================================
|
||||
|
||||
This command reads a block of up to 32 bytes from a device, from a
|
||||
designated register that is specified through the Comm byte. The amount
|
||||
|
@ -124,8 +130,8 @@ S Addr Wr [A] Comm [A]
|
|||
S Addr Rd [A] [Count] A [Data] A [Data] A ... A [Data] NA P
|
||||
|
||||
|
||||
SMBus Block Write
|
||||
=================
|
||||
SMBus Block Write: i2c_smbus_write_block_data()
|
||||
================================================
|
||||
|
||||
The opposite of the Block Read command, this writes up to 32 bytes to
|
||||
a device, to a designated register that is specified through the
|
||||
|
@ -134,10 +140,11 @@ Comm byte. The amount of data is specified in the Count byte.
|
|||
S Addr Wr [A] Comm [A] Count [A] Data [A] Data [A] ... [A] Data [A] P
|
||||
|
||||
|
||||
SMBus Block Process Call
|
||||
========================
|
||||
SMBus Block Write - Block Read Process Call
|
||||
===========================================
|
||||
|
||||
SMBus Block Process Call was introduced in Revision 2.0 of the specification.
|
||||
SMBus Block Write - Block Read Process Call was introduced in
|
||||
Revision 2.0 of the specification.
|
||||
|
||||
This command selects a device register (through the Comm byte), sends
|
||||
1 to 31 bytes of data to it, and reads 1 to 31 bytes of data in return.
|
||||
|
@ -159,13 +166,16 @@ alerting device's address.
|
|||
|
||||
Packet Error Checking (PEC)
|
||||
===========================
|
||||
|
||||
Packet Error Checking was introduced in Revision 1.1 of the specification.
|
||||
|
||||
PEC adds a CRC-8 error-checking byte to all transfers.
|
||||
PEC adds a CRC-8 error-checking byte to transfers using it, immediately
|
||||
before the terminating STOP.
|
||||
|
||||
|
||||
Address Resolution Protocol (ARP)
|
||||
=================================
|
||||
|
||||
The Address Resolution Protocol was introduced in Revision 2.0 of
|
||||
the specification. It is a higher-layer protocol which uses the
|
||||
messages above.
|
||||
|
@ -177,14 +187,17 @@ require PEC checksums.
|
|||
|
||||
I2C Block Transactions
|
||||
======================
|
||||
|
||||
The following I2C block transactions are supported by the
|
||||
SMBus layer and are described here for completeness.
|
||||
They are *NOT* defined by the SMBus specification.
|
||||
|
||||
I2C block transactions do not limit the number of bytes transferred
|
||||
but the SMBus layer places a limit of 32 bytes.
|
||||
|
||||
|
||||
I2C Block Read
|
||||
==============
|
||||
I2C Block Read: i2c_smbus_read_i2c_block_data()
|
||||
================================================
|
||||
|
||||
This command reads a block of bytes from a device, from a
|
||||
designated register that is specified through the Comm byte.
|
||||
|
@ -203,8 +216,8 @@ S Addr Wr [A] Comm1 [A] Comm2 [A]
|
|||
S Addr Rd [A] [Data] A [Data] A ... A [Data] NA P
|
||||
|
||||
|
||||
I2C Block Write
|
||||
===============
|
||||
I2C Block Write: i2c_smbus_write_i2c_block_data()
|
||||
==================================================
|
||||
|
||||
The opposite of the Block Read command, this writes bytes to
|
||||
a device, to a designated register that is specified through the
|
||||
|
@ -212,5 +225,3 @@ Comm byte. Note that command lengths of 0, 2, or more bytes are
|
|||
supported as they are indistinguishable from data.
|
||||
|
||||
S Addr Wr [A] Comm [A] Data [A] Data [A] ... [A] Data [A] P
|
||||
|
||||
|
||||
|
|
|
@ -1094,9 +1094,6 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||
mac5380= [HW,SCSI] Format:
|
||||
<can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags>
|
||||
|
||||
mac53c9x= [HW,SCSI] Format:
|
||||
<num_esps>,<disconnect>,<nosync>,<can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags>
|
||||
|
||||
machvec= [IA64] Force the use of a particular machine-vector
|
||||
(machvec) in a generic kernel.
|
||||
Example: machvec=hpzx1_swiotlb
|
||||
|
@ -1525,6 +1522,8 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||
This is normally done in pci_enable_device(),
|
||||
so this option is a temporary workaround
|
||||
for broken drivers that don't call it.
|
||||
skip_isa_align [X86] do not align io start addr, so can
|
||||
handle more pci cards
|
||||
firmware [ARM] Do not re-enumerate the bus but instead
|
||||
just use the configuration from the
|
||||
bootloader. This is currently used on
|
||||
|
|
|
@ -994,7 +994,17 @@ The Linux kernel has eight basic CPU memory barriers:
|
|||
DATA DEPENDENCY read_barrier_depends() smp_read_barrier_depends()
|
||||
|
||||
|
||||
All CPU memory barriers unconditionally imply compiler barriers.
|
||||
All memory barriers except the data dependency barriers imply a compiler
|
||||
barrier. Data dependencies do not impose any additional compiler ordering.
|
||||
|
||||
Aside: In the case of data dependencies, the compiler would be expected to
|
||||
issue the loads in the correct order (eg. `a[b]` would have to load the value
|
||||
of b before loading a[b]), however there is no guarantee in the C specification
|
||||
that the compiler may not speculate the value of b (eg. is equal to 1) and load
|
||||
a before b (eg. tmp = a[1]; if (b != 1) tmp = a[b]; ). There is also the
|
||||
problem of a compiler reloading b after having loaded a[b], thus having a newer
|
||||
copy of b than a[b]. A consensus has not yet been reached about these problems,
|
||||
however the ACCESS_ONCE macro is a good place to start looking.
|
||||
|
||||
SMP memory barriers are reduced to compiler barriers on uniprocessor compiled
|
||||
systems because it is assumed that a CPU will appear to be self-consistent,
|
||||
|
|
|
@ -8,17 +8,6 @@ Command line parameters
|
|||
|
||||
Enable logging of debug information in case of ccw device timeouts.
|
||||
|
||||
|
||||
* cio_msg = yes | no
|
||||
|
||||
Determines whether information on found devices and sensed device
|
||||
characteristics should be shown during startup or when new devices are
|
||||
found, i. e. messages of the types "Detected device 0.0.4711 on subchannel
|
||||
0.0.0042" and "SenseID: Device 0.0.4711 reports: ...".
|
||||
|
||||
Default is off.
|
||||
|
||||
|
||||
* cio_ignore = {all} |
|
||||
{<device> | <range of devices>} |
|
||||
{!<device> | !<range of devices>}
|
||||
|
|
|
@ -1,165 +0,0 @@
|
|||
Goals, Design and Implementation of the
|
||||
new ultra-scalable O(1) scheduler
|
||||
|
||||
|
||||
This is an edited version of an email Ingo Molnar sent to
|
||||
lkml on 4 Jan 2002. It describes the goals, design, and
|
||||
implementation of Ingo's new ultra-scalable O(1) scheduler.
|
||||
Last Updated: 18 April 2002.
|
||||
|
||||
|
||||
Goal
|
||||
====
|
||||
|
||||
The main goal of the new scheduler is to keep all the good things we know
|
||||
and love about the current Linux scheduler:
|
||||
|
||||
- good interactive performance even during high load: if the user
|
||||
types or clicks then the system must react instantly and must execute
|
||||
the user tasks smoothly, even during considerable background load.
|
||||
|
||||
- good scheduling/wakeup performance with 1-2 runnable processes.
|
||||
|
||||
- fairness: no process should stay without any timeslice for any
|
||||
unreasonable amount of time. No process should get an unjustly high
|
||||
amount of CPU time.
|
||||
|
||||
- priorities: less important tasks can be started with lower priority,
|
||||
more important tasks with higher priority.
|
||||
|
||||
- SMP efficiency: no CPU should stay idle if there is work to do.
|
||||
|
||||
- SMP affinity: processes which run on one CPU should stay affine to
|
||||
that CPU. Processes should not bounce between CPUs too frequently.
|
||||
|
||||
- plus additional scheduler features: RT scheduling, CPU binding.
|
||||
|
||||
and the goal is also to add a few new things:
|
||||
|
||||
- fully O(1) scheduling. Are you tired of the recalculation loop
|
||||
blowing the L1 cache away every now and then? Do you think the goodness
|
||||
loop is taking a bit too long to finish if there are lots of runnable
|
||||
processes? This new scheduler takes no prisoners: wakeup(), schedule(),
|
||||
the timer interrupt are all O(1) algorithms. There is no recalculation
|
||||
loop. There is no goodness loop either.
|
||||
|
||||
- 'perfect' SMP scalability. With the new scheduler there is no 'big'
|
||||
runqueue_lock anymore - it's all per-CPU runqueues and locks - two
|
||||
tasks on two separate CPUs can wake up, schedule and context-switch
|
||||
completely in parallel, without any interlocking. All
|
||||
scheduling-relevant data is structured for maximum scalability.
|
||||
|
||||
- better SMP affinity. The old scheduler has a particular weakness that
|
||||
causes the random bouncing of tasks between CPUs if/when higher
|
||||
priority/interactive tasks, this was observed and reported by many
|
||||
people. The reason is that the timeslice recalculation loop first needs
|
||||
every currently running task to consume its timeslice. But when this
|
||||
happens on eg. an 8-way system, then this property starves an
|
||||
increasing number of CPUs from executing any process. Once the last
|
||||
task that has a timeslice left has finished using up that timeslice,
|
||||
the recalculation loop is triggered and other CPUs can start executing
|
||||
tasks again - after having idled around for a number of timer ticks.
|
||||
The more CPUs, the worse this effect.
|
||||
|
||||
Furthermore, this same effect causes the bouncing effect as well:
|
||||
whenever there is such a 'timeslice squeeze' of the global runqueue,
|
||||
idle processors start executing tasks which are not affine to that CPU.
|
||||
(because the affine tasks have finished off their timeslices already.)
|
||||
|
||||
The new scheduler solves this problem by distributing timeslices on a
|
||||
per-CPU basis, without having any global synchronization or
|
||||
recalculation.
|
||||
|
||||
- batch scheduling. A significant proportion of computing-intensive tasks
|
||||
benefit from batch-scheduling, where timeslices are long and processes
|
||||
are roundrobin scheduled. The new scheduler does such batch-scheduling
|
||||
of the lowest priority tasks - so nice +19 jobs will get
|
||||
'batch-scheduled' automatically. With this scheduler, nice +19 jobs are
|
||||
in essence SCHED_IDLE, from an interactiveness point of view.
|
||||
|
||||
- handle extreme loads more smoothly, without breakdown and scheduling
|
||||
storms.
|
||||
|
||||
- O(1) RT scheduling. For those RT folks who are paranoid about the
|
||||
O(nr_running) property of the goodness loop and the recalculation loop.
|
||||
|
||||
- run fork()ed children before the parent. Andrea has pointed out the
|
||||
advantages of this a few months ago, but patches for this feature
|
||||
do not work with the old scheduler as well as they should,
|
||||
because idle processes often steal the new child before the fork()ing
|
||||
CPU gets to execute it.
|
||||
|
||||
|
||||
Design
|
||||
======
|
||||
|
||||
The core of the new scheduler contains the following mechanisms:
|
||||
|
||||
- *two* priority-ordered 'priority arrays' per CPU. There is an 'active'
|
||||
array and an 'expired' array. The active array contains all tasks that
|
||||
are affine to this CPU and have timeslices left. The expired array
|
||||
contains all tasks which have used up their timeslices - but this array
|
||||
is kept sorted as well. The active and expired array is not accessed
|
||||
directly, it's accessed through two pointers in the per-CPU runqueue
|
||||
structure. If all active tasks are used up then we 'switch' the two
|
||||
pointers and from now on the ready-to-go (former-) expired array is the
|
||||
active array - and the empty active array serves as the new collector
|
||||
for expired tasks.
|
||||
|
||||
- there is a 64-bit bitmap cache for array indices. Finding the highest
|
||||
priority task is thus a matter of two x86 BSFL bit-search instructions.
|
||||
|
||||
the split-array solution enables us to have an arbitrary number of active
|
||||
and expired tasks, and the recalculation of timeslices can be done
|
||||
immediately when the timeslice expires. Because the arrays are always
|
||||
access through the pointers in the runqueue, switching the two arrays can
|
||||
be done very quickly.
|
||||
|
||||
this is a hybride priority-list approach coupled with roundrobin
|
||||
scheduling and the array-switch method of distributing timeslices.
|
||||
|
||||
- there is a per-task 'load estimator'.
|
||||
|
||||
one of the toughest things to get right is good interactive feel during
|
||||
heavy system load. While playing with various scheduler variants i found
|
||||
that the best interactive feel is achieved not by 'boosting' interactive
|
||||
tasks, but by 'punishing' tasks that want to use more CPU time than there
|
||||
is available. This method is also much easier to do in an O(1) fashion.
|
||||
|
||||
to establish the actual 'load' the task contributes to the system, a
|
||||
complex-looking but pretty accurate method is used: there is a 4-entry
|
||||
'history' ringbuffer of the task's activities during the last 4 seconds.
|
||||
This ringbuffer is operated without much overhead. The entries tell the
|
||||
scheduler a pretty accurate load-history of the task: has it used up more
|
||||
CPU time or less during the past N seconds. [the size '4' and the interval
|
||||
of 4x 1 seconds was found by lots of experimentation - this part is
|
||||
flexible and can be changed in both directions.]
|
||||
|
||||
the penalty a task gets for generating more load than the CPU can handle
|
||||
is a priority decrease - there is a maximum amount to this penalty
|
||||
relative to their static priority, so even fully CPU-bound tasks will
|
||||
observe each other's priorities, and will share the CPU accordingly.
|
||||
|
||||
the SMP load-balancer can be extended/switched with additional parallel
|
||||
computing and cache hierarchy concepts: NUMA scheduling, multi-core CPUs
|
||||
can be supported easily by changing the load-balancer. Right now it's
|
||||
tuned for my SMP systems.
|
||||
|
||||
i skipped the prev->mm == next->mm advantage - no workload i know of shows
|
||||
any sensitivity to this. It can be added back by sacrificing O(1)
|
||||
schedule() [the current and one-lower priority list can be searched for a
|
||||
that->mm == current->mm condition], but costs a fair number of cycles
|
||||
during a number of important workloads, so i wanted to avoid this as much
|
||||
as possible.
|
||||
|
||||
- the SMP idle-task startup code was still racy and the new scheduler
|
||||
triggered this. So i streamlined the idle-setup code a bit. We do not call
|
||||
into schedule() before all processors have started up fully and all idle
|
||||
threads are in place.
|
||||
|
||||
- the patch also cleans up a number of aspects of sched.c - moves code
|
||||
into other areas of the kernel where it's appropriate, and simplifies
|
||||
certain code paths and data constructs. As a result, the new scheduler's
|
||||
code is smaller than the old one.
|
||||
|
||||
Ingo
|
|
@ -5,6 +5,6 @@
|
|||
4 -> DViCO FusionHDTV5 Express [18ac:d500]
|
||||
5 -> Hauppauge WinTV-HVR1500Q [0070:7790,0070:7797]
|
||||
6 -> Hauppauge WinTV-HVR1500 [0070:7710,0070:7717]
|
||||
7 -> Hauppauge WinTV-HVR1200 [0070:71d1]
|
||||
7 -> Hauppauge WinTV-HVR1200 [0070:71d1,0070:71d3]
|
||||
8 -> Hauppauge WinTV-HVR1700 [0070:8101]
|
||||
9 -> Hauppauge WinTV-HVR1400 [0070:8010]
|
||||
|
|
|
@ -14,4 +14,4 @@
|
|||
13 -> Terratec Prodigy XS (em2880) [0ccd:0047]
|
||||
14 -> Pixelview Prolink PlayTV USB 2.0 (em2820/em2840)
|
||||
15 -> V-Gear PocketTV (em2800)
|
||||
16 -> Hauppauge WinTV HVR 950 (em2880) [2040:6513]
|
||||
16 -> Hauppauge WinTV HVR 950 (em2880) [2040:6513,2040:6517,2040:651b,2040:651f]
|
||||
|
|
19
MAINTAINERS
19
MAINTAINERS
|
@ -367,12 +367,12 @@ S: Maintained for 2.4; PCI support for 2.6.
|
|||
AMD GEODE CS5536 USB DEVICE CONTROLLER DRIVER
|
||||
P: Thomas Dahlmann
|
||||
M: thomas.dahlmann@amd.com
|
||||
L: info-linux@geode.amd.com (subscribers-only)
|
||||
L: linux-geode@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Supported
|
||||
|
||||
AMD GEODE PROCESSOR/CHIPSET SUPPORT
|
||||
P: Jordan Crouse
|
||||
L: info-linux@geode.amd.com (subscribers-only)
|
||||
L: linux-geode@lists.infradead.org (moderated for non-subscribers)
|
||||
W: http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html
|
||||
S: Supported
|
||||
|
||||
|
@ -1230,6 +1230,15 @@ P: Jaya Kumar
|
|||
M: jayakumar.alsa@gmail.com
|
||||
S: Maintained
|
||||
|
||||
CX18 VIDEO4LINUX DRIVER
|
||||
P: Hans Verkuil, Andy Walls
|
||||
M: hverkuil@xs4all.nl, awalls@radix.net
|
||||
L: ivtv-devel@ivtvdriver.org
|
||||
L: ivtv-users@ivtvdriver.org
|
||||
L: video4linux-list@redhat.com
|
||||
W: http://linuxtv.org
|
||||
S: Maintained
|
||||
|
||||
CYBERPRO FB DRIVER
|
||||
P: Russell King
|
||||
M: rmk@arm.linux.org.uk
|
||||
|
@ -2112,12 +2121,10 @@ L: netdev@vger.kernel.org
|
|||
S: Maintained
|
||||
|
||||
INTEL ETHERNET DRIVERS (e100/e1000/e1000e/igb/ixgb/ixgbe)
|
||||
P: Auke Kok
|
||||
M: auke-jan.h.kok@intel.com
|
||||
P: Jesse Brandeburg
|
||||
M: jesse.brandeburg@intel.com
|
||||
P: Jeff Kirsher
|
||||
M: jeffrey.t.kirsher@intel.com
|
||||
P: Jesse Brandeburg
|
||||
M: jesse.brandeburg@intel.com
|
||||
P: Bruce Allan
|
||||
M: bruce.w.allan@intel.com
|
||||
P: John Ronciak
|
||||
|
|
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
|||
VERSION = 2
|
||||
PATCHLEVEL = 6
|
||||
SUBLEVEL = 26
|
||||
EXTRAVERSION = -rc1
|
||||
EXTRAVERSION = -rc2
|
||||
NAME = Funky Weasel is Jiggy wit it
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
|
@ -544,10 +544,10 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
|
|||
struct resource *fb_res = &lcdc_resources[2];
|
||||
size_t fb_len = fb_res->end - fb_res->start + 1;
|
||||
|
||||
fb = ioremap_writecombine(fb_res->start, fb_len);
|
||||
fb = ioremap(fb_res->start, fb_len);
|
||||
if (fb) {
|
||||
memset(fb, 0, fb_len);
|
||||
iounmap(fb, fb_len);
|
||||
iounmap(fb);
|
||||
}
|
||||
}
|
||||
lcdc_data = *data;
|
||||
|
|
|
@ -332,13 +332,6 @@ static struct resource lcdc_resources[] = {
|
|||
.end = AT91SAM9RL_ID_LCDC,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
#if defined(CONFIG_FB_INTSRAM)
|
||||
[2] = {
|
||||
.start = AT91SAM9RL_SRAM_BASE,
|
||||
.end = AT91SAM9RL_SRAM_BASE + AT91SAM9RL_SRAM_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct platform_device at91_lcdc_device = {
|
||||
|
@ -381,20 +374,6 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
|
|||
at91_set_B_periph(AT91_PIN_PC24, 0); /* LCDD22 */
|
||||
at91_set_B_periph(AT91_PIN_PC25, 0); /* LCDD23 */
|
||||
|
||||
#ifdef CONFIG_FB_INTSRAM
|
||||
{
|
||||
void __iomem *fb;
|
||||
struct resource *fb_res = &lcdc_resources[2];
|
||||
size_t fb_len = fb_res->end - fb_res->start + 1;
|
||||
|
||||
fb = ioremap_writecombine(fb_res->start, fb_len);
|
||||
if (fb) {
|
||||
memset(fb, 0, fb_len);
|
||||
iounmap(fb, fb_len);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
lcdc_data = *data;
|
||||
platform_device_register(&at91_lcdc_device);
|
||||
}
|
||||
|
|
|
@ -280,7 +280,7 @@ static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type)
|
|||
const int port = gpio >> 3;
|
||||
const int port_mask = 1 << (gpio & 7);
|
||||
|
||||
gpio_direction_output(gpio, gpio_get_value(gpio));
|
||||
gpio_direction_input(gpio);
|
||||
|
||||
switch (type) {
|
||||
case IRQT_RISING:
|
||||
|
|
|
@ -62,7 +62,7 @@ static struct irq_chip ns9xxx_chip = {
|
|||
#if 0
|
||||
#define handle_irq handle_level_irq
|
||||
#else
|
||||
void handle_prio_irq(unsigned int irq, struct irq_desc *desc)
|
||||
static void handle_prio_irq(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
unsigned int cpu = smp_processor_id();
|
||||
struct irqaction *action;
|
||||
|
@ -70,27 +70,35 @@ void handle_prio_irq(unsigned int irq, struct irq_desc *desc)
|
|||
|
||||
spin_lock(&desc->lock);
|
||||
|
||||
if (unlikely(desc->status & IRQ_INPROGRESS))
|
||||
goto out_unlock;
|
||||
BUG_ON(desc->status & IRQ_INPROGRESS);
|
||||
|
||||
desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
|
||||
kstat_cpu(cpu).irqs[irq]++;
|
||||
|
||||
action = desc->action;
|
||||
if (unlikely(!action || (desc->status & IRQ_DISABLED)))
|
||||
goto out_unlock;
|
||||
goto out_mask;
|
||||
|
||||
desc->status |= IRQ_INPROGRESS;
|
||||
spin_unlock(&desc->lock);
|
||||
|
||||
action_ret = handle_IRQ_event(irq, action);
|
||||
|
||||
/* XXX: There is no direct way to access noirqdebug, so check
|
||||
* unconditionally for spurious irqs...
|
||||
* Maybe this function should go to kernel/irq/chip.c? */
|
||||
note_interrupt(irq, desc, action_ret);
|
||||
|
||||
spin_lock(&desc->lock);
|
||||
desc->status &= ~IRQ_INPROGRESS;
|
||||
if (!(desc->status & IRQ_DISABLED) && desc->chip->ack)
|
||||
desc->chip->ack(irq);
|
||||
|
||||
out_unlock:
|
||||
if (desc->status & IRQ_DISABLED)
|
||||
out_mask:
|
||||
desc->chip->mask(irq);
|
||||
|
||||
/* ack unconditionally to unmask lower prio irqs */
|
||||
desc->chip->ack(irq);
|
||||
|
||||
spin_unlock(&desc->lock);
|
||||
}
|
||||
#define handle_irq handle_prio_irq
|
||||
|
|
|
@ -34,11 +34,7 @@
|
|||
* Non-CPU Masters address decoding --
|
||||
* Unlike the CPU, we setup the access from Orion's master interfaces to DDR
|
||||
* banks only (the typical use case).
|
||||
* Setup access for each master to DDR is issued by common.c.
|
||||
*
|
||||
* Note: although orion_setbits() and orion_clrbits() are not atomic
|
||||
* no locking is necessary here since code in this file is only called
|
||||
* at boot time when there is no concurrency issues.
|
||||
* Setup access for each master to DDR is issued by platform device setup.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -48,10 +44,6 @@
|
|||
#define TARGET_DEV_BUS 1
|
||||
#define TARGET_PCI 3
|
||||
#define TARGET_PCIE 4
|
||||
#define ATTR_DDR_CS(n) (((n) ==0) ? 0xe : \
|
||||
((n) == 1) ? 0xd : \
|
||||
((n) == 2) ? 0xb : \
|
||||
((n) == 3) ? 0x7 : 0xf)
|
||||
#define ATTR_PCIE_MEM 0x59
|
||||
#define ATTR_PCIE_IO 0x51
|
||||
#define ATTR_PCIE_WA 0x79
|
||||
|
@ -61,17 +53,12 @@
|
|||
#define ATTR_DEV_CS1 0x1d
|
||||
#define ATTR_DEV_CS2 0x1b
|
||||
#define ATTR_DEV_BOOT 0xf
|
||||
#define WIN_EN 1
|
||||
|
||||
/*
|
||||
* Helpers to get DDR bank info
|
||||
*/
|
||||
#define DDR_BASE_CS(n) ORION5X_DDR_REG(0x1500 + ((n) * 8))
|
||||
#define DDR_SIZE_CS(n) ORION5X_DDR_REG(0x1504 + ((n) * 8))
|
||||
#define DDR_MAX_CS 4
|
||||
#define DDR_REG_TO_SIZE(reg) (((reg) | 0xffffff) + 1)
|
||||
#define DDR_REG_TO_BASE(reg) ((reg) & 0xff000000)
|
||||
#define DDR_BANK_EN 1
|
||||
#define DDR_BASE_CS(n) ORION5X_DDR_REG(0x1500 + ((n) << 3))
|
||||
#define DDR_SIZE_CS(n) ORION5X_DDR_REG(0x1504 + ((n) << 3))
|
||||
|
||||
/*
|
||||
* CPU Address Decode Windows registers
|
||||
|
@ -81,17 +68,6 @@
|
|||
#define CPU_WIN_REMAP_LO(n) ORION5X_BRIDGE_REG(0x008 | ((n) << 4))
|
||||
#define CPU_WIN_REMAP_HI(n) ORION5X_BRIDGE_REG(0x00c | ((n) << 4))
|
||||
|
||||
/*
|
||||
* Gigabit Ethernet Address Decode Windows registers
|
||||
*/
|
||||
#define ETH_WIN_BASE(win) ORION5X_ETH_REG(0x200 + ((win) * 8))
|
||||
#define ETH_WIN_SIZE(win) ORION5X_ETH_REG(0x204 + ((win) * 8))
|
||||
#define ETH_WIN_REMAP(win) ORION5X_ETH_REG(0x280 + ((win) * 4))
|
||||
#define ETH_WIN_EN ORION5X_ETH_REG(0x290)
|
||||
#define ETH_WIN_PROT ORION5X_ETH_REG(0x294)
|
||||
#define ETH_MAX_WIN 6
|
||||
#define ETH_MAX_REMAP_WIN 4
|
||||
|
||||
|
||||
struct mbus_dram_target_info orion5x_mbus_dram_info;
|
||||
|
||||
|
@ -202,39 +178,3 @@ void __init orion5x_setup_pcie_wa_win(u32 base, u32 size)
|
|||
{
|
||||
setup_cpu_win(7, base, size, TARGET_PCIE, ATTR_PCIE_WA, -1);
|
||||
}
|
||||
|
||||
void __init orion5x_setup_eth_wins(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
* First, disable and clear windows
|
||||
*/
|
||||
for (i = 0; i < ETH_MAX_WIN; i++) {
|
||||
orion5x_write(ETH_WIN_BASE(i), 0);
|
||||
orion5x_write(ETH_WIN_SIZE(i), 0);
|
||||
orion5x_setbits(ETH_WIN_EN, 1 << i);
|
||||
orion5x_clrbits(ETH_WIN_PROT, 0x3 << (i * 2));
|
||||
if (i < ETH_MAX_REMAP_WIN)
|
||||
orion5x_write(ETH_WIN_REMAP(i), 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup windows for DDR banks.
|
||||
*/
|
||||
for (i = 0; i < DDR_MAX_CS; i++) {
|
||||
u32 base, size;
|
||||
size = orion5x_read(DDR_SIZE_CS(i));
|
||||
base = orion5x_read(DDR_BASE_CS(i));
|
||||
if (size & DDR_BANK_EN) {
|
||||
base = DDR_REG_TO_BASE(base);
|
||||
size = DDR_REG_TO_SIZE(size);
|
||||
orion5x_write(ETH_WIN_SIZE(i), (size-1) & 0xffff0000);
|
||||
orion5x_write(ETH_WIN_BASE(i), (base & 0xffff0000) |
|
||||
(ATTR_DDR_CS(i) << 8) |
|
||||
TARGET_DDR);
|
||||
orion5x_clrbits(ETH_WIN_EN, 1 << i);
|
||||
orion5x_setbits(ETH_WIN_PROT, 0x3 << (i * 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -190,6 +190,11 @@ static struct platform_device orion5x_ehci1 = {
|
|||
* (The Orion and Discovery (MV643xx) families use the same Ethernet driver)
|
||||
****************************************************************************/
|
||||
|
||||
struct mv643xx_eth_shared_platform_data orion5x_eth_shared_data = {
|
||||
.dram = &orion5x_mbus_dram_info,
|
||||
.t_clk = ORION5X_TCLK,
|
||||
};
|
||||
|
||||
static struct resource orion5x_eth_shared_resources[] = {
|
||||
{
|
||||
.start = ORION5X_ETH_PHYS_BASE + 0x2000,
|
||||
|
@ -201,6 +206,9 @@ static struct resource orion5x_eth_shared_resources[] = {
|
|||
static struct platform_device orion5x_eth_shared = {
|
||||
.name = MV643XX_ETH_SHARED_NAME,
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &orion5x_eth_shared_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = orion5x_eth_shared_resources,
|
||||
};
|
||||
|
@ -223,7 +231,9 @@ static struct platform_device orion5x_eth = {
|
|||
|
||||
void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data)
|
||||
{
|
||||
eth_data->shared = &orion5x_eth_shared;
|
||||
orion5x_eth.dev.platform_data = eth_data;
|
||||
|
||||
platform_device_register(&orion5x_eth_shared);
|
||||
platform_device_register(&orion5x_eth);
|
||||
}
|
||||
|
@ -360,7 +370,6 @@ void __init orion5x_init(void)
|
|||
* Setup Orion address map
|
||||
*/
|
||||
orion5x_setup_cpu_mbus_bridge();
|
||||
orion5x_setup_eth_wins();
|
||||
|
||||
/*
|
||||
* Register devices.
|
||||
|
|
|
@ -22,7 +22,6 @@ void orion5x_setup_dev0_win(u32 base, u32 size);
|
|||
void orion5x_setup_dev1_win(u32 base, u32 size);
|
||||
void orion5x_setup_dev2_win(u32 base, u32 size);
|
||||
void orion5x_setup_pcie_wa_win(u32 base, u32 size);
|
||||
void orion5x_setup_eth_wins(void);
|
||||
|
||||
/*
|
||||
* Shared code used internally by other Orion core functions.
|
||||
|
|
|
@ -5,6 +5,13 @@
|
|||
# Common support (must be linked before board specific support)
|
||||
obj-y += clock.o devices.o generic.o irq.o dma.o \
|
||||
time.o gpio.o
|
||||
obj-$(CONFIG_PM) += pm.o sleep.o standby.o
|
||||
obj-$(CONFIG_CPU_FREQ) += cpu-pxa.o
|
||||
|
||||
# Generic drivers that other drivers may depend upon
|
||||
obj-$(CONFIG_PXA_SSP) += ssp.o
|
||||
|
||||
# SoC-specific code
|
||||
obj-$(CONFIG_PXA25x) += mfp-pxa2xx.o pxa25x.o
|
||||
obj-$(CONFIG_PXA27x) += mfp-pxa2xx.o pxa27x.o
|
||||
obj-$(CONFIG_PXA3xx) += mfp-pxa3xx.o pxa3xx.o smemc.o
|
||||
|
@ -48,11 +55,6 @@ led-$(CONFIG_MACH_TRIZEPS4) += leds-trizeps4.o
|
|||
|
||||
obj-$(CONFIG_LEDS) += $(led-y)
|
||||
|
||||
# Misc features
|
||||
obj-$(CONFIG_PM) += pm.o sleep.o standby.o
|
||||
obj-$(CONFIG_CPU_FREQ) += cpu-pxa.o
|
||||
obj-$(CONFIG_PXA_SSP) += ssp.o
|
||||
|
||||
ifeq ($(CONFIG_PCI),y)
|
||||
obj-$(CONFIG_MACH_ARMCORE) += cm-x270-pci.o
|
||||
endif
|
||||
|
|
|
@ -493,8 +493,6 @@ static struct platform_device *devices[] __initdata = {
|
|||
|
||||
static void corgi_poweroff(void)
|
||||
{
|
||||
RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
|
||||
|
||||
if (!machine_is_corgi())
|
||||
/* Green LED off tells the bootloader to halt */
|
||||
reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN);
|
||||
|
@ -503,8 +501,6 @@ static void corgi_poweroff(void)
|
|||
|
||||
static void corgi_restart(char mode)
|
||||
{
|
||||
RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
|
||||
|
||||
if (!machine_is_corgi())
|
||||
/* Green LED on tells the bootloader to reboot */
|
||||
set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN);
|
||||
|
|
|
@ -49,125 +49,216 @@ MODULE_PARM_DESC(freq_debug, "Set the debug messages to on=1/off=0");
|
|||
#define freq_debug 0
|
||||
#endif
|
||||
|
||||
static unsigned int pxa27x_maxfreq;
|
||||
module_param(pxa27x_maxfreq, uint, 0);
|
||||
MODULE_PARM_DESC(pxa27x_maxfreq, "Set the pxa27x maxfreq in MHz"
|
||||
"(typically 624=>pxa270, 416=>pxa271, 520=>pxa272)");
|
||||
|
||||
typedef struct {
|
||||
unsigned int khz;
|
||||
unsigned int membus;
|
||||
unsigned int cccr;
|
||||
unsigned int div2;
|
||||
unsigned int cclkcfg;
|
||||
} pxa_freqs_t;
|
||||
|
||||
/* Define the refresh period in mSec for the SDRAM and the number of rows */
|
||||
#define SDRAM_TREF 64 /* standard 64ms SDRAM */
|
||||
#define SDRAM_ROWS 4096 /* 64MB=8192 32MB=4096 */
|
||||
#define MDREFR_DRI(x) (((x) * SDRAM_TREF) / (SDRAM_ROWS * 32))
|
||||
|
||||
#define CCLKCFG_TURBO 0x1
|
||||
#define CCLKCFG_FCS 0x2
|
||||
#define PXA25x_MIN_FREQ 99500
|
||||
#define PXA25x_MAX_FREQ 398100
|
||||
#define MDREFR_DB2_MASK (MDREFR_K2DB2 | MDREFR_K1DB2)
|
||||
#define MDREFR_DRI_MASK 0xFFF
|
||||
#define SDRAM_TREF 64 /* standard 64ms SDRAM */
|
||||
#define SDRAM_ROWS 4096 /* 64MB=8192 32MB=4096 */
|
||||
|
||||
#define CCLKCFG_TURBO 0x1
|
||||
#define CCLKCFG_FCS 0x2
|
||||
#define CCLKCFG_HALFTURBO 0x4
|
||||
#define CCLKCFG_FASTBUS 0x8
|
||||
#define MDREFR_DB2_MASK (MDREFR_K2DB2 | MDREFR_K1DB2)
|
||||
#define MDREFR_DRI_MASK 0xFFF
|
||||
|
||||
/*
|
||||
* PXA255 definitions
|
||||
*/
|
||||
/* Use the run mode frequencies for the CPUFREQ_POLICY_PERFORMANCE policy */
|
||||
#define CCLKCFG CCLKCFG_TURBO | CCLKCFG_FCS
|
||||
|
||||
static pxa_freqs_t pxa255_run_freqs[] =
|
||||
{
|
||||
/* CPU MEMBUS CCCR DIV2*/
|
||||
{ 99500, 99500, 0x121, 1}, /* run= 99, turbo= 99, PXbus=50, SDRAM=50 */
|
||||
{132700, 132700, 0x123, 1}, /* run=133, turbo=133, PXbus=66, SDRAM=66 */
|
||||
{199100, 99500, 0x141, 0}, /* run=199, turbo=199, PXbus=99, SDRAM=99 */
|
||||
{265400, 132700, 0x143, 1}, /* run=265, turbo=265, PXbus=133, SDRAM=66 */
|
||||
{331800, 165900, 0x145, 1}, /* run=331, turbo=331, PXbus=166, SDRAM=83 */
|
||||
{398100, 99500, 0x161, 0}, /* run=398, turbo=398, PXbus=196, SDRAM=99 */
|
||||
{0,}
|
||||
/* CPU MEMBUS CCCR DIV2 CCLKCFG run turbo PXbus SDRAM */
|
||||
{ 99500, 99500, 0x121, 1, CCLKCFG}, /* 99, 99, 50, 50 */
|
||||
{132700, 132700, 0x123, 1, CCLKCFG}, /* 133, 133, 66, 66 */
|
||||
{199100, 99500, 0x141, 0, CCLKCFG}, /* 199, 199, 99, 99 */
|
||||
{265400, 132700, 0x143, 1, CCLKCFG}, /* 265, 265, 133, 66 */
|
||||
{331800, 165900, 0x145, 1, CCLKCFG}, /* 331, 331, 166, 83 */
|
||||
{398100, 99500, 0x161, 0, CCLKCFG}, /* 398, 398, 196, 99 */
|
||||
};
|
||||
#define NUM_RUN_FREQS ARRAY_SIZE(pxa255_run_freqs)
|
||||
|
||||
static struct cpufreq_frequency_table pxa255_run_freq_table[NUM_RUN_FREQS+1];
|
||||
|
||||
/* Use the turbo mode frequencies for the CPUFREQ_POLICY_POWERSAVE policy */
|
||||
static pxa_freqs_t pxa255_turbo_freqs[] =
|
||||
{
|
||||
/* CPU MEMBUS CCCR DIV2*/
|
||||
{ 99500, 99500, 0x121, 1}, /* run=99, turbo= 99, PXbus=50, SDRAM=50 */
|
||||
{199100, 99500, 0x221, 0}, /* run=99, turbo=199, PXbus=50, SDRAM=99 */
|
||||
{298500, 99500, 0x321, 0}, /* run=99, turbo=287, PXbus=50, SDRAM=99 */
|
||||
{298600, 99500, 0x1c1, 0}, /* run=199, turbo=287, PXbus=99, SDRAM=99 */
|
||||
{398100, 99500, 0x241, 0}, /* run=199, turbo=398, PXbus=99, SDRAM=99 */
|
||||
{0,}
|
||||
/* CPU MEMBUS CCCR DIV2 CCLKCFG run turbo PXbus SDRAM */
|
||||
{ 99500, 99500, 0x121, 1, CCLKCFG}, /* 99, 99, 50, 50 */
|
||||
{199100, 99500, 0x221, 0, CCLKCFG}, /* 99, 199, 50, 99 */
|
||||
{298500, 99500, 0x321, 0, CCLKCFG}, /* 99, 287, 50, 99 */
|
||||
{298600, 99500, 0x1c1, 0, CCLKCFG}, /* 199, 287, 99, 99 */
|
||||
{398100, 99500, 0x241, 0, CCLKCFG}, /* 199, 398, 99, 99 */
|
||||
};
|
||||
#define NUM_TURBO_FREQS ARRAY_SIZE(pxa255_turbo_freqs)
|
||||
|
||||
static struct cpufreq_frequency_table pxa255_turbo_freq_table[NUM_TURBO_FREQS+1];
|
||||
#define NUM_PXA25x_RUN_FREQS ARRAY_SIZE(pxa255_run_freqs)
|
||||
#define NUM_PXA25x_TURBO_FREQS ARRAY_SIZE(pxa255_turbo_freqs)
|
||||
|
||||
static struct cpufreq_frequency_table
|
||||
pxa255_run_freq_table[NUM_PXA25x_RUN_FREQS+1];
|
||||
static struct cpufreq_frequency_table
|
||||
pxa255_turbo_freq_table[NUM_PXA25x_TURBO_FREQS+1];
|
||||
|
||||
/*
|
||||
* PXA270 definitions
|
||||
*
|
||||
* For the PXA27x:
|
||||
* Control variables are A, L, 2N for CCCR; B, HT, T for CLKCFG.
|
||||
*
|
||||
* A = 0 => memory controller clock from table 3-7,
|
||||
* A = 1 => memory controller clock = system bus clock
|
||||
* Run mode frequency = 13 MHz * L
|
||||
* Turbo mode frequency = 13 MHz * L * N
|
||||
* System bus frequency = 13 MHz * L / (B + 1)
|
||||
*
|
||||
* In CCCR:
|
||||
* A = 1
|
||||
* L = 16 oscillator to run mode ratio
|
||||
* 2N = 6 2 * (turbo mode to run mode ratio)
|
||||
*
|
||||
* In CCLKCFG:
|
||||
* B = 1 Fast bus mode
|
||||
* HT = 0 Half-Turbo mode
|
||||
* T = 1 Turbo mode
|
||||
*
|
||||
* For now, just support some of the combinations in table 3-7 of
|
||||
* PXA27x Processor Family Developer's Manual to simplify frequency
|
||||
* change sequences.
|
||||
*/
|
||||
#define PXA27x_CCCR(A, L, N2) (A << 25 | N2 << 7 | L)
|
||||
#define CCLKCFG2(B, HT, T) \
|
||||
(CCLKCFG_FCS | \
|
||||
((B) ? CCLKCFG_FASTBUS : 0) | \
|
||||
((HT) ? CCLKCFG_HALFTURBO : 0) | \
|
||||
((T) ? CCLKCFG_TURBO : 0))
|
||||
|
||||
static pxa_freqs_t pxa27x_freqs[] = {
|
||||
{104000, 104000, PXA27x_CCCR(1, 8, 2), 0, CCLKCFG2(1, 0, 1)},
|
||||
{156000, 104000, PXA27x_CCCR(1, 8, 6), 0, CCLKCFG2(1, 1, 1)},
|
||||
{208000, 208000, PXA27x_CCCR(0, 16, 2), 1, CCLKCFG2(0, 0, 1)},
|
||||
{312000, 208000, PXA27x_CCCR(1, 16, 3), 1, CCLKCFG2(1, 0, 1)},
|
||||
{416000, 208000, PXA27x_CCCR(1, 16, 4), 1, CCLKCFG2(1, 0, 1)},
|
||||
{520000, 208000, PXA27x_CCCR(1, 16, 5), 1, CCLKCFG2(1, 0, 1)},
|
||||
{624000, 208000, PXA27x_CCCR(1, 16, 6), 1, CCLKCFG2(1, 0, 1)}
|
||||
};
|
||||
|
||||
#define NUM_PXA27x_FREQS ARRAY_SIZE(pxa27x_freqs)
|
||||
static struct cpufreq_frequency_table
|
||||
pxa27x_freq_table[NUM_PXA27x_FREQS+1];
|
||||
|
||||
extern unsigned get_clk_frequency_khz(int info);
|
||||
|
||||
static void find_freq_tables(struct cpufreq_policy *policy,
|
||||
struct cpufreq_frequency_table **freq_table,
|
||||
pxa_freqs_t **pxa_freqs)
|
||||
{
|
||||
if (cpu_is_pxa25x()) {
|
||||
if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
|
||||
*pxa_freqs = pxa255_run_freqs;
|
||||
*freq_table = pxa255_run_freq_table;
|
||||
} else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
|
||||
*pxa_freqs = pxa255_turbo_freqs;
|
||||
*freq_table = pxa255_turbo_freq_table;
|
||||
} else {
|
||||
printk("CPU PXA: Unknown policy found. "
|
||||
"Using CPUFREQ_POLICY_PERFORMANCE\n");
|
||||
*pxa_freqs = pxa255_run_freqs;
|
||||
*freq_table = pxa255_run_freq_table;
|
||||
}
|
||||
}
|
||||
if (cpu_is_pxa27x()) {
|
||||
*pxa_freqs = pxa27x_freqs;
|
||||
*freq_table = pxa27x_freq_table;
|
||||
}
|
||||
}
|
||||
|
||||
static void pxa27x_guess_max_freq(void)
|
||||
{
|
||||
if (!pxa27x_maxfreq) {
|
||||
pxa27x_maxfreq = 416000;
|
||||
printk(KERN_INFO "PXA CPU 27x max frequency not defined "
|
||||
"(pxa27x_maxfreq), assuming pxa271 with %dkHz maxfreq\n",
|
||||
pxa27x_maxfreq);
|
||||
} else {
|
||||
pxa27x_maxfreq *= 1000;
|
||||
}
|
||||
}
|
||||
|
||||
static u32 mdrefr_dri(unsigned int freq)
|
||||
{
|
||||
u32 dri = 0;
|
||||
|
||||
if (cpu_is_pxa25x())
|
||||
dri = ((freq * SDRAM_TREF) / (SDRAM_ROWS * 32));
|
||||
if (cpu_is_pxa27x())
|
||||
dri = ((freq * SDRAM_TREF) / (SDRAM_ROWS - 31)) / 32;
|
||||
return dri;
|
||||
}
|
||||
|
||||
/* find a valid frequency point */
|
||||
static int pxa_verify_policy(struct cpufreq_policy *policy)
|
||||
{
|
||||
struct cpufreq_frequency_table *pxa_freqs_table;
|
||||
pxa_freqs_t *pxa_freqs;
|
||||
int ret;
|
||||
|
||||
if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
|
||||
pxa_freqs_table = pxa255_run_freq_table;
|
||||
} else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
|
||||
pxa_freqs_table = pxa255_turbo_freq_table;
|
||||
} else {
|
||||
printk("CPU PXA: Unknown policy found. "
|
||||
"Using CPUFREQ_POLICY_PERFORMANCE\n");
|
||||
pxa_freqs_table = pxa255_run_freq_table;
|
||||
}
|
||||
|
||||
find_freq_tables(policy, &pxa_freqs_table, &pxa_freqs);
|
||||
ret = cpufreq_frequency_table_verify(policy, pxa_freqs_table);
|
||||
|
||||
if (freq_debug)
|
||||
pr_debug("Verified CPU policy: %dKhz min to %dKhz max\n",
|
||||
policy->min, policy->max);
|
||||
policy->min, policy->max);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static unsigned int pxa_cpufreq_get(unsigned int cpu)
|
||||
{
|
||||
return get_clk_frequency_khz(0);
|
||||
}
|
||||
|
||||
static int pxa_set_target(struct cpufreq_policy *policy,
|
||||
unsigned int target_freq,
|
||||
unsigned int relation)
|
||||
unsigned int target_freq,
|
||||
unsigned int relation)
|
||||
{
|
||||
struct cpufreq_frequency_table *pxa_freqs_table;
|
||||
pxa_freqs_t *pxa_freq_settings;
|
||||
struct cpufreq_freqs freqs;
|
||||
unsigned int idx;
|
||||
unsigned long flags;
|
||||
unsigned int unused, preset_mdrefr, postset_mdrefr;
|
||||
void *ramstart = phys_to_virt(0xa0000000);
|
||||
unsigned int new_freq_cpu, new_freq_mem;
|
||||
unsigned int unused, preset_mdrefr, postset_mdrefr, cclkcfg;
|
||||
|
||||
/* Get the current policy */
|
||||
if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
|
||||
pxa_freq_settings = pxa255_run_freqs;
|
||||
pxa_freqs_table = pxa255_run_freq_table;
|
||||
} else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
|
||||
pxa_freq_settings = pxa255_turbo_freqs;
|
||||
pxa_freqs_table = pxa255_turbo_freq_table;
|
||||
} else {
|
||||
printk("CPU PXA: Unknown policy found. "
|
||||
"Using CPUFREQ_POLICY_PERFORMANCE\n");
|
||||
pxa_freq_settings = pxa255_run_freqs;
|
||||
pxa_freqs_table = pxa255_run_freq_table;
|
||||
}
|
||||
find_freq_tables(policy, &pxa_freqs_table, &pxa_freq_settings);
|
||||
|
||||
/* Lookup the next frequency */
|
||||
if (cpufreq_frequency_table_target(policy, pxa_freqs_table,
|
||||
target_freq, relation, &idx)) {
|
||||
target_freq, relation, &idx)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
new_freq_cpu = pxa_freq_settings[idx].khz;
|
||||
new_freq_mem = pxa_freq_settings[idx].membus;
|
||||
freqs.old = policy->cur;
|
||||
freqs.new = pxa_freq_settings[idx].khz;
|
||||
freqs.new = new_freq_cpu;
|
||||
freqs.cpu = policy->cpu;
|
||||
|
||||
if (freq_debug)
|
||||
pr_debug(KERN_INFO "Changing CPU frequency to %d Mhz, (SDRAM %d Mhz)\n",
|
||||
freqs.new / 1000, (pxa_freq_settings[idx].div2) ?
|
||||
(pxa_freq_settings[idx].membus / 2000) :
|
||||
(pxa_freq_settings[idx].membus / 1000));
|
||||
pr_debug(KERN_INFO "Changing CPU frequency to %d Mhz, "
|
||||
"(SDRAM %d Mhz)\n",
|
||||
freqs.new / 1000, (pxa_freq_settings[idx].div2) ?
|
||||
(new_freq_mem / 2000) : (new_freq_mem / 1000));
|
||||
|
||||
/*
|
||||
* Tell everyone what we're about to do...
|
||||
|
@ -177,16 +268,16 @@ static int pxa_set_target(struct cpufreq_policy *policy,
|
|||
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
|
||||
|
||||
/* Calculate the next MDREFR. If we're slowing down the SDRAM clock
|
||||
* we need to preset the smaller DRI before the change. If we're speeding
|
||||
* up we need to set the larger DRI value after the change.
|
||||
* we need to preset the smaller DRI before the change. If we're
|
||||
* speeding up we need to set the larger DRI value after the change.
|
||||
*/
|
||||
preset_mdrefr = postset_mdrefr = MDREFR;
|
||||
if ((MDREFR & MDREFR_DRI_MASK) > MDREFR_DRI(pxa_freq_settings[idx].membus)) {
|
||||
preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK) |
|
||||
MDREFR_DRI(pxa_freq_settings[idx].membus);
|
||||
if ((MDREFR & MDREFR_DRI_MASK) > mdrefr_dri(new_freq_mem)) {
|
||||
preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK);
|
||||
preset_mdrefr |= mdrefr_dri(new_freq_mem);
|
||||
}
|
||||
postset_mdrefr = (postset_mdrefr & ~MDREFR_DRI_MASK) |
|
||||
MDREFR_DRI(pxa_freq_settings[idx].membus);
|
||||
postset_mdrefr =
|
||||
(postset_mdrefr & ~MDREFR_DRI_MASK) | mdrefr_dri(new_freq_mem);
|
||||
|
||||
/* If we're dividing the memory clock by two for the SDRAM clock, this
|
||||
* must be set prior to the change. Clearing the divide must be done
|
||||
|
@ -201,26 +292,27 @@ static int pxa_set_target(struct cpufreq_policy *policy,
|
|||
|
||||
local_irq_save(flags);
|
||||
|
||||
/* Set new the CCCR */
|
||||
/* Set new the CCCR and prepare CCLKCFG */
|
||||
CCCR = pxa_freq_settings[idx].cccr;
|
||||
cclkcfg = pxa_freq_settings[idx].cclkcfg;
|
||||
|
||||
asm volatile(" \n\
|
||||
ldr r4, [%1] /* load MDREFR */ \n\
|
||||
b 2f \n\
|
||||
.align 5 \n\
|
||||
.align 5 \n\
|
||||
1: \n\
|
||||
str %4, [%1] /* preset the MDREFR */ \n\
|
||||
str %3, [%1] /* preset the MDREFR */ \n\
|
||||
mcr p14, 0, %2, c6, c0, 0 /* set CCLKCFG[FCS] */ \n\
|
||||
str %5, [%1] /* postset the MDREFR */ \n\
|
||||
str %4, [%1] /* postset the MDREFR */ \n\
|
||||
\n\
|
||||
b 3f \n\
|
||||
2: b 1b \n\
|
||||
3: nop \n\
|
||||
"
|
||||
: "=&r" (unused)
|
||||
: "r" (&MDREFR), "r" (CCLKCFG_TURBO|CCLKCFG_FCS), "r" (ramstart),
|
||||
"r" (preset_mdrefr), "r" (postset_mdrefr)
|
||||
: "r4", "r5");
|
||||
: "=&r" (unused)
|
||||
: "r" (&MDREFR), "r" (cclkcfg),
|
||||
"r" (preset_mdrefr), "r" (postset_mdrefr)
|
||||
: "r4", "r5");
|
||||
local_irq_restore(flags);
|
||||
|
||||
/*
|
||||
|
@ -233,38 +325,57 @@ static int pxa_set_target(struct cpufreq_policy *policy,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int pxa_cpufreq_get(unsigned int cpu)
|
||||
{
|
||||
return get_clk_frequency_khz(0);
|
||||
}
|
||||
|
||||
static int pxa_cpufreq_init(struct cpufreq_policy *policy)
|
||||
static __init int pxa_cpufreq_init(struct cpufreq_policy *policy)
|
||||
{
|
||||
int i;
|
||||
unsigned int freq;
|
||||
|
||||
/* try to guess pxa27x cpu */
|
||||
if (cpu_is_pxa27x())
|
||||
pxa27x_guess_max_freq();
|
||||
|
||||
/* set default policy and cpuinfo */
|
||||
policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
|
||||
policy->policy = CPUFREQ_POLICY_PERFORMANCE;
|
||||
policy->cpuinfo.max_freq = PXA25x_MAX_FREQ;
|
||||
policy->cpuinfo.min_freq = PXA25x_MIN_FREQ;
|
||||
if (cpu_is_pxa25x())
|
||||
policy->policy = CPUFREQ_POLICY_PERFORMANCE;
|
||||
policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */
|
||||
policy->cur = get_clk_frequency_khz(0); /* current freq */
|
||||
policy->cur = get_clk_frequency_khz(0); /* current freq */
|
||||
policy->min = policy->max = policy->cur;
|
||||
|
||||
/* Generate the run cpufreq_frequency_table struct */
|
||||
for (i = 0; i < NUM_RUN_FREQS; i++) {
|
||||
/* Generate pxa25x the run cpufreq_frequency_table struct */
|
||||
for (i = 0; i < NUM_PXA25x_RUN_FREQS; i++) {
|
||||
pxa255_run_freq_table[i].frequency = pxa255_run_freqs[i].khz;
|
||||
pxa255_run_freq_table[i].index = i;
|
||||
}
|
||||
|
||||
pxa255_run_freq_table[i].frequency = CPUFREQ_TABLE_END;
|
||||
/* Generate the turbo cpufreq_frequency_table struct */
|
||||
for (i = 0; i < NUM_TURBO_FREQS; i++) {
|
||||
pxa255_turbo_freq_table[i].frequency = pxa255_turbo_freqs[i].khz;
|
||||
|
||||
/* Generate pxa25x the turbo cpufreq_frequency_table struct */
|
||||
for (i = 0; i < NUM_PXA25x_TURBO_FREQS; i++) {
|
||||
pxa255_turbo_freq_table[i].frequency =
|
||||
pxa255_turbo_freqs[i].khz;
|
||||
pxa255_turbo_freq_table[i].index = i;
|
||||
}
|
||||
pxa255_turbo_freq_table[i].frequency = CPUFREQ_TABLE_END;
|
||||
|
||||
/* Generate the pxa27x cpufreq_frequency_table struct */
|
||||
for (i = 0; i < NUM_PXA27x_FREQS; i++) {
|
||||
freq = pxa27x_freqs[i].khz;
|
||||
if (freq > pxa27x_maxfreq)
|
||||
break;
|
||||
pxa27x_freq_table[i].frequency = freq;
|
||||
pxa27x_freq_table[i].index = i;
|
||||
}
|
||||
pxa27x_freq_table[i].frequency = CPUFREQ_TABLE_END;
|
||||
|
||||
/*
|
||||
* Set the policy's minimum and maximum frequencies from the tables
|
||||
* just constructed. This sets cpuinfo.mxx_freq, min and max.
|
||||
*/
|
||||
if (cpu_is_pxa25x())
|
||||
cpufreq_frequency_table_cpuinfo(policy, pxa255_run_freq_table);
|
||||
else if (cpu_is_pxa27x())
|
||||
cpufreq_frequency_table_cpuinfo(policy, pxa27x_freq_table);
|
||||
|
||||
printk(KERN_INFO "PXA CPU frequency change support initialized\n");
|
||||
|
||||
return 0;
|
||||
|
@ -275,26 +386,25 @@ static struct cpufreq_driver pxa_cpufreq_driver = {
|
|||
.target = pxa_set_target,
|
||||
.init = pxa_cpufreq_init,
|
||||
.get = pxa_cpufreq_get,
|
||||
.name = "PXA25x",
|
||||
.name = "PXA2xx",
|
||||
};
|
||||
|
||||
static int __init pxa_cpu_init(void)
|
||||
{
|
||||
int ret = -ENODEV;
|
||||
if (cpu_is_pxa25x())
|
||||
if (cpu_is_pxa25x() || cpu_is_pxa27x())
|
||||
ret = cpufreq_register_driver(&pxa_cpufreq_driver);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit pxa_cpu_exit(void)
|
||||
{
|
||||
if (cpu_is_pxa25x())
|
||||
cpufreq_unregister_driver(&pxa_cpufreq_driver);
|
||||
cpufreq_unregister_driver(&pxa_cpufreq_driver);
|
||||
}
|
||||
|
||||
|
||||
MODULE_AUTHOR ("Intrinsyc Software Inc.");
|
||||
MODULE_DESCRIPTION ("CPU frequency changing driver for the PXA architecture");
|
||||
MODULE_AUTHOR("Intrinsyc Software Inc.");
|
||||
MODULE_DESCRIPTION("CPU frequency changing driver for the PXA architecture");
|
||||
MODULE_LICENSE("GPL");
|
||||
module_init(pxa_cpu_init);
|
||||
module_exit(pxa_cpu_exit);
|
||||
|
|
|
@ -396,7 +396,7 @@ static struct pxafb_mach_info sharp_lm8v31 = {
|
|||
.cmap_inverse = 0,
|
||||
.cmap_static = 0,
|
||||
.lcd_conn = LCD_COLOR_DSTN_16BPP | LCD_PCLK_EDGE_FALL |
|
||||
LCD_AC_BIAS_FREQ(255);
|
||||
LCD_AC_BIAS_FREQ(255),
|
||||
};
|
||||
|
||||
#define MMC_POLL_RATE msecs_to_jiffies(1000)
|
||||
|
|
|
@ -42,20 +42,17 @@ int pxa_pm_enter(suspend_state_t state)
|
|||
if (state != PM_SUSPEND_STANDBY) {
|
||||
pxa_cpu_pm_fns->save(sleep_save);
|
||||
/* before sleeping, calculate and save a checksum */
|
||||
for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++)
|
||||
for (i = 0; i < pxa_cpu_pm_fns->save_count - 1; i++)
|
||||
sleep_save_checksum += sleep_save[i];
|
||||
}
|
||||
|
||||
/* Clear reset status */
|
||||
RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
|
||||
|
||||
/* *** go zzz *** */
|
||||
pxa_cpu_pm_fns->enter(state);
|
||||
cpu_init();
|
||||
|
||||
if (state != PM_SUSPEND_STANDBY) {
|
||||
/* after sleeping, validate the checksum */
|
||||
for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++)
|
||||
for (i = 0; i < pxa_cpu_pm_fns->save_count - 1; i++)
|
||||
checksum += sleep_save[i];
|
||||
|
||||
/* if invalid, display message and wait for a hardware reset */
|
||||
|
@ -101,7 +98,8 @@ static int __init pxa_pm_init(void)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
sleep_save = kmalloc(pxa_cpu_pm_fns->save_size, GFP_KERNEL);
|
||||
sleep_save = kmalloc(pxa_cpu_pm_fns->save_count * sizeof(unsigned long),
|
||||
GFP_KERNEL);
|
||||
if (!sleep_save) {
|
||||
printk(KERN_ERR "failed to alloc memory for pm save\n");
|
||||
return -ENOMEM;
|
||||
|
|
|
@ -326,13 +326,11 @@ static struct platform_device *devices[] __initdata = {
|
|||
|
||||
static void poodle_poweroff(void)
|
||||
{
|
||||
RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
|
||||
arm_machine_restart('h');
|
||||
}
|
||||
|
||||
static void poodle_restart(char mode)
|
||||
{
|
||||
RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
|
||||
arm_machine_restart('h');
|
||||
}
|
||||
|
||||
|
|
|
@ -150,9 +150,7 @@ static struct clk pxa25x_clks[] = {
|
|||
* More ones like CP and general purpose register values are preserved
|
||||
* with the stack pointer in sleep.S.
|
||||
*/
|
||||
enum { SLEEP_SAVE_START = 0,
|
||||
|
||||
SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2,
|
||||
enum { SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2,
|
||||
|
||||
SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U,
|
||||
SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR1_U,
|
||||
|
@ -162,7 +160,7 @@ enum { SLEEP_SAVE_START = 0,
|
|||
|
||||
SLEEP_SAVE_CKEN,
|
||||
|
||||
SLEEP_SAVE_SIZE
|
||||
SLEEP_SAVE_COUNT
|
||||
};
|
||||
|
||||
|
||||
|
@ -200,6 +198,9 @@ static void pxa25x_cpu_pm_restore(unsigned long *sleep_save)
|
|||
|
||||
static void pxa25x_cpu_pm_enter(suspend_state_t state)
|
||||
{
|
||||
/* Clear reset status */
|
||||
RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
|
||||
|
||||
switch (state) {
|
||||
case PM_SUSPEND_MEM:
|
||||
/* set resume return address */
|
||||
|
@ -210,7 +211,7 @@ static void pxa25x_cpu_pm_enter(suspend_state_t state)
|
|||
}
|
||||
|
||||
static struct pxa_cpu_pm_fns pxa25x_cpu_pm_fns = {
|
||||
.save_size = SLEEP_SAVE_SIZE,
|
||||
.save_count = SLEEP_SAVE_COUNT,
|
||||
.valid = suspend_valid_only_mem,
|
||||
.save = pxa25x_cpu_pm_save,
|
||||
.restore = pxa25x_cpu_pm_restore,
|
||||
|
|
|
@ -181,9 +181,7 @@ static struct clk pxa27x_clks[] = {
|
|||
* More ones like CP and general purpose register values are preserved
|
||||
* with the stack pointer in sleep.S.
|
||||
*/
|
||||
enum { SLEEP_SAVE_START = 0,
|
||||
|
||||
SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3,
|
||||
enum { SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3,
|
||||
|
||||
SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U,
|
||||
SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR1_U,
|
||||
|
@ -198,7 +196,7 @@ enum { SLEEP_SAVE_START = 0,
|
|||
SLEEP_SAVE_PWER, SLEEP_SAVE_PCFR, SLEEP_SAVE_PRER,
|
||||
SLEEP_SAVE_PFER, SLEEP_SAVE_PKWR,
|
||||
|
||||
SLEEP_SAVE_SIZE
|
||||
SLEEP_SAVE_COUNT
|
||||
};
|
||||
|
||||
void pxa27x_cpu_pm_save(unsigned long *sleep_save)
|
||||
|
@ -251,6 +249,9 @@ void pxa27x_cpu_pm_enter(suspend_state_t state)
|
|||
/* Clear edge-detect status register. */
|
||||
PEDR = 0xDF12FE1B;
|
||||
|
||||
/* Clear reset status */
|
||||
RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
|
||||
|
||||
switch (state) {
|
||||
case PM_SUSPEND_STANDBY:
|
||||
pxa_cpu_standby();
|
||||
|
@ -269,7 +270,7 @@ static int pxa27x_cpu_pm_valid(suspend_state_t state)
|
|||
}
|
||||
|
||||
static struct pxa_cpu_pm_fns pxa27x_cpu_pm_fns = {
|
||||
.save_size = SLEEP_SAVE_SIZE,
|
||||
.save_count = SLEEP_SAVE_COUNT,
|
||||
.save = pxa27x_cpu_pm_save,
|
||||
.restore = pxa27x_cpu_pm_restore,
|
||||
.valid = pxa27x_cpu_pm_valid,
|
||||
|
|
|
@ -256,12 +256,11 @@ static unsigned long wakeup_src;
|
|||
#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
|
||||
#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
|
||||
|
||||
enum { SLEEP_SAVE_START = 0,
|
||||
SLEEP_SAVE_CKENA,
|
||||
enum { SLEEP_SAVE_CKENA,
|
||||
SLEEP_SAVE_CKENB,
|
||||
SLEEP_SAVE_ACCR,
|
||||
|
||||
SLEEP_SAVE_SIZE,
|
||||
SLEEP_SAVE_COUNT,
|
||||
};
|
||||
|
||||
static void pxa3xx_cpu_pm_save(unsigned long *sleep_save)
|
||||
|
@ -376,7 +375,7 @@ static int pxa3xx_cpu_pm_valid(suspend_state_t state)
|
|||
}
|
||||
|
||||
static struct pxa_cpu_pm_fns pxa3xx_cpu_pm_fns = {
|
||||
.save_size = SLEEP_SAVE_SIZE,
|
||||
.save_count = SLEEP_SAVE_COUNT,
|
||||
.save = pxa3xx_cpu_pm_save,
|
||||
.restore = pxa3xx_cpu_pm_restore,
|
||||
.valid = pxa3xx_cpu_pm_valid,
|
||||
|
|
|
@ -529,8 +529,6 @@ static struct platform_device *devices[] __initdata = {
|
|||
|
||||
static void spitz_poweroff(void)
|
||||
{
|
||||
RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
|
||||
|
||||
pxa_gpio_mode(SPITZ_GPIO_ON_RESET | GPIO_OUT);
|
||||
GPSR(SPITZ_GPIO_ON_RESET) = GPIO_bit(SPITZ_GPIO_ON_RESET);
|
||||
|
||||
|
|
|
@ -119,9 +119,6 @@ static void spitz_presuspend(void)
|
|||
/* nRESET_OUT Disable */
|
||||
PSLR |= PSLR_SL_ROD;
|
||||
|
||||
/* Clear reset status */
|
||||
RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
|
||||
|
||||
/* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
|
||||
PCFR = PCFR_GPR_EN | PCFR_OPDE;
|
||||
}
|
||||
|
|
|
@ -467,8 +467,6 @@ static struct platform_device *devices[] __initdata = {
|
|||
|
||||
static void tosa_poweroff(void)
|
||||
{
|
||||
RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
|
||||
|
||||
pxa_gpio_mode(TOSA_GPIO_ON_RESET | GPIO_OUT);
|
||||
GPSR(TOSA_GPIO_ON_RESET) = GPIO_bit(TOSA_GPIO_ON_RESET);
|
||||
|
||||
|
|
|
@ -43,20 +43,18 @@ extern void sa1100_cpu_resume(void);
|
|||
* More ones like CP and general purpose register values are preserved
|
||||
* on the stack and then the stack pointer is stored last in sleep.S.
|
||||
*/
|
||||
enum { SLEEP_SAVE_SP = 0,
|
||||
|
||||
SLEEP_SAVE_GPDR, SLEEP_SAVE_GAFR,
|
||||
enum { SLEEP_SAVE_GPDR, SLEEP_SAVE_GAFR,
|
||||
SLEEP_SAVE_PPDR, SLEEP_SAVE_PPSR, SLEEP_SAVE_PPAR, SLEEP_SAVE_PSDR,
|
||||
|
||||
SLEEP_SAVE_Ser1SDCR0,
|
||||
|
||||
SLEEP_SAVE_SIZE
|
||||
SLEEP_SAVE_COUNT
|
||||
};
|
||||
|
||||
|
||||
static int sa11x0_pm_enter(suspend_state_t state)
|
||||
{
|
||||
unsigned long gpio, sleep_save[SLEEP_SAVE_SIZE];
|
||||
unsigned long gpio, sleep_save[SLEEP_SAVE_COUNT];
|
||||
|
||||
gpio = GPLR;
|
||||
|
||||
|
|
|
@ -411,7 +411,7 @@ static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent)
|
|||
|
||||
clk->parent = parent;
|
||||
|
||||
if (clk == &s3c24xx_dclk0)
|
||||
if (clk == &s3c24xx_clkout0)
|
||||
mask = S3C2410_MISCCR_CLK0_MASK;
|
||||
else {
|
||||
source <<= 4;
|
||||
|
@ -437,7 +437,7 @@ struct clk s3c24xx_dclk0 = {
|
|||
struct clk s3c24xx_dclk1 = {
|
||||
.name = "dclk1",
|
||||
.id = -1,
|
||||
.ctrlbit = S3C2410_DCLKCON_DCLK0EN,
|
||||
.ctrlbit = S3C2410_DCLKCON_DCLK1EN,
|
||||
.enable = s3c24xx_dclk_enable,
|
||||
.set_parent = s3c24xx_dclk_setparent,
|
||||
.set_rate = s3c24xx_set_dclk_rate,
|
||||
|
|
|
@ -832,6 +832,7 @@ config BANK_0
|
|||
config BANK_1
|
||||
hex "Bank 1"
|
||||
default 0x7BB0
|
||||
default 0x5558 if BF54x
|
||||
|
||||
config BANK_2
|
||||
hex "Bank 2"
|
||||
|
@ -963,21 +964,22 @@ endchoice
|
|||
|
||||
endmenu
|
||||
|
||||
if (BF537 || BF533 || BF54x)
|
||||
|
||||
menu "CPU Frequency scaling"
|
||||
|
||||
source "drivers/cpufreq/Kconfig"
|
||||
|
||||
config CPU_FREQ
|
||||
bool
|
||||
config CPU_VOLTAGE
|
||||
bool "CPU Voltage scaling"
|
||||
depends on EXPERIMENTAL
|
||||
depends on CPU_FREQ
|
||||
default n
|
||||
help
|
||||
If you want to enable this option, you should select the
|
||||
DPMC driver from Character Devices.
|
||||
endmenu
|
||||
Say Y here if you want CPU voltage scaling according to the CPU frequency.
|
||||
This option violates the PLL BYPASS recommendation in the Blackfin Processor
|
||||
manuals. There is a theoretical risk that during VDDINT transitions
|
||||
the PLL may unlock.
|
||||
|
||||
endif
|
||||
endmenu
|
||||
|
||||
source "net/Kconfig"
|
||||
|
||||
|
|
|
@ -56,9 +56,6 @@ int main(void)
|
|||
/* offsets into the thread struct */
|
||||
DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
|
||||
DEFINE(THREAD_USP, offsetof(struct thread_struct, usp));
|
||||
DEFINE(THREAD_SR, offsetof(struct thread_struct, seqstat));
|
||||
DEFINE(PT_SR, offsetof(struct thread_struct, seqstat));
|
||||
DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0));
|
||||
DEFINE(THREAD_PC, offsetof(struct thread_struct, pc));
|
||||
DEFINE(KERNEL_STACK_SIZE, THREAD_SIZE);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* This file contains sequences of code that will be copied to a
|
||||
* fixed location, defined in <asm/atomic_seq.h>. The interrupt
|
||||
* fixed location, defined in <asm/fixed_code.h>. The interrupt
|
||||
* handlers ensure that these sequences appear to be atomic when
|
||||
* executed from userspace.
|
||||
* These are aligned to 16 bytes, so that we have some space to replace
|
||||
|
|
|
@ -160,6 +160,13 @@ int
|
|||
module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
|
||||
char *secstrings, struct module *mod)
|
||||
{
|
||||
/*
|
||||
* XXX: sechdrs are vmalloced in kernel/module.c
|
||||
* and would be vfreed just after module is loaded,
|
||||
* so we hack to keep the only information we needed
|
||||
* in mod->arch to correctly free L1 I/D sram later.
|
||||
* NOTE: this breaks the semantic of mod->arch structure.
|
||||
*/
|
||||
Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum;
|
||||
void *dest = NULL;
|
||||
|
||||
|
@ -167,8 +174,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
|
|||
if ((strcmp(".l1.text", secstrings + s->sh_name) == 0) ||
|
||||
((strcmp(".text", secstrings + s->sh_name) == 0) &&
|
||||
(hdr->e_flags & FLG_CODE_IN_L1) && (s->sh_size > 0))) {
|
||||
mod->arch.text_l1 = s;
|
||||
dest = l1_inst_sram_alloc(s->sh_size);
|
||||
mod->arch.text_l1 = dest;
|
||||
if (dest == NULL) {
|
||||
printk(KERN_ERR
|
||||
"module %s: L1 instruction memory allocation failed\n",
|
||||
|
@ -182,8 +189,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
|
|||
if ((strcmp(".l1.data", secstrings + s->sh_name) == 0) ||
|
||||
((strcmp(".data", secstrings + s->sh_name) == 0) &&
|
||||
(hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) {
|
||||
mod->arch.data_a_l1 = s;
|
||||
dest = l1_data_sram_alloc(s->sh_size);
|
||||
mod->arch.data_a_l1 = dest;
|
||||
if (dest == NULL) {
|
||||
printk(KERN_ERR
|
||||
"module %s: L1 data memory allocation failed\n",
|
||||
|
@ -197,8 +204,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
|
|||
if (strcmp(".l1.bss", secstrings + s->sh_name) == 0 ||
|
||||
((strcmp(".bss", secstrings + s->sh_name) == 0) &&
|
||||
(hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) {
|
||||
mod->arch.bss_a_l1 = s;
|
||||
dest = l1_data_sram_alloc(s->sh_size);
|
||||
mod->arch.bss_a_l1 = dest;
|
||||
if (dest == NULL) {
|
||||
printk(KERN_ERR
|
||||
"module %s: L1 data memory allocation failed\n",
|
||||
|
@ -210,8 +217,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
|
|||
s->sh_addr = (unsigned long)dest;
|
||||
}
|
||||
if (strcmp(".l1.data.B", secstrings + s->sh_name) == 0) {
|
||||
mod->arch.data_b_l1 = s;
|
||||
dest = l1_data_B_sram_alloc(s->sh_size);
|
||||
mod->arch.data_b_l1 = dest;
|
||||
if (dest == NULL) {
|
||||
printk(KERN_ERR
|
||||
"module %s: L1 data memory allocation failed\n",
|
||||
|
@ -223,8 +230,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
|
|||
s->sh_addr = (unsigned long)dest;
|
||||
}
|
||||
if (strcmp(".l1.bss.B", secstrings + s->sh_name) == 0) {
|
||||
mod->arch.bss_b_l1 = s;
|
||||
dest = l1_data_B_sram_alloc(s->sh_size);
|
||||
mod->arch.bss_b_l1 = dest;
|
||||
if (dest == NULL) {
|
||||
printk(KERN_ERR
|
||||
"module %s: L1 data memory allocation failed\n",
|
||||
|
@ -416,14 +423,14 @@ module_finalize(const Elf_Ehdr * hdr,
|
|||
|
||||
void module_arch_cleanup(struct module *mod)
|
||||
{
|
||||
if ((mod->arch.text_l1) && (mod->arch.text_l1->sh_addr))
|
||||
l1_inst_sram_free((void *)mod->arch.text_l1->sh_addr);
|
||||
if ((mod->arch.data_a_l1) && (mod->arch.data_a_l1->sh_addr))
|
||||
l1_data_sram_free((void *)mod->arch.data_a_l1->sh_addr);
|
||||
if ((mod->arch.bss_a_l1) && (mod->arch.bss_a_l1->sh_addr))
|
||||
l1_data_sram_free((void *)mod->arch.bss_a_l1->sh_addr);
|
||||
if ((mod->arch.data_b_l1) && (mod->arch.data_b_l1->sh_addr))
|
||||
l1_data_B_sram_free((void *)mod->arch.data_b_l1->sh_addr);
|
||||
if ((mod->arch.bss_b_l1) && (mod->arch.bss_b_l1->sh_addr))
|
||||
l1_data_B_sram_free((void *)mod->arch.bss_b_l1->sh_addr);
|
||||
if (mod->arch.text_l1)
|
||||
l1_inst_sram_free((void *)mod->arch.text_l1);
|
||||
if (mod->arch.data_a_l1)
|
||||
l1_data_sram_free((void *)mod->arch.data_a_l1);
|
||||
if (mod->arch.bss_a_l1)
|
||||
l1_data_sram_free((void *)mod->arch.bss_a_l1);
|
||||
if (mod->arch.data_b_l1)
|
||||
l1_data_B_sram_free((void *)mod->arch.data_b_l1);
|
||||
if (mod->arch.bss_b_l1)
|
||||
l1_data_B_sram_free((void *)mod->arch.bss_b_l1);
|
||||
}
|
||||
|
|
|
@ -245,7 +245,7 @@ unsigned long get_wchan(struct task_struct *p)
|
|||
|
||||
void finish_atomic_sections (struct pt_regs *regs)
|
||||
{
|
||||
int __user *up0 = (int __user *)®s->p0;
|
||||
int __user *up0 = (int __user *)regs->p0;
|
||||
|
||||
if (regs->pc < ATOMIC_SEQS_START || regs->pc >= ATOMIC_SEQS_END)
|
||||
return;
|
||||
|
|
|
@ -185,8 +185,8 @@ void ptrace_disable(struct task_struct *child)
|
|||
{
|
||||
unsigned long tmp;
|
||||
/* make sure the single step bit is not set. */
|
||||
tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
|
||||
put_reg(child, PT_SR, tmp);
|
||||
tmp = get_reg(child, PT_SYSCFG) & ~TRACE_BITS;
|
||||
put_reg(child, PT_SYSCFG, tmp);
|
||||
}
|
||||
|
||||
long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
||||
|
|
|
@ -42,6 +42,9 @@
|
|||
|
||||
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
|
||||
|
||||
/* Location of the trace bit in SYSCFG. */
|
||||
#define TRACE_BITS 0x0001
|
||||
|
||||
struct fdpic_func_descriptor {
|
||||
unsigned long text;
|
||||
unsigned long GOT;
|
||||
|
@ -225,6 +228,16 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,
|
|||
regs->r1 = (unsigned long)(&frame->info);
|
||||
regs->r2 = (unsigned long)(&frame->uc);
|
||||
|
||||
/*
|
||||
* Clear the trace flag when entering the signal handler, but
|
||||
* notify any tracer that was single-stepping it. The tracer
|
||||
* may want to single-step inside the handler too.
|
||||
*/
|
||||
if (regs->syscfg & TRACE_BITS) {
|
||||
regs->syscfg &= ~TRACE_BITS;
|
||||
ptrace_notify(SIGTRAP);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
give_sigsegv:
|
||||
|
|
|
@ -60,7 +60,7 @@ static inline unsigned long long cycles_2_ns(cycle_t cyc)
|
|||
|
||||
static cycle_t read_cycles(void)
|
||||
{
|
||||
return get_cycles();
|
||||
return __bfin_cycles_off + (get_cycles() << __bfin_cycles_mod);
|
||||
}
|
||||
|
||||
unsigned long long sched_clock(void)
|
||||
|
@ -117,7 +117,7 @@ static void bfin_timer_set_mode(enum clock_event_mode mode,
|
|||
break;
|
||||
}
|
||||
case CLOCK_EVT_MODE_ONESHOT:
|
||||
bfin_write_TSCALE(0);
|
||||
bfin_write_TSCALE(TIME_SCALE - 1);
|
||||
bfin_write_TCOUNT(0);
|
||||
bfin_write_TCNTL(TMPWR | TMREN);
|
||||
CSYNC();
|
||||
|
@ -183,10 +183,14 @@ irqreturn_t timer_interrupt(int irq, void *dev_id)
|
|||
|
||||
static int __init bfin_clockevent_init(void)
|
||||
{
|
||||
unsigned long timer_clk;
|
||||
|
||||
timer_clk = get_cclk() / TIME_SCALE;
|
||||
|
||||
setup_irq(IRQ_CORETMR, &bfin_timer_irq);
|
||||
bfin_timer_init();
|
||||
|
||||
clockevent_bfin.mult = div_sc(get_cclk(), NSEC_PER_SEC, clockevent_bfin.shift);
|
||||
clockevent_bfin.mult = div_sc(timer_clk, NSEC_PER_SEC, clockevent_bfin.shift);
|
||||
clockevent_bfin.max_delta_ns = clockevent_delta2ns(-1, &clockevent_bfin);
|
||||
clockevent_bfin.min_delta_ns = clockevent_delta2ns(100, &clockevent_bfin);
|
||||
clockevents_register_device(&clockevent_bfin);
|
||||
|
|
|
@ -32,12 +32,14 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/mtd/physmap.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/flash.h>
|
||||
#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
|
||||
#include <linux/usb/isp1362.h>
|
||||
#endif
|
||||
#include <linux/ata_platform.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/usb/sl811.h>
|
||||
|
@ -50,6 +52,7 @@
|
|||
#include <asm/reboot.h>
|
||||
#include <asm/nand.h>
|
||||
#include <asm/portmux.h>
|
||||
#include <asm/dpmc.h>
|
||||
#include <linux/spi/ad7877.h>
|
||||
|
||||
/*
|
||||
|
@ -171,6 +174,46 @@ static struct platform_device bf52x_t350mcqb_device = {
|
|||
};
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
|
||||
static struct mtd_partition ezkit_partitions[] = {
|
||||
{
|
||||
.name = "Bootloader",
|
||||
.size = 0x40000,
|
||||
.offset = 0,
|
||||
}, {
|
||||
.name = "Kernel",
|
||||
.size = 0x1C0000,
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
}, {
|
||||
.name = "RootFS",
|
||||
.size = MTDPART_SIZ_FULL,
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
}
|
||||
};
|
||||
|
||||
static struct physmap_flash_data ezkit_flash_data = {
|
||||
.width = 2,
|
||||
.parts = ezkit_partitions,
|
||||
.nr_parts = ARRAY_SIZE(ezkit_partitions),
|
||||
};
|
||||
|
||||
static struct resource ezkit_flash_resource = {
|
||||
.start = 0x20000000,
|
||||
.end = 0x203fffff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct platform_device ezkit_flash_device = {
|
||||
.name = "physmap-flash",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &ezkit_flash_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &ezkit_flash_resource,
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE)
|
||||
static struct mtd_partition partition_info[] = {
|
||||
{
|
||||
|
@ -420,11 +463,7 @@ static struct mtd_partition bfin_spi_flash_partitions[] = {
|
|||
.offset = 0,
|
||||
.mask_flags = MTD_CAP_ROM
|
||||
}, {
|
||||
.name = "kernel",
|
||||
.size = 0xe0000,
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
}, {
|
||||
.name = "file system",
|
||||
.name = "linux kernel",
|
||||
.size = MTDPART_SIZ_FULL,
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
}
|
||||
|
@ -434,7 +473,7 @@ static struct flash_platform_data bfin_spi_flash_data = {
|
|||
.name = "m25p80",
|
||||
.parts = bfin_spi_flash_partitions,
|
||||
.nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
|
||||
.type = "m25p64",
|
||||
.type = "m25p16",
|
||||
};
|
||||
|
||||
/* SPI flash chip (m25p64) */
|
||||
|
@ -755,6 +794,24 @@ static struct platform_device i2c_bfin_twi_device = {
|
|||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_I2C_BOARDINFO
|
||||
static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
|
||||
#if defined(CONFIG_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE)
|
||||
{
|
||||
I2C_BOARD_INFO("pcf8574_lcd", 0x22),
|
||||
.type = "pcf8574_lcd",
|
||||
},
|
||||
#endif
|
||||
#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE)
|
||||
{
|
||||
I2C_BOARD_INFO("pcf8574_keypad", 0x27),
|
||||
.type = "pcf8574_keypad",
|
||||
.irq = IRQ_PF8,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
|
||||
static struct platform_device bfin_sport0_uart_device = {
|
||||
.name = "bfin-sport-uart",
|
||||
|
@ -839,7 +896,32 @@ static struct platform_device bfin_gpios_device = {
|
|||
.resource = &bfin_gpios_resources,
|
||||
};
|
||||
|
||||
static const unsigned int cclk_vlev_datasheet[] =
|
||||
{
|
||||
VRPAIR(VLEV_100, 400000000),
|
||||
VRPAIR(VLEV_105, 426000000),
|
||||
VRPAIR(VLEV_110, 500000000),
|
||||
VRPAIR(VLEV_115, 533000000),
|
||||
VRPAIR(VLEV_120, 600000000),
|
||||
};
|
||||
|
||||
static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
|
||||
.tuple_tab = cclk_vlev_datasheet,
|
||||
.tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
|
||||
.vr_settling_time = 25 /* us */,
|
||||
};
|
||||
|
||||
static struct platform_device bfin_dpmc = {
|
||||
.name = "bfin dpmc",
|
||||
.dev = {
|
||||
.platform_data = &bfin_dmpc_vreg_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device *stamp_devices[] __initdata = {
|
||||
|
||||
&bfin_dpmc,
|
||||
|
||||
#if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE)
|
||||
&bf5xx_nand_device,
|
||||
#endif
|
||||
|
@ -921,12 +1003,22 @@ static struct platform_device *stamp_devices[] __initdata = {
|
|||
&bfin_device_gpiokeys,
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
|
||||
&ezkit_flash_device,
|
||||
#endif
|
||||
|
||||
&bfin_gpios_device,
|
||||
};
|
||||
|
||||
static int __init stamp_init(void)
|
||||
{
|
||||
printk(KERN_INFO "%s(): registering device resources\n", __func__);
|
||||
|
||||
#ifdef CONFIG_I2C_BOARDINFO
|
||||
i2c_register_board_info(0, bfin_i2c_board_info,
|
||||
ARRAY_SIZE(bfin_i2c_board_info));
|
||||
#endif
|
||||
|
||||
platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
|
||||
#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
|
||||
spi_register_board_info(bfin_spi_board_info,
|
||||
|
|
|
@ -33,12 +33,15 @@
|
|||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/flash.h>
|
||||
#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
|
||||
#include <linux/usb/isp1362.h>
|
||||
#endif
|
||||
#include <linux/ata_platform.h>
|
||||
#include <linux/irq.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/bfin5xx_spi.h>
|
||||
#include <asm/portmux.h>
|
||||
#include <asm/dpmc.h>
|
||||
|
||||
/*
|
||||
* Name the Board for the /proc/cpuinfo
|
||||
|
@ -341,7 +344,37 @@ static struct platform_device bfin_pata_device = {
|
|||
};
|
||||
#endif
|
||||
|
||||
static const unsigned int cclk_vlev_datasheet[] =
|
||||
{
|
||||
VRPAIR(VLEV_085, 250000000),
|
||||
VRPAIR(VLEV_090, 376000000),
|
||||
VRPAIR(VLEV_095, 426000000),
|
||||
VRPAIR(VLEV_100, 426000000),
|
||||
VRPAIR(VLEV_105, 476000000),
|
||||
VRPAIR(VLEV_110, 476000000),
|
||||
VRPAIR(VLEV_115, 476000000),
|
||||
VRPAIR(VLEV_120, 600000000),
|
||||
VRPAIR(VLEV_125, 600000000),
|
||||
VRPAIR(VLEV_130, 600000000),
|
||||
};
|
||||
|
||||
static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
|
||||
.tuple_tab = cclk_vlev_datasheet,
|
||||
.tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
|
||||
.vr_settling_time = 25 /* us */,
|
||||
};
|
||||
|
||||
static struct platform_device bfin_dpmc = {
|
||||
.name = "bfin dpmc",
|
||||
.dev = {
|
||||
.platform_data = &bfin_dmpc_vreg_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device *cm_bf533_devices[] __initdata = {
|
||||
|
||||
&bfin_dpmc,
|
||||
|
||||
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
|
||||
&bfin_uart_device,
|
||||
#endif
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include <asm/dma.h>
|
||||
#include <asm/bfin5xx_spi.h>
|
||||
#include <asm/portmux.h>
|
||||
#include <asm/dpmc.h>
|
||||
|
||||
/*
|
||||
* Name the Board for the /proc/cpuinfo
|
||||
|
@ -350,7 +351,37 @@ static struct platform_device i2c_gpio_device = {
|
|||
};
|
||||
#endif
|
||||
|
||||
static const unsigned int cclk_vlev_datasheet[] =
|
||||
{
|
||||
VRPAIR(VLEV_085, 250000000),
|
||||
VRPAIR(VLEV_090, 376000000),
|
||||
VRPAIR(VLEV_095, 426000000),
|
||||
VRPAIR(VLEV_100, 426000000),
|
||||
VRPAIR(VLEV_105, 476000000),
|
||||
VRPAIR(VLEV_110, 476000000),
|
||||
VRPAIR(VLEV_115, 476000000),
|
||||
VRPAIR(VLEV_120, 600000000),
|
||||
VRPAIR(VLEV_125, 600000000),
|
||||
VRPAIR(VLEV_130, 600000000),
|
||||
};
|
||||
|
||||
static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
|
||||
.tuple_tab = cclk_vlev_datasheet,
|
||||
.tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
|
||||
.vr_settling_time = 25 /* us */,
|
||||
};
|
||||
|
||||
static struct platform_device bfin_dpmc = {
|
||||
.name = "bfin dpmc",
|
||||
.dev = {
|
||||
.platform_data = &bfin_dmpc_vreg_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device *ezkit_devices[] __initdata = {
|
||||
|
||||
&bfin_dpmc,
|
||||
|
||||
#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
|
||||
&smc91x_device,
|
||||
#endif
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include <asm/bfin5xx_spi.h>
|
||||
#include <asm/reboot.h>
|
||||
#include <asm/portmux.h>
|
||||
#include <asm/dpmc.h>
|
||||
|
||||
/*
|
||||
* Name the Board for the /proc/cpuinfo
|
||||
|
@ -516,7 +517,37 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
|
|||
};
|
||||
#endif
|
||||
|
||||
static const unsigned int cclk_vlev_datasheet[] =
|
||||
{
|
||||
VRPAIR(VLEV_085, 250000000),
|
||||
VRPAIR(VLEV_090, 376000000),
|
||||
VRPAIR(VLEV_095, 426000000),
|
||||
VRPAIR(VLEV_100, 426000000),
|
||||
VRPAIR(VLEV_105, 476000000),
|
||||
VRPAIR(VLEV_110, 476000000),
|
||||
VRPAIR(VLEV_115, 476000000),
|
||||
VRPAIR(VLEV_120, 600000000),
|
||||
VRPAIR(VLEV_125, 600000000),
|
||||
VRPAIR(VLEV_130, 600000000),
|
||||
};
|
||||
|
||||
static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
|
||||
.tuple_tab = cclk_vlev_datasheet,
|
||||
.tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
|
||||
.vr_settling_time = 25 /* us */,
|
||||
};
|
||||
|
||||
static struct platform_device bfin_dpmc = {
|
||||
.name = "bfin dpmc",
|
||||
.dev = {
|
||||
.platform_data = &bfin_dmpc_vreg_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device *stamp_devices[] __initdata = {
|
||||
|
||||
&bfin_dpmc,
|
||||
|
||||
#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
|
||||
&rtc_device,
|
||||
#endif
|
||||
|
|
|
@ -35,12 +35,15 @@
|
|||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/flash.h>
|
||||
#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
|
||||
#include <linux/usb/isp1362.h>
|
||||
#endif
|
||||
#include <linux/ata_platform.h>
|
||||
#include <linux/irq.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/bfin5xx_spi.h>
|
||||
#include <asm/portmux.h>
|
||||
#include <asm/dpmc.h>
|
||||
|
||||
/*
|
||||
* Name the Board for the /proc/cpuinfo
|
||||
|
@ -428,7 +431,37 @@ static struct platform_device bfin_pata_device = {
|
|||
};
|
||||
#endif
|
||||
|
||||
static const unsigned int cclk_vlev_datasheet[] =
|
||||
{
|
||||
VRPAIR(VLEV_085, 250000000),
|
||||
VRPAIR(VLEV_090, 376000000),
|
||||
VRPAIR(VLEV_095, 426000000),
|
||||
VRPAIR(VLEV_100, 426000000),
|
||||
VRPAIR(VLEV_105, 476000000),
|
||||
VRPAIR(VLEV_110, 476000000),
|
||||
VRPAIR(VLEV_115, 476000000),
|
||||
VRPAIR(VLEV_120, 500000000),
|
||||
VRPAIR(VLEV_125, 533000000),
|
||||
VRPAIR(VLEV_130, 600000000),
|
||||
};
|
||||
|
||||
static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
|
||||
.tuple_tab = cclk_vlev_datasheet,
|
||||
.tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
|
||||
.vr_settling_time = 25 /* us */,
|
||||
};
|
||||
|
||||
static struct platform_device bfin_dpmc = {
|
||||
.name = "bfin dpmc",
|
||||
.dev = {
|
||||
.platform_data = &bfin_dmpc_vreg_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device *cm_bf537_devices[] __initdata = {
|
||||
|
||||
&bfin_dpmc,
|
||||
|
||||
#if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE)
|
||||
&hitachi_fb_device,
|
||||
#endif
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include <asm/bfin5xx_spi.h>
|
||||
#include <asm/reboot.h>
|
||||
#include <asm/portmux.h>
|
||||
#include <asm/dpmc.h>
|
||||
#include <linux/spi/ad7877.h>
|
||||
|
||||
/*
|
||||
|
@ -817,7 +818,37 @@ static struct platform_device bfin_pata_device = {
|
|||
};
|
||||
#endif
|
||||
|
||||
static const unsigned int cclk_vlev_datasheet[] =
|
||||
{
|
||||
VRPAIR(VLEV_085, 250000000),
|
||||
VRPAIR(VLEV_090, 376000000),
|
||||
VRPAIR(VLEV_095, 426000000),
|
||||
VRPAIR(VLEV_100, 426000000),
|
||||
VRPAIR(VLEV_105, 476000000),
|
||||
VRPAIR(VLEV_110, 476000000),
|
||||
VRPAIR(VLEV_115, 476000000),
|
||||
VRPAIR(VLEV_120, 500000000),
|
||||
VRPAIR(VLEV_125, 533000000),
|
||||
VRPAIR(VLEV_130, 600000000),
|
||||
};
|
||||
|
||||
static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
|
||||
.tuple_tab = cclk_vlev_datasheet,
|
||||
.tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
|
||||
.vr_settling_time = 25 /* us */,
|
||||
};
|
||||
|
||||
static struct platform_device bfin_dpmc = {
|
||||
.name = "bfin dpmc",
|
||||
.dev = {
|
||||
.platform_data = &bfin_dmpc_vreg_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device *stamp_devices[] __initdata = {
|
||||
|
||||
&bfin_dpmc,
|
||||
|
||||
#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
|
||||
&bfin_pcmcia_cf_device,
|
||||
#endif
|
||||
|
|
|
@ -36,7 +36,9 @@
|
|||
#include <linux/spi/flash.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/interrupt.h>
|
||||
#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE)
|
||||
#include <linux/usb/musb.h>
|
||||
#endif
|
||||
#include <asm/bfin5xx_spi.h>
|
||||
#include <asm/cplb.h>
|
||||
#include <asm/dma.h>
|
||||
|
@ -44,6 +46,7 @@
|
|||
#include <asm/nand.h>
|
||||
#include <asm/portmux.h>
|
||||
#include <asm/mach/bf54x_keys.h>
|
||||
#include <asm/dpmc.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/spi/ad7877.h>
|
||||
|
||||
|
@ -590,7 +593,38 @@ static struct platform_device bfin_device_gpiokeys = {
|
|||
};
|
||||
#endif
|
||||
|
||||
static const unsigned int cclk_vlev_datasheet[] =
|
||||
{
|
||||
/*
|
||||
* Internal VLEV BF54XSBBC1533
|
||||
****temporarily using these values until data sheet is updated
|
||||
*/
|
||||
VRPAIR(VLEV_085, 150000000),
|
||||
VRPAIR(VLEV_090, 250000000),
|
||||
VRPAIR(VLEV_110, 276000000),
|
||||
VRPAIR(VLEV_115, 301000000),
|
||||
VRPAIR(VLEV_120, 525000000),
|
||||
VRPAIR(VLEV_125, 550000000),
|
||||
VRPAIR(VLEV_130, 600000000),
|
||||
};
|
||||
|
||||
static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
|
||||
.tuple_tab = cclk_vlev_datasheet,
|
||||
.tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
|
||||
.vr_settling_time = 25 /* us */,
|
||||
};
|
||||
|
||||
static struct platform_device bfin_dpmc = {
|
||||
.name = "bfin dpmc",
|
||||
.dev = {
|
||||
.platform_data = &bfin_dmpc_vreg_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device *cm_bf548_devices[] __initdata = {
|
||||
|
||||
&bfin_dpmc,
|
||||
|
||||
#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
|
||||
&rtc_device,
|
||||
#endif
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include <asm/dma.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/nand.h>
|
||||
#include <asm/dpmc.h>
|
||||
#include <asm/portmux.h>
|
||||
#include <asm/mach/bf54x_keys.h>
|
||||
#include <linux/input.h>
|
||||
|
@ -689,7 +690,38 @@ static struct platform_device bfin_gpios_device = {
|
|||
.resource = &bfin_gpios_resources,
|
||||
};
|
||||
|
||||
static const unsigned int cclk_vlev_datasheet[] =
|
||||
{
|
||||
/*
|
||||
* Internal VLEV BF54XSBBC1533
|
||||
****temporarily using these values until data sheet is updated
|
||||
*/
|
||||
VRPAIR(VLEV_085, 150000000),
|
||||
VRPAIR(VLEV_090, 250000000),
|
||||
VRPAIR(VLEV_110, 276000000),
|
||||
VRPAIR(VLEV_115, 301000000),
|
||||
VRPAIR(VLEV_120, 525000000),
|
||||
VRPAIR(VLEV_125, 550000000),
|
||||
VRPAIR(VLEV_130, 600000000),
|
||||
};
|
||||
|
||||
static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
|
||||
.tuple_tab = cclk_vlev_datasheet,
|
||||
.tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
|
||||
.vr_settling_time = 25 /* us */,
|
||||
};
|
||||
|
||||
static struct platform_device bfin_dpmc = {
|
||||
.name = "bfin dpmc",
|
||||
.dev = {
|
||||
.platform_data = &bfin_dmpc_vreg_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device *ezkit_devices[] __initdata = {
|
||||
|
||||
&bfin_dpmc,
|
||||
|
||||
#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
|
||||
&rtc_device,
|
||||
#endif
|
||||
|
|
|
@ -33,12 +33,15 @@
|
|||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/flash.h>
|
||||
#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
|
||||
#include <linux/usb/isp1362.h>
|
||||
#endif
|
||||
#include <linux/ata_platform.h>
|
||||
#include <linux/irq.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/bfin5xx_spi.h>
|
||||
#include <asm/portmux.h>
|
||||
#include <asm/dpmc.h>
|
||||
|
||||
/*
|
||||
* Name the Board for the /proc/cpuinfo
|
||||
|
@ -339,8 +342,37 @@ static struct platform_device bfin_pata_device = {
|
|||
};
|
||||
#endif
|
||||
|
||||
static const unsigned int cclk_vlev_datasheet[] =
|
||||
{
|
||||
VRPAIR(VLEV_085, 250000000),
|
||||
VRPAIR(VLEV_090, 300000000),
|
||||
VRPAIR(VLEV_095, 313000000),
|
||||
VRPAIR(VLEV_100, 350000000),
|
||||
VRPAIR(VLEV_105, 400000000),
|
||||
VRPAIR(VLEV_110, 444000000),
|
||||
VRPAIR(VLEV_115, 450000000),
|
||||
VRPAIR(VLEV_120, 475000000),
|
||||
VRPAIR(VLEV_125, 500000000),
|
||||
VRPAIR(VLEV_130, 600000000),
|
||||
};
|
||||
|
||||
static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
|
||||
.tuple_tab = cclk_vlev_datasheet,
|
||||
.tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
|
||||
.vr_settling_time = 25 /* us */,
|
||||
};
|
||||
|
||||
static struct platform_device bfin_dpmc = {
|
||||
.name = "bfin dpmc",
|
||||
.dev = {
|
||||
.platform_data = &bfin_dmpc_vreg_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device *cm_bf561_devices[] __initdata = {
|
||||
|
||||
&bfin_dpmc,
|
||||
|
||||
#if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE)
|
||||
&hitachi_fb_device,
|
||||
#endif
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include <asm/dma.h>
|
||||
#include <asm/bfin5xx_spi.h>
|
||||
#include <asm/portmux.h>
|
||||
#include <asm/dpmc.h>
|
||||
|
||||
/*
|
||||
* Name the Board for the /proc/cpuinfo
|
||||
|
@ -443,7 +444,37 @@ static struct platform_device i2c_gpio_device = {
|
|||
};
|
||||
#endif
|
||||
|
||||
static const unsigned int cclk_vlev_datasheet[] =
|
||||
{
|
||||
VRPAIR(VLEV_085, 250000000),
|
||||
VRPAIR(VLEV_090, 300000000),
|
||||
VRPAIR(VLEV_095, 313000000),
|
||||
VRPAIR(VLEV_100, 350000000),
|
||||
VRPAIR(VLEV_105, 400000000),
|
||||
VRPAIR(VLEV_110, 444000000),
|
||||
VRPAIR(VLEV_115, 450000000),
|
||||
VRPAIR(VLEV_120, 475000000),
|
||||
VRPAIR(VLEV_125, 500000000),
|
||||
VRPAIR(VLEV_130, 600000000),
|
||||
};
|
||||
|
||||
static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
|
||||
.tuple_tab = cclk_vlev_datasheet,
|
||||
.tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
|
||||
.vr_settling_time = 25 /* us */,
|
||||
};
|
||||
|
||||
static struct platform_device bfin_dpmc = {
|
||||
.name = "bfin dpmc",
|
||||
.dev = {
|
||||
.platform_data = &bfin_dmpc_vreg_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device *ezkit_devices[] __initdata = {
|
||||
|
||||
&bfin_dpmc,
|
||||
|
||||
#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
|
||||
&smc91x_device,
|
||||
#endif
|
||||
|
|
|
@ -6,5 +6,6 @@ obj-y := \
|
|||
cache.o cacheinit.o entry.o \
|
||||
interrupt.o lock.o irqpanic.o arch_checks.o ints-priority.o
|
||||
|
||||
obj-$(CONFIG_PM) += pm.o dpmc.o
|
||||
obj-$(CONFIG_CPU_FREQ) += cpufreq.o
|
||||
obj-$(CONFIG_PM) += pm.o dpmc_modes.o
|
||||
obj-$(CONFIG_CPU_FREQ) += cpufreq.o
|
||||
obj-$(CONFIG_CPU_VOLTAGE) += dpmc.o
|
||||
|
|
|
@ -62,6 +62,14 @@ static struct bfin_dpm_state {
|
|||
unsigned int tscale; /* change the divider on the core timer interrupt */
|
||||
} dpm_state_table[3];
|
||||
|
||||
/*
|
||||
normalized to maximum frequncy offset for CYCLES,
|
||||
used in time-ts cycles clock source, but could be used
|
||||
somewhere also.
|
||||
*/
|
||||
unsigned long long __bfin_cycles_off;
|
||||
unsigned int __bfin_cycles_mod;
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
static unsigned int bfin_getfreq(unsigned int cpu)
|
||||
|
@ -80,6 +88,7 @@ static int bfin_target(struct cpufreq_policy *policy,
|
|||
unsigned int index, plldiv, tscale;
|
||||
unsigned long flags, cclk_hz;
|
||||
struct cpufreq_freqs freqs;
|
||||
cycles_t cycles;
|
||||
|
||||
if (cpufreq_frequency_table_target(policy, bfin_freq_table,
|
||||
target_freq, relation, &index))
|
||||
|
@ -101,8 +110,14 @@ static int bfin_target(struct cpufreq_policy *policy,
|
|||
bfin_write_PLL_DIV(plldiv);
|
||||
/* we have to adjust the core timer, because it is using cclk */
|
||||
bfin_write_TSCALE(tscale);
|
||||
cycles = get_cycles();
|
||||
SSYNC();
|
||||
cycles += 10; /* ~10 cycles we loose after get_cycles() */
|
||||
__bfin_cycles_off += (cycles << __bfin_cycles_mod) - (cycles << index);
|
||||
__bfin_cycles_mod = index;
|
||||
local_irq_restore(flags);
|
||||
/* TODO: just test case for cycles clock source, remove later */
|
||||
pr_debug("cpufreq: done\n");
|
||||
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
|
||||
|
||||
return 0;
|
||||
|
@ -119,22 +134,13 @@ static int __init __bfin_cpu_init(struct cpufreq_policy *policy)
|
|||
unsigned long cclk, sclk, csel, min_cclk;
|
||||
int index;
|
||||
|
||||
#ifdef CONFIG_CYCLES_CLOCKSOURCE
|
||||
/*
|
||||
* Clocksource CYCLES is still CONTINUOUS but not longer MONOTONIC in case we enable
|
||||
* CPU frequency scaling, since CYCLES runs off Core Clock.
|
||||
*/
|
||||
printk(KERN_WARNING "CPU frequency scaling not supported: Clocksource not suitable\n"
|
||||
return -ENODEV;
|
||||
#endif
|
||||
|
||||
if (policy->cpu != 0)
|
||||
return -EINVAL;
|
||||
|
||||
cclk = get_cclk();
|
||||
sclk = get_sclk();
|
||||
|
||||
#if ANOMALY_05000273
|
||||
#if ANOMALY_05000273 || (!defined(CONFIG_BF54x) && defined(CONFIG_BFIN_DCACHE))
|
||||
min_cclk = sclk * 2;
|
||||
#else
|
||||
min_cclk = sclk;
|
||||
|
|
137
arch/blackfin/mach-common/dpmc.c
Normal file
137
arch/blackfin/mach-common/dpmc.c
Normal file
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* Copyright 2008 Analog Devices Inc.
|
||||
*
|
||||
* Licensed under the GPL-2 or later.
|
||||
*/
|
||||
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/cpufreq.h>
|
||||
|
||||
#include <asm/delay.h>
|
||||
#include <asm/dpmc.h>
|
||||
|
||||
#define DRIVER_NAME "bfin dpmc"
|
||||
|
||||
#define dprintk(msg...) \
|
||||
cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, DRIVER_NAME, msg)
|
||||
|
||||
struct bfin_dpmc_platform_data *pdata;
|
||||
|
||||
/**
|
||||
* bfin_set_vlev - Update VLEV field in VR_CTL Reg.
|
||||
* Avoid BYPASS sequence
|
||||
*/
|
||||
static void bfin_set_vlev(unsigned int vlev)
|
||||
{
|
||||
unsigned pll_lcnt;
|
||||
|
||||
pll_lcnt = bfin_read_PLL_LOCKCNT();
|
||||
|
||||
bfin_write_PLL_LOCKCNT(1);
|
||||
bfin_write_VR_CTL((bfin_read_VR_CTL() & ~VLEV) | vlev);
|
||||
bfin_write_PLL_LOCKCNT(pll_lcnt);
|
||||
}
|
||||
|
||||
/**
|
||||
* bfin_get_vlev - Get CPU specific VLEV from platform device data
|
||||
*/
|
||||
static unsigned int bfin_get_vlev(unsigned int freq)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!pdata)
|
||||
goto err_out;
|
||||
|
||||
freq >>= 16;
|
||||
|
||||
for (i = 0; i < pdata->tabsize; i++)
|
||||
if (freq <= (pdata->tuple_tab[i] & 0xFFFF))
|
||||
return pdata->tuple_tab[i] >> 16;
|
||||
|
||||
err_out:
|
||||
printk(KERN_WARNING "DPMC: No suitable CCLK VDDINT voltage pair found\n");
|
||||
return VLEV_120;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CPU_FREQ
|
||||
static int
|
||||
vreg_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data)
|
||||
{
|
||||
struct cpufreq_freqs *freq = data;
|
||||
|
||||
if (val == CPUFREQ_PRECHANGE && freq->old < freq->new) {
|
||||
bfin_set_vlev(bfin_get_vlev(freq->new));
|
||||
udelay(pdata->vr_settling_time); /* Wait until Volatge settled */
|
||||
|
||||
} else if (val == CPUFREQ_POSTCHANGE && freq->old > freq->new)
|
||||
bfin_set_vlev(bfin_get_vlev(freq->new));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct notifier_block vreg_cpufreq_notifier_block = {
|
||||
.notifier_call = vreg_cpufreq_notifier
|
||||
};
|
||||
#endif /* CONFIG_CPU_FREQ */
|
||||
|
||||
/**
|
||||
* bfin_dpmc_probe -
|
||||
*
|
||||
*/
|
||||
static int __devinit bfin_dpmc_probe(struct platform_device *pdev)
|
||||
{
|
||||
if (pdev->dev.platform_data)
|
||||
pdata = pdev->dev.platform_data;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
return cpufreq_register_notifier(&vreg_cpufreq_notifier_block,
|
||||
CPUFREQ_TRANSITION_NOTIFIER);
|
||||
}
|
||||
|
||||
/**
|
||||
* bfin_dpmc_remove -
|
||||
*/
|
||||
static int __devexit bfin_dpmc_remove(struct platform_device *pdev)
|
||||
{
|
||||
pdata = NULL;
|
||||
return cpufreq_unregister_notifier(&vreg_cpufreq_notifier_block,
|
||||
CPUFREQ_TRANSITION_NOTIFIER);
|
||||
}
|
||||
|
||||
struct platform_driver bfin_dpmc_device_driver = {
|
||||
.probe = bfin_dpmc_probe,
|
||||
.remove = __devexit_p(bfin_dpmc_remove),
|
||||
.driver = {
|
||||
.name = DRIVER_NAME,
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* bfin_dpmc_init - Init driver
|
||||
*/
|
||||
static int __init bfin_dpmc_init(void)
|
||||
{
|
||||
return platform_driver_register(&bfin_dpmc_device_driver);
|
||||
}
|
||||
module_init(bfin_dpmc_init);
|
||||
|
||||
/**
|
||||
* bfin_dpmc_exit - break down driver
|
||||
*/
|
||||
static void __exit bfin_dpmc_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&bfin_dpmc_device_driver);
|
||||
}
|
||||
module_exit(bfin_dpmc_exit);
|
||||
|
||||
MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
|
||||
MODULE_DESCRIPTION("cpu power management driver for Blackfin");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -1,30 +1,7 @@
|
|||
/*
|
||||
* File: arch/blackfin/mach-common/dpmc.S
|
||||
* Based on:
|
||||
* Author: LG Soft India
|
||||
* Copyright 2004-2008 Analog Devices Inc.
|
||||
*
|
||||
* Created: ?
|
||||
* Description: Watchdog Timer APIs
|
||||
*
|
||||
* Modified:
|
||||
* Copyright 2004-2006 Analog Devices Inc.
|
||||
*
|
||||
* Bugs: Enter bugs at http://blackfin.uclinux.org/
|
||||
*
|
||||
* 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, see the file COPYING, or write
|
||||
* to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
* Licensed under the GPL-2 or later.
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
|
@ -151,26 +151,62 @@ ENTRY(_ex_soft_bp)
|
|||
ENDPROC(_ex_soft_bp)
|
||||
|
||||
ENTRY(_ex_single_step)
|
||||
/* If we just returned from an interrupt, the single step event is
|
||||
for the RTI instruction. */
|
||||
r7 = retx;
|
||||
r6 = reti;
|
||||
cc = r7 == r6;
|
||||
if cc jump _bfin_return_from_exception
|
||||
if cc jump _bfin_return_from_exception;
|
||||
|
||||
/* If we were in user mode, do the single step normally. */
|
||||
p5.l = lo(IPEND);
|
||||
p5.h = hi(IPEND);
|
||||
r6 = [p5];
|
||||
r7 = 0xffe0 (z);
|
||||
r7 = r7 & r6;
|
||||
cc = r7 == 0;
|
||||
if !cc jump 1f;
|
||||
|
||||
/* Single stepping only a single instruction, so clear the trace
|
||||
* bit here. */
|
||||
r7 = syscfg;
|
||||
bitclr (r7, 0);
|
||||
syscfg = R7;
|
||||
jump _ex_trap_c;
|
||||
|
||||
1:
|
||||
/*
|
||||
* We were in an interrupt handler. By convention, all of them save
|
||||
* SYSCFG with their first instruction, so by checking whether our
|
||||
* RETX points at the entry point, we can determine whether to allow
|
||||
* a single step, or whether to clear SYSCFG.
|
||||
*
|
||||
* First, find out the interrupt level and the event vector for it.
|
||||
*/
|
||||
p5.l = lo(EVT0);
|
||||
p5.h = hi(EVT0);
|
||||
p5 += -4;
|
||||
2:
|
||||
r7 = rot r7 by -1;
|
||||
p5 += 4;
|
||||
if !cc jump 2b;
|
||||
|
||||
/* What we actually do is test for the _second_ instruction in the
|
||||
* IRQ handler. That way, if there are insns following the restore
|
||||
* of SYSCFG after leaving the handler, we will not turn off SYSCFG
|
||||
* for them. */
|
||||
|
||||
r7 = [p5];
|
||||
r7 += 2;
|
||||
r6 = RETX;
|
||||
cc = R7 == R6;
|
||||
if !cc jump _bfin_return_from_exception;
|
||||
|
||||
r7 = syscfg;
|
||||
bitclr (r7, 0);
|
||||
syscfg = R7;
|
||||
|
||||
p5.l = lo(IPEND);
|
||||
p5.h = hi(IPEND);
|
||||
r6 = [p5];
|
||||
cc = bittst(r6, 5);
|
||||
if !cc jump _ex_trap_c;
|
||||
p4.l = lo(EVT5);
|
||||
p4.h = hi(EVT5);
|
||||
r6.h = _exception_to_level5;
|
||||
r6.l = _exception_to_level5;
|
||||
r7 = [p4];
|
||||
cc = r6 == r7;
|
||||
if !cc jump _ex_trap_c;
|
||||
/* Fall through to _bfin_return_from_exception. */
|
||||
ENDPROC(_ex_single_step)
|
||||
|
||||
ENTRY(_bfin_return_from_exception)
|
||||
|
@ -234,20 +270,26 @@ ENTRY(_ex_trap_c)
|
|||
p5.l = _saved_icplb_fault_addr;
|
||||
[p5] = r7;
|
||||
|
||||
p4.l = __retx;
|
||||
p4.h = __retx;
|
||||
p4.l = _excpt_saved_stuff;
|
||||
p4.h = _excpt_saved_stuff;
|
||||
|
||||
r6 = retx;
|
||||
[p4] = r6;
|
||||
p4.l = lo(SAFE_USER_INSTRUCTION);
|
||||
p4.h = hi(SAFE_USER_INSTRUCTION);
|
||||
retx = p4;
|
||||
|
||||
r6 = SYSCFG;
|
||||
[p4 + 4] = r6;
|
||||
BITCLR(r6, 0);
|
||||
SYSCFG = r6;
|
||||
|
||||
/* Disable all interrupts, but make sure level 5 is enabled so
|
||||
* we can switch to that level. Save the old mask. */
|
||||
cli r6;
|
||||
p4.l = _excpt_saved_imask;
|
||||
p4.h = _excpt_saved_imask;
|
||||
[p4] = r6;
|
||||
[p4 + 8] = r6;
|
||||
|
||||
p4.l = lo(SAFE_USER_INSTRUCTION);
|
||||
p4.h = hi(SAFE_USER_INSTRUCTION);
|
||||
retx = p4;
|
||||
|
||||
r6 = 0x3f;
|
||||
sti r6;
|
||||
|
||||
|
@ -295,6 +337,11 @@ ENTRY(_double_fault)
|
|||
*/
|
||||
SAVE_ALL_SYS
|
||||
|
||||
/* The dumping functions expect the return address in the RETI
|
||||
* slot. */
|
||||
r6 = retx;
|
||||
[sp + PT_PC] = r6;
|
||||
|
||||
r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */
|
||||
SP += -12;
|
||||
call _double_fault_c;
|
||||
|
@ -307,16 +354,17 @@ ENDPROC(_double_fault)
|
|||
ENTRY(_exception_to_level5)
|
||||
SAVE_ALL_SYS
|
||||
|
||||
p4.l = __retx;
|
||||
p4.h = __retx;
|
||||
p4.l = _excpt_saved_stuff;
|
||||
p4.h = _excpt_saved_stuff;
|
||||
r6 = [p4];
|
||||
[sp + PT_PC] = r6;
|
||||
|
||||
r6 = [p4 + 4];
|
||||
[sp + PT_SYSCFG] = r6;
|
||||
|
||||
/* Restore interrupt mask. We haven't pushed RETI, so this
|
||||
* doesn't enable interrupts until we return from this handler. */
|
||||
p4.l = _excpt_saved_imask;
|
||||
p4.h = _excpt_saved_imask;
|
||||
r6 = [p4];
|
||||
r6 = [p4 + 8];
|
||||
sti r6;
|
||||
|
||||
/* Restore the hardware error vector. */
|
||||
|
@ -1344,7 +1392,14 @@ ENTRY(_sys_call_table)
|
|||
.rept NR_syscalls-(.-_sys_call_table)/4
|
||||
.long _sys_ni_syscall
|
||||
.endr
|
||||
_excpt_saved_imask:
|
||||
|
||||
/*
|
||||
* Used to save the real RETX, IMASK and SYSCFG when temporarily
|
||||
* storing safe values across the transition from exception to IRQ5.
|
||||
*/
|
||||
_excpt_saved_stuff:
|
||||
.long 0;
|
||||
.long 0;
|
||||
.long 0;
|
||||
|
||||
_exception_stack:
|
||||
|
@ -1358,7 +1413,3 @@ _exception_stack_top:
|
|||
_last_cplb_fault_retx:
|
||||
.long 0;
|
||||
#endif
|
||||
/* Used to save the real RETX when temporarily storing a safe
|
||||
* return address. */
|
||||
__retx:
|
||||
.long 0;
|
||||
|
|
|
@ -27,25 +27,6 @@
|
|||
#include <asm/uaccess.h>
|
||||
#include <asm/segment.h>
|
||||
|
||||
/*
|
||||
* sys_pipe() is the normal C calling standard for creating
|
||||
* a pipe. It's not the way Unix traditionally does this, though.
|
||||
*/
|
||||
asmlinkage int sys_pipe(unsigned long __user * fildes)
|
||||
{
|
||||
int fd[2];
|
||||
int error;
|
||||
|
||||
lock_kernel();
|
||||
error = do_pipe(fd);
|
||||
unlock_kernel();
|
||||
if (!error) {
|
||||
if (copy_to_user(fildes, fd, 2*sizeof(int)))
|
||||
error = -EFAULT;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
/* common code for old and new mmaps */
|
||||
static inline long
|
||||
do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
|
||||
|
|
|
@ -76,26 +76,6 @@ asmlinkage int sys_tas(int __user *addr)
|
|||
return oldval;
|
||||
}
|
||||
|
||||
/*
|
||||
* sys_pipe() is the normal C calling standard for creating
|
||||
* a pipe. It's not the way Unix traditionally does this, though.
|
||||
*/
|
||||
asmlinkage int
|
||||
sys_pipe(unsigned long r0, unsigned long r1, unsigned long r2,
|
||||
unsigned long r3, unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, struct pt_regs regs)
|
||||
{
|
||||
int fd[2];
|
||||
int error;
|
||||
|
||||
error = do_pipe(fd);
|
||||
if (!error) {
|
||||
if (copy_to_user((void __user *)r0, fd, 2*sizeof(int)))
|
||||
error = -EFAULT;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
|
||||
unsigned long prot, unsigned long flags,
|
||||
unsigned long fd, unsigned long pgoff)
|
||||
|
|
|
@ -468,15 +468,26 @@ static inline void access_error040(struct frame *fp)
|
|||
* (if do_page_fault didn't fix the mapping,
|
||||
* the writeback won't do good)
|
||||
*/
|
||||
disable_wb:
|
||||
#ifdef DEBUG
|
||||
printk(".. disabling wb2\n");
|
||||
#endif
|
||||
if (fp->un.fmt7.wb2a == fp->un.fmt7.faddr)
|
||||
fp->un.fmt7.wb2s &= ~WBV_040;
|
||||
if (fp->un.fmt7.wb3a == fp->un.fmt7.faddr)
|
||||
fp->un.fmt7.wb3s &= ~WBV_040;
|
||||
}
|
||||
} else if (send_fault_sig(&fp->ptregs) > 0) {
|
||||
printk("68040 access error, ssw=%x\n", ssw);
|
||||
trap_c(fp);
|
||||
} else {
|
||||
/* In case of a bus error we either kill the process or expect
|
||||
* the kernel to catch the fault, which then is also responsible
|
||||
* for cleaning up the mess.
|
||||
*/
|
||||
current->thread.signo = SIGBUS;
|
||||
current->thread.faddr = fp->un.fmt7.faddr;
|
||||
if (send_fault_sig(&fp->ptregs) >= 0)
|
||||
printk("68040 bus error (ssw=%x, faddr=%lx)\n", ssw,
|
||||
fp->un.fmt7.faddr);
|
||||
goto disable_wb;
|
||||
}
|
||||
|
||||
do_040writebacks(fp);
|
||||
|
|
|
@ -48,9 +48,6 @@
|
|||
struct mac_booter_data mac_bi_data;
|
||||
int mac_bisize = sizeof mac_bi_data;
|
||||
|
||||
struct mac_hw_present mac_hw_present;
|
||||
EXPORT_SYMBOL(mac_hw_present);
|
||||
|
||||
/* New m68k bootinfo stuff and videobase */
|
||||
|
||||
extern int m68k_num_memory;
|
||||
|
@ -817,27 +814,6 @@ void __init mac_identify(void)
|
|||
m68k_ramdisk.addr, m68k_ramdisk.size);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* TODO: set the various fields in macintosh_config->hw_present here!
|
||||
*/
|
||||
switch (macintosh_config->scsi_type) {
|
||||
case MAC_SCSI_OLD:
|
||||
MACHW_SET(MAC_SCSI_80);
|
||||
break;
|
||||
case MAC_SCSI_QUADRA:
|
||||
case MAC_SCSI_QUADRA2:
|
||||
case MAC_SCSI_QUADRA3:
|
||||
MACHW_SET(MAC_SCSI_96);
|
||||
if ((macintosh_config->ident == MAC_MODEL_Q900) ||
|
||||
(macintosh_config->ident == MAC_MODEL_Q950))
|
||||
MACHW_SET(MAC_SCSI_96_2);
|
||||
break;
|
||||
default:
|
||||
printk(KERN_WARNING "config.c: wtf: unknown scsi, using 53c80\n");
|
||||
MACHW_SET(MAC_SCSI_80);
|
||||
break;
|
||||
}
|
||||
|
||||
iop_init();
|
||||
via_init();
|
||||
oss_init();
|
||||
|
|
|
@ -671,6 +671,9 @@ config ROMKERNEL
|
|||
|
||||
endchoice
|
||||
|
||||
if COLDFIRE
|
||||
source "kernel/Kconfig.preempt"
|
||||
endif
|
||||
source "mm/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -114,6 +114,16 @@ SECTIONS {
|
|||
*(__kcrctab_gpl)
|
||||
__stop___kcrctab_gpl = .;
|
||||
|
||||
/* Kernel symbol table: Normal unused symbols */
|
||||
__start___kcrctab_unused = .;
|
||||
*(__kcrctab_unused)
|
||||
__stop___kcrctab_unused = .;
|
||||
|
||||
/* Kernel symbol table: GPL-only unused symbols */
|
||||
__start___kcrctab_unused_gpl = .;
|
||||
*(__kcrctab_unused_gpl)
|
||||
__stop___kcrctab_unused_gpl = .;
|
||||
|
||||
/* Kernel symbol table: GPL-future symbols */
|
||||
__start___kcrctab_gpl_future = .;
|
||||
*(__kcrctab_gpl_future)
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
#
|
||||
# Copyright 2000 MontaVista Software Inc.
|
||||
# Author: MontaVista Software, Inc.
|
||||
# ppopov@mvista.com or source@mvista.com
|
||||
# Copyright 2000, 2008 MontaVista Software Inc.
|
||||
# Author: MontaVista Software, Inc. <source@mvista.com>
|
||||
#
|
||||
# Makefile for the Alchemy Au1000 CPU, generic files.
|
||||
# Makefile for the Alchemy Au1xx0 CPUs, generic files.
|
||||
#
|
||||
|
||||
obj-y += prom.o irq.o puts.o time.o reset.o \
|
||||
|
|
|
@ -40,20 +40,20 @@
|
|||
struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = {
|
||||
|
||||
#if defined(CONFIG_SOC_AU1000)
|
||||
{ AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_UART1_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_UART2_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_UART1_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_UART2_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
|
@ -62,32 +62,32 @@ struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = {
|
|||
{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
|
||||
{ AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
|
||||
#elif defined(CONFIG_SOC_AU1500)
|
||||
|
||||
{ AU1500_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1500_UART0_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_PCI_INTA, INTC_INT_LOW_LEVEL, 0 },
|
||||
{ AU1000_PCI_INTB, INTC_INT_LOW_LEVEL, 0 },
|
||||
{ AU1500_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1500_UART3_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_PCI_INTC, INTC_INT_LOW_LEVEL, 0 },
|
||||
{ AU1000_PCI_INTD, INTC_INT_LOW_LEVEL, 0 },
|
||||
{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
|
@ -100,26 +100,26 @@ struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = {
|
|||
{ AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
|
||||
{ AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1500_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1500_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1500_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1500_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
|
||||
#elif defined(CONFIG_SOC_AU1100)
|
||||
|
||||
{ AU1100_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1100_UART1_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1100_SD_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1100_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1100_UART0_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1100_UART1_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1100_SD_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1100_UART3_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
|
@ -128,33 +128,33 @@ struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = {
|
|||
{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
|
||||
{ AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1100_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
/*{ AU1000_GPIO215_208_INT, INTC_INT_HIGH_LEVEL, 0},*/
|
||||
{ AU1100_LCD_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1100_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
/* { AU1000_GPIO215_208_INT, INTC_INT_HIGH_LEVEL, 0 }, */
|
||||
{ AU1100_LCD_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
|
||||
#elif defined(CONFIG_SOC_AU1550)
|
||||
|
||||
{ AU1550_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1550_UART0_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1550_PCI_INTA, INTC_INT_LOW_LEVEL, 0 },
|
||||
{ AU1550_PCI_INTB, INTC_INT_LOW_LEVEL, 0 },
|
||||
{ AU1550_DDMA_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1550_CRYPTO_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1550_DDMA_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1550_CRYPTO_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1550_PCI_INTC, INTC_INT_LOW_LEVEL, 0 },
|
||||
{ AU1550_PCI_INTD, INTC_INT_LOW_LEVEL, 0 },
|
||||
{ AU1550_PCI_RST_INT, INTC_INT_LOW_LEVEL, 0 },
|
||||
{ AU1550_UART1_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1550_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1550_PSC0_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1550_PSC1_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1550_PSC2_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1550_PSC3_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1550_UART1_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1550_UART3_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1550_PSC0_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1550_PSC1_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1550_PSC2_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1550_PSC3_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
|
@ -163,26 +163,26 @@ struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = {
|
|||
{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1550_NAND_INT, INTC_INT_RISE_EDGE, 0},
|
||||
{ AU1550_NAND_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1550_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1550_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1550_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
|
||||
{ AU1550_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1550_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1550_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1550_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
|
||||
#elif defined(CONFIG_SOC_AU1200)
|
||||
|
||||
{ AU1200_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1200_UART0_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1200_SWT_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1200_SD_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1200_DDMA_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1200_SD_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1200_DDMA_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1200_MAE_BE_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1200_UART1_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1200_UART1_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1200_MAE_FE_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1200_PSC0_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1200_PSC1_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1200_AES_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1200_CAMERA_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1200_PSC0_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1200_PSC1_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1200_AES_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1200_CAMERA_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
|
@ -191,10 +191,10 @@ struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = {
|
|||
{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1200_NAND_INT, INTC_INT_RISE_EDGE, 0},
|
||||
{ AU1200_NAND_INT, INTC_INT_RISE_EDGE, 0 },
|
||||
{ AU1200_USB_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1200_LCD_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1200_MAE_BOTH_INT, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1200_LCD_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1200_MAE_BOTH_INT, INTC_INT_HIGH_LEVEL, 0 },
|
||||
|
||||
#else
|
||||
#error "Error: Unknown Alchemy SOC"
|
||||
|
@ -203,4 +203,3 @@ struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = {
|
|||
};
|
||||
|
||||
int __initdata au1xxx_ic0_nr_irqs = ARRAY_SIZE(au1xxx_ic0_map);
|
||||
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
/*
|
||||
* BRIEF MODULE DESCRIPTION
|
||||
* Simple Au1000 clocks routines.
|
||||
* Simple Au1xx0 clocks routines.
|
||||
*
|
||||
* Copyright 2001 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc.
|
||||
* ppopov@mvista.com or source@mvista.com
|
||||
* Copyright 2001, 2008 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc. <source@mvista.com>
|
||||
*
|
||||
* 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
|
||||
|
@ -30,8 +29,8 @@
|
|||
#include <linux/module.h>
|
||||
#include <asm/mach-au1x00/au1000.h>
|
||||
|
||||
static unsigned int au1x00_clock; // Hz
|
||||
static unsigned int lcd_clock; // KHz
|
||||
static unsigned int au1x00_clock; /* Hz */
|
||||
static unsigned int lcd_clock; /* KHz */
|
||||
static unsigned long uart_baud_base;
|
||||
|
||||
/*
|
||||
|
@ -47,8 +46,6 @@ unsigned int get_au1x00_speed(void)
|
|||
return au1x00_clock;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* The UART baud base is not known at compile time ... if
|
||||
* we want to be able to use the same code on different
|
||||
|
@ -73,24 +70,23 @@ void set_au1x00_uart_baud_base(unsigned long new_baud_base)
|
|||
void set_au1x00_lcd_clock(void)
|
||||
{
|
||||
unsigned int static_cfg0;
|
||||
unsigned int sys_busclk =
|
||||
(get_au1x00_speed()/1000) /
|
||||
((int)(au_readl(SYS_POWERCTRL)&0x03) + 2);
|
||||
unsigned int sys_busclk = (get_au1x00_speed() / 1000) /
|
||||
((int)(au_readl(SYS_POWERCTRL) & 0x03) + 2);
|
||||
|
||||
static_cfg0 = au_readl(MEM_STCFG0);
|
||||
|
||||
if (static_cfg0 & (1<<11))
|
||||
if (static_cfg0 & (1 << 11))
|
||||
lcd_clock = sys_busclk / 5; /* note: BCLK switching fails with D5 */
|
||||
else
|
||||
lcd_clock = sys_busclk / 4;
|
||||
|
||||
if (lcd_clock > 50000) /* Epson MAX */
|
||||
printk("warning: LCD clock too high (%d KHz)\n", lcd_clock);
|
||||
printk(KERN_WARNING "warning: LCD clock too high (%u KHz)\n",
|
||||
lcd_clock);
|
||||
}
|
||||
|
||||
unsigned int get_au1x00_lcd_clock(void)
|
||||
{
|
||||
return lcd_clock;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(get_au1x00_lcd_clock);
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#include <asm/mach-au1x00/au1000.h>
|
||||
|
||||
struct cpu_spec* cur_cpu_spec[NR_CPUS];
|
||||
struct cpu_spec *cur_cpu_spec[NR_CPUS];
|
||||
|
||||
/* With some thought, we can probably use the mask to reduce the
|
||||
* size of the table.
|
||||
|
@ -39,8 +39,7 @@ struct cpu_spec cpu_specs[] = {
|
|||
{ 0x00000000, 0x00000000, "Unknown Au1xxx", 1, 0, 0 }
|
||||
};
|
||||
|
||||
void
|
||||
set_cpuspec(void)
|
||||
void set_cpuspec(void)
|
||||
{
|
||||
struct cpu_spec *sp;
|
||||
u32 prid;
|
||||
|
|
|
@ -53,12 +53,11 @@
|
|||
*/
|
||||
static DEFINE_SPINLOCK(au1xxx_dbdma_spin_lock);
|
||||
|
||||
/* I couldn't find a macro that did this......
|
||||
*/
|
||||
/* I couldn't find a macro that did this... */
|
||||
#define ALIGN_ADDR(x, a) ((((u32)(x)) + (a-1)) & ~(a-1))
|
||||
|
||||
static dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE;
|
||||
static int dbdma_initialized=0;
|
||||
static int dbdma_initialized;
|
||||
static void au1xxx_dbdma_init(void);
|
||||
|
||||
static dbdev_tab_t dbdev_tab[] = {
|
||||
|
@ -149,7 +148,7 @@ static dbdev_tab_t dbdev_tab[] = {
|
|||
|
||||
{ DSCR_CMD0_NAND_FLASH, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
|
||||
|
||||
#endif // CONFIG_SOC_AU1200
|
||||
#endif /* CONFIG_SOC_AU1200 */
|
||||
|
||||
{ DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
|
||||
{ DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
|
||||
|
@ -177,8 +176,7 @@ static dbdev_tab_t dbdev_tab[] = {
|
|||
|
||||
static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS];
|
||||
|
||||
static dbdev_tab_t *
|
||||
find_dbdev_id(u32 id)
|
||||
static dbdev_tab_t *find_dbdev_id(u32 id)
|
||||
{
|
||||
int i;
|
||||
dbdev_tab_t *p;
|
||||
|
@ -190,29 +188,27 @@ find_dbdev_id(u32 id)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void * au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp)
|
||||
void *au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp)
|
||||
{
|
||||
return phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
|
||||
return phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
|
||||
}
|
||||
EXPORT_SYMBOL(au1xxx_ddma_get_nextptr_virt);
|
||||
|
||||
u32
|
||||
au1xxx_ddma_add_device(dbdev_tab_t *dev)
|
||||
u32 au1xxx_ddma_add_device(dbdev_tab_t *dev)
|
||||
{
|
||||
u32 ret = 0;
|
||||
dbdev_tab_t *p=NULL;
|
||||
static u16 new_id=0x1000;
|
||||
dbdev_tab_t *p;
|
||||
static u16 new_id = 0x1000;
|
||||
|
||||
p = find_dbdev_id(~0);
|
||||
if ( NULL != p )
|
||||
{
|
||||
if (NULL != p) {
|
||||
memcpy(p, dev, sizeof(dbdev_tab_t));
|
||||
p->dev_id = DSCR_DEV2CUSTOM_ID(new_id, dev->dev_id);
|
||||
ret = p->dev_id;
|
||||
new_id++;
|
||||
#if 0
|
||||
printk("add_device: id:%x flags:%x padd:%x\n",
|
||||
p->dev_id, p->dev_flags, p->dev_physaddr );
|
||||
printk(KERN_DEBUG "add_device: id:%x flags:%x padd:%x\n",
|
||||
p->dev_id, p->dev_flags, p->dev_physaddr);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -220,10 +216,8 @@ au1xxx_ddma_add_device(dbdev_tab_t *dev)
|
|||
}
|
||||
EXPORT_SYMBOL(au1xxx_ddma_add_device);
|
||||
|
||||
/* Allocate a channel and return a non-zero descriptor if successful.
|
||||
*/
|
||||
u32
|
||||
au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
|
||||
/* Allocate a channel and return a non-zero descriptor if successful. */
|
||||
u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
|
||||
void (*callback)(int, void *), void *callparam)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
@ -234,7 +228,8 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
|
|||
chan_tab_t *ctp;
|
||||
au1x_dma_chan_t *cp;
|
||||
|
||||
/* We do the intialization on the first channel allocation.
|
||||
/*
|
||||
* We do the intialization on the first channel allocation.
|
||||
* We have to wait because of the interrupt handler initialization
|
||||
* which can't be done successfully during board set up.
|
||||
*/
|
||||
|
@ -242,16 +237,17 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
|
|||
au1xxx_dbdma_init();
|
||||
dbdma_initialized = 1;
|
||||
|
||||
if ((stp = find_dbdev_id(srcid)) == NULL)
|
||||
stp = find_dbdev_id(srcid);
|
||||
if (stp == NULL)
|
||||
return 0;
|
||||
if ((dtp = find_dbdev_id(destid)) == NULL)
|
||||
dtp = find_dbdev_id(destid);
|
||||
if (dtp == NULL)
|
||||
return 0;
|
||||
|
||||
used = 0;
|
||||
rv = 0;
|
||||
|
||||
/* Check to see if we can get both channels.
|
||||
*/
|
||||
/* Check to see if we can get both channels. */
|
||||
spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags);
|
||||
if (!(stp->dev_flags & DEV_FLAGS_INUSE) ||
|
||||
(stp->dev_flags & DEV_FLAGS_ANYUSE)) {
|
||||
|
@ -261,35 +257,30 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
|
|||
(dtp->dev_flags & DEV_FLAGS_ANYUSE)) {
|
||||
/* Got destination */
|
||||
dtp->dev_flags |= DEV_FLAGS_INUSE;
|
||||
}
|
||||
else {
|
||||
/* Can't get dest. Release src.
|
||||
*/
|
||||
} else {
|
||||
/* Can't get dest. Release src. */
|
||||
stp->dev_flags &= ~DEV_FLAGS_INUSE;
|
||||
used++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else
|
||||
used++;
|
||||
}
|
||||
spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags);
|
||||
|
||||
if (!used) {
|
||||
/* Let's see if we can allocate a channel for it.
|
||||
*/
|
||||
/* Let's see if we can allocate a channel for it. */
|
||||
ctp = NULL;
|
||||
chan = 0;
|
||||
spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags);
|
||||
for (i=0; i<NUM_DBDMA_CHANS; i++) {
|
||||
for (i = 0; i < NUM_DBDMA_CHANS; i++)
|
||||
if (chan_tab_ptr[i] == NULL) {
|
||||
/* If kmalloc fails, it is caught below same
|
||||
/*
|
||||
* If kmalloc fails, it is caught below same
|
||||
* as a channel not available.
|
||||
*/
|
||||
ctp = kmalloc(sizeof(chan_tab_t), GFP_ATOMIC);
|
||||
chan_tab_ptr[i] = ctp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags);
|
||||
|
||||
if (ctp != NULL) {
|
||||
|
@ -304,8 +295,7 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
|
|||
ctp->chan_callback = callback;
|
||||
ctp->chan_callparam = callparam;
|
||||
|
||||
/* Initialize channel configuration.
|
||||
*/
|
||||
/* Initialize channel configuration. */
|
||||
i = 0;
|
||||
if (stp->dev_intlevel)
|
||||
i |= DDMA_CFG_SED;
|
||||
|
@ -326,8 +316,7 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
|
|||
* operations.
|
||||
*/
|
||||
rv = (u32)(&chan_tab_ptr[chan]);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
/* Release devices */
|
||||
stp->dev_flags &= ~DEV_FLAGS_INUSE;
|
||||
dtp->dev_flags &= ~DEV_FLAGS_INUSE;
|
||||
|
@ -337,11 +326,11 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
|
|||
}
|
||||
EXPORT_SYMBOL(au1xxx_dbdma_chan_alloc);
|
||||
|
||||
/* Set the device width if source or destination is a FIFO.
|
||||
/*
|
||||
* Set the device width if source or destination is a FIFO.
|
||||
* Should be 8, 16, or 32 bits.
|
||||
*/
|
||||
u32
|
||||
au1xxx_dbdma_set_devwidth(u32 chanid, int bits)
|
||||
u32 au1xxx_dbdma_set_devwidth(u32 chanid, int bits)
|
||||
{
|
||||
u32 rv;
|
||||
chan_tab_t *ctp;
|
||||
|
@ -365,10 +354,8 @@ au1xxx_dbdma_set_devwidth(u32 chanid, int bits)
|
|||
}
|
||||
EXPORT_SYMBOL(au1xxx_dbdma_set_devwidth);
|
||||
|
||||
/* Allocate a descriptor ring, initializing as much as possible.
|
||||
*/
|
||||
u32
|
||||
au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
|
||||
/* Allocate a descriptor ring, initializing as much as possible. */
|
||||
u32 au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
|
||||
{
|
||||
int i;
|
||||
u32 desc_base, srcid, destid;
|
||||
|
@ -378,43 +365,45 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
|
|||
dbdev_tab_t *stp, *dtp;
|
||||
au1x_ddma_desc_t *dp;
|
||||
|
||||
/* I guess we could check this to be within the
|
||||
/*
|
||||
* I guess we could check this to be within the
|
||||
* range of the table......
|
||||
*/
|
||||
ctp = *((chan_tab_t **)chanid);
|
||||
stp = ctp->chan_src;
|
||||
dtp = ctp->chan_dest;
|
||||
|
||||
/* The descriptors must be 32-byte aligned. There is a
|
||||
/*
|
||||
* The descriptors must be 32-byte aligned. There is a
|
||||
* possibility the allocation will give us such an address,
|
||||
* and if we try that first we are likely to not waste larger
|
||||
* slabs of memory.
|
||||
*/
|
||||
desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t),
|
||||
GFP_KERNEL|GFP_DMA);
|
||||
GFP_KERNEL|GFP_DMA);
|
||||
if (desc_base == 0)
|
||||
return 0;
|
||||
|
||||
if (desc_base & 0x1f) {
|
||||
/* Lost....do it again, allocate extra, and round
|
||||
/*
|
||||
* Lost....do it again, allocate extra, and round
|
||||
* the address base.
|
||||
*/
|
||||
kfree((const void *)desc_base);
|
||||
i = entries * sizeof(au1x_ddma_desc_t);
|
||||
i += (sizeof(au1x_ddma_desc_t) - 1);
|
||||
if ((desc_base = (u32)kmalloc(i, GFP_KERNEL|GFP_DMA)) == 0)
|
||||
desc_base = (u32)kmalloc(i, GFP_KERNEL|GFP_DMA);
|
||||
if (desc_base == 0)
|
||||
return 0;
|
||||
|
||||
desc_base = ALIGN_ADDR(desc_base, sizeof(au1x_ddma_desc_t));
|
||||
}
|
||||
dp = (au1x_ddma_desc_t *)desc_base;
|
||||
|
||||
/* Keep track of the base descriptor.
|
||||
*/
|
||||
/* Keep track of the base descriptor. */
|
||||
ctp->chan_desc_base = dp;
|
||||
|
||||
/* Initialize the rings with as much information as we know.
|
||||
*/
|
||||
/* Initialize the rings with as much information as we know. */
|
||||
srcid = stp->dev_id;
|
||||
destid = dtp->dev_id;
|
||||
|
||||
|
@ -426,11 +415,12 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
|
|||
cmd0 |= DSCR_CMD0_IE | DSCR_CMD0_CV;
|
||||
cmd0 |= DSCR_CMD0_ST(DSCR_CMD0_ST_NOCHANGE);
|
||||
|
||||
/* is it mem to mem transfer? */
|
||||
if(((DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_THROTTLE) || (DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_ALWAYS)) &&
|
||||
((DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_THROTTLE) || (DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_ALWAYS))) {
|
||||
cmd0 |= DSCR_CMD0_MEM;
|
||||
}
|
||||
/* Is it mem to mem transfer? */
|
||||
if (((DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_THROTTLE) ||
|
||||
(DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_ALWAYS)) &&
|
||||
((DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_THROTTLE) ||
|
||||
(DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_ALWAYS)))
|
||||
cmd0 |= DSCR_CMD0_MEM;
|
||||
|
||||
switch (stp->dev_devwidth) {
|
||||
case 8:
|
||||
|
@ -458,15 +448,17 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
|
|||
break;
|
||||
}
|
||||
|
||||
/* If the device is marked as an in/out FIFO, ensure it is
|
||||
/*
|
||||
* If the device is marked as an in/out FIFO, ensure it is
|
||||
* set non-coherent.
|
||||
*/
|
||||
if (stp->dev_flags & DEV_FLAGS_IN)
|
||||
cmd0 |= DSCR_CMD0_SN; /* Source in fifo */
|
||||
cmd0 |= DSCR_CMD0_SN; /* Source in FIFO */
|
||||
if (dtp->dev_flags & DEV_FLAGS_OUT)
|
||||
cmd0 |= DSCR_CMD0_DN; /* Destination out fifo */
|
||||
cmd0 |= DSCR_CMD0_DN; /* Destination out FIFO */
|
||||
|
||||
/* Set up source1. For now, assume no stride and increment.
|
||||
/*
|
||||
* Set up source1. For now, assume no stride and increment.
|
||||
* A channel attribute update can change this later.
|
||||
*/
|
||||
switch (stp->dev_tsize) {
|
||||
|
@ -485,19 +477,19 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
|
|||
break;
|
||||
}
|
||||
|
||||
/* If source input is fifo, set static address.
|
||||
*/
|
||||
/* If source input is FIFO, set static address. */
|
||||
if (stp->dev_flags & DEV_FLAGS_IN) {
|
||||
if ( stp->dev_flags & DEV_FLAGS_BURSTABLE )
|
||||
if (stp->dev_flags & DEV_FLAGS_BURSTABLE)
|
||||
src1 |= DSCR_SRC1_SAM(DSCR_xAM_BURST);
|
||||
else
|
||||
src1 |= DSCR_SRC1_SAM(DSCR_xAM_STATIC);
|
||||
|
||||
src1 |= DSCR_SRC1_SAM(DSCR_xAM_STATIC);
|
||||
}
|
||||
|
||||
if (stp->dev_physaddr)
|
||||
src0 = stp->dev_physaddr;
|
||||
|
||||
/* Set up dest1. For now, assume no stride and increment.
|
||||
/*
|
||||
* Set up dest1. For now, assume no stride and increment.
|
||||
* A channel attribute update can change this later.
|
||||
*/
|
||||
switch (dtp->dev_tsize) {
|
||||
|
@ -516,22 +508,24 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
|
|||
break;
|
||||
}
|
||||
|
||||
/* If destination output is fifo, set static address.
|
||||
*/
|
||||
/* If destination output is FIFO, set static address. */
|
||||
if (dtp->dev_flags & DEV_FLAGS_OUT) {
|
||||
if ( dtp->dev_flags & DEV_FLAGS_BURSTABLE )
|
||||
dest1 |= DSCR_DEST1_DAM(DSCR_xAM_BURST);
|
||||
else
|
||||
dest1 |= DSCR_DEST1_DAM(DSCR_xAM_STATIC);
|
||||
if (dtp->dev_flags & DEV_FLAGS_BURSTABLE)
|
||||
dest1 |= DSCR_DEST1_DAM(DSCR_xAM_BURST);
|
||||
else
|
||||
dest1 |= DSCR_DEST1_DAM(DSCR_xAM_STATIC);
|
||||
}
|
||||
|
||||
if (dtp->dev_physaddr)
|
||||
dest0 = dtp->dev_physaddr;
|
||||
|
||||
#if 0
|
||||
printk("did:%x sid:%x cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n",
|
||||
dtp->dev_id, stp->dev_id, cmd0, cmd1, src0, src1, dest0, dest1 );
|
||||
printk(KERN_DEBUG "did:%x sid:%x cmd0:%x cmd1:%x source0:%x "
|
||||
"source1:%x dest0:%x dest1:%x\n",
|
||||
dtp->dev_id, stp->dev_id, cmd0, cmd1, src0,
|
||||
src1, dest0, dest1);
|
||||
#endif
|
||||
for (i=0; i<entries; i++) {
|
||||
for (i = 0; i < entries; i++) {
|
||||
dp->dscr_cmd0 = cmd0;
|
||||
dp->dscr_cmd1 = cmd1;
|
||||
dp->dscr_source0 = src0;
|
||||
|
@ -545,49 +539,49 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
|
|||
dp++;
|
||||
}
|
||||
|
||||
/* Make last descrptor point to the first.
|
||||
*/
|
||||
/* Make last descrptor point to the first. */
|
||||
dp--;
|
||||
dp->dscr_nxtptr = DSCR_NXTPTR(virt_to_phys(ctp->chan_desc_base));
|
||||
ctp->get_ptr = ctp->put_ptr = ctp->cur_ptr = ctp->chan_desc_base;
|
||||
|
||||
return (u32)(ctp->chan_desc_base);
|
||||
return (u32)ctp->chan_desc_base;
|
||||
}
|
||||
EXPORT_SYMBOL(au1xxx_dbdma_ring_alloc);
|
||||
|
||||
/* Put a source buffer into the DMA ring.
|
||||
/*
|
||||
* Put a source buffer into the DMA ring.
|
||||
* This updates the source pointer and byte count. Normally used
|
||||
* for memory to fifo transfers.
|
||||
*/
|
||||
u32
|
||||
_au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags)
|
||||
u32 _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags)
|
||||
{
|
||||
chan_tab_t *ctp;
|
||||
au1x_ddma_desc_t *dp;
|
||||
|
||||
/* I guess we could check this to be within the
|
||||
/*
|
||||
* I guess we could check this to be within the
|
||||
* range of the table......
|
||||
*/
|
||||
ctp = *((chan_tab_t **)chanid);
|
||||
ctp = *(chan_tab_t **)chanid;
|
||||
|
||||
/* We should have multiple callers for a particular channel,
|
||||
/*
|
||||
* We should have multiple callers for a particular channel,
|
||||
* an interrupt doesn't affect this pointer nor the descriptor,
|
||||
* so no locking should be needed.
|
||||
*/
|
||||
dp = ctp->put_ptr;
|
||||
|
||||
/* If the descriptor is valid, we are way ahead of the DMA
|
||||
/*
|
||||
* If the descriptor is valid, we are way ahead of the DMA
|
||||
* engine, so just return an error condition.
|
||||
*/
|
||||
if (dp->dscr_cmd0 & DSCR_CMD0_V) {
|
||||
if (dp->dscr_cmd0 & DSCR_CMD0_V)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Load up buffer address and byte count.
|
||||
*/
|
||||
/* Load up buffer address and byte count. */
|
||||
dp->dscr_source0 = virt_to_phys(buf);
|
||||
dp->dscr_cmd1 = nbytes;
|
||||
/* Check flags */
|
||||
/* Check flags */
|
||||
if (flags & DDMA_FLAGS_IE)
|
||||
dp->dscr_cmd0 |= DSCR_CMD0_IE;
|
||||
if (flags & DDMA_FLAGS_NOIE)
|
||||
|
@ -595,23 +589,21 @@ _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags)
|
|||
|
||||
/*
|
||||
* There is an errata on the Au1200/Au1550 parts that could result
|
||||
* in "stale" data being DMA'd. It has to do with the snoop logic on
|
||||
* the dache eviction buffer. NONCOHERENT_IO is on by default for
|
||||
* these parts. If it is fixedin the future, these dma_cache_inv will
|
||||
* in "stale" data being DMA'ed. It has to do with the snoop logic on
|
||||
* the cache eviction buffer. DMA_NONCOHERENT is on by default for
|
||||
* these parts. If it is fixed in the future, these dma_cache_inv will
|
||||
* just be nothing more than empty macros. See io.h.
|
||||
* */
|
||||
*/
|
||||
dma_cache_wback_inv((unsigned long)buf, nbytes);
|
||||
dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */
|
||||
dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */
|
||||
au_sync();
|
||||
dma_cache_wback_inv((unsigned long)dp, sizeof(dp));
|
||||
ctp->chan_ptr->ddma_dbell = 0;
|
||||
ctp->chan_ptr->ddma_dbell = 0;
|
||||
|
||||
/* Get next descriptor pointer.
|
||||
*/
|
||||
/* Get next descriptor pointer. */
|
||||
ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
|
||||
|
||||
/* return something not zero.
|
||||
*/
|
||||
/* Return something non-zero. */
|
||||
return nbytes;
|
||||
}
|
||||
EXPORT_SYMBOL(_au1xxx_dbdma_put_source);
|
||||
|
@ -654,81 +646,77 @@ _au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags)
|
|||
dp->dscr_dest0 = virt_to_phys(buf);
|
||||
dp->dscr_cmd1 = nbytes;
|
||||
#if 0
|
||||
printk("cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n",
|
||||
dp->dscr_cmd0, dp->dscr_cmd1, dp->dscr_source0,
|
||||
dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1 );
|
||||
printk(KERN_DEBUG "cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n",
|
||||
dp->dscr_cmd0, dp->dscr_cmd1, dp->dscr_source0,
|
||||
dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1);
|
||||
#endif
|
||||
/*
|
||||
* There is an errata on the Au1200/Au1550 parts that could result in
|
||||
* "stale" data being DMA'd. It has to do with the snoop logic on the
|
||||
* dache eviction buffer. NONCOHERENT_IO is on by default for these
|
||||
* parts. If it is fixedin the future, these dma_cache_inv will just
|
||||
* "stale" data being DMA'ed. It has to do with the snoop logic on the
|
||||
* cache eviction buffer. DMA_NONCOHERENT is on by default for these
|
||||
* parts. If it is fixed in the future, these dma_cache_inv will just
|
||||
* be nothing more than empty macros. See io.h.
|
||||
* */
|
||||
*/
|
||||
dma_cache_inv((unsigned long)buf, nbytes);
|
||||
dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */
|
||||
au_sync();
|
||||
dma_cache_wback_inv((unsigned long)dp, sizeof(dp));
|
||||
ctp->chan_ptr->ddma_dbell = 0;
|
||||
ctp->chan_ptr->ddma_dbell = 0;
|
||||
|
||||
/* Get next descriptor pointer.
|
||||
*/
|
||||
/* Get next descriptor pointer. */
|
||||
ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
|
||||
|
||||
/* return something not zero.
|
||||
*/
|
||||
/* Return something non-zero. */
|
||||
return nbytes;
|
||||
}
|
||||
EXPORT_SYMBOL(_au1xxx_dbdma_put_dest);
|
||||
|
||||
/* Get a destination buffer into the DMA ring.
|
||||
/*
|
||||
* Get a destination buffer into the DMA ring.
|
||||
* Normally used to get a full buffer from the ring during fifo
|
||||
* to memory transfers. This does not set the valid bit, you will
|
||||
* have to put another destination buffer to keep the DMA going.
|
||||
*/
|
||||
u32
|
||||
au1xxx_dbdma_get_dest(u32 chanid, void **buf, int *nbytes)
|
||||
u32 au1xxx_dbdma_get_dest(u32 chanid, void **buf, int *nbytes)
|
||||
{
|
||||
chan_tab_t *ctp;
|
||||
au1x_ddma_desc_t *dp;
|
||||
u32 rv;
|
||||
|
||||
/* I guess we could check this to be within the
|
||||
/*
|
||||
* I guess we could check this to be within the
|
||||
* range of the table......
|
||||
*/
|
||||
ctp = *((chan_tab_t **)chanid);
|
||||
|
||||
/* We should have multiple callers for a particular channel,
|
||||
/*
|
||||
* We should have multiple callers for a particular channel,
|
||||
* an interrupt doesn't affect this pointer nor the descriptor,
|
||||
* so no locking should be needed.
|
||||
*/
|
||||
dp = ctp->get_ptr;
|
||||
|
||||
/* If the descriptor is valid, we are way ahead of the DMA
|
||||
/*
|
||||
* If the descriptor is valid, we are way ahead of the DMA
|
||||
* engine, so just return an error condition.
|
||||
*/
|
||||
if (dp->dscr_cmd0 & DSCR_CMD0_V)
|
||||
return 0;
|
||||
|
||||
/* Return buffer address and byte count.
|
||||
*/
|
||||
/* Return buffer address and byte count. */
|
||||
*buf = (void *)(phys_to_virt(dp->dscr_dest0));
|
||||
*nbytes = dp->dscr_cmd1;
|
||||
rv = dp->dscr_stat;
|
||||
|
||||
/* Get next descriptor pointer.
|
||||
*/
|
||||
/* Get next descriptor pointer. */
|
||||
ctp->get_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
|
||||
|
||||
/* return something not zero.
|
||||
*/
|
||||
/* Return something non-zero. */
|
||||
return rv;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(au1xxx_dbdma_get_dest);
|
||||
|
||||
void
|
||||
au1xxx_dbdma_stop(u32 chanid)
|
||||
void au1xxx_dbdma_stop(u32 chanid)
|
||||
{
|
||||
chan_tab_t *ctp;
|
||||
au1x_dma_chan_t *cp;
|
||||
|
@ -743,7 +731,7 @@ au1xxx_dbdma_stop(u32 chanid)
|
|||
udelay(1);
|
||||
halt_timeout++;
|
||||
if (halt_timeout > 100) {
|
||||
printk("warning: DMA channel won't halt\n");
|
||||
printk(KERN_WARNING "warning: DMA channel won't halt\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -753,12 +741,12 @@ au1xxx_dbdma_stop(u32 chanid)
|
|||
}
|
||||
EXPORT_SYMBOL(au1xxx_dbdma_stop);
|
||||
|
||||
/* Start using the current descriptor pointer. If the dbdma encounters
|
||||
* a not valid descriptor, it will stop. In this case, we can just
|
||||
/*
|
||||
* Start using the current descriptor pointer. If the DBDMA encounters
|
||||
* a non-valid descriptor, it will stop. In this case, we can just
|
||||
* continue by adding a buffer to the list and starting again.
|
||||
*/
|
||||
void
|
||||
au1xxx_dbdma_start(u32 chanid)
|
||||
void au1xxx_dbdma_start(u32 chanid)
|
||||
{
|
||||
chan_tab_t *ctp;
|
||||
au1x_dma_chan_t *cp;
|
||||
|
@ -773,8 +761,7 @@ au1xxx_dbdma_start(u32 chanid)
|
|||
}
|
||||
EXPORT_SYMBOL(au1xxx_dbdma_start);
|
||||
|
||||
void
|
||||
au1xxx_dbdma_reset(u32 chanid)
|
||||
void au1xxx_dbdma_reset(u32 chanid)
|
||||
{
|
||||
chan_tab_t *ctp;
|
||||
au1x_ddma_desc_t *dp;
|
||||
|
@ -784,14 +771,14 @@ au1xxx_dbdma_reset(u32 chanid)
|
|||
ctp = *((chan_tab_t **)chanid);
|
||||
ctp->get_ptr = ctp->put_ptr = ctp->cur_ptr = ctp->chan_desc_base;
|
||||
|
||||
/* Run through the descriptors and reset the valid indicator.
|
||||
*/
|
||||
/* Run through the descriptors and reset the valid indicator. */
|
||||
dp = ctp->chan_desc_base;
|
||||
|
||||
do {
|
||||
dp->dscr_cmd0 &= ~DSCR_CMD0_V;
|
||||
/* reset our SW status -- this is used to determine
|
||||
* if a descriptor is in use by upper level SW. Since
|
||||
/*
|
||||
* Reset our software status -- this is used to determine
|
||||
* if a descriptor is in use by upper level software. Since
|
||||
* posting can reset 'V' bit.
|
||||
*/
|
||||
dp->sw_status = 0;
|
||||
|
@ -800,8 +787,7 @@ au1xxx_dbdma_reset(u32 chanid)
|
|||
}
|
||||
EXPORT_SYMBOL(au1xxx_dbdma_reset);
|
||||
|
||||
u32
|
||||
au1xxx_get_dma_residue(u32 chanid)
|
||||
u32 au1xxx_get_dma_residue(u32 chanid)
|
||||
{
|
||||
chan_tab_t *ctp;
|
||||
au1x_dma_chan_t *cp;
|
||||
|
@ -810,18 +796,15 @@ au1xxx_get_dma_residue(u32 chanid)
|
|||
ctp = *((chan_tab_t **)chanid);
|
||||
cp = ctp->chan_ptr;
|
||||
|
||||
/* This is only valid if the channel is stopped.
|
||||
*/
|
||||
/* This is only valid if the channel is stopped. */
|
||||
rv = cp->ddma_bytecnt;
|
||||
au_sync();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(au1xxx_get_dma_residue);
|
||||
|
||||
void
|
||||
au1xxx_dbdma_chan_free(u32 chanid)
|
||||
void au1xxx_dbdma_chan_free(u32 chanid)
|
||||
{
|
||||
chan_tab_t *ctp;
|
||||
dbdev_tab_t *stp, *dtp;
|
||||
|
@ -842,8 +825,7 @@ au1xxx_dbdma_chan_free(u32 chanid)
|
|||
}
|
||||
EXPORT_SYMBOL(au1xxx_dbdma_chan_free);
|
||||
|
||||
static irqreturn_t
|
||||
dbdma_interrupt(int irq, void *dev_id)
|
||||
static irqreturn_t dbdma_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
u32 intstat;
|
||||
u32 chan_index;
|
||||
|
@ -859,13 +841,12 @@ dbdma_interrupt(int irq, void *dev_id)
|
|||
cp = ctp->chan_ptr;
|
||||
dp = ctp->cur_ptr;
|
||||
|
||||
/* Reset interrupt.
|
||||
*/
|
||||
/* Reset interrupt. */
|
||||
cp->ddma_irq = 0;
|
||||
au_sync();
|
||||
|
||||
if (ctp->chan_callback)
|
||||
(ctp->chan_callback)(irq, ctp->chan_callparam);
|
||||
ctp->chan_callback(irq, ctp->chan_callparam);
|
||||
|
||||
ctp->cur_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
|
||||
return IRQ_RETVAL(1);
|
||||
|
@ -890,47 +871,47 @@ static void au1xxx_dbdma_init(void)
|
|||
|
||||
if (request_irq(irq_nr, dbdma_interrupt, IRQF_DISABLED,
|
||||
"Au1xxx dbdma", (void *)dbdma_gptr))
|
||||
printk("Can't get 1550 dbdma irq");
|
||||
printk(KERN_ERR "Can't get 1550 dbdma irq");
|
||||
}
|
||||
|
||||
void
|
||||
au1xxx_dbdma_dump(u32 chanid)
|
||||
void au1xxx_dbdma_dump(u32 chanid)
|
||||
{
|
||||
chan_tab_t *ctp;
|
||||
au1x_ddma_desc_t *dp;
|
||||
dbdev_tab_t *stp, *dtp;
|
||||
au1x_dma_chan_t *cp;
|
||||
u32 i = 0;
|
||||
chan_tab_t *ctp;
|
||||
au1x_ddma_desc_t *dp;
|
||||
dbdev_tab_t *stp, *dtp;
|
||||
au1x_dma_chan_t *cp;
|
||||
u32 i = 0;
|
||||
|
||||
ctp = *((chan_tab_t **)chanid);
|
||||
stp = ctp->chan_src;
|
||||
dtp = ctp->chan_dest;
|
||||
cp = ctp->chan_ptr;
|
||||
|
||||
printk("Chan %x, stp %x (dev %d) dtp %x (dev %d) \n",
|
||||
(u32)ctp, (u32)stp, stp - dbdev_tab, (u32)dtp, dtp - dbdev_tab);
|
||||
printk("desc base %x, get %x, put %x, cur %x\n",
|
||||
(u32)(ctp->chan_desc_base), (u32)(ctp->get_ptr),
|
||||
(u32)(ctp->put_ptr), (u32)(ctp->cur_ptr));
|
||||
printk(KERN_DEBUG "Chan %x, stp %x (dev %d) dtp %x (dev %d) \n",
|
||||
(u32)ctp, (u32)stp, stp - dbdev_tab, (u32)dtp,
|
||||
dtp - dbdev_tab);
|
||||
printk(KERN_DEBUG "desc base %x, get %x, put %x, cur %x\n",
|
||||
(u32)(ctp->chan_desc_base), (u32)(ctp->get_ptr),
|
||||
(u32)(ctp->put_ptr), (u32)(ctp->cur_ptr));
|
||||
|
||||
printk("dbdma chan %x\n", (u32)cp);
|
||||
printk("cfg %08x, desptr %08x, statptr %08x\n",
|
||||
cp->ddma_cfg, cp->ddma_desptr, cp->ddma_statptr);
|
||||
printk("dbell %08x, irq %08x, stat %08x, bytecnt %08x\n",
|
||||
cp->ddma_dbell, cp->ddma_irq, cp->ddma_stat, cp->ddma_bytecnt);
|
||||
printk(KERN_DEBUG "dbdma chan %x\n", (u32)cp);
|
||||
printk(KERN_DEBUG "cfg %08x, desptr %08x, statptr %08x\n",
|
||||
cp->ddma_cfg, cp->ddma_desptr, cp->ddma_statptr);
|
||||
printk(KERN_DEBUG "dbell %08x, irq %08x, stat %08x, bytecnt %08x\n",
|
||||
cp->ddma_dbell, cp->ddma_irq, cp->ddma_stat,
|
||||
cp->ddma_bytecnt);
|
||||
|
||||
|
||||
/* Run through the descriptors
|
||||
*/
|
||||
/* Run through the descriptors */
|
||||
dp = ctp->chan_desc_base;
|
||||
|
||||
do {
|
||||
printk("Dp[%d]= %08x, cmd0 %08x, cmd1 %08x\n",
|
||||
i++, (u32)dp, dp->dscr_cmd0, dp->dscr_cmd1);
|
||||
printk("src0 %08x, src1 %08x, dest0 %08x, dest1 %08x\n",
|
||||
dp->dscr_source0, dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1);
|
||||
printk("stat %08x, nxtptr %08x\n",
|
||||
dp->dscr_stat, dp->dscr_nxtptr);
|
||||
printk(KERN_DEBUG "Dp[%d]= %08x, cmd0 %08x, cmd1 %08x\n",
|
||||
i++, (u32)dp, dp->dscr_cmd0, dp->dscr_cmd1);
|
||||
printk(KERN_DEBUG "src0 %08x, src1 %08x, dest0 %08x, dest1 %08x\n",
|
||||
dp->dscr_source0, dp->dscr_source1,
|
||||
dp->dscr_dest0, dp->dscr_dest1);
|
||||
printk(KERN_DEBUG "stat %08x, nxtptr %08x\n",
|
||||
dp->dscr_stat, dp->dscr_nxtptr);
|
||||
dp = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
|
||||
} while (dp != ctp->chan_desc_base);
|
||||
}
|
||||
|
@ -938,32 +919,33 @@ au1xxx_dbdma_dump(u32 chanid)
|
|||
/* Put a descriptor into the DMA ring.
|
||||
* This updates the source/destination pointers and byte count.
|
||||
*/
|
||||
u32
|
||||
au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr )
|
||||
u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr)
|
||||
{
|
||||
chan_tab_t *ctp;
|
||||
au1x_ddma_desc_t *dp;
|
||||
u32 nbytes=0;
|
||||
u32 nbytes = 0;
|
||||
|
||||
/* I guess we could check this to be within the
|
||||
* range of the table......
|
||||
*/
|
||||
/*
|
||||
* I guess we could check this to be within the
|
||||
* range of the table......
|
||||
*/
|
||||
ctp = *((chan_tab_t **)chanid);
|
||||
|
||||
/* We should have multiple callers for a particular channel,
|
||||
* an interrupt doesn't affect this pointer nor the descriptor,
|
||||
* so no locking should be needed.
|
||||
*/
|
||||
/*
|
||||
* We should have multiple callers for a particular channel,
|
||||
* an interrupt doesn't affect this pointer nor the descriptor,
|
||||
* so no locking should be needed.
|
||||
*/
|
||||
dp = ctp->put_ptr;
|
||||
|
||||
/* If the descriptor is valid, we are way ahead of the DMA
|
||||
* engine, so just return an error condition.
|
||||
*/
|
||||
/*
|
||||
* If the descriptor is valid, we are way ahead of the DMA
|
||||
* engine, so just return an error condition.
|
||||
*/
|
||||
if (dp->dscr_cmd0 & DSCR_CMD0_V)
|
||||
return 0;
|
||||
|
||||
/* Load up buffer addresses and byte count.
|
||||
*/
|
||||
/* Load up buffer addresses and byte count. */
|
||||
dp->dscr_dest0 = dscr->dscr_dest0;
|
||||
dp->dscr_source0 = dscr->dscr_source0;
|
||||
dp->dscr_dest1 = dscr->dscr_dest1;
|
||||
|
@ -975,14 +957,11 @@ au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr )
|
|||
dp->dscr_cmd0 |= dscr->dscr_cmd0 | DSCR_CMD0_V;
|
||||
ctp->chan_ptr->ddma_dbell = 0;
|
||||
|
||||
/* Get next descriptor pointer.
|
||||
*/
|
||||
/* Get next descriptor pointer. */
|
||||
ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
|
||||
|
||||
/* return something not zero.
|
||||
*/
|
||||
/* Return something non-zero. */
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
#endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include <linux/types.h>
|
||||
|
||||
#include <asm/mach-au1x00/au1000.h>
|
||||
|
||||
|
@ -8,12 +9,6 @@
|
|||
* uart to be used for debugging.
|
||||
*/
|
||||
#define DEBUG_BASE UART_DEBUG_BASE
|
||||
/**/
|
||||
|
||||
/* we need uint32 uint8 */
|
||||
/* #include "types.h" */
|
||||
typedef unsigned char uint8;
|
||||
typedef unsigned int uint32;
|
||||
|
||||
#define UART16550_BAUD_2400 2400
|
||||
#define UART16550_BAUD_4800 4800
|
||||
|
@ -51,17 +46,15 @@ typedef unsigned int uint32;
|
|||
#define UART_MOD_CNTRL 0x100 /* Module Control */
|
||||
|
||||
/* memory-mapped read/write of the port */
|
||||
#define UART16550_READ(y) (au_readl(DEBUG_BASE + y) & 0xff)
|
||||
#define UART16550_WRITE(y, z) (au_writel(z&0xff, DEBUG_BASE + y))
|
||||
#define UART16550_READ(y) (au_readl(DEBUG_BASE + y) & 0xff)
|
||||
#define UART16550_WRITE(y, z) (au_writel(z & 0xff, DEBUG_BASE + y))
|
||||
|
||||
extern unsigned long calc_clock(void);
|
||||
|
||||
void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
|
||||
void debugInit(u32 baud, u8 data, u8 parity, u8 stop)
|
||||
{
|
||||
|
||||
if (UART16550_READ(UART_MOD_CNTRL) != 0x3) {
|
||||
if (UART16550_READ(UART_MOD_CNTRL) != 0x3)
|
||||
UART16550_WRITE(UART_MOD_CNTRL, 3);
|
||||
}
|
||||
calc_clock();
|
||||
|
||||
/* disable interrupts */
|
||||
|
@ -69,7 +62,7 @@ void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
|
|||
|
||||
/* set up baud rate */
|
||||
{
|
||||
uint32 divisor;
|
||||
u32 divisor;
|
||||
|
||||
/* set divisor */
|
||||
divisor = get_au1x00_uart_baud_base() / baud;
|
||||
|
@ -80,9 +73,9 @@ void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
|
|||
UART16550_WRITE(UART_LCR, (data | parity | stop));
|
||||
}
|
||||
|
||||
static int remoteDebugInitialized = 0;
|
||||
static int remoteDebugInitialized;
|
||||
|
||||
uint8 getDebugChar(void)
|
||||
u8 getDebugChar(void)
|
||||
{
|
||||
if (!remoteDebugInitialized) {
|
||||
remoteDebugInitialized = 1;
|
||||
|
@ -92,15 +85,13 @@ uint8 getDebugChar(void)
|
|||
UART16550_STOP_1BIT);
|
||||
}
|
||||
|
||||
while((UART16550_READ(UART_LSR) & 0x1) == 0);
|
||||
while ((UART16550_READ(UART_LSR) & 0x1) == 0);
|
||||
return UART16550_READ(UART_RX);
|
||||
}
|
||||
|
||||
|
||||
int putDebugChar(uint8 byte)
|
||||
int putDebugChar(u8 byte)
|
||||
{
|
||||
// int i;
|
||||
|
||||
if (!remoteDebugInitialized) {
|
||||
remoteDebugInitialized = 1;
|
||||
debugInit(UART16550_BAUD_115200,
|
||||
|
@ -109,9 +100,8 @@ int putDebugChar(uint8 byte)
|
|||
UART16550_STOP_1BIT);
|
||||
}
|
||||
|
||||
while ((UART16550_READ(UART_LSR)&0x40) == 0);
|
||||
while ((UART16550_READ(UART_LSR) & 0x40) == 0);
|
||||
UART16550_WRITE(UART_TX, byte);
|
||||
//for (i=0;i<0xfff;i++);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
/*
|
||||
*
|
||||
* BRIEF MODULE DESCRIPTION
|
||||
* A DMA channel allocator for Au1000. API is modeled loosely off of
|
||||
* A DMA channel allocator for Au1x00. API is modeled loosely off of
|
||||
* linux/kernel/dma.c.
|
||||
*
|
||||
* Copyright 2000 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc.
|
||||
* stevel@mvista.com or source@mvista.com
|
||||
* Copyright 2000, 2008 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc. <source@mvista.com>
|
||||
* Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -39,7 +38,8 @@
|
|||
#include <asm/mach-au1x00/au1000.h>
|
||||
#include <asm/mach-au1x00/au1000_dma.h>
|
||||
|
||||
#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1100)
|
||||
#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || \
|
||||
defined(CONFIG_SOC_AU1100)
|
||||
/*
|
||||
* A note on resource allocation:
|
||||
*
|
||||
|
@ -56,7 +56,6 @@
|
|||
* returned from request_dma.
|
||||
*/
|
||||
|
||||
|
||||
DEFINE_SPINLOCK(au1000_dma_spin_lock);
|
||||
|
||||
struct dma_chan au1000_dma_table[NUM_AU1000_DMA_CHANNELS] = {
|
||||
|
@ -71,7 +70,7 @@ struct dma_chan au1000_dma_table[NUM_AU1000_DMA_CHANNELS] = {
|
|||
};
|
||||
EXPORT_SYMBOL(au1000_dma_table);
|
||||
|
||||
// Device FIFO addresses and default DMA modes
|
||||
/* Device FIFO addresses and default DMA modes */
|
||||
static const struct dma_dev {
|
||||
unsigned int fifo_addr;
|
||||
unsigned int dma_mode;
|
||||
|
@ -80,8 +79,8 @@ static const struct dma_dev {
|
|||
{UART0_ADDR + UART_RX, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{AC97C_DATA, DMA_DW16 }, // coherent
|
||||
{AC97C_DATA, DMA_DR | DMA_DW16 }, // coherent
|
||||
{AC97C_DATA, DMA_DW16 }, /* coherent */
|
||||
{AC97C_DATA, DMA_DR | DMA_DW16 }, /* coherent */
|
||||
{UART3_ADDR + UART_TX, DMA_DW8 | DMA_NC},
|
||||
{UART3_ADDR + UART_RX, DMA_DR | DMA_DW8 | DMA_NC},
|
||||
{USBD_EP0RD, DMA_DR | DMA_DW8 | DMA_NC},
|
||||
|
@ -101,10 +100,10 @@ int au1000_dma_read_proc(char *buf, char **start, off_t fpos,
|
|||
struct dma_chan *chan;
|
||||
|
||||
for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) {
|
||||
if ((chan = get_dma_chan(i)) != NULL) {
|
||||
chan = get_dma_chan(i);
|
||||
if (chan != NULL)
|
||||
len += sprintf(buf + len, "%2d: %s\n",
|
||||
i, chan->dev_str);
|
||||
}
|
||||
}
|
||||
|
||||
if (fpos >= len) {
|
||||
|
@ -113,18 +112,19 @@ int au1000_dma_read_proc(char *buf, char **start, off_t fpos,
|
|||
return 0;
|
||||
}
|
||||
*start = buf + fpos;
|
||||
if ((len -= fpos) > length)
|
||||
len -= fpos;
|
||||
if (len > length)
|
||||
return length;
|
||||
*eof = 1;
|
||||
return len;
|
||||
}
|
||||
|
||||
// Device FIFO addresses and default DMA modes - 2nd bank
|
||||
/* Device FIFO addresses and default DMA modes - 2nd bank */
|
||||
static const struct dma_dev dma_dev_table_bank2[DMA_NUM_DEV_BANK2] = {
|
||||
{SD0_XMIT_FIFO, DMA_DS | DMA_DW8}, // coherent
|
||||
{SD0_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8}, // coherent
|
||||
{SD1_XMIT_FIFO, DMA_DS | DMA_DW8}, // coherent
|
||||
{SD1_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8} // coherent
|
||||
{ SD0_XMIT_FIFO, DMA_DS | DMA_DW8 }, /* coherent */
|
||||
{ SD0_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8 }, /* coherent */
|
||||
{ SD1_XMIT_FIFO, DMA_DS | DMA_DW8 }, /* coherent */
|
||||
{ SD1_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8 } /* coherent */
|
||||
};
|
||||
|
||||
void dump_au1000_dma_channel(unsigned int dmanr)
|
||||
|
@ -150,7 +150,6 @@ void dump_au1000_dma_channel(unsigned int dmanr)
|
|||
au_readl(chan->io + DMA_BUFFER1_COUNT));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Finds a free channel, and binds the requested device to it.
|
||||
* Returns the allocated channel number, or negative on error.
|
||||
|
@ -169,14 +168,14 @@ int request_au1000_dma(int dev_id, const char *dev_str,
|
|||
if (dev_id < 0 || dev_id >= (DMA_NUM_DEV + DMA_NUM_DEV_BANK2))
|
||||
return -EINVAL;
|
||||
#else
|
||||
if (dev_id < 0 || dev_id >= DMA_NUM_DEV)
|
||||
if (dev_id < 0 || dev_id >= DMA_NUM_DEV)
|
||||
return -EINVAL;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) {
|
||||
for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++)
|
||||
if (au1000_dma_table[i].dev_id < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == NUM_AU1000_DMA_CHANNELS)
|
||||
return -ENODEV;
|
||||
|
||||
|
@ -185,15 +184,15 @@ int request_au1000_dma(int dev_id, const char *dev_str,
|
|||
if (dev_id >= DMA_NUM_DEV) {
|
||||
dev_id -= DMA_NUM_DEV;
|
||||
dev = &dma_dev_table_bank2[dev_id];
|
||||
} else {
|
||||
} else
|
||||
dev = &dma_dev_table[dev_id];
|
||||
}
|
||||
|
||||
if (irqhandler) {
|
||||
chan->irq = AU1000_DMA_INT_BASE + i;
|
||||
chan->irq_dev = irq_dev_id;
|
||||
if ((ret = request_irq(chan->irq, irqhandler, irqflags,
|
||||
dev_str, chan->irq_dev))) {
|
||||
ret = request_irq(chan->irq, irqhandler, irqflags, dev_str,
|
||||
chan->irq_dev);
|
||||
if (ret) {
|
||||
chan->irq = 0;
|
||||
chan->irq_dev = NULL;
|
||||
return ret;
|
||||
|
@ -203,7 +202,7 @@ int request_au1000_dma(int dev_id, const char *dev_str,
|
|||
chan->irq_dev = NULL;
|
||||
}
|
||||
|
||||
// fill it in
|
||||
/* fill it in */
|
||||
chan->io = DMA_CHANNEL_BASE + i * DMA_CHANNEL_LEN;
|
||||
chan->dev_id = dev_id;
|
||||
chan->dev_str = dev_str;
|
||||
|
@ -220,8 +219,9 @@ EXPORT_SYMBOL(request_au1000_dma);
|
|||
void free_au1000_dma(unsigned int dmanr)
|
||||
{
|
||||
struct dma_chan *chan = get_dma_chan(dmanr);
|
||||
|
||||
if (!chan) {
|
||||
printk("Trying to free DMA%d\n", dmanr);
|
||||
printk(KERN_ERR "Error trying to free DMA%d\n", dmanr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -235,4 +235,4 @@ void free_au1000_dma(unsigned int dmanr)
|
|||
}
|
||||
EXPORT_SYMBOL(free_au1000_dma);
|
||||
|
||||
#endif // AU1000 AU1500 AU1100
|
||||
#endif /* AU1000 AU1500 AU1100 */
|
||||
|
|
|
@ -69,7 +69,7 @@ static int au1xxx_gpio2_direction_output(unsigned gpio, int value)
|
|||
|
||||
static int au1xxx_gpio1_read(unsigned gpio)
|
||||
{
|
||||
return ((gpio1->pinstaterd >> gpio) & 0x01);
|
||||
return (gpio1->pinstaterd >> gpio) & 0x01;
|
||||
}
|
||||
|
||||
static void au1xxx_gpio1_write(unsigned gpio, int value)
|
||||
|
@ -104,7 +104,6 @@ int au1xxx_gpio_get_value(unsigned gpio)
|
|||
else
|
||||
return au1xxx_gpio1_read(gpio);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(au1xxx_gpio_get_value);
|
||||
|
||||
void au1xxx_gpio_set_value(unsigned gpio, int value)
|
||||
|
@ -118,7 +117,6 @@ void au1xxx_gpio_set_value(unsigned gpio, int value)
|
|||
else
|
||||
au1xxx_gpio1_write(gpio, value);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(au1xxx_gpio_set_value);
|
||||
|
||||
int au1xxx_gpio_direction_input(unsigned gpio)
|
||||
|
@ -132,7 +130,6 @@ int au1xxx_gpio_direction_input(unsigned gpio)
|
|||
|
||||
return au1xxx_gpio1_direction_input(gpio);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(au1xxx_gpio_direction_input);
|
||||
|
||||
int au1xxx_gpio_direction_output(unsigned gpio, int value)
|
||||
|
@ -146,5 +143,4 @@ int au1xxx_gpio_direction_output(unsigned gpio, int value)
|
|||
|
||||
return au1xxx_gpio1_direction_output(gpio, value);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(au1xxx_gpio_direction_output);
|
||||
|
|
|
@ -210,10 +210,8 @@ static inline void mask_and_ack_either_edge_irq(unsigned int irq_nr)
|
|||
au_sync();
|
||||
}
|
||||
|
||||
|
||||
static inline void mask_and_ack_level_irq(unsigned int irq_nr)
|
||||
{
|
||||
|
||||
local_disable_irq(irq_nr);
|
||||
au_sync();
|
||||
#if defined(CONFIG_MIPS_PB1000)
|
||||
|
@ -263,14 +261,14 @@ void restore_local_and_enable(int controller, unsigned long mask)
|
|||
unsigned long flags, new_mask;
|
||||
|
||||
spin_lock_irqsave(&irq_lock, flags);
|
||||
for (i = 0; i < 32; i++) {
|
||||
for (i = 0; i < 32; i++)
|
||||
if (mask & (1 << i)) {
|
||||
if (controller)
|
||||
local_enable_irq(i + 32);
|
||||
else
|
||||
local_enable_irq(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (controller)
|
||||
new_mask = au_readl(IC1_MASKSET);
|
||||
else
|
||||
|
|
|
@ -2,9 +2,8 @@
|
|||
* BRIEF MODULE DESCRIPTION
|
||||
* Alchemy/AMD Au1x00 PCI support.
|
||||
*
|
||||
* Copyright 2001-2003, 2007 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc.
|
||||
* ppopov@mvista.com or source@mvista.com
|
||||
* Copyright 2001-2003, 2007-2008 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc. <source@mvista.com>
|
||||
*
|
||||
* Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
|
||||
*
|
||||
|
@ -86,9 +85,9 @@ static int __init au1x_pci_setup(void)
|
|||
u32 prid = read_c0_prid();
|
||||
|
||||
if ((prid & 0xFF000000) == 0x01000000 && prid < 0x01030202) {
|
||||
au_writel((1 << 16) | au_readl(Au1500_PCI_CFG),
|
||||
Au1500_PCI_CFG);
|
||||
printk("Non-coherent PCI accesses enabled\n");
|
||||
au_writel((1 << 16) | au_readl(Au1500_PCI_CFG),
|
||||
Au1500_PCI_CFG);
|
||||
printk(KERN_INFO "Non-coherent PCI accesses enabled\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -269,8 +269,8 @@ static struct platform_device au1x00_pcmcia_device = {
|
|||
#ifdef SMBUS_PSC_BASE
|
||||
static struct resource pbdb_smbus_resources[] = {
|
||||
{
|
||||
.start = SMBUS_PSC_BASE,
|
||||
.end = SMBUS_PSC_BASE + 0x24 - 1,
|
||||
.start = CPHYSADDR(SMBUS_PSC_BASE),
|
||||
.end = CPHYSADDR(SMBUS_PSC_BASE + 0xfffff),
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
@ -302,16 +302,17 @@ static struct platform_device *au1xxx_platform_devices[] __initdata = {
|
|||
#endif
|
||||
};
|
||||
|
||||
int __init au1xxx_platform_init(void)
|
||||
static int __init au1xxx_platform_init(void)
|
||||
{
|
||||
unsigned int uartclk = get_au1x00_uart_baud_base() * 16;
|
||||
int i;
|
||||
|
||||
/* Fill up uartclk. */
|
||||
for (i = 0; au1x00_uart_data[i].flags ; i++)
|
||||
for (i = 0; au1x00_uart_data[i].flags; i++)
|
||||
au1x00_uart_data[i].uartclk = uartclk;
|
||||
|
||||
return platform_add_devices(au1xxx_platform_devices, ARRAY_SIZE(au1xxx_platform_devices));
|
||||
return platform_add_devices(au1xxx_platform_devices,
|
||||
ARRAY_SIZE(au1xxx_platform_devices));
|
||||
}
|
||||
|
||||
arch_initcall(au1xxx_platform_init);
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
/*
|
||||
* BRIEF MODULE DESCRIPTION
|
||||
* Au1000 Power Management routines.
|
||||
* Au1xx0 Power Management routines.
|
||||
*
|
||||
* Copyright 2001 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc.
|
||||
* ppopov@mvista.com or source@mvista.com
|
||||
* Copyright 2001, 2008 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc. <source@mvista.com>
|
||||
*
|
||||
* Some of the routines are right out of init/main.c, whose
|
||||
* copyrights apply here.
|
||||
|
@ -43,10 +42,10 @@
|
|||
#ifdef CONFIG_PM
|
||||
|
||||
#define DEBUG 1
|
||||
#ifdef DEBUG
|
||||
# define DPRINTK(fmt, args...) printk("%s: " fmt, __func__, ## args)
|
||||
#ifdef DEBUG
|
||||
#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__, ## args)
|
||||
#else
|
||||
# define DPRINTK(fmt, args...)
|
||||
#define DPRINTK(fmt, args...)
|
||||
#endif
|
||||
|
||||
static void au1000_calibrate_delay(void);
|
||||
|
@ -57,7 +56,8 @@ extern void local_enable_irq(unsigned int irq_nr);
|
|||
|
||||
static DEFINE_SPINLOCK(pm_lock);
|
||||
|
||||
/* We need to save/restore a bunch of core registers that are
|
||||
/*
|
||||
* We need to save/restore a bunch of core registers that are
|
||||
* either volatile or reset to some state across a processor sleep.
|
||||
* If reading a register doesn't provide a proper result for a
|
||||
* later restore, we have to provide a function for loading that
|
||||
|
@ -78,24 +78,25 @@ static unsigned int sleep_usbhost_enable;
|
|||
static unsigned int sleep_usbdev_enable;
|
||||
static unsigned int sleep_static_memctlr[4][3];
|
||||
|
||||
/* Define this to cause the value you write to /proc/sys/pm/sleep to
|
||||
/*
|
||||
* Define this to cause the value you write to /proc/sys/pm/sleep to
|
||||
* set the TOY timer for the amount of time you want to sleep.
|
||||
* This is done mainly for testing, but may be useful in other cases.
|
||||
* The value is number of 32KHz ticks to sleep.
|
||||
*/
|
||||
#define SLEEP_TEST_TIMEOUT 1
|
||||
#ifdef SLEEP_TEST_TIMEOUT
|
||||
static int sleep_ticks;
|
||||
#ifdef SLEEP_TEST_TIMEOUT
|
||||
static int sleep_ticks;
|
||||
void wakeup_counter0_set(int ticks);
|
||||
#endif
|
||||
|
||||
static void
|
||||
save_core_regs(void)
|
||||
static void save_core_regs(void)
|
||||
{
|
||||
extern void save_au1xxx_intctl(void);
|
||||
extern void pm_eth0_shutdown(void);
|
||||
|
||||
/* Do the serial ports.....these really should be a pm_*
|
||||
/*
|
||||
* Do the serial ports.....these really should be a pm_*
|
||||
* registered function by the driver......but of course the
|
||||
* standard serial driver doesn't understand our Au1xxx
|
||||
* unique registers.
|
||||
|
@ -106,27 +107,24 @@ save_core_regs(void)
|
|||
sleep_uart0_clkdiv = au_readl(UART0_ADDR + UART_CLK);
|
||||
sleep_uart0_enable = au_readl(UART0_ADDR + UART_MOD_CNTRL);
|
||||
|
||||
/* Shutdown USB host/device.
|
||||
*/
|
||||
/* Shutdown USB host/device. */
|
||||
sleep_usbhost_enable = au_readl(USB_HOST_CONFIG);
|
||||
|
||||
/* There appears to be some undocumented reset register....
|
||||
*/
|
||||
/* There appears to be some undocumented reset register.... */
|
||||
au_writel(0, 0xb0100004); au_sync();
|
||||
au_writel(0, USB_HOST_CONFIG); au_sync();
|
||||
|
||||
sleep_usbdev_enable = au_readl(USBD_ENABLE);
|
||||
au_writel(0, USBD_ENABLE); au_sync();
|
||||
|
||||
/* Save interrupt controller state.
|
||||
*/
|
||||
/* Save interrupt controller state. */
|
||||
save_au1xxx_intctl();
|
||||
|
||||
/* Clocks and PLLs.
|
||||
*/
|
||||
/* Clocks and PLLs. */
|
||||
sleep_aux_pll_cntrl = au_readl(SYS_AUXPLL);
|
||||
|
||||
/* We don't really need to do this one, but unless we
|
||||
/*
|
||||
* We don't really need to do this one, but unless we
|
||||
* write it again it won't have a valid value if we
|
||||
* happen to read it.
|
||||
*/
|
||||
|
@ -134,8 +132,7 @@ save_core_regs(void)
|
|||
|
||||
sleep_pin_function = au_readl(SYS_PINFUNC);
|
||||
|
||||
/* Save the static memory controller configuration.
|
||||
*/
|
||||
/* Save the static memory controller configuration. */
|
||||
sleep_static_memctlr[0][0] = au_readl(MEM_STCFG0);
|
||||
sleep_static_memctlr[0][1] = au_readl(MEM_STTIME0);
|
||||
sleep_static_memctlr[0][2] = au_readl(MEM_STADDR0);
|
||||
|
@ -150,8 +147,7 @@ save_core_regs(void)
|
|||
sleep_static_memctlr[3][2] = au_readl(MEM_STADDR3);
|
||||
}
|
||||
|
||||
static void
|
||||
restore_core_regs(void)
|
||||
static void restore_core_regs(void)
|
||||
{
|
||||
extern void restore_au1xxx_intctl(void);
|
||||
extern void wakeup_counter0_adjust(void);
|
||||
|
@ -160,8 +156,7 @@ restore_core_regs(void)
|
|||
au_writel(sleep_cpu_pll_cntrl, SYS_CPUPLL); au_sync();
|
||||
au_writel(sleep_pin_function, SYS_PINFUNC); au_sync();
|
||||
|
||||
/* Restore the static memory controller configuration.
|
||||
*/
|
||||
/* Restore the static memory controller configuration. */
|
||||
au_writel(sleep_static_memctlr[0][0], MEM_STCFG0);
|
||||
au_writel(sleep_static_memctlr[0][1], MEM_STTIME0);
|
||||
au_writel(sleep_static_memctlr[0][2], MEM_STADDR0);
|
||||
|
@ -175,7 +170,8 @@ restore_core_regs(void)
|
|||
au_writel(sleep_static_memctlr[3][1], MEM_STTIME3);
|
||||
au_writel(sleep_static_memctlr[3][2], MEM_STADDR3);
|
||||
|
||||
/* Enable the UART if it was enabled before sleep.
|
||||
/*
|
||||
* Enable the UART if it was enabled before sleep.
|
||||
* I guess I should define module control bits........
|
||||
*/
|
||||
if (sleep_uart0_enable & 0x02) {
|
||||
|
@ -202,7 +198,7 @@ void wakeup_from_suspend(void)
|
|||
int au_sleep(void)
|
||||
{
|
||||
unsigned long wakeup, flags;
|
||||
extern void save_and_sleep(void);
|
||||
extern void save_and_sleep(void);
|
||||
|
||||
spin_lock_irqsave(&pm_lock, flags);
|
||||
|
||||
|
@ -210,23 +206,22 @@ int au_sleep(void)
|
|||
|
||||
flush_cache_all();
|
||||
|
||||
/** The code below is all system dependent and we should probably
|
||||
/**
|
||||
** The code below is all system dependent and we should probably
|
||||
** have a function call out of here to set this up. You need
|
||||
** to configure the GPIO or timer interrupts that will bring
|
||||
** you out of sleep.
|
||||
** For testing, the TOY counter wakeup is useful.
|
||||
**/
|
||||
|
||||
#if 0
|
||||
au_writel(au_readl(SYS_PINSTATERD) & ~(1 << 11), SYS_PINSTATERD);
|
||||
|
||||
/* gpio 6 can cause a wake up event */
|
||||
/* GPIO 6 can cause a wake up event */
|
||||
wakeup = au_readl(SYS_WAKEMSK);
|
||||
wakeup &= ~(1 << 8); /* turn off match20 wakeup */
|
||||
wakeup |= 1 << 6; /* turn on gpio 6 wakeup */
|
||||
wakeup |= 1 << 6; /* turn on GPIO 6 wakeup */
|
||||
#else
|
||||
/* For testing, allow match20 to wake us up.
|
||||
*/
|
||||
/* For testing, allow match20 to wake us up. */
|
||||
#ifdef SLEEP_TEST_TIMEOUT
|
||||
wakeup_counter0_set(sleep_ticks);
|
||||
#endif
|
||||
|
@ -240,7 +235,8 @@ int au_sleep(void)
|
|||
|
||||
save_and_sleep();
|
||||
|
||||
/* after a wakeup, the cpu vectors back to 0x1fc00000 so
|
||||
/*
|
||||
* After a wakeup, the cpu vectors back to 0x1fc00000, so
|
||||
* it's up to the boot code to get us back here.
|
||||
*/
|
||||
restore_core_regs();
|
||||
|
@ -248,24 +244,22 @@ int au_sleep(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int pm_do_sleep(ctl_table * ctl, int write, struct file *file,
|
||||
void __user *buffer, size_t * len, loff_t *ppos)
|
||||
static int pm_do_sleep(ctl_table *ctl, int write, struct file *file,
|
||||
void __user *buffer, size_t *len, loff_t *ppos)
|
||||
{
|
||||
#ifdef SLEEP_TEST_TIMEOUT
|
||||
#define TMPBUFLEN2 16
|
||||
char buf[TMPBUFLEN2], *p;
|
||||
#endif
|
||||
|
||||
if (!write) {
|
||||
if (!write)
|
||||
*len = 0;
|
||||
} else {
|
||||
else {
|
||||
#ifdef SLEEP_TEST_TIMEOUT
|
||||
if (*len > TMPBUFLEN2 - 1) {
|
||||
if (*len > TMPBUFLEN2 - 1)
|
||||
return -EFAULT;
|
||||
}
|
||||
if (copy_from_user(buf, buffer, *len)) {
|
||||
if (copy_from_user(buf, buffer, *len))
|
||||
return -EFAULT;
|
||||
}
|
||||
buf[*len] = 0;
|
||||
p = buf;
|
||||
sleep_ticks = simple_strtoul(p, &p, 0);
|
||||
|
@ -276,8 +270,8 @@ static int pm_do_sleep(ctl_table * ctl, int write, struct file *file,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
|
||||
void __user *buffer, size_t * len, loff_t *ppos)
|
||||
static int pm_do_freq(ctl_table *ctl, int write, struct file *file,
|
||||
void __user *buffer, size_t *len, loff_t *ppos)
|
||||
{
|
||||
int retval = 0, i;
|
||||
unsigned long val, pll;
|
||||
|
@ -285,14 +279,14 @@ static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
|
|||
#define MAX_CPU_FREQ 396
|
||||
char buf[TMPBUFLEN], *p;
|
||||
unsigned long flags, intc0_mask, intc1_mask;
|
||||
unsigned long old_baud_base, old_cpu_freq, baud_rate, old_clk,
|
||||
old_refresh;
|
||||
unsigned long old_baud_base, old_cpu_freq, old_clk, old_refresh;
|
||||
unsigned long new_baud_base, new_cpu_freq, new_clk, new_refresh;
|
||||
unsigned long baud_rate;
|
||||
|
||||
spin_lock_irqsave(&pm_lock, flags);
|
||||
if (!write) {
|
||||
if (!write)
|
||||
*len = 0;
|
||||
} else {
|
||||
else {
|
||||
/* Parse the new frequency */
|
||||
if (*len > TMPBUFLEN - 1) {
|
||||
spin_unlock_irqrestore(&pm_lock, flags);
|
||||
|
@ -312,7 +306,7 @@ static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
|
|||
|
||||
pll = val / 12;
|
||||
if ((pll > 33) || (pll < 7)) { /* 396 MHz max, 84 MHz min */
|
||||
/* revisit this for higher speed cpus */
|
||||
/* Revisit this for higher speed CPUs */
|
||||
spin_unlock_irqrestore(&pm_lock, flags);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
@ -321,30 +315,28 @@ static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
|
|||
old_cpu_freq = get_au1x00_speed();
|
||||
|
||||
new_cpu_freq = pll * 12 * 1000000;
|
||||
new_baud_base = (new_cpu_freq / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16));
|
||||
new_baud_base = (new_cpu_freq / (2 * ((int)(au_readl(SYS_POWERCTRL)
|
||||
& 0x03) + 2) * 16));
|
||||
set_au1x00_speed(new_cpu_freq);
|
||||
set_au1x00_uart_baud_base(new_baud_base);
|
||||
|
||||
old_refresh = au_readl(MEM_SDREFCFG) & 0x1ffffff;
|
||||
new_refresh =
|
||||
((old_refresh * new_cpu_freq) /
|
||||
old_cpu_freq) | (au_readl(MEM_SDREFCFG) & ~0x1ffffff);
|
||||
new_refresh = ((old_refresh * new_cpu_freq) / old_cpu_freq) |
|
||||
(au_readl(MEM_SDREFCFG) & ~0x1ffffff);
|
||||
|
||||
au_writel(pll, SYS_CPUPLL);
|
||||
au_sync_delay(1);
|
||||
au_writel(new_refresh, MEM_SDREFCFG);
|
||||
au_sync_delay(1);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (au_readl
|
||||
(UART_BASE + UART_MOD_CNTRL +
|
||||
i * 0x00100000) == 3) {
|
||||
old_clk =
|
||||
au_readl(UART_BASE + UART_CLK +
|
||||
i * 0x00100000);
|
||||
// baud_rate = baud_base/clk
|
||||
for (i = 0; i < 4; i++)
|
||||
if (au_readl(UART_BASE + UART_MOD_CNTRL +
|
||||
i * 0x00100000) == 3) {
|
||||
old_clk = au_readl(UART_BASE + UART_CLK +
|
||||
i * 0x00100000);
|
||||
baud_rate = old_baud_base / old_clk;
|
||||
/* we won't get an exact baud rate and the error
|
||||
/*
|
||||
* We won't get an exact baud rate and the error
|
||||
* could be significant enough that our new
|
||||
* calculation will result in a clock that will
|
||||
* give us a baud rate that's too far off from
|
||||
|
@ -359,18 +351,14 @@ static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
|
|||
else if (baud_rate > 17000)
|
||||
baud_rate = 19200;
|
||||
else
|
||||
(baud_rate = 9600);
|
||||
// new_clk = new_baud_base/baud_rate
|
||||
baud_rate = 9600;
|
||||
new_clk = new_baud_base / baud_rate;
|
||||
au_writel(new_clk,
|
||||
UART_BASE + UART_CLK +
|
||||
i * 0x00100000);
|
||||
au_writel(new_clk, UART_BASE + UART_CLK +
|
||||
i * 0x00100000);
|
||||
au_sync_delay(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* We don't want _any_ interrupts other than match20. Otherwise our
|
||||
* au1000_calibrate_delay() calculation will be off, potentially a lot.
|
||||
|
@ -428,14 +416,15 @@ static int __init pm_init(void)
|
|||
|
||||
__initcall(pm_init);
|
||||
|
||||
|
||||
/*
|
||||
* This is right out of init/main.c
|
||||
*/
|
||||
|
||||
/* This is the number of bits of precision for the loops_per_jiffy. Each
|
||||
bit takes on average 1.5/HZ seconds. This (like the original) is a little
|
||||
better than 1% */
|
||||
/*
|
||||
* This is the number of bits of precision for the loops_per_jiffy.
|
||||
* Each bit takes on average 1.5/HZ seconds. This (like the original)
|
||||
* is a little better than 1%.
|
||||
*/
|
||||
#define LPS_PREC 8
|
||||
|
||||
static void au1000_calibrate_delay(void)
|
||||
|
@ -443,14 +432,14 @@ static void au1000_calibrate_delay(void)
|
|||
unsigned long ticks, loopbit;
|
||||
int lps_precision = LPS_PREC;
|
||||
|
||||
loops_per_jiffy = (1 << 12);
|
||||
loops_per_jiffy = 1 << 12;
|
||||
|
||||
while (loops_per_jiffy <<= 1) {
|
||||
/* wait for "start of" clock tick */
|
||||
/* Wait for "start of" clock tick */
|
||||
ticks = jiffies;
|
||||
while (ticks == jiffies)
|
||||
/* nothing */ ;
|
||||
/* Go .. */
|
||||
/* Go ... */
|
||||
ticks = jiffies;
|
||||
__delay(loops_per_jiffy);
|
||||
ticks = jiffies - ticks;
|
||||
|
@ -458,8 +447,10 @@ static void au1000_calibrate_delay(void)
|
|||
break;
|
||||
}
|
||||
|
||||
/* Do a binary approximation to get loops_per_jiffy set to equal one clock
|
||||
(up to lps_precision bits) */
|
||||
/*
|
||||
* Do a binary approximation to get loops_per_jiffy set to be equal
|
||||
* one clock (up to lps_precision bits)
|
||||
*/
|
||||
loops_per_jiffy >>= 1;
|
||||
loopbit = loops_per_jiffy;
|
||||
while (lps_precision-- && (loopbit >>= 1)) {
|
||||
|
@ -472,4 +463,4 @@ static void au1000_calibrate_delay(void)
|
|||
loops_per_jiffy &= ~loopbit;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_PM */
|
||||
#endif /* CONFIG_PM */
|
||||
|
|
|
@ -3,9 +3,8 @@
|
|||
* BRIEF MODULE DESCRIPTION
|
||||
* PROM library initialisation code, supports YAMON and U-Boot.
|
||||
*
|
||||
* Copyright 2000, 2001, 2006 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc.
|
||||
* ppopov@mvista.com or source@mvista.com
|
||||
* Copyright 2000-2001, 2006, 2008 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc. <source@mvista.com>
|
||||
*
|
||||
* This file was derived from Carsten Langgaard's
|
||||
* arch/mips/mips-boards/xx files.
|
||||
|
@ -57,7 +56,7 @@ void prom_init_cmdline(void)
|
|||
actr = 1; /* Always ignore argv[0] */
|
||||
|
||||
cp = &(arcs_cmdline[0]);
|
||||
while(actr < prom_argc) {
|
||||
while (actr < prom_argc) {
|
||||
strcpy(cp, prom_argv[actr]);
|
||||
cp += strlen(prom_argv[actr]);
|
||||
*cp++ = ' ';
|
||||
|
@ -84,10 +83,8 @@ char *prom_getenv(char *envname)
|
|||
if (yamon) {
|
||||
if (strcmp(envname, *env++) == 0)
|
||||
return *env;
|
||||
} else {
|
||||
if (strncmp(envname, *env, i) == 0 && (*env)[i] == '=')
|
||||
return *env + i + 1;
|
||||
}
|
||||
} else if (strncmp(envname, *env, i) == 0 && (*env)[i] == '=')
|
||||
return *env + i + 1;
|
||||
env++;
|
||||
}
|
||||
|
||||
|
@ -110,13 +107,13 @@ static inline void str2eaddr(unsigned char *ea, unsigned char *str)
|
|||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < 6; i++) {
|
||||
for (i = 0; i < 6; i++) {
|
||||
unsigned char num;
|
||||
|
||||
if((*str == '.') || (*str == ':'))
|
||||
if ((*str == '.') || (*str == ':'))
|
||||
str++;
|
||||
num = str2hexnum(*str++) << 4;
|
||||
num |= (str2hexnum(*str++));
|
||||
num = str2hexnum(*str++) << 4;
|
||||
num |= str2hexnum(*str++);
|
||||
ea[i] = num;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
/*
|
||||
*
|
||||
* BRIEF MODULE DESCRIPTION
|
||||
* Low level uart routines to directly access a 16550 uart.
|
||||
* Low level UART routines to directly access Alchemy UART.
|
||||
*
|
||||
* Copyright 2001 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc.
|
||||
* ppopov@mvista.com or source@mvista.com
|
||||
* Copyright 2001, 2008 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc. <source@mvista.com>
|
||||
*
|
||||
* 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
|
||||
|
@ -40,12 +39,12 @@
|
|||
|
||||
static volatile unsigned long * const com1 = (unsigned long *)SERIAL_BASE;
|
||||
|
||||
|
||||
#ifdef SLOW_DOWN
|
||||
static inline void slow_down(void)
|
||||
{
|
||||
int k;
|
||||
for (k=0; k<10000; k++);
|
||||
int k;
|
||||
|
||||
for (k = 0; k < 10000; k++);
|
||||
}
|
||||
#else
|
||||
#define slow_down()
|
||||
|
@ -54,16 +53,16 @@ static inline void slow_down(void)
|
|||
void
|
||||
prom_putchar(const unsigned char c)
|
||||
{
|
||||
unsigned char ch;
|
||||
int i = 0;
|
||||
unsigned char ch;
|
||||
int i = 0;
|
||||
|
||||
do {
|
||||
ch = com1[SER_CMD];
|
||||
slow_down();
|
||||
i++;
|
||||
if (i>TIMEOUT) {
|
||||
break;
|
||||
}
|
||||
} while (0 == (ch & TX_BUSY));
|
||||
com1[SER_DATA] = c;
|
||||
do {
|
||||
ch = com1[SER_CMD];
|
||||
slow_down();
|
||||
i++;
|
||||
if (i > TIMEOUT)
|
||||
break;
|
||||
} while (0 == (ch & TX_BUSY));
|
||||
|
||||
com1[SER_DATA] = c;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
/*
|
||||
*
|
||||
* BRIEF MODULE DESCRIPTION
|
||||
* Au1000 reset routines.
|
||||
* Au1xx0 reset routines.
|
||||
*
|
||||
* Copyright 2001 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc.
|
||||
* ppopov@mvista.com or source@mvista.com
|
||||
* Copyright 2001, 2006, 2008 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc. <source@mvista.com>
|
||||
*
|
||||
* 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
|
||||
|
@ -28,10 +27,11 @@
|
|||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
|
||||
#include <asm/mach-au1x00/au1000.h>
|
||||
|
||||
extern int au_sleep(void);
|
||||
extern void (*flush_cache_all)(void);
|
||||
|
||||
void au1000_restart(char *command)
|
||||
{
|
||||
|
@ -40,8 +40,8 @@ void au1000_restart(char *command)
|
|||
u32 prid = read_c0_prid();
|
||||
|
||||
printk(KERN_NOTICE "\n** Resetting Integrated Peripherals\n");
|
||||
switch (prid & 0xFF000000)
|
||||
{
|
||||
|
||||
switch (prid & 0xFF000000) {
|
||||
case 0x00000000: /* Au1000 */
|
||||
au_writel(0x02, 0xb0000010); /* ac97_enable */
|
||||
au_writel(0x08, 0xb017fffc); /* usbh_enable - early errata */
|
||||
|
@ -138,9 +138,6 @@ void au1000_restart(char *command)
|
|||
au_writel(0x00, 0xb1900064); /* sys_auxpll */
|
||||
au_writel(0x00, 0xb1900100); /* sys_pininputen */
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
set_c0_status(ST0_BEV | ST0_ERL);
|
||||
|
@ -158,25 +155,25 @@ void au1000_restart(char *command)
|
|||
void au1000_halt(void)
|
||||
{
|
||||
#if defined(CONFIG_MIPS_PB1550) || defined(CONFIG_MIPS_DB1550)
|
||||
/* power off system */
|
||||
printk("\n** Powering off...\n");
|
||||
au_writew(au_readw(0xAF00001C) | (3<<14), 0xAF00001C);
|
||||
/* Power off system */
|
||||
printk(KERN_NOTICE "\n** Powering off...\n");
|
||||
au_writew(au_readw(0xAF00001C) | (3 << 14), 0xAF00001C);
|
||||
au_sync();
|
||||
while(1); /* should not get here */
|
||||
while (1); /* should not get here */
|
||||
#else
|
||||
printk(KERN_NOTICE "\n** You can safely turn off the power\n");
|
||||
#ifdef CONFIG_MIPS_MIRAGE
|
||||
au_writel((1 << 26) | (1 << 10), GPIO2_OUTPUT);
|
||||
#endif
|
||||
#ifdef CONFIG_MIPS_DB1200
|
||||
au_writew(au_readw(0xB980001C) | (1<<14), 0xB980001C);
|
||||
au_writew(au_readw(0xB980001C) | (1 << 14), 0xB980001C);
|
||||
#endif
|
||||
#ifdef CONFIG_PM
|
||||
au_sleep();
|
||||
|
||||
/* should not get here */
|
||||
printk(KERN_ERR "Unable to put cpu in sleep mode\n");
|
||||
while(1);
|
||||
/* Should not get here */
|
||||
printk(KERN_ERR "Unable to put CPU in sleep mode\n");
|
||||
while (1);
|
||||
#else
|
||||
while (1)
|
||||
__asm__(".set\tmips3\n\t"
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* Copyright 2000 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc.
|
||||
* ppopov@mvista.com or source@mvista.com
|
||||
* Copyright 2000, 2007-2008 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc. <source@mvista.com
|
||||
*
|
||||
* Updates to 2.6, Pete Popov, Embedded Alley Solutions, Inc.
|
||||
*
|
||||
|
@ -48,7 +47,7 @@ void __init plat_mem_setup(void)
|
|||
{
|
||||
struct cpu_spec *sp;
|
||||
char *argptr;
|
||||
unsigned long prid, cpufreq, bclk = 1;
|
||||
unsigned long prid, cpufreq, bclk;
|
||||
|
||||
set_cpuspec();
|
||||
sp = cur_cpu_spec[0];
|
||||
|
@ -66,42 +65,39 @@ void __init plat_mem_setup(void)
|
|||
cpufreq = (au_readl(SYS_CPUPLL) & 0x3F) * 12;
|
||||
printk(KERN_INFO "(PRID %08lx) @ %ld MHz\n", prid, cpufreq);
|
||||
|
||||
bclk = sp->cpu_bclk;
|
||||
if (bclk)
|
||||
{
|
||||
if (sp->cpu_bclk) {
|
||||
/* Enable BCLK switching */
|
||||
bclk = au_readl(0xB190003C);
|
||||
au_writel(bclk | 0x60, 0xB190003C);
|
||||
printk("BCLK switching enabled!\n");
|
||||
bclk = au_readl(SYS_POWERCTRL);
|
||||
au_writel(bclk | 0x60, SYS_POWERCTRL);
|
||||
printk(KERN_INFO "BCLK switching enabled!\n");
|
||||
}
|
||||
|
||||
if (sp->cpu_od) {
|
||||
/* Various early Au1000 Errata corrected by this */
|
||||
set_c0_config(1<<19); /* Set Config[OD] */
|
||||
}
|
||||
else {
|
||||
if (sp->cpu_od)
|
||||
/* Various early Au1xx0 errata corrected by this */
|
||||
set_c0_config(1 << 19); /* Set Config[OD] */
|
||||
else
|
||||
/* Clear to obtain best system bus performance */
|
||||
clear_c0_config(1<<19); /* Clear Config[OD] */
|
||||
}
|
||||
clear_c0_config(1 << 19); /* Clear Config[OD] */
|
||||
|
||||
argptr = prom_getcmdline();
|
||||
|
||||
#ifdef CONFIG_SERIAL_8250_CONSOLE
|
||||
if ((argptr = strstr(argptr, "console=")) == NULL) {
|
||||
argptr = strstr(argptr, "console=");
|
||||
if (argptr == NULL) {
|
||||
argptr = prom_getcmdline();
|
||||
strcat(argptr, " console=ttyS0,115200");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FB_AU1100
|
||||
if ((argptr = strstr(argptr, "video=")) == NULL) {
|
||||
argptr = prom_getcmdline();
|
||||
/* default panel */
|
||||
/*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/
|
||||
}
|
||||
argptr = strstr(argptr, "video=");
|
||||
if (argptr == NULL) {
|
||||
argptr = prom_getcmdline();
|
||||
/* default panel */
|
||||
/*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(CONFIG_SOUND_AU1X00) && !defined(CONFIG_SOC_AU1000)
|
||||
/* au1000 does not support vra, au1500 and au1100 do */
|
||||
strcat(argptr, " au1000_audio=vra");
|
||||
|
@ -129,7 +125,7 @@ void __init plat_mem_setup(void)
|
|||
/* This routine should be valid for all Au1x based boards */
|
||||
phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
|
||||
{
|
||||
/* Don't fixup 36 bit addresses */
|
||||
/* Don't fixup 36-bit addresses */
|
||||
if ((phys_addr >> 32) != 0)
|
||||
return phys_addr;
|
||||
|
||||
|
@ -145,17 +141,17 @@ phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* All Au1x SOCs have a pcmcia controller */
|
||||
/* We setup our 32 bit pseudo addresses to be equal to the
|
||||
* 36 bit addr >> 4, to make it easier to check the address
|
||||
/*
|
||||
* All Au1xx0 SOCs have a PCMCIA controller.
|
||||
* We setup our 32-bit pseudo addresses to be equal to the
|
||||
* 36-bit addr >> 4, to make it easier to check the address
|
||||
* and fix it.
|
||||
* The Au1x socket 0 phys attribute address is 0xF 4000 0000.
|
||||
* The PCMCIA socket 0 physical attribute address is 0xF 4000 0000.
|
||||
* The pseudo address we use is 0xF400 0000. Any address over
|
||||
* 0xF400 0000 is a pcmcia pseudo address.
|
||||
* 0xF400 0000 is a PCMCIA pseudo address.
|
||||
*/
|
||||
if ((phys_addr >= 0xF4000000) && (phys_addr < 0xFFFFFFFF)) {
|
||||
if ((phys_addr >= 0xF4000000) && (phys_addr < 0xFFFFFFFF))
|
||||
return (phys_t)(phys_addr << 4);
|
||||
}
|
||||
|
||||
/* default nop */
|
||||
return phys_addr;
|
||||
|
|
|
@ -25,11 +25,9 @@
|
|||
*
|
||||
* Setting up the clock on the MIPS boards.
|
||||
*
|
||||
* Update. Always configure the kernel with CONFIG_NEW_TIME_C. This
|
||||
* will use the user interface gettimeofday() functions from the
|
||||
* arch/mips/kernel/time.c, and we provide the clock interrupt processing
|
||||
* and the timer offset compute functions. If CONFIG_PM is selected,
|
||||
* we also ensure the 32KHz timer is available. -- Dan
|
||||
* We provide the clock interrupt processing and the timer offset compute
|
||||
* functions. If CONFIG_PM is selected, we also ensure the 32KHz timer is
|
||||
* available. -- Dan
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
|
@ -47,8 +45,7 @@ extern int allow_au1k_wait; /* default off for CP0 Counter */
|
|||
#if HZ < 100 || HZ > 1000
|
||||
#error "unsupported HZ value! Must be in [100,1000]"
|
||||
#endif
|
||||
#define MATCH20_INC (328*100/HZ) /* magic number 328 is for HZ=100... */
|
||||
extern void startup_match20_interrupt(irq_handler_t handler);
|
||||
#define MATCH20_INC (328 * 100 / HZ) /* magic number 328 is for HZ=100... */
|
||||
static unsigned long last_pc0, last_match20;
|
||||
#endif
|
||||
|
||||
|
@ -61,7 +58,7 @@ static irqreturn_t counter0_irq(int irq, void *dev_id)
|
|||
{
|
||||
unsigned long pc0;
|
||||
int time_elapsed;
|
||||
static int jiffie_drift = 0;
|
||||
static int jiffie_drift;
|
||||
|
||||
if (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20) {
|
||||
/* should never happen! */
|
||||
|
@ -70,13 +67,11 @@ static irqreturn_t counter0_irq(int irq, void *dev_id)
|
|||
}
|
||||
|
||||
pc0 = au_readl(SYS_TOYREAD);
|
||||
if (pc0 < last_match20) {
|
||||
if (pc0 < last_match20)
|
||||
/* counter overflowed */
|
||||
time_elapsed = (0xffffffff - last_match20) + pc0;
|
||||
}
|
||||
else {
|
||||
else
|
||||
time_elapsed = pc0 - last_match20;
|
||||
}
|
||||
|
||||
while (time_elapsed > 0) {
|
||||
do_timer(1);
|
||||
|
@ -92,8 +87,9 @@ static irqreturn_t counter0_irq(int irq, void *dev_id)
|
|||
au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
|
||||
au_sync();
|
||||
|
||||
/* our counter ticks at 10.009765625 ms/tick, we we're running
|
||||
* almost 10uS too slow per tick.
|
||||
/*
|
||||
* Our counter ticks at 10.009765625 ms/tick, we we're running
|
||||
* almost 10 uS too slow per tick.
|
||||
*/
|
||||
|
||||
if (jiffie_drift >= 999) {
|
||||
|
@ -117,20 +113,17 @@ struct irqaction counter0_action = {
|
|||
/* When we wakeup from sleep, we have to "catch up" on all of the
|
||||
* timer ticks we have missed.
|
||||
*/
|
||||
void
|
||||
wakeup_counter0_adjust(void)
|
||||
void wakeup_counter0_adjust(void)
|
||||
{
|
||||
unsigned long pc0;
|
||||
int time_elapsed;
|
||||
|
||||
pc0 = au_readl(SYS_TOYREAD);
|
||||
if (pc0 < last_match20) {
|
||||
if (pc0 < last_match20)
|
||||
/* counter overflowed */
|
||||
time_elapsed = (0xffffffff - last_match20) + pc0;
|
||||
}
|
||||
else {
|
||||
else
|
||||
time_elapsed = pc0 - last_match20;
|
||||
}
|
||||
|
||||
while (time_elapsed > 0) {
|
||||
time_elapsed -= MATCH20_INC;
|
||||
|
@ -143,10 +136,8 @@ wakeup_counter0_adjust(void)
|
|||
|
||||
}
|
||||
|
||||
/* This is just for debugging to set the timer for a sleep delay.
|
||||
*/
|
||||
void
|
||||
wakeup_counter0_set(int ticks)
|
||||
/* This is just for debugging to set the timer for a sleep delay. */
|
||||
void wakeup_counter0_set(int ticks)
|
||||
{
|
||||
unsigned long pc0;
|
||||
|
||||
|
@ -157,21 +148,22 @@ wakeup_counter0_set(int ticks)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* I haven't found anyone that doesn't use a 12 MHz source clock,
|
||||
/*
|
||||
* I haven't found anyone that doesn't use a 12 MHz source clock,
|
||||
* but just in case.....
|
||||
*/
|
||||
#define AU1000_SRC_CLK 12000000
|
||||
|
||||
/*
|
||||
* We read the real processor speed from the PLL. This is important
|
||||
* because it is more accurate than computing it from the 32KHz
|
||||
* because it is more accurate than computing it from the 32 KHz
|
||||
* counter, if it exists. If we don't have an accurate processor
|
||||
* speed, all of the peripherals that derive their clocks based on
|
||||
* this advertised speed will introduce error and sometimes not work
|
||||
* properly. This function is futher convoluted to still allow configurations
|
||||
* to do that in case they have really, really old silicon with a
|
||||
* write-only PLL register, that we need the 32KHz when power management
|
||||
* "wait" is enabled, and we need to detect if the 32KHz isn't present
|
||||
* write-only PLL register, that we need the 32 KHz when power management
|
||||
* "wait" is enabled, and we need to detect if the 32 KHz isn't present
|
||||
* but requested......got it? :-) -- Dan
|
||||
*/
|
||||
unsigned long calc_clock(void)
|
||||
|
@ -182,8 +174,7 @@ unsigned long calc_clock(void)
|
|||
|
||||
spin_lock_irqsave(&time_lock, flags);
|
||||
|
||||
/* Power management cares if we don't have a 32KHz counter.
|
||||
*/
|
||||
/* Power management cares if we don't have a 32 KHz counter. */
|
||||
no_au1xxx_32khz = 0;
|
||||
counter = au_readl(SYS_COUNTER_CNTRL);
|
||||
if (counter & SYS_CNTRL_E0) {
|
||||
|
@ -193,7 +184,7 @@ unsigned long calc_clock(void)
|
|||
|
||||
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S);
|
||||
/* RTC now ticks at 32.768/16 kHz */
|
||||
au_writel(trim_divide-1, SYS_RTCTRIM);
|
||||
au_writel(trim_divide - 1, SYS_RTCTRIM);
|
||||
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S);
|
||||
|
||||
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S);
|
||||
|
@ -215,9 +206,11 @@ unsigned long calc_clock(void)
|
|||
#endif
|
||||
else
|
||||
cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK;
|
||||
/* On Alchemy CPU:counter ratio is 1:1 */
|
||||
mips_hpt_frequency = cpu_speed;
|
||||
// Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16)
|
||||
set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16));
|
||||
/* Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16) */
|
||||
set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)
|
||||
& 0x03) + 2) * 16));
|
||||
spin_unlock_irqrestore(&time_lock, flags);
|
||||
return cpu_speed;
|
||||
}
|
||||
|
@ -228,10 +221,10 @@ void __init plat_time_init(void)
|
|||
|
||||
est_freq += 5000; /* round */
|
||||
est_freq -= est_freq%10000;
|
||||
printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
|
||||
(est_freq%1000000)*100/1000000);
|
||||
set_au1x00_speed(est_freq);
|
||||
set_au1x00_lcd_clock(); // program the LCD clock
|
||||
printk(KERN_INFO "CPU frequency %u.%02u MHz\n",
|
||||
est_freq / 1000000, ((est_freq % 1000000) * 100) / 1000000);
|
||||
set_au1x00_speed(est_freq);
|
||||
set_au1x00_lcd_clock(); /* program the LCD clock */
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
/*
|
||||
|
@ -243,30 +236,29 @@ void __init plat_time_init(void)
|
|||
* counter 0 interrupt as a special irq and it doesn't show
|
||||
* up under /proc/interrupts.
|
||||
*
|
||||
* Check to ensure we really have a 32KHz oscillator before
|
||||
* Check to ensure we really have a 32 KHz oscillator before
|
||||
* we do this.
|
||||
*/
|
||||
if (no_au1xxx_32khz)
|
||||
printk("WARNING: no 32KHz clock found.\n");
|
||||
printk(KERN_WARNING "WARNING: no 32KHz clock found.\n");
|
||||
else {
|
||||
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
|
||||
au_writel(0, SYS_TOYWRITE);
|
||||
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
|
||||
|
||||
au_writel(au_readl(SYS_WAKEMSK) | (1<<8), SYS_WAKEMSK);
|
||||
au_writel(au_readl(SYS_WAKEMSK) | (1 << 8), SYS_WAKEMSK);
|
||||
au_writel(~0, SYS_WAKESRC);
|
||||
au_sync();
|
||||
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
|
||||
|
||||
/* setup match20 to interrupt once every HZ */
|
||||
/* Setup match20 to interrupt once every HZ */
|
||||
last_pc0 = last_match20 = au_readl(SYS_TOYREAD);
|
||||
au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
|
||||
au_sync();
|
||||
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
|
||||
setup_irq(AU1000_TOY_MATCH2_INT, &counter0_action);
|
||||
|
||||
/* We can use the real 'wait' instruction.
|
||||
*/
|
||||
/* We can use the real 'wait' instruction. */
|
||||
allow_au1k_wait = 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#
|
||||
# Copyright 2000 MontaVista Software Inc.
|
||||
# Author: MontaVista Software, Inc.
|
||||
# ppopov@mvista.com or source@mvista.com
|
||||
# Copyright 2000, 2008 MontaVista Software Inc.
|
||||
# Author: MontaVista Software, Inc. <source@mvista.com>
|
||||
#
|
||||
# Makefile for the Alchemy Semiconductor DBAu1xx0 boards.
|
||||
#
|
||||
# Makefile for the Alchemy Semiconductor Db1x00 board.
|
||||
|
||||
lib-y := init.o board_setup.o irqmap.o
|
||||
|
|
|
@ -3,9 +3,8 @@
|
|||
* BRIEF MODULE DESCRIPTION
|
||||
* Alchemy Db1x00 board setup.
|
||||
*
|
||||
* Copyright 2000 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc.
|
||||
* ppopov@mvista.com or source@mvista.com
|
||||
* Copyright 2000, 2008 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc. <source@mvista.com>
|
||||
*
|
||||
* 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
|
||||
|
@ -37,49 +36,49 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
|
|||
|
||||
void board_reset(void)
|
||||
{
|
||||
/* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
|
||||
/* Hit BCSR.SW_RESET[RESET] */
|
||||
bcsr->swreset = 0x0000;
|
||||
}
|
||||
|
||||
void __init board_setup(void)
|
||||
{
|
||||
u32 pin_func;
|
||||
u32 pin_func = 0;
|
||||
|
||||
pin_func = 0;
|
||||
/* not valid for 1550 */
|
||||
|
||||
#if defined(CONFIG_IRDA) && (defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100))
|
||||
/* set IRFIRSEL instead of GPIO15 */
|
||||
pin_func = au_readl(SYS_PINFUNC) | (u32)((1<<8));
|
||||
/* Not valid for Au1550 */
|
||||
#if defined(CONFIG_IRDA) && \
|
||||
(defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100))
|
||||
/* Set IRFIRSEL instead of GPIO15 */
|
||||
pin_func = au_readl(SYS_PINFUNC) | SYS_PF_IRF;
|
||||
au_writel(pin_func, SYS_PINFUNC);
|
||||
/* power off until the driver is in use */
|
||||
/* Power off until the driver is in use */
|
||||
bcsr->resets &= ~BCSR_RESETS_IRDA_MODE_MASK;
|
||||
bcsr->resets |= BCSR_RESETS_IRDA_MODE_OFF;
|
||||
bcsr->resets |= BCSR_RESETS_IRDA_MODE_OFF;
|
||||
au_sync();
|
||||
#endif
|
||||
bcsr->pcmcia = 0x0000; /* turn off PCMCIA power */
|
||||
|
||||
#ifdef CONFIG_MIPS_MIRAGE
|
||||
/* enable GPIO[31:0] inputs */
|
||||
/* Enable GPIO[31:0] inputs */
|
||||
au_writel(0, SYS_PININPUTEN);
|
||||
|
||||
/* GPIO[20] is output, tristate the other input primary GPIO's */
|
||||
au_writel((u32)(~(1<<20)), SYS_TRIOUTCLR);
|
||||
/* GPIO[20] is output, tristate the other input primary GPIOs */
|
||||
au_writel(~(1 << 20), SYS_TRIOUTCLR);
|
||||
|
||||
/* set GPIO[210:208] instead of SSI_0 */
|
||||
pin_func = au_readl(SYS_PINFUNC) | (u32)(1);
|
||||
/* Set GPIO[210:208] instead of SSI_0 */
|
||||
pin_func = au_readl(SYS_PINFUNC) | SYS_PF_S0;
|
||||
|
||||
/* set GPIO[215:211] for LED's */
|
||||
pin_func |= (u32)((5<<2));
|
||||
/* Set GPIO[215:211] for LEDs */
|
||||
pin_func |= 5 << 2;
|
||||
|
||||
/* set GPIO[214:213] for more LED's */
|
||||
pin_func |= (u32)((5<<12));
|
||||
/* Set GPIO[214:213] for more LEDs */
|
||||
pin_func |= 5 << 12;
|
||||
|
||||
/* set GPIO[207:200] instead of PCMCIA/LCD */
|
||||
pin_func |= (u32)((3<<17));
|
||||
/* Set GPIO[207:200] instead of PCMCIA/LCD */
|
||||
pin_func |= SYS_PF_LCD | SYS_PF_PC;
|
||||
au_writel(pin_func, SYS_PINFUNC);
|
||||
|
||||
/* Enable speaker amplifier. This should
|
||||
/*
|
||||
* Enable speaker amplifier. This should
|
||||
* be part of the audio driver.
|
||||
*/
|
||||
au_writel(au_readl(GPIO2_DIR) | 0x200, GPIO2_DIR);
|
||||
|
@ -89,21 +88,21 @@ void __init board_setup(void)
|
|||
au_sync();
|
||||
|
||||
#ifdef CONFIG_MIPS_DB1000
|
||||
printk("AMD Alchemy Au1000/Db1000 Board\n");
|
||||
printk(KERN_INFO "AMD Alchemy Au1000/Db1000 Board\n");
|
||||
#endif
|
||||
#ifdef CONFIG_MIPS_DB1500
|
||||
printk("AMD Alchemy Au1500/Db1500 Board\n");
|
||||
printk(KERN_INFO "AMD Alchemy Au1500/Db1500 Board\n");
|
||||
#endif
|
||||
#ifdef CONFIG_MIPS_DB1100
|
||||
printk("AMD Alchemy Au1100/Db1100 Board\n");
|
||||
printk(KERN_INFO "AMD Alchemy Au1100/Db1100 Board\n");
|
||||
#endif
|
||||
#ifdef CONFIG_MIPS_BOSPORUS
|
||||
printk("AMD Alchemy Bosporus Board\n");
|
||||
printk(KERN_INFO "AMD Alchemy Bosporus Board\n");
|
||||
#endif
|
||||
#ifdef CONFIG_MIPS_MIRAGE
|
||||
printk("AMD Alchemy Mirage Board\n");
|
||||
printk(KERN_INFO "AMD Alchemy Mirage Board\n");
|
||||
#endif
|
||||
#ifdef CONFIG_MIPS_DB1550
|
||||
printk("AMD Alchemy Au1550/Db1550 Board\n");
|
||||
printk(KERN_INFO "AMD Alchemy Au1550/Db1550 Board\n");
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -2,9 +2,8 @@
|
|||
* BRIEF MODULE DESCRIPTION
|
||||
* PB1000 board setup
|
||||
*
|
||||
* Copyright 2001 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc.
|
||||
* ppopov@mvista.com or source@mvista.com
|
||||
* Copyright 2001, 2008 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc. <source@mvista.com>
|
||||
*
|
||||
* 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
|
||||
|
@ -49,8 +48,8 @@ void __init prom_init(void)
|
|||
unsigned long memsize;
|
||||
|
||||
prom_argc = fw_arg0;
|
||||
prom_argv = (char **) fw_arg1;
|
||||
prom_envp = (char **) fw_arg2;
|
||||
prom_argv = (char **)fw_arg1;
|
||||
prom_envp = (char **)fw_arg2;
|
||||
|
||||
prom_init_cmdline();
|
||||
|
||||
|
@ -58,6 +57,6 @@ void __init prom_init(void)
|
|||
if (!memsize_str)
|
||||
memsize = 0x04000000;
|
||||
else
|
||||
memsize = simple_strtol(memsize_str, NULL, 0);
|
||||
memsize = strict_strtol(memsize_str, 0, NULL);
|
||||
add_memory_region(0, memsize, BOOT_MEM_RAM);
|
||||
}
|
||||
|
|
|
@ -32,32 +32,32 @@
|
|||
|
||||
#ifdef CONFIG_MIPS_DB1500
|
||||
char irq_tab_alchemy[][5] __initdata = {
|
||||
[12] = { -1, INTA, INTX, INTX, INTX}, /* IDSEL 12 - HPT371 */
|
||||
[13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot */
|
||||
[12] = { -1, INTA, INTX, INTX, INTX }, /* IDSEL 12 - HPT371 */
|
||||
[13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot */
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MIPS_BOSPORUS
|
||||
char irq_tab_alchemy[][5] __initdata = {
|
||||
[11] = { -1, INTA, INTB, INTX, INTX}, /* IDSEL 11 - miniPCI */
|
||||
[12] = { -1, INTA, INTX, INTX, INTX}, /* IDSEL 12 - SN1741 */
|
||||
[13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot */
|
||||
[11] = { -1, INTA, INTB, INTX, INTX }, /* IDSEL 11 - miniPCI */
|
||||
[12] = { -1, INTA, INTX, INTX, INTX }, /* IDSEL 12 - SN1741 */
|
||||
[13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot */
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MIPS_MIRAGE
|
||||
char irq_tab_alchemy[][5] __initdata = {
|
||||
[11] = { -1, INTD, INTX, INTX, INTX}, /* IDSEL 11 - SMI VGX */
|
||||
[12] = { -1, INTX, INTX, INTC, INTX}, /* IDSEL 12 - PNX1300 */
|
||||
[13] = { -1, INTA, INTB, INTX, INTX}, /* IDSEL 13 - miniPCI */
|
||||
[11] = { -1, INTD, INTX, INTX, INTX }, /* IDSEL 11 - SMI VGX */
|
||||
[12] = { -1, INTX, INTX, INTC, INTX }, /* IDSEL 12 - PNX1300 */
|
||||
[13] = { -1, INTA, INTB, INTX, INTX }, /* IDSEL 13 - miniPCI */
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MIPS_DB1550
|
||||
char irq_tab_alchemy[][5] __initdata = {
|
||||
[11] = { -1, INTC, INTX, INTX, INTX}, /* IDSEL 11 - on-board HPT371 */
|
||||
[12] = { -1, INTB, INTC, INTD, INTA}, /* IDSEL 12 - PCI slot 2 (left) */
|
||||
[13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot 1 (right) */
|
||||
[11] = { -1, INTC, INTX, INTX, INTX }, /* IDSEL 11 - on-board HPT371 */
|
||||
[12] = { -1, INTB, INTC, INTD, INTA }, /* IDSEL 12 - PCI slot 2 (left) */
|
||||
[13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot 1 (right) */
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#
|
||||
# Copyright 2003 MontaVista Software Inc.
|
||||
# Author: MontaVista Software, Inc.
|
||||
# ppopov@mvista.com or source@mvista.com
|
||||
# Author: MontaVista Software, Inc. <source@mvista.com>
|
||||
# Bruno Randolf <bruno.randolf@4g-systems.biz>
|
||||
#
|
||||
# Makefile for 4G Systems MTX-1 board.
|
||||
|
|
|
@ -3,9 +3,8 @@
|
|||
* BRIEF MODULE DESCRIPTION
|
||||
* 4G Systems MTX-1 board setup.
|
||||
*
|
||||
* Copyright 2003 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc.
|
||||
* ppopov@mvista.com or source@mvista.com
|
||||
* Copyright 2003, 2008 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc. <source@mvista.com>
|
||||
* Bruno Randolf <bruno.randolf@4g-systems.biz>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -34,7 +33,7 @@
|
|||
#include <asm/mach-au1x00/au1000.h>
|
||||
|
||||
extern int (*board_pci_idsel)(unsigned int devsel, int assert);
|
||||
int mtx1_pci_idsel(unsigned int devsel, int assert);
|
||||
int mtx1_pci_idsel(unsigned int devsel, int assert);
|
||||
|
||||
void board_reset(void)
|
||||
{
|
||||
|
@ -45,36 +44,36 @@ void board_reset(void)
|
|||
void __init board_setup(void)
|
||||
{
|
||||
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
|
||||
// enable USB power switch
|
||||
au_writel( au_readl(GPIO2_DIR) | 0x10, GPIO2_DIR );
|
||||
au_writel( 0x100000, GPIO2_OUTPUT );
|
||||
/* Enable USB power switch */
|
||||
au_writel(au_readl(GPIO2_DIR) | 0x10, GPIO2_DIR);
|
||||
au_writel(0x100000, GPIO2_OUTPUT);
|
||||
#endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
#if defined(__MIPSEB__)
|
||||
au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG);
|
||||
au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG);
|
||||
#else
|
||||
au_writel(0xf, Au1500_PCI_CFG);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// initialize sys_pinfunc:
|
||||
au_writel( SYS_PF_NI2, SYS_PINFUNC );
|
||||
/* Initialize sys_pinfunc */
|
||||
au_writel(SYS_PF_NI2, SYS_PINFUNC);
|
||||
|
||||
// initialize GPIO
|
||||
au_writel( 0xFFFFFFFF, SYS_TRIOUTCLR );
|
||||
au_writel( 0x00000001, SYS_OUTPUTCLR ); // set M66EN (PCI 66MHz) to OFF
|
||||
au_writel( 0x00000008, SYS_OUTPUTSET ); // set PCI CLKRUN# to OFF
|
||||
au_writel( 0x00000002, SYS_OUTPUTSET ); // set EXT_IO3 ON
|
||||
au_writel( 0x00000020, SYS_OUTPUTCLR ); // set eth PHY TX_ER to OFF
|
||||
/* Initialize GPIO */
|
||||
au_writel(0xFFFFFFFF, SYS_TRIOUTCLR);
|
||||
au_writel(0x00000001, SYS_OUTPUTCLR); /* set M66EN (PCI 66MHz) to OFF */
|
||||
au_writel(0x00000008, SYS_OUTPUTSET); /* set PCI CLKRUN# to OFF */
|
||||
au_writel(0x00000002, SYS_OUTPUTSET); /* set EXT_IO3 ON */
|
||||
au_writel(0x00000020, SYS_OUTPUTCLR); /* set eth PHY TX_ER to OFF */
|
||||
|
||||
// enable LED and set it to green
|
||||
au_writel( au_readl(GPIO2_DIR) | 0x1800, GPIO2_DIR );
|
||||
au_writel( 0x18000800, GPIO2_OUTPUT );
|
||||
/* Enable LED and set it to green */
|
||||
au_writel(au_readl(GPIO2_DIR) | 0x1800, GPIO2_DIR);
|
||||
au_writel(0x18000800, GPIO2_OUTPUT);
|
||||
|
||||
board_pci_idsel = mtx1_pci_idsel;
|
||||
|
||||
printk("4G Systems MTX-1 Board\n");
|
||||
printk(KERN_INFO "4G Systems MTX-1 Board\n");
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -82,20 +81,18 @@ mtx1_pci_idsel(unsigned int devsel, int assert)
|
|||
{
|
||||
#define MTX_IDSEL_ONLY_0_AND_3 0
|
||||
#if MTX_IDSEL_ONLY_0_AND_3
|
||||
if (devsel != 0 && devsel != 3) {
|
||||
printk("*** not 0 or 3\n");
|
||||
return 0;
|
||||
}
|
||||
if (devsel != 0 && devsel != 3) {
|
||||
printk(KERN_ERR "*** not 0 or 3\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (assert && devsel != 0) {
|
||||
// suppress signal to cardbus
|
||||
au_writel( 0x00000002, SYS_OUTPUTCLR ); // set EXT_IO3 OFF
|
||||
}
|
||||
else {
|
||||
au_writel( 0x00000002, SYS_OUTPUTSET ); // set EXT_IO3 ON
|
||||
}
|
||||
au_sync_udelay(1);
|
||||
return 1;
|
||||
if (assert && devsel != 0)
|
||||
/* Suppress signal to Cardbus */
|
||||
au_writel(0x00000002, SYS_OUTPUTCLR); /* set EXT_IO3 OFF */
|
||||
else
|
||||
au_writel(0x00000002, SYS_OUTPUTSET); /* set EXT_IO3 ON */
|
||||
au_sync_udelay(1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,9 +3,8 @@
|
|||
* BRIEF MODULE DESCRIPTION
|
||||
* 4G Systems MTX-1 board setup
|
||||
*
|
||||
* Copyright 2003 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc.
|
||||
* ppopov@mvista.com or source@mvista.com
|
||||
* Copyright 2003, 2008 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc. <source@mvista.com>
|
||||
* Bruno Randolf <bruno.randolf@4g-systems.biz>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -47,8 +46,8 @@ void __init prom_init(void)
|
|||
unsigned long memsize;
|
||||
|
||||
prom_argc = fw_arg0;
|
||||
prom_argv = (char **) fw_arg1;
|
||||
prom_envp = (char **) fw_arg2;
|
||||
prom_argv = (char **)fw_arg1;
|
||||
prom_envp = (char **)fw_arg2;
|
||||
|
||||
prom_init_cmdline();
|
||||
|
||||
|
@ -56,6 +55,6 @@ void __init prom_init(void)
|
|||
if (!memsize_str)
|
||||
memsize = 0x04000000;
|
||||
else
|
||||
memsize = simple_strtol(memsize_str, NULL, 0);
|
||||
memsize = strict_strtol(memsize_str, 0, NULL);
|
||||
add_memory_region(0, memsize, BOOT_MEM_RAM);
|
||||
}
|
||||
|
|
|
@ -31,18 +31,18 @@
|
|||
#include <asm/mach-au1x00/au1000.h>
|
||||
|
||||
char irq_tab_alchemy[][5] __initdata = {
|
||||
[0] = { -1, INTA, INTA, INTX, INTX}, /* IDSEL 00 - AdapterA-Slot0 (top) */
|
||||
[1] = { -1, INTB, INTA, INTX, INTX}, /* IDSEL 01 - AdapterA-Slot1 (bottom) */
|
||||
[2] = { -1, INTC, INTD, INTX, INTX}, /* IDSEL 02 - AdapterB-Slot0 (top) */
|
||||
[3] = { -1, INTD, INTC, INTX, INTX}, /* IDSEL 03 - AdapterB-Slot1 (bottom) */
|
||||
[4] = { -1, INTA, INTB, INTX, INTX}, /* IDSEL 04 - AdapterC-Slot0 (top) */
|
||||
[5] = { -1, INTB, INTA, INTX, INTX}, /* IDSEL 05 - AdapterC-Slot1 (bottom) */
|
||||
[6] = { -1, INTC, INTD, INTX, INTX}, /* IDSEL 06 - AdapterD-Slot0 (top) */
|
||||
[7] = { -1, INTD, INTC, INTX, INTX}, /* IDSEL 07 - AdapterD-Slot1 (bottom) */
|
||||
[0] = { -1, INTA, INTA, INTX, INTX }, /* IDSEL 00 - AdapterA-Slot0 (top) */
|
||||
[1] = { -1, INTB, INTA, INTX, INTX }, /* IDSEL 01 - AdapterA-Slot1 (bottom) */
|
||||
[2] = { -1, INTC, INTD, INTX, INTX }, /* IDSEL 02 - AdapterB-Slot0 (top) */
|
||||
[3] = { -1, INTD, INTC, INTX, INTX }, /* IDSEL 03 - AdapterB-Slot1 (bottom) */
|
||||
[4] = { -1, INTA, INTB, INTX, INTX }, /* IDSEL 04 - AdapterC-Slot0 (top) */
|
||||
[5] = { -1, INTB, INTA, INTX, INTX }, /* IDSEL 05 - AdapterC-Slot1 (bottom) */
|
||||
[6] = { -1, INTC, INTD, INTX, INTX }, /* IDSEL 06 - AdapterD-Slot0 (top) */
|
||||
[7] = { -1, INTD, INTC, INTX, INTX }, /* IDSEL 07 - AdapterD-Slot1 (bottom) */
|
||||
};
|
||||
|
||||
struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
|
||||
{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
|
||||
{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0 },
|
||||
{ AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
|
||||
{ AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 },
|
||||
{ AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 },
|
||||
|
|
|
@ -21,11 +21,10 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio_keys.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
#include <asm/gpio.h>
|
||||
|
||||
static struct gpio_keys_button mtx1_gpio_button[] = {
|
||||
{
|
||||
.gpio = 207,
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#
|
||||
# Copyright 2000 MontaVista Software Inc.
|
||||
# Author: MontaVista Software, Inc.
|
||||
# ppopov@mvista.com or source@mvista.com
|
||||
# Copyright 2000, 2008 MontaVista Software Inc.
|
||||
# Author: MontaVista Software, Inc. <source@mvista.com>
|
||||
#
|
||||
# Makefile for the Alchemy Semiconductor Pb1000 board.
|
||||
#
|
||||
# Makefile for the Alchemy Semiconductor PB1000 board.
|
||||
|
||||
lib-y := init.o board_setup.o irqmap.o
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* Copyright 2000 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc.
|
||||
* ppopov@mvista.com or source@mvista.com
|
||||
* Copyright 2000, 2008 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc. <source@mvista.com>
|
||||
*
|
||||
* 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
|
||||
|
@ -40,128 +39,126 @@ void __init board_setup(void)
|
|||
u32 sys_freqctrl, sys_clksrc;
|
||||
u32 prid = read_c0_prid();
|
||||
|
||||
// set AUX clock to 12MHz * 8 = 96 MHz
|
||||
/* Set AUX clock to 12 MHz * 8 = 96 MHz */
|
||||
au_writel(8, SYS_AUXPLL);
|
||||
au_writel(0, SYS_PINSTATERD);
|
||||
udelay(100);
|
||||
|
||||
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
|
||||
/* zero and disable FREQ2 */
|
||||
/* Zero and disable FREQ2 */
|
||||
sys_freqctrl = au_readl(SYS_FREQCTRL0);
|
||||
sys_freqctrl &= ~0xFFF00000;
|
||||
au_writel(sys_freqctrl, SYS_FREQCTRL0);
|
||||
|
||||
/* zero and disable USBH/USBD clocks */
|
||||
/* Zero and disable USBH/USBD clocks */
|
||||
sys_clksrc = au_readl(SYS_CLKSRC);
|
||||
sys_clksrc &= ~0x00007FE0;
|
||||
sys_clksrc &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK |
|
||||
SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK);
|
||||
au_writel(sys_clksrc, SYS_CLKSRC);
|
||||
|
||||
sys_freqctrl = au_readl(SYS_FREQCTRL0);
|
||||
sys_freqctrl &= ~0xFFF00000;
|
||||
|
||||
sys_clksrc = au_readl(SYS_CLKSRC);
|
||||
sys_clksrc &= ~0x00007FE0;
|
||||
sys_clksrc &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK |
|
||||
SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK);
|
||||
|
||||
switch (prid & 0x000000FF)
|
||||
{
|
||||
switch (prid & 0x000000FF) {
|
||||
case 0x00: /* DA */
|
||||
case 0x01: /* HA */
|
||||
case 0x02: /* HB */
|
||||
/* CPU core freq to 48MHz to slow it way down... */
|
||||
au_writel(4, SYS_CPUPLL);
|
||||
/* CPU core freq to 48 MHz to slow it way down... */
|
||||
au_writel(4, SYS_CPUPLL);
|
||||
|
||||
/*
|
||||
* Setup 48MHz FREQ2 from CPUPLL for USB Host
|
||||
*/
|
||||
/* FRDIV2=3 -> div by 8 of 384MHz -> 48MHz */
|
||||
sys_freqctrl |= ((3<<22) | (1<<21) | (0<<20));
|
||||
au_writel(sys_freqctrl, SYS_FREQCTRL0);
|
||||
/*
|
||||
* Setup 48 MHz FREQ2 from CPUPLL for USB Host
|
||||
* FRDIV2 = 3 -> div by 8 of 384 MHz -> 48 MHz
|
||||
*/
|
||||
sys_freqctrl |= (3 << SYS_FC_FRDIV2_BIT) | SYS_FC_FE2;
|
||||
au_writel(sys_freqctrl, SYS_FREQCTRL0);
|
||||
|
||||
/* CPU core freq to 384MHz */
|
||||
au_writel(0x20, SYS_CPUPLL);
|
||||
/* CPU core freq to 384 MHz */
|
||||
au_writel(0x20, SYS_CPUPLL);
|
||||
|
||||
printk("Au1000: 48MHz OHCI workaround enabled\n");
|
||||
printk(KERN_INFO "Au1000: 48 MHz OHCI workaround enabled\n");
|
||||
break;
|
||||
|
||||
default: /* HC and newer */
|
||||
// FREQ2 = aux/2 = 48 MHz
|
||||
sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
|
||||
au_writel(sys_freqctrl, SYS_FREQCTRL0);
|
||||
default: /* HC and newer */
|
||||
/* FREQ2 = aux / 2 = 48 MHz */
|
||||
sys_freqctrl |= (0 << SYS_FC_FRDIV2_BIT) |
|
||||
SYS_FC_FE2 | SYS_FC_FS2;
|
||||
au_writel(sys_freqctrl, SYS_FREQCTRL0);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Route 48MHz FREQ2 into USB Host and/or Device
|
||||
* Route 48 MHz FREQ2 into USB Host and/or Device
|
||||
*/
|
||||
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
|
||||
sys_clksrc |= ((4<<12) | (0<<11) | (0<<10));
|
||||
#endif
|
||||
sys_clksrc |= SYS_CS_MUX_FQ2 << SYS_CS_MUH_BIT;
|
||||
au_writel(sys_clksrc, SYS_CLKSRC);
|
||||
|
||||
// configure pins GPIO[14:9] as GPIO
|
||||
pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8080);
|
||||
/* Configure pins GPIO[14:9] as GPIO */
|
||||
pin_func = au_readl(SYS_PINFUNC) & ~(SYS_PF_UR3 | SYS_PF_USB);
|
||||
|
||||
// 2nd USB port is USB host
|
||||
pin_func |= 0x8000;
|
||||
/* 2nd USB port is USB host */
|
||||
pin_func |= SYS_PF_USB;
|
||||
|
||||
au_writel(pin_func, SYS_PINFUNC);
|
||||
au_writel(0x2800, SYS_TRIOUTCLR);
|
||||
au_writel(0x0030, SYS_OUTPUTCLR);
|
||||
#endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
|
||||
|
||||
// make gpio 15 an input (for interrupt line)
|
||||
pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x100);
|
||||
// we don't need I2S, so make it available for GPIO[31:29]
|
||||
pin_func |= (1<<5);
|
||||
/* Make GPIO 15 an input (for interrupt line) */
|
||||
pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_IRF;
|
||||
/* We don't need I2S, so make it available for GPIO[31:29] */
|
||||
pin_func |= SYS_PF_I2S;
|
||||
au_writel(pin_func, SYS_PINFUNC);
|
||||
|
||||
au_writel(0x8000, SYS_TRIOUTCLR);
|
||||
|
||||
static_cfg0 = au_readl(MEM_STCFG0) & (u32)(~0xc00);
|
||||
static_cfg0 = au_readl(MEM_STCFG0) & ~0xc00;
|
||||
au_writel(static_cfg0, MEM_STCFG0);
|
||||
|
||||
// configure RCE2* for LCD
|
||||
/* configure RCE2* for LCD */
|
||||
au_writel(0x00000004, MEM_STCFG2);
|
||||
|
||||
// MEM_STTIME2
|
||||
/* MEM_STTIME2 */
|
||||
au_writel(0x09000000, MEM_STTIME2);
|
||||
|
||||
// Set 32-bit base address decoding for RCE2*
|
||||
/* Set 32-bit base address decoding for RCE2* */
|
||||
au_writel(0x10003ff0, MEM_STADDR2);
|
||||
|
||||
// PCI CPLD setup
|
||||
// expand CE0 to cover PCI
|
||||
/*
|
||||
* PCI CPLD setup
|
||||
* Expand CE0 to cover PCI
|
||||
*/
|
||||
au_writel(0x11803e40, MEM_STADDR1);
|
||||
|
||||
// burst visibility on
|
||||
/* Burst visibility on */
|
||||
au_writel(au_readl(MEM_STCFG0) | 0x1000, MEM_STCFG0);
|
||||
|
||||
au_writel(0x83, MEM_STCFG1); // ewait enabled, flash timing
|
||||
au_writel(0x33030a10, MEM_STTIME1); // slower timing for FPGA
|
||||
au_writel(0x83, MEM_STCFG1); /* ewait enabled, flash timing */
|
||||
au_writel(0x33030a10, MEM_STTIME1); /* slower timing for FPGA */
|
||||
|
||||
/* setup the static bus controller */
|
||||
/* Setup the static bus controller */
|
||||
au_writel(0x00000002, MEM_STCFG3); /* type = PCMCIA */
|
||||
au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */
|
||||
au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
au_writel(0, PCI_BRIDGE_CONFIG); // set extend byte to 0
|
||||
au_writel(0, SDRAM_MBAR); // set mbar to 0
|
||||
au_writel(0x2, SDRAM_CMD); // enable memory accesses
|
||||
au_sync_delay(1);
|
||||
#endif
|
||||
|
||||
/* Enable Au1000 BCLK switching - note: sed1356 must not use
|
||||
* its BCLK (Au1000 LCLK) for any timings */
|
||||
switch (prid & 0x000000FF)
|
||||
{
|
||||
/*
|
||||
* Enable Au1000 BCLK switching - note: sed1356 must not use
|
||||
* its BCLK (Au1000 LCLK) for any timings
|
||||
*/
|
||||
switch (prid & 0x000000FF) {
|
||||
case 0x00: /* DA */
|
||||
case 0x01: /* HA */
|
||||
case 0x02: /* HB */
|
||||
break;
|
||||
default: /* HC and newer */
|
||||
/* Enable sys bus clock divider when IDLE state or no bus
|
||||
activity. */
|
||||
/*
|
||||
* Enable sys bus clock divider when IDLE state or no bus
|
||||
* activity.
|
||||
*/
|
||||
au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
/*
|
||||
* BRIEF MODULE DESCRIPTION
|
||||
* PB1000 board setup
|
||||
* Pb1000 board setup
|
||||
*
|
||||
* Copyright 2001 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc.
|
||||
* ppopov@mvista.com or source@mvista.com
|
||||
* Copyright 2001, 2008 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc. <source@mvista.com>
|
||||
*
|
||||
* 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
|
||||
|
@ -44,16 +43,15 @@ void __init prom_init(void)
|
|||
unsigned char *memsize_str;
|
||||
unsigned long memsize;
|
||||
|
||||
prom_argc = (int) fw_arg0;
|
||||
prom_argv = (char **) fw_arg1;
|
||||
prom_envp = (char **) fw_arg2;
|
||||
prom_argc = (int)fw_arg0;
|
||||
prom_argv = (char **)fw_arg1;
|
||||
prom_envp = (char **)fw_arg2;
|
||||
|
||||
prom_init_cmdline();
|
||||
memsize_str = prom_getenv("memsize");
|
||||
if (!memsize_str) {
|
||||
if (!memsize_str)
|
||||
memsize = 0x04000000;
|
||||
} else {
|
||||
memsize = simple_strtol(memsize_str, NULL, 0);
|
||||
}
|
||||
else
|
||||
memsize = strict_strtol(memsize_str, 0, NULL);
|
||||
add_memory_region(0, memsize, BOOT_MEM_RAM);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#
|
||||
# Copyright 2000,2001 MontaVista Software Inc.
|
||||
# Author: MontaVista Software, Inc.
|
||||
# ppopov@mvista.com or source@mvista.com
|
||||
# Copyright 2000, 2001, 2008 MontaVista Software Inc.
|
||||
# Author: MontaVista Software, Inc. <source@mvista.com>
|
||||
#
|
||||
# Makefile for the Alchemy Semiconductor Pb1100 board.
|
||||
#
|
||||
|
||||
lib-y := init.o board_setup.o irqmap.o
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* Copyright 2002 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc.
|
||||
* ppopov@mvista.com or source@mvista.com
|
||||
* Copyright 2002, 2008 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc. <source@mvista.com>
|
||||
*
|
||||
* 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
|
||||
|
@ -32,15 +31,15 @@
|
|||
|
||||
void board_reset(void)
|
||||
{
|
||||
/* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
|
||||
au_writel(0x00000000, 0xAE00001C);
|
||||
/* Hit BCSR.RST_VDDI[SOFT_RESET] */
|
||||
au_writel(0x00000000, PB1100_RST_VDDI);
|
||||
}
|
||||
|
||||
void __init board_setup(void)
|
||||
{
|
||||
volatile void __iomem * base = (volatile void __iomem *) 0xac000000UL;
|
||||
volatile void __iomem *base = (volatile void __iomem *)0xac000000UL;
|
||||
|
||||
// set AUX clock to 12MHz * 8 = 96 MHz
|
||||
/* Set AUX clock to 12 MHz * 8 = 96 MHz */
|
||||
au_writel(8, SYS_AUXPLL);
|
||||
au_writel(0, SYS_PININPUTEN);
|
||||
udelay(100);
|
||||
|
@ -49,44 +48,47 @@ void __init board_setup(void)
|
|||
{
|
||||
u32 pin_func, sys_freqctrl, sys_clksrc;
|
||||
|
||||
// configure pins GPIO[14:9] as GPIO
|
||||
pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x80);
|
||||
/* Configure pins GPIO[14:9] as GPIO */
|
||||
pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_UR3;
|
||||
|
||||
/* zero and disable FREQ2 */
|
||||
/* Zero and disable FREQ2 */
|
||||
sys_freqctrl = au_readl(SYS_FREQCTRL0);
|
||||
sys_freqctrl &= ~0xFFF00000;
|
||||
au_writel(sys_freqctrl, SYS_FREQCTRL0);
|
||||
|
||||
/* zero and disable USBH/USBD/IrDA clock */
|
||||
/* Zero and disable USBH/USBD/IrDA clock */
|
||||
sys_clksrc = au_readl(SYS_CLKSRC);
|
||||
sys_clksrc &= ~0x0000001F;
|
||||
sys_clksrc &= ~(SYS_CS_CIR | SYS_CS_DIR | SYS_CS_MIR_MASK);
|
||||
au_writel(sys_clksrc, SYS_CLKSRC);
|
||||
|
||||
sys_freqctrl = au_readl(SYS_FREQCTRL0);
|
||||
sys_freqctrl &= ~0xFFF00000;
|
||||
|
||||
sys_clksrc = au_readl(SYS_CLKSRC);
|
||||
sys_clksrc &= ~0x0000001F;
|
||||
sys_clksrc &= ~(SYS_CS_CIR | SYS_CS_DIR | SYS_CS_MIR_MASK);
|
||||
|
||||
// FREQ2 = aux/2 = 48 MHz
|
||||
sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
|
||||
/* FREQ2 = aux / 2 = 48 MHz */
|
||||
sys_freqctrl |= (0 << SYS_FC_FRDIV2_BIT) |
|
||||
SYS_FC_FE2 | SYS_FC_FS2;
|
||||
au_writel(sys_freqctrl, SYS_FREQCTRL0);
|
||||
|
||||
/*
|
||||
* Route 48MHz FREQ2 into USBH/USBD/IrDA
|
||||
* Route 48 MHz FREQ2 into USBH/USBD/IrDA
|
||||
*/
|
||||
sys_clksrc |= ((4<<2) | (0<<1) | 0 );
|
||||
sys_clksrc |= SYS_CS_MUX_FQ2 << SYS_CS_MIR_BIT;
|
||||
au_writel(sys_clksrc, SYS_CLKSRC);
|
||||
|
||||
/* setup the static bus controller */
|
||||
/* Setup the static bus controller */
|
||||
au_writel(0x00000002, MEM_STCFG3); /* type = PCMCIA */
|
||||
au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */
|
||||
au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */
|
||||
|
||||
// get USB Functionality pin state (device vs host drive pins)
|
||||
pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);
|
||||
// 2nd USB port is USB host
|
||||
pin_func |= 0x8000;
|
||||
/*
|
||||
* Get USB Functionality pin state (device vs host drive pins).
|
||||
*/
|
||||
pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_USB;
|
||||
/* 2nd USB port is USB host. */
|
||||
pin_func |= SYS_PF_USB;
|
||||
au_writel(pin_func, SYS_PINFUNC);
|
||||
}
|
||||
#endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
|
||||
|
@ -94,12 +96,12 @@ void __init board_setup(void)
|
|||
/* Enable sys bus clock divider when IDLE state or no bus activity. */
|
||||
au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);
|
||||
|
||||
// Enable the RTC if not already enabled
|
||||
/* Enable the RTC if not already enabled. */
|
||||
if (!(readb(base + 0x28) & 0x20)) {
|
||||
writeb(readb(base + 0x28) | 0x20, base + 0x28);
|
||||
au_sync();
|
||||
}
|
||||
// Put the clock in BCD mode
|
||||
/* Put the clock in BCD mode. */
|
||||
if (readb(base + 0x2C) & 0x4) { /* reg B */
|
||||
writeb(readb(base + 0x2c) & ~0x4, base + 0x2c);
|
||||
au_sync();
|
||||
|
|
|
@ -3,9 +3,8 @@
|
|||
* BRIEF MODULE DESCRIPTION
|
||||
* Pb1100 board setup
|
||||
*
|
||||
* Copyright 2002 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc.
|
||||
* ppopov@mvista.com or source@mvista.com
|
||||
* Copyright 2002, 2008 MontaVista Software Inc.
|
||||
* Author: MontaVista Software, Inc. <source@mvista.com>
|
||||
*
|
||||
* 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
|
||||
|
@ -46,8 +45,8 @@ void __init prom_init(void)
|
|||
unsigned long memsize;
|
||||
|
||||
prom_argc = fw_arg0;
|
||||
prom_argv = (char **) fw_arg1;
|
||||
prom_envp = (char **) fw_arg3;
|
||||
prom_argv = (char **)fw_arg1;
|
||||
prom_envp = (char **)fw_arg3;
|
||||
|
||||
prom_init_cmdline();
|
||||
|
||||
|
@ -55,7 +54,7 @@ void __init prom_init(void)
|
|||
if (!memsize_str)
|
||||
memsize = 0x04000000;
|
||||
else
|
||||
memsize = simple_strtol(memsize_str, NULL, 0);
|
||||
memsize = strict_strtol(memsize_str, 0, NULL);
|
||||
|
||||
add_memory_region(0, memsize, BOOT_MEM_RAM);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* BRIEF MODULE DESCRIPTION
|
||||
* Au1xxx irq map table
|
||||
* Au1xx0 IRQ map table
|
||||
*
|
||||
* Copyright 2003 Embedded Edge, LLC
|
||||
* dan@embeddededge.com
|
||||
|
@ -31,10 +31,10 @@
|
|||
#include <asm/mach-au1x00/au1000.h>
|
||||
|
||||
struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
|
||||
{ AU1000_GPIO_9, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card Fully_Interted#
|
||||
{ AU1000_GPIO_10, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card STSCHG#
|
||||
{ AU1000_GPIO_11, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card IRQ#
|
||||
{ AU1000_GPIO_13, INTC_INT_LOW_LEVEL, 0 }, // DC_IRQ#
|
||||
{ AU1000_GPIO_9, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card Fully_Inserted# */
|
||||
{ AU1000_GPIO_10, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card STSCHG# */
|
||||
{ AU1000_GPIO_11, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card IRQ# */
|
||||
{ AU1000_GPIO_13, INTC_INT_LOW_LEVEL, 0 }, /* DC_IRQ# */
|
||||
};
|
||||
|
||||
int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Makefile for the Alchemy Semiconductor PB1200 board.
|
||||
# Makefile for the Alchemy Semiconductor Pb1200/DBAu1200 boards.
|
||||
#
|
||||
|
||||
lib-y := init.o board_setup.o irqmap.o
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue