mirror of
https://github.com/torvalds/linux.git
synced 2024-11-27 14:41:39 +00:00
Merge branch 'master'
This commit is contained in:
commit
76467874b8
@ -2,7 +2,7 @@
|
||||
# This makefile is used to generate the kernel documentation,
|
||||
# primarily based on in-line comments in various source files.
|
||||
# See Documentation/kernel-doc-nano-HOWTO.txt for instruction in how
|
||||
# to ducument the SRC - and how to read it.
|
||||
# to document the SRC - and how to read it.
|
||||
# To add a new book the only step required is to add the book to the
|
||||
# list of DOCBOOKS.
|
||||
|
||||
|
@ -322,7 +322,6 @@ X!Earch/i386/kernel/mca.c
|
||||
<chapter id="sysfs">
|
||||
<title>The Filesystem for Exporting Kernel Objects</title>
|
||||
!Efs/sysfs/file.c
|
||||
!Efs/sysfs/dir.c
|
||||
!Efs/sysfs/symlink.c
|
||||
!Efs/sysfs/bin.c
|
||||
</chapter>
|
||||
|
@ -30,7 +30,7 @@ specific hotkey(event))
|
||||
echo "event_num:event_type:event_argument" >
|
||||
/proc/acpi/hotkey/action.
|
||||
The result of the execution of this aml method is
|
||||
attached to /proc/acpi/hotkey/poll_method, which is dnyamically
|
||||
attached to /proc/acpi/hotkey/poll_method, which is dynamically
|
||||
created. Please use command "cat /proc/acpi/hotkey/polling_method"
|
||||
to retrieve it.
|
||||
|
||||
|
@ -127,13 +127,6 @@ Who: Christoph Hellwig <hch@lst.de>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: EXPORT_SYMBOL(lookup_hash)
|
||||
When: January 2006
|
||||
Why: Too low-level interface. Use lookup_one_len or lookup_create instead.
|
||||
Who: Christoph Hellwig <hch@lst.de>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: CONFIG_FORCED_INLINING
|
||||
When: June 2006
|
||||
Why: Config option is there to see if gcc is good enough. (in january
|
||||
@ -241,3 +234,15 @@ Why: The USB subsystem has changed a lot over time, and it has been
|
||||
Who: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: find_trylock_page
|
||||
When: January 2007
|
||||
Why: The interface no longer has any callers left in the kernel. It
|
||||
is an odd interface (compared with other find_*_page functions), in
|
||||
that it does not take a refcount to the page, only the page lock.
|
||||
It should be replaced with find_get_page or find_lock_page if possible.
|
||||
This feature removal can be reevaluated if users of the interface
|
||||
cannot cleanly use something else.
|
||||
Who: Nick Piggin <npiggin@suse.de>
|
||||
|
||||
---------------------------
|
||||
|
@ -1,17 +1,19 @@
|
||||
=================================
|
||||
INTERNAL KERNEL ABI FOR FR-V ARCH
|
||||
=================================
|
||||
=================================
|
||||
INTERNAL KERNEL ABI FOR FR-V ARCH
|
||||
=================================
|
||||
|
||||
The internal FRV kernel ABI is not quite the same as the userspace ABI. A number of the registers
|
||||
are used for special purposed, and the ABI is not consistent between modules vs core, and MMU vs
|
||||
no-MMU.
|
||||
The internal FRV kernel ABI is not quite the same as the userspace ABI. A
|
||||
number of the registers are used for special purposed, and the ABI is not
|
||||
consistent between modules vs core, and MMU vs no-MMU.
|
||||
|
||||
This partly stems from the fact that FRV CPUs do not have a separate supervisor stack pointer, and
|
||||
most of them do not have any scratch registers, thus requiring at least one general purpose
|
||||
register to be clobbered in such an event. Also, within the kernel core, it is possible to simply
|
||||
jump or call directly between functions using a relative offset. This cannot be extended to modules
|
||||
for the displacement is likely to be too far. Thus in modules the address of a function to call
|
||||
must be calculated in a register and then used, requiring two extra instructions.
|
||||
This partly stems from the fact that FRV CPUs do not have a separate
|
||||
supervisor stack pointer, and most of them do not have any scratch
|
||||
registers, thus requiring at least one general purpose register to be
|
||||
clobbered in such an event. Also, within the kernel core, it is possible to
|
||||
simply jump or call directly between functions using a relative offset.
|
||||
This cannot be extended to modules for the displacement is likely to be too
|
||||
far. Thus in modules the address of a function to call must be calculated
|
||||
in a register and then used, requiring two extra instructions.
|
||||
|
||||
This document has the following sections:
|
||||
|
||||
@ -39,7 +41,8 @@ When a system call is made, the following registers are effective:
|
||||
CPU OPERATING MODES
|
||||
===================
|
||||
|
||||
The FR-V CPU has three basic operating modes. In order of increasing capability:
|
||||
The FR-V CPU has three basic operating modes. In order of increasing
|
||||
capability:
|
||||
|
||||
(1) User mode.
|
||||
|
||||
@ -47,42 +50,46 @@ The FR-V CPU has three basic operating modes. In order of increasing capability:
|
||||
|
||||
(2) Kernel mode.
|
||||
|
||||
Normal kernel mode. There are many additional control registers available that may be
|
||||
accessed in this mode, in addition to all the stuff available to user mode. This has two
|
||||
submodes:
|
||||
Normal kernel mode. There are many additional control registers
|
||||
available that may be accessed in this mode, in addition to all the
|
||||
stuff available to user mode. This has two submodes:
|
||||
|
||||
(a) Exceptions enabled (PSR.T == 1).
|
||||
|
||||
Exceptions will invoke the appropriate normal kernel mode handler. On entry to the
|
||||
handler, the PSR.T bit will be cleared.
|
||||
Exceptions will invoke the appropriate normal kernel mode
|
||||
handler. On entry to the handler, the PSR.T bit will be cleared.
|
||||
|
||||
(b) Exceptions disabled (PSR.T == 0).
|
||||
|
||||
No exceptions or interrupts may happen. Any mandatory exceptions will cause the CPU to
|
||||
halt unless the CPU is told to jump into debug mode instead.
|
||||
No exceptions or interrupts may happen. Any mandatory exceptions
|
||||
will cause the CPU to halt unless the CPU is told to jump into
|
||||
debug mode instead.
|
||||
|
||||
(3) Debug mode.
|
||||
|
||||
No exceptions may happen in this mode. Memory protection and management exceptions will be
|
||||
flagged for later consideration, but the exception handler won't be invoked. Debugging traps
|
||||
such as hardware breakpoints and watchpoints will be ignored. This mode is entered only by
|
||||
debugging events obtained from the other two modes.
|
||||
No exceptions may happen in this mode. Memory protection and
|
||||
management exceptions will be flagged for later consideration, but
|
||||
the exception handler won't be invoked. Debugging traps such as
|
||||
hardware breakpoints and watchpoints will be ignored. This mode is
|
||||
entered only by debugging events obtained from the other two modes.
|
||||
|
||||
All kernel mode registers may be accessed, plus a few extra debugging specific registers.
|
||||
All kernel mode registers may be accessed, plus a few extra debugging
|
||||
specific registers.
|
||||
|
||||
|
||||
=================================
|
||||
INTERNAL KERNEL-MODE REGISTER ABI
|
||||
=================================
|
||||
|
||||
There are a number of permanent register assignments that are set up by entry.S in the exception
|
||||
prologue. Note that there is a complete set of exception prologues for each of user->kernel
|
||||
transition and kernel->kernel transition. There are also user->debug and kernel->debug mode
|
||||
transition prologues.
|
||||
There are a number of permanent register assignments that are set up by
|
||||
entry.S in the exception prologue. Note that there is a complete set of
|
||||
exception prologues for each of user->kernel transition and kernel->kernel
|
||||
transition. There are also user->debug and kernel->debug mode transition
|
||||
prologues.
|
||||
|
||||
|
||||
REGISTER FLAVOUR USE
|
||||
=============== ======= ====================================================
|
||||
=============== ======= ==============================================
|
||||
GR1 Supervisor stack pointer
|
||||
GR15 Current thread info pointer
|
||||
GR16 GP-Rel base register for small data
|
||||
@ -92,10 +99,12 @@ transition prologues.
|
||||
GR31 NOMMU Destroyed by debug mode entry
|
||||
GR31 MMU Destroyed by TLB miss kernel mode entry
|
||||
CCR.ICC2 Virtual interrupt disablement tracking
|
||||
CCCR.CC3 Cleared by exception prologue (atomic op emulation)
|
||||
CCCR.CC3 Cleared by exception prologue
|
||||
(atomic op emulation)
|
||||
SCR0 MMU See mmu-layout.txt.
|
||||
SCR1 MMU See mmu-layout.txt.
|
||||
SCR2 MMU Save for EAR0 (destroyed by icache insns in debug mode)
|
||||
SCR2 MMU Save for EAR0 (destroyed by icache insns
|
||||
in debug mode)
|
||||
SCR3 MMU Save for GR31 during debug exceptions
|
||||
DAMR/IAMR NOMMU Fixed memory protection layout.
|
||||
DAMR/IAMR MMU See mmu-layout.txt.
|
||||
@ -104,18 +113,21 @@ transition prologues.
|
||||
Certain registers are also used or modified across function calls:
|
||||
|
||||
REGISTER CALL RETURN
|
||||
=============== =============================== ===============================
|
||||
=============== =============================== ======================
|
||||
GR0 Fixed Zero -
|
||||
GR2 Function call frame pointer
|
||||
GR3 Special Preserved
|
||||
GR3-GR7 - Clobbered
|
||||
GR8 Function call arg #1 Return value (or clobbered)
|
||||
GR9 Function call arg #2 Return value MSW (or clobbered)
|
||||
GR8 Function call arg #1 Return value
|
||||
(or clobbered)
|
||||
GR9 Function call arg #2 Return value MSW
|
||||
(or clobbered)
|
||||
GR10-GR13 Function call arg #3-#6 Clobbered
|
||||
GR14 - Clobbered
|
||||
GR15-GR16 Special Preserved
|
||||
GR17-GR27 - Preserved
|
||||
GR28-GR31 Special Only accessed explicitly
|
||||
GR28-GR31 Special Only accessed
|
||||
explicitly
|
||||
LR Return address after CALL Clobbered
|
||||
CCR/CCCR - Mostly Clobbered
|
||||
|
||||
@ -124,46 +136,53 @@ Certain registers are also used or modified across function calls:
|
||||
INTERNAL DEBUG-MODE REGISTER ABI
|
||||
================================
|
||||
|
||||
This is the same as the kernel-mode register ABI for functions calls. The difference is that in
|
||||
debug-mode there's a different stack and a different exception frame. Almost all the global
|
||||
registers from kernel-mode (including the stack pointer) may be changed.
|
||||
This is the same as the kernel-mode register ABI for functions calls. The
|
||||
difference is that in debug-mode there's a different stack and a different
|
||||
exception frame. Almost all the global registers from kernel-mode
|
||||
(including the stack pointer) may be changed.
|
||||
|
||||
REGISTER FLAVOUR USE
|
||||
=============== ======= ====================================================
|
||||
=============== ======= ==============================================
|
||||
GR1 Debug stack pointer
|
||||
GR16 GP-Rel base register for small data
|
||||
GR31 Current debug exception frame pointer (__debug_frame)
|
||||
GR31 Current debug exception frame pointer
|
||||
(__debug_frame)
|
||||
SCR3 MMU Saved value of GR31
|
||||
|
||||
|
||||
Note that debug mode is able to interfere with the kernel's emulated atomic ops, so it must be
|
||||
exceedingly careful not to do any that would interact with the main kernel in this regard. Hence
|
||||
the debug mode code (gdbstub) is almost completely self-contained. The only external code used is
|
||||
the sprintf family of functions.
|
||||
Note that debug mode is able to interfere with the kernel's emulated atomic
|
||||
ops, so it must be exceedingly careful not to do any that would interact
|
||||
with the main kernel in this regard. Hence the debug mode code (gdbstub) is
|
||||
almost completely self-contained. The only external code used is the
|
||||
sprintf family of functions.
|
||||
|
||||
Futhermore, break.S is so complicated because single-step mode does not switch off on entry to an
|
||||
exception. That means unless manually disabled, single-stepping will blithely go on stepping into
|
||||
things like interrupts. See gdbstub.txt for more information.
|
||||
Futhermore, break.S is so complicated because single-step mode does not
|
||||
switch off on entry to an exception. That means unless manually disabled,
|
||||
single-stepping will blithely go on stepping into things like interrupts.
|
||||
See gdbstub.txt for more information.
|
||||
|
||||
|
||||
==========================
|
||||
VIRTUAL INTERRUPT HANDLING
|
||||
==========================
|
||||
|
||||
Because accesses to the PSR is so slow, and to disable interrupts we have to access it twice (once
|
||||
to read and once to write), we don't actually disable interrupts at all if we don't have to. What
|
||||
we do instead is use the ICC2 condition code flags to note virtual disablement, such that if we
|
||||
then do take an interrupt, we note the flag, really disable interrupts, set another flag and resume
|
||||
execution at the point the interrupt happened. Setting condition flags as a side effect of an
|
||||
arithmetic or logical instruction is really fast. This use of the ICC2 only occurs within the
|
||||
Because accesses to the PSR is so slow, and to disable interrupts we have
|
||||
to access it twice (once to read and once to write), we don't actually
|
||||
disable interrupts at all if we don't have to. What we do instead is use
|
||||
the ICC2 condition code flags to note virtual disablement, such that if we
|
||||
then do take an interrupt, we note the flag, really disable interrupts, set
|
||||
another flag and resume execution at the point the interrupt happened.
|
||||
Setting condition flags as a side effect of an arithmetic or logical
|
||||
instruction is really fast. This use of the ICC2 only occurs within the
|
||||
kernel - it does not affect userspace.
|
||||
|
||||
The flags we use are:
|
||||
|
||||
(*) CCR.ICC2.Z [Zero flag]
|
||||
|
||||
Set to virtually disable interrupts, clear when interrupts are virtually enabled. Can be
|
||||
modified by logical instructions without affecting the Carry flag.
|
||||
Set to virtually disable interrupts, clear when interrupts are
|
||||
virtually enabled. Can be modified by logical instructions without
|
||||
affecting the Carry flag.
|
||||
|
||||
(*) CCR.ICC2.C [Carry flag]
|
||||
|
||||
@ -176,8 +195,9 @@ What happens is this:
|
||||
|
||||
ICC2.Z is 0, ICC2.C is 1.
|
||||
|
||||
(2) An interrupt occurs. The exception prologue examines ICC2.Z and determines that nothing needs
|
||||
doing. This is done simply with an unlikely BEQ instruction.
|
||||
(2) An interrupt occurs. The exception prologue examines ICC2.Z and
|
||||
determines that nothing needs doing. This is done simply with an
|
||||
unlikely BEQ instruction.
|
||||
|
||||
(3) The interrupts are disabled (local_irq_disable)
|
||||
|
||||
@ -187,48 +207,56 @@ What happens is this:
|
||||
|
||||
ICC2.Z would be set to 0.
|
||||
|
||||
A TIHI #2 instruction (trap #2 if condition HI - Z==0 && C==0) would be used to trap if
|
||||
interrupts were now virtually enabled, but physically disabled - which they're not, so the
|
||||
trap isn't taken. The kernel would then be back to state (1).
|
||||
A TIHI #2 instruction (trap #2 if condition HI - Z==0 && C==0) would
|
||||
be used to trap if interrupts were now virtually enabled, but
|
||||
physically disabled - which they're not, so the trap isn't taken. The
|
||||
kernel would then be back to state (1).
|
||||
|
||||
(5) An interrupt occurs. The exception prologue examines ICC2.Z and determines that the interrupt
|
||||
shouldn't actually have happened. It jumps aside, and there disabled interrupts by setting
|
||||
PSR.PIL to 14 and then it clears ICC2.C.
|
||||
(5) An interrupt occurs. The exception prologue examines ICC2.Z and
|
||||
determines that the interrupt shouldn't actually have happened. It
|
||||
jumps aside, and there disabled interrupts by setting PSR.PIL to 14
|
||||
and then it clears ICC2.C.
|
||||
|
||||
(6) If interrupts were then saved and disabled again (local_irq_save):
|
||||
|
||||
ICC2.Z would be shifted into the save variable and masked off (giving a 1).
|
||||
ICC2.Z would be shifted into the save variable and masked off
|
||||
(giving a 1).
|
||||
|
||||
ICC2.Z would then be set to 1 (thus unchanged), and ICC2.C would be unaffected (ie: 0).
|
||||
ICC2.Z would then be set to 1 (thus unchanged), and ICC2.C would be
|
||||
unaffected (ie: 0).
|
||||
|
||||
(7) If interrupts were then restored from state (6) (local_irq_restore):
|
||||
|
||||
ICC2.Z would be set to indicate the result of XOR'ing the saved value (ie: 1) with 1, which
|
||||
gives a result of 0 - thus leaving ICC2.Z set.
|
||||
ICC2.Z would be set to indicate the result of XOR'ing the saved
|
||||
value (ie: 1) with 1, which gives a result of 0 - thus leaving
|
||||
ICC2.Z set.
|
||||
|
||||
ICC2.C would remain unaffected (ie: 0).
|
||||
|
||||
A TIHI #2 instruction would be used to again assay the current state, but this would do
|
||||
nothing as Z==1.
|
||||
A TIHI #2 instruction would be used to again assay the current state,
|
||||
but this would do nothing as Z==1.
|
||||
|
||||
(8) If interrupts were then enabled (local_irq_enable):
|
||||
|
||||
ICC2.Z would be cleared. ICC2.C would be left unaffected. Both flags would now be 0.
|
||||
ICC2.Z would be cleared. ICC2.C would be left unaffected. Both
|
||||
flags would now be 0.
|
||||
|
||||
A TIHI #2 instruction again issued to assay the current state would then trap as both Z==0
|
||||
[interrupts virtually enabled] and C==0 [interrupts really disabled] would then be true.
|
||||
A TIHI #2 instruction again issued to assay the current state would
|
||||
then trap as both Z==0 [interrupts virtually enabled] and C==0
|
||||
[interrupts really disabled] would then be true.
|
||||
|
||||
(9) The trap #2 handler would simply enable hardware interrupts (set PSR.PIL to 0), set ICC2.C to
|
||||
1 and return.
|
||||
(9) The trap #2 handler would simply enable hardware interrupts
|
||||
(set PSR.PIL to 0), set ICC2.C to 1 and return.
|
||||
|
||||
(10) Immediately upon returning, the pending interrupt would be taken.
|
||||
|
||||
(11) The interrupt handler would take the path of actually processing the interrupt (ICC2.Z is
|
||||
clear, BEQ fails as per step (2)).
|
||||
(11) The interrupt handler would take the path of actually processing the
|
||||
interrupt (ICC2.Z is clear, BEQ fails as per step (2)).
|
||||
|
||||
(12) The interrupt handler would then set ICC2.C to 1 since hardware interrupts are definitely
|
||||
enabled - or else the kernel wouldn't be here.
|
||||
(12) The interrupt handler would then set ICC2.C to 1 since hardware
|
||||
interrupts are definitely enabled - or else the kernel wouldn't be here.
|
||||
|
||||
(13) On return from the interrupt handler, things would be back to state (1).
|
||||
|
||||
This trap (#2) is only available in kernel mode. In user mode it will result in SIGILL.
|
||||
This trap (#2) is only available in kernel mode. In user mode it will
|
||||
result in SIGILL.
|
||||
|
@ -36,12 +36,12 @@ with them.
|
||||
|
||||
All NES and SNES use the same synchronous serial protocol, clocked from
|
||||
the computer's side (and thus timing insensitive). To allow up to 5 NES
|
||||
and/or SNES gamepads connected to the parallel port at once, the output
|
||||
lines of the parallel port are shared, while one of 5 available input lines
|
||||
is assigned to each gamepad.
|
||||
and/or SNES gamepads and/or SNES mice connected to the parallel port at once,
|
||||
the output lines of the parallel port are shared, while one of 5 available
|
||||
input lines is assigned to each gamepad.
|
||||
|
||||
This protocol is handled by the gamecon.c driver, so that's the one
|
||||
you'll use for NES and SNES gamepads.
|
||||
you'll use for NES, SNES gamepads and SNES mice.
|
||||
|
||||
The main problem with PC parallel ports is that they don't have +5V power
|
||||
source on any of their pins. So, if you want a reliable source of power
|
||||
@ -106,7 +106,7 @@ A, Turbo B, Select and Start, and is connected through 5 wires, then it is
|
||||
either a NES or NES clone and will work with this connection. SNES gamepads
|
||||
also use 5 wires, but have more buttons. They will work as well, of course.
|
||||
|
||||
Pinout for NES gamepads Pinout for SNES gamepads
|
||||
Pinout for NES gamepads Pinout for SNES gamepads and mice
|
||||
|
||||
+----> Power +-----------------------\
|
||||
| 7 | o o o o | x x o | 1
|
||||
@ -454,6 +454,7 @@ uses the following kernel/module command line:
|
||||
6 | N64 pad
|
||||
7 | Sony PSX controller
|
||||
8 | Sony PSX DDR controller
|
||||
9 | SNES mouse
|
||||
|
||||
The exact type of the PSX controller type is autoprobed when used so
|
||||
hot swapping should work (but is not recomended).
|
||||
|
@ -1,4 +1,4 @@
|
||||
February 2003 Kernel Parameters v2.5.59
|
||||
Kernel Parameters
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
The following is a consolidated list of the kernel parameters as implemented
|
||||
@ -17,9 +17,17 @@ are specified on the kernel command line with the module name plus
|
||||
|
||||
usbcore.blinkenlights=1
|
||||
|
||||
The text in square brackets at the beginning of the description states the
|
||||
restrictions on the kernel for the said kernel parameter to be valid. The
|
||||
restrictions referred to are that the relevant option is valid if:
|
||||
This document may not be entirely up to date and comprehensive. The command
|
||||
"modinfo -p ${modulename}" shows a current list of all parameters of a loadable
|
||||
module. Loadable modules, after being loaded into the running kernel, also
|
||||
reveal their parameters in /sys/module/${modulename}/parameters/. Some of these
|
||||
parameters may be changed at runtime by the command
|
||||
"echo -n ${value} > /sys/module/${modulename}/parameters/${parm}".
|
||||
|
||||
The parameters listed below are only valid if certain kernel build options were
|
||||
enabled and if respective hardware is present. The text in square brackets at
|
||||
the beginning of each description states the restrictions within which a
|
||||
parameter is applicable:
|
||||
|
||||
ACPI ACPI support is enabled.
|
||||
ALSA ALSA sound support is enabled.
|
||||
@ -1046,10 +1054,10 @@ running once the system is up.
|
||||
noltlbs [PPC] Do not use large page/tlb entries for kernel
|
||||
lowmem mapping on PPC40x.
|
||||
|
||||
nomce [IA-32] Machine Check Exception
|
||||
|
||||
nomca [IA-64] Disable machine check abort handling
|
||||
|
||||
nomce [IA-32] Machine Check Exception
|
||||
|
||||
noresidual [PPC] Don't use residual data on PReP machines.
|
||||
|
||||
noresume [SWSUSP] Disables resume and restores original swap
|
||||
@ -1682,20 +1690,6 @@ running once the system is up.
|
||||
|
||||
|
||||
______________________________________________________________________
|
||||
Changelog:
|
||||
|
||||
2000-06-?? Mr. Unknown
|
||||
The last known update (for 2.4.0) - the changelog was not kept before.
|
||||
|
||||
2002-11-24 Petr Baudis <pasky@ucw.cz>
|
||||
Randy Dunlap <randy.dunlap@verizon.net>
|
||||
Update for 2.5.49, description for most of the options introduced,
|
||||
references to other documentation (C files, READMEs, ..), added S390,
|
||||
PPC, SPARC, MTD, ALSA and OSS category. Minor corrections and
|
||||
reformatting.
|
||||
|
||||
2005-10-19 Randy Dunlap <rdunlap@xenotime.net>
|
||||
Lots of typos, whitespace, some reformatting.
|
||||
|
||||
TODO:
|
||||
|
||||
|
71
Documentation/leds-class.txt
Normal file
71
Documentation/leds-class.txt
Normal file
@ -0,0 +1,71 @@
|
||||
LED handling under Linux
|
||||
========================
|
||||
|
||||
If you're reading this and thinking about keyboard leds, these are
|
||||
handled by the input subsystem and the led class is *not* needed.
|
||||
|
||||
In its simplest form, the LED class just allows control of LEDs from
|
||||
userspace. LEDs appear in /sys/class/leds/. The brightness file will
|
||||
set the brightness of the LED (taking a value 0-255). Most LEDs don't
|
||||
have hardware brightness support so will just be turned on for non-zero
|
||||
brightness settings.
|
||||
|
||||
The class also introduces the optional concept of an LED trigger. A trigger
|
||||
is a kernel based source of led events. Triggers can either be simple or
|
||||
complex. A simple trigger isn't configurable and is designed to slot into
|
||||
existing subsystems with minimal additional code. Examples are the ide-disk,
|
||||
nand-disk and sharpsl-charge triggers. With led triggers disabled, the code
|
||||
optimises away.
|
||||
|
||||
Complex triggers whilst available to all LEDs have LED specific
|
||||
parameters and work on a per LED basis. The timer trigger is an example.
|
||||
|
||||
You can change triggers in a similar manner to the way an IO scheduler
|
||||
is chosen (via /sys/class/leds/<device>/trigger). Trigger specific
|
||||
parameters can appear in /sys/class/leds/<device> once a given trigger is
|
||||
selected.
|
||||
|
||||
|
||||
Design Philosophy
|
||||
=================
|
||||
|
||||
The underlying design philosophy is simplicity. LEDs are simple devices
|
||||
and the aim is to keep a small amount of code giving as much functionality
|
||||
as possible. Please keep this in mind when suggesting enhancements.
|
||||
|
||||
|
||||
LED Device Naming
|
||||
=================
|
||||
|
||||
Is currently of the form:
|
||||
|
||||
"devicename:colour"
|
||||
|
||||
There have been calls for LED properties such as colour to be exported as
|
||||
individual led class attributes. As a solution which doesn't incur as much
|
||||
overhead, I suggest these become part of the device name. The naming scheme
|
||||
above leaves scope for further attributes should they be needed.
|
||||
|
||||
|
||||
Known Issues
|
||||
============
|
||||
|
||||
The LED Trigger core cannot be a module as the simple trigger functions
|
||||
would cause nightmare dependency issues. I see this as a minor issue
|
||||
compared to the benefits the simple trigger functionality brings. The
|
||||
rest of the LED subsystem can be modular.
|
||||
|
||||
Some leds can be programmed to flash in hardware. As this isn't a generic
|
||||
LED device property, this should be exported as a device specific sysfs
|
||||
attribute rather than part of the class if this functionality is required.
|
||||
|
||||
|
||||
Future Development
|
||||
==================
|
||||
|
||||
At the moment, a trigger can't be created specifically for a single LED.
|
||||
There are a number of cases where a trigger might only be mappable to a
|
||||
particular LED (ACPI?). The addition of triggers provided by the LED driver
|
||||
should cover this option and be possible to add without breaking the
|
||||
current interface.
|
||||
|
1913
Documentation/memory-barriers.txt
Normal file
1913
Documentation/memory-barriers.txt
Normal file
File diff suppressed because it is too large
Load Diff
@ -254,7 +254,7 @@ and, the number of frames be
|
||||
|
||||
<block number> * <block size> / <frame size>
|
||||
|
||||
Suposse the following parameters, which apply for 2.6 kernel and an
|
||||
Suppose the following parameters, which apply for 2.6 kernel and an
|
||||
i386 architecture:
|
||||
|
||||
<size-max> = 131072 bytes
|
||||
|
@ -138,7 +138,7 @@ This means that you have to read/write IP packets when you are using tun and
|
||||
ethernet frames when using tap.
|
||||
|
||||
5. What is the difference between BPF and TUN/TAP driver?
|
||||
BFP is an advanced packet filter. It can be attached to existing
|
||||
BPF is an advanced packet filter. It can be attached to existing
|
||||
network interface. It does not provide a virtual network interface.
|
||||
A TUN/TAP driver does provide a virtual network interface and it is possible
|
||||
to attach BPF to this interface.
|
||||
|
@ -1,5 +1,11 @@
|
||||
This file details changes in 2.6 which affect PCMCIA card driver authors:
|
||||
|
||||
* New release helper (as of 2.6.17)
|
||||
Instead of calling pcmcia_release_{configuration,io,irq,win}, all that's
|
||||
necessary now is calling pcmcia_disable_device. As there is no valid
|
||||
reason left to call pcmcia_release_io and pcmcia_release_irq, the
|
||||
exports for them were removed.
|
||||
|
||||
* Unify detach and REMOVAL event code, as well as attach and INSERTION
|
||||
code (as of 2.6.16)
|
||||
void (*remove) (struct pcmcia_device *dev);
|
||||
|
@ -120,6 +120,34 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||
enable - enable card
|
||||
- Default: enabled, for PCI and ISA PnP cards
|
||||
|
||||
Module snd-adlib
|
||||
----------------
|
||||
|
||||
Module for AdLib FM cards.
|
||||
|
||||
port - port # for OPL chip
|
||||
|
||||
This module supports multiple cards. It does not support autoprobe, so
|
||||
the port must be specified. For actual AdLib FM cards it will be 0x388.
|
||||
Note that this card does not have PCM support and no mixer; only FM
|
||||
synthesis.
|
||||
|
||||
Make sure you have "sbiload" from the alsa-tools package available and,
|
||||
after loading the module, find out the assigned ALSA sequencer port
|
||||
number through "sbiload -l". Example output:
|
||||
|
||||
Port Client name Port name
|
||||
64:0 OPL2 FM synth OPL2 FM Port
|
||||
|
||||
Load the std.sb and drums.sb patches also supplied by sbiload:
|
||||
|
||||
sbiload -p 64:0 std.sb drums.sb
|
||||
|
||||
If you use this driver to drive an OPL3, you can use std.o3 and drums.o3
|
||||
instead. To have the card produce sound, use aplaymidi from alsa-utils:
|
||||
|
||||
aplaymidi -p 64:0 foo.mid
|
||||
|
||||
Module snd-ad1816a
|
||||
------------------
|
||||
|
||||
@ -190,6 +218,15 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||
|
||||
The power-management is supported.
|
||||
|
||||
Module snd-als300
|
||||
-----------------
|
||||
|
||||
Module for Avance Logic ALS300 and ALS300+
|
||||
|
||||
This module supports multiple cards.
|
||||
|
||||
The power-management is supported.
|
||||
|
||||
Module snd-als4000
|
||||
------------------
|
||||
|
||||
@ -701,6 +738,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||
uniwill 3-jack
|
||||
F1734 2-jack
|
||||
lg LG laptop (m1 express dual)
|
||||
lg-lw LG LW20 laptop
|
||||
test for testing/debugging purpose, almost all controls can be
|
||||
adjusted. Appearing only when compiled with
|
||||
$CONFIG_SND_DEBUG=y
|
||||
@ -1013,6 +1051,23 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||
|
||||
The power-management is supported.
|
||||
|
||||
Module snd-miro
|
||||
---------------
|
||||
|
||||
Module for Miro soundcards: miroSOUND PCM 1 pro,
|
||||
miroSOUND PCM 12,
|
||||
miroSOUND PCM 20 Radio.
|
||||
|
||||
port - Port # (0x530,0x604,0xe80,0xf40)
|
||||
irq - IRQ # (5,7,9,10,11)
|
||||
dma1 - 1st dma # (0,1,3)
|
||||
dma2 - 2nd dma # (0,1)
|
||||
mpu_port - MPU-401 port # (0x300,0x310,0x320,0x330)
|
||||
mpu_irq - MPU-401 irq # (5,7,9,10)
|
||||
fm_port - FM Port # (0x388)
|
||||
wss - enable WSS mode
|
||||
ide - enable onboard ide support
|
||||
|
||||
Module snd-mixart
|
||||
-----------------
|
||||
|
||||
@ -1202,6 +1257,20 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||
|
||||
The power-management is supported.
|
||||
|
||||
Module snd-riptide
|
||||
------------------
|
||||
|
||||
Module for Conexant Riptide chip
|
||||
|
||||
joystick_port - Joystick port # (default: 0x200)
|
||||
mpu_port - MPU401 port # (default: 0x330)
|
||||
opl3_port - OPL3 port # (default: 0x388)
|
||||
|
||||
This module supports multiple cards.
|
||||
The driver requires the firmware loader support on kernel.
|
||||
You need to install the firmware file "riptide.hex" to the standard
|
||||
firmware path (e.g. /lib/firmware).
|
||||
|
||||
Module snd-rme32
|
||||
----------------
|
||||
|
||||
|
@ -52,7 +52,7 @@
|
||||
51 -> ProVideo PV952 [1540:9524]
|
||||
52 -> AverMedia AverTV/305 [1461:2108]
|
||||
53 -> ASUS TV-FM 7135 [1043:4845]
|
||||
54 -> LifeView FlyTV Platinum FM [5168:0214,1489:0214]
|
||||
54 -> LifeView FlyTV Platinum FM / Gold [5168:0214,1489:0214,5168:0304]
|
||||
55 -> LifeView FlyDVB-T DUO [5168:0306]
|
||||
56 -> Avermedia AVerTV 307 [1461:a70a]
|
||||
57 -> Avermedia AVerTV GO 007 FM [1461:f31f]
|
||||
@ -84,7 +84,7 @@
|
||||
83 -> Terratec Cinergy 250 PCI TV [153b:1160]
|
||||
84 -> LifeView FlyDVB Trio [5168:0319]
|
||||
85 -> AverTV DVB-T 777 [1461:2c05]
|
||||
86 -> LifeView FlyDVB-T [5168:0301]
|
||||
86 -> LifeView FlyDVB-T / Genius VideoWonder DVB-T [5168:0301,1489:0301]
|
||||
87 -> ADS Instant TV Duo Cardbus PTV331 [0331:1421]
|
||||
88 -> Tevion/KWorld DVB-T 220RF [17de:7201]
|
||||
89 -> ELSA EX-VISION 700TV [1048:226c]
|
||||
@ -92,3 +92,4 @@
|
||||
91 -> AVerMedia A169 B [1461:7360]
|
||||
92 -> AVerMedia A169 B1 [1461:6360]
|
||||
93 -> Medion 7134 Bridge #2 [16be:0005]
|
||||
94 -> LifeView FlyDVB-T Hybrid Cardbus [5168:3306,5168:3502]
|
||||
|
@ -122,7 +122,7 @@ WHAT YOU NEED:
|
||||
- A Linux box with USB support (2.3/2.4; 2.2 w/backport may work)
|
||||
|
||||
- A Video4Linux compatible frame grabber program such as xawtv.
|
||||
|
||||
|
||||
HOW TO COMPILE THE DRIVER:
|
||||
|
||||
You need to compile the driver only if you are a developer
|
@ -9,7 +9,7 @@ INTRODUCTION:
|
||||
|
||||
This is a driver for the OV511, a USB-only chip used in many "webcam" devices.
|
||||
Any camera using the OV511/OV511+ and the OV6620/OV7610/20/20AE should work.
|
||||
Video capture devices that use the Philips SAA7111A decoder also work. It
|
||||
Video capture devices that use the Philips SAA7111A decoder also work. It
|
||||
supports streaming and capture of color or monochrome video via the Video4Linux
|
||||
API. Most V4L apps are compatible with it. Most resolutions with a width and
|
||||
height that are a multiple of 8 are supported.
|
||||
@ -52,15 +52,15 @@ from it:
|
||||
|
||||
chmod 666 /dev/video
|
||||
chmod 666 /dev/video0 (if necessary)
|
||||
|
||||
|
||||
Now you are ready to run a video app! Both vidcat and xawtv work well for me
|
||||
at 640x480.
|
||||
|
||||
|
||||
[Using vidcat:]
|
||||
|
||||
vidcat -s 640x480 -p c > test.jpg
|
||||
xview test.jpg
|
||||
|
||||
|
||||
[Using xawtv:]
|
||||
|
||||
From the main xawtv directory:
|
||||
@ -70,7 +70,7 @@ From the main xawtv directory:
|
||||
make
|
||||
make install
|
||||
|
||||
Now you should be able to run xawtv. Right click for the options dialog.
|
||||
Now you should be able to run xawtv. Right click for the options dialog.
|
||||
|
||||
MODULE PARAMETERS:
|
||||
|
||||
@ -286,4 +286,3 @@ Randy Dunlap, and others. Big thanks to them for their pioneering work on that
|
||||
and the USB stack. Thanks to Bret Wallach for getting camera reg IO, ISOC, and
|
||||
image capture working. Thanks to Orion Sky Lawlor, Kevin Moore, and Claudio
|
||||
Matsuoka for their work as well.
|
||||
|
@ -174,7 +174,7 @@ Module parameters are listed below:
|
||||
-------------------------------------------------------------------------------
|
||||
Name: video_nr
|
||||
Type: short array (min = 0, max = 64)
|
||||
Syntax: <-1|n[,...]>
|
||||
Syntax: <-1|n[,...]>
|
||||
Description: Specify V4L2 minor mode number:
|
||||
-1 = use next available
|
||||
n = use minor number n
|
||||
@ -187,7 +187,7 @@ Default: -1
|
||||
-------------------------------------------------------------------------------
|
||||
Name: force_munmap
|
||||
Type: bool array (min = 0, max = 64)
|
||||
Syntax: <0|1[,...]>
|
||||
Syntax: <0|1[,...]>
|
||||
Description: Force the application to unmap previously mapped buffer memory
|
||||
before calling any VIDIOC_S_CROP or VIDIOC_S_FMT ioctl's. Not
|
||||
all the applications support this feature. This parameter is
|
||||
@ -206,7 +206,7 @@ Default: 2
|
||||
-------------------------------------------------------------------------------
|
||||
Name: debug
|
||||
Type: ushort
|
||||
Syntax: <n>
|
||||
Syntax: <n>
|
||||
Description: Debugging information level, from 0 to 3:
|
||||
0 = none (use carefully)
|
||||
1 = critical errors
|
||||
@ -267,7 +267,7 @@ The sysfs interface also provides the "frame_header" entry, which exports the
|
||||
frame header of the most recent requested and captured video frame. The header
|
||||
is always 18-bytes long and is appended to every video frame by the SN9C10x
|
||||
controllers. As an example, this additional information can be used by the user
|
||||
application for implementing auto-exposure features via software.
|
||||
application for implementing auto-exposure features via software.
|
||||
|
||||
The following table describes the frame header:
|
||||
|
||||
@ -441,7 +441,7 @@ blue pixels in one video frame. Each pixel is associated with a 8-bit long
|
||||
value and is disposed in memory according to the pattern shown below:
|
||||
|
||||
B[0] G[1] B[2] G[3] ... B[m-2] G[m-1]
|
||||
G[m] R[m+1] G[m+2] R[m+2] ... G[2m-2] R[2m-1]
|
||||
G[m] R[m+1] G[m+2] R[m+2] ... G[2m-2] R[2m-1]
|
||||
...
|
||||
... B[(n-1)(m-2)] G[(n-1)(m-1)]
|
||||
... G[n(m-2)] R[n(m-1)]
|
||||
@ -472,12 +472,12 @@ The pixel reference value is calculated as follows:
|
||||
The algorithm purely describes the conversion from compressed Bayer code used
|
||||
in the SN9C10x chips to uncompressed Bayer. Additional steps are required to
|
||||
convert this to a color image (i.e. a color interpolation algorithm).
|
||||
|
||||
|
||||
The following Huffman codes have been found:
|
||||
0: +0 (relative to reference pixel value)
|
||||
0: +0 (relative to reference pixel value)
|
||||
100: +4
|
||||
101: -4?
|
||||
1110xxxx: set absolute value to xxxx.0000
|
||||
1110xxxx: set absolute value to xxxx.0000
|
||||
1101: +11
|
||||
1111: -11
|
||||
11001: +20
|
@ -5,15 +5,15 @@ Copyright, 2001, Kevin Sisson
|
||||
|
||||
INTRODUCTION:
|
||||
|
||||
STMicroelectronics produces the STV0680B chip, which comes in two
|
||||
types, -001 and -003. The -003 version allows the recording and downloading
|
||||
of sound clips from the camera, and allows a flash attachment. Otherwise,
|
||||
it uses the same commands as the -001 version. Both versions support a
|
||||
variety of SDRAM sizes and sensors, allowing for a maximum of 26 VGA or 20
|
||||
CIF pictures. The STV0680 supports either a serial or a usb interface, and
|
||||
STMicroelectronics produces the STV0680B chip, which comes in two
|
||||
types, -001 and -003. The -003 version allows the recording and downloading
|
||||
of sound clips from the camera, and allows a flash attachment. Otherwise,
|
||||
it uses the same commands as the -001 version. Both versions support a
|
||||
variety of SDRAM sizes and sensors, allowing for a maximum of 26 VGA or 20
|
||||
CIF pictures. The STV0680 supports either a serial or a usb interface, and
|
||||
video is possible through the usb interface.
|
||||
|
||||
The following cameras are known to work with this driver, although any
|
||||
The following cameras are known to work with this driver, although any
|
||||
camera with Vendor/Product codes of 0553/0202 should work:
|
||||
|
||||
Aiptek Pencam (various models)
|
||||
@ -34,15 +34,15 @@ http://www.linux-usb.org
|
||||
MODULE OPTIONS:
|
||||
|
||||
When the driver is compiled as a module, you can set a "swapRGB=1"
|
||||
option, if necessary, for those applications that require it
|
||||
(such as xawtv). However, the driver should detect and set this
|
||||
option, if necessary, for those applications that require it
|
||||
(such as xawtv). However, the driver should detect and set this
|
||||
automatically, so this option should not normally be used.
|
||||
|
||||
|
||||
KNOWN PROBLEMS:
|
||||
|
||||
The driver seems to work better with the usb-ohci than the usb-uhci host
|
||||
controller driver.
|
||||
The driver seems to work better with the usb-ohci than the usb-uhci host
|
||||
controller driver.
|
||||
|
||||
HELP:
|
||||
|
||||
@ -50,6 +50,4 @@ The latest info on this driver can be found at:
|
||||
http://personal.clt.bellsouth.net/~kjsisson or at
|
||||
http://stv0680-usb.sourceforge.net
|
||||
|
||||
Any questions to me can be send to: kjsisson@bellsouth.net
|
||||
|
||||
|
||||
Any questions to me can be send to: kjsisson@bellsouth.net
|
@ -1,5 +1,5 @@
|
||||
|
||||
W996[87]CF JPEG USB Dual Mode Camera Chip
|
||||
W996[87]CF JPEG USB Dual Mode Camera Chip
|
||||
Driver for Linux 2.6 (basic version)
|
||||
=========================================
|
||||
|
||||
@ -115,7 +115,7 @@ additional testing and full support, would be much appreciated.
|
||||
======================
|
||||
For it to work properly, the driver needs kernel support for Video4Linux, USB
|
||||
and I2C, and the "ovcamchip" module for the image sensor. Make sure you are not
|
||||
actually using any external "ovcamchip" module, given that the W996[87]CF
|
||||
actually using any external "ovcamchip" module, given that the W996[87]CF
|
||||
driver depends on the version of the module present in the official kernels.
|
||||
|
||||
The following options of the kernel configuration file must be enabled and
|
||||
@ -197,16 +197,16 @@ Note: The kernel must be compiled with the CONFIG_KMOD option
|
||||
enabled for the 'ovcamchip' module to be loaded and for
|
||||
this parameter to be present.
|
||||
-------------------------------------------------------------------------------
|
||||
Name: simcams
|
||||
Type: int
|
||||
Syntax: <n>
|
||||
Name: simcams
|
||||
Type: int
|
||||
Syntax: <n>
|
||||
Description: Number of cameras allowed to stream simultaneously.
|
||||
n may vary from 0 to 32.
|
||||
Default: 32
|
||||
-------------------------------------------------------------------------------
|
||||
Name: video_nr
|
||||
Type: int array (min = 0, max = 32)
|
||||
Syntax: <-1|n[,...]>
|
||||
Syntax: <-1|n[,...]>
|
||||
Description: Specify V4L minor mode number.
|
||||
-1 = use next available
|
||||
n = use minor number n
|
||||
@ -219,7 +219,7 @@ Default: -1
|
||||
-------------------------------------------------------------------------------
|
||||
Name: packet_size
|
||||
Type: int array (min = 0, max = 32)
|
||||
Syntax: <n[,...]>
|
||||
Syntax: <n[,...]>
|
||||
Description: Specify the maximum data payload size in bytes for alternate
|
||||
settings, for each device. n is scaled between 63 and 1023.
|
||||
Default: 1023
|
||||
@ -234,7 +234,7 @@ Default: 2
|
||||
-------------------------------------------------------------------------------
|
||||
Name: double_buffer
|
||||
Type: bool array (min = 0, max = 32)
|
||||
Syntax: <0|1[,...]>
|
||||
Syntax: <0|1[,...]>
|
||||
Description: Hardware double buffering: 0 disabled, 1 enabled.
|
||||
It should be enabled if you want smooth video output: if you
|
||||
obtain out of sync. video, disable it, or try to
|
||||
@ -243,13 +243,13 @@ Default: 1 for every device.
|
||||
-------------------------------------------------------------------------------
|
||||
Name: clamping
|
||||
Type: bool array (min = 0, max = 32)
|
||||
Syntax: <0|1[,...]>
|
||||
Syntax: <0|1[,...]>
|
||||
Description: Video data clamping: 0 disabled, 1 enabled.
|
||||
Default: 0 for every device.
|
||||
-------------------------------------------------------------------------------
|
||||
Name: filter_type
|
||||
Type: int array (min = 0, max = 32)
|
||||
Syntax: <0|1|2[,...]>
|
||||
Syntax: <0|1|2[,...]>
|
||||
Description: Video filter type.
|
||||
0 none, 1 (1-2-1) 3-tap filter, 2 (2-3-6-3-2) 5-tap filter.
|
||||
The filter is used to reduce noise and aliasing artifacts
|
||||
@ -258,13 +258,13 @@ Default: 0 for every device.
|
||||
-------------------------------------------------------------------------------
|
||||
Name: largeview
|
||||
Type: bool array (min = 0, max = 32)
|
||||
Syntax: <0|1[,...]>
|
||||
Syntax: <0|1[,...]>
|
||||
Description: Large view: 0 disabled, 1 enabled.
|
||||
Default: 1 for every device.
|
||||
-------------------------------------------------------------------------------
|
||||
Name: upscaling
|
||||
Type: bool array (min = 0, max = 32)
|
||||
Syntax: <0|1[,...]>
|
||||
Syntax: <0|1[,...]>
|
||||
Description: Software scaling (for non-compressed video only):
|
||||
0 disabled, 1 enabled.
|
||||
Disable it if you have a slow CPU or you don't have enough
|
||||
@ -341,8 +341,8 @@ Default: 50 for every device.
|
||||
-------------------------------------------------------------------------------
|
||||
Name: bandingfilter
|
||||
Type: bool array (min = 0, max = 32)
|
||||
Syntax: <0|1[,...]>
|
||||
Description: Banding filter to reduce effects of fluorescent
|
||||
Syntax: <0|1[,...]>
|
||||
Description: Banding filter to reduce effects of fluorescent
|
||||
lighting:
|
||||
0 disabled, 1 enabled.
|
||||
This filter tries to reduce the pattern of horizontal
|
||||
@ -374,7 +374,7 @@ Default: 0 for every device.
|
||||
-------------------------------------------------------------------------------
|
||||
Name: monochrome
|
||||
Type: bool array (min = 0, max = 32)
|
||||
Syntax: <0|1[,...]>
|
||||
Syntax: <0|1[,...]>
|
||||
Description: The image sensor is monochrome:
|
||||
0 = no, 1 = yes
|
||||
Default: 0 for every device.
|
||||
@ -400,19 +400,19 @@ Default: 32768 for every device.
|
||||
-------------------------------------------------------------------------------
|
||||
Name: contrast
|
||||
Type: long array (min = 0, max = 32)
|
||||
Syntax: <n[,...]>
|
||||
Syntax: <n[,...]>
|
||||
Description: Set picture contrast (0-65535).
|
||||
Default: 50000 for every device.
|
||||
-------------------------------------------------------------------------------
|
||||
Name: whiteness
|
||||
Type: long array (min = 0, max = 32)
|
||||
Syntax: <n[,...]>
|
||||
Syntax: <n[,...]>
|
||||
Description: Set picture whiteness (0-65535).
|
||||
Default: 32768 for every device.
|
||||
-------------------------------------------------------------------------------
|
||||
Name: debug
|
||||
Type: int
|
||||
Syntax: <n>
|
||||
Syntax: <n>
|
||||
Description: Debugging information level, from 0 to 6:
|
||||
0 = none (use carefully)
|
||||
1 = critical errors
|
@ -1451,6 +1451,12 @@ P: Juanjo Ciarlante
|
||||
M: jjciarla@raiz.uncu.edu.ar
|
||||
S: Maintained
|
||||
|
||||
IPATH DRIVER:
|
||||
P: Bryan O'Sullivan
|
||||
M: support@pathscale.com
|
||||
L: openib-general@openib.org
|
||||
S: Supported
|
||||
|
||||
IPX NETWORK LAYER
|
||||
P: Arnaldo Carvalho de Melo
|
||||
M: acme@conectiva.com.br
|
||||
|
4
Makefile
4
Makefile
@ -1,7 +1,7 @@
|
||||
VERSION = 2
|
||||
PATCHLEVEL = 6
|
||||
SUBLEVEL = 16
|
||||
EXTRAVERSION =
|
||||
SUBLEVEL = 17
|
||||
EXTRAVERSION =-rc1
|
||||
NAME=Sliding Snow Leopard
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
@ -216,8 +216,6 @@ EXPORT_SYMBOL(memcpy);
|
||||
EXPORT_SYMBOL(memset);
|
||||
EXPORT_SYMBOL(memchr);
|
||||
|
||||
EXPORT_SYMBOL(get_wchan);
|
||||
|
||||
#ifdef CONFIG_ALPHA_IRONGATE
|
||||
EXPORT_SYMBOL(irongate_ioremap);
|
||||
EXPORT_SYMBOL(irongate_iounmap);
|
||||
|
@ -435,7 +435,7 @@ marvel_specify_io7(char *str)
|
||||
str = pchar;
|
||||
} while(*str);
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
__setup("io7=", marvel_specify_io7);
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/seq_file.h>
|
||||
@ -1478,3 +1479,20 @@ alpha_panic_event(struct notifier_block *this, unsigned long event, void *ptr)
|
||||
#endif
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static __init int add_pcspkr(void)
|
||||
{
|
||||
struct platform_device *pd;
|
||||
int ret;
|
||||
|
||||
pd = platform_device_alloc("pcspkr", -1);
|
||||
if (!pd)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = platform_device_add(pd);
|
||||
if (ret)
|
||||
platform_device_put(pd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
device_initcall(add_pcspkr);
|
||||
|
@ -77,6 +77,14 @@ config FIQ
|
||||
config ARCH_MTD_XIP
|
||||
bool
|
||||
|
||||
config VECTORS_BASE
|
||||
hex
|
||||
default 0xffff0000 if MMU
|
||||
default DRAM_BASE if REMAP_VECTORS_TO_RAM
|
||||
default 0x00000000
|
||||
help
|
||||
The base address of exception vectors.
|
||||
|
||||
source "init/Kconfig"
|
||||
|
||||
menu "System Type"
|
||||
@ -839,6 +847,8 @@ source "drivers/misc/Kconfig"
|
||||
|
||||
source "drivers/mfd/Kconfig"
|
||||
|
||||
source "drivers/leds/Kconfig"
|
||||
|
||||
source "drivers/media/Kconfig"
|
||||
|
||||
source "drivers/video/Kconfig"
|
||||
|
44
arch/arm/Kconfig-nommu
Normal file
44
arch/arm/Kconfig-nommu
Normal file
@ -0,0 +1,44 @@
|
||||
#
|
||||
# Kconfig for uClinux(non-paged MM) depend configurations
|
||||
# Hyok S. Choi <hyok.choi@samsung.com>
|
||||
#
|
||||
|
||||
config SET_MEM_PARAM
|
||||
bool "Set flash/sdram size and base addr"
|
||||
help
|
||||
Say Y to manually set the base addresses and sizes.
|
||||
otherwise, the default values are assigned.
|
||||
|
||||
config DRAM_BASE
|
||||
hex '(S)DRAM Base Address' if SET_MEM_PARAM
|
||||
default 0x00800000
|
||||
|
||||
config DRAM_SIZE
|
||||
hex '(S)DRAM SIZE' if SET_MEM_PARAM
|
||||
default 0x00800000
|
||||
|
||||
config FLASH_MEM_BASE
|
||||
hex 'FLASH Base Address' if SET_MEM_PARAM
|
||||
default 0x00400000
|
||||
|
||||
config FLASH_SIZE
|
||||
hex 'FLASH Size' if SET_MEM_PARAM
|
||||
default 0x00400000
|
||||
|
||||
config REMAP_VECTORS_TO_RAM
|
||||
bool 'Install vectors to the begining of RAM' if DRAM_BASE
|
||||
depends on DRAM_BASE
|
||||
help
|
||||
The kernel needs to change the hardware exception vectors.
|
||||
In nommu mode, the hardware exception vectors are normally
|
||||
placed at address 0x00000000. However, this region may be
|
||||
occupied by read-only memory depending on H/W design.
|
||||
|
||||
If the region contains read-write memory, say 'n' here.
|
||||
|
||||
If your CPU provides a remap facility which allows the exception
|
||||
vectors to be mapped to writable memory, say 'n' here.
|
||||
|
||||
Otherwise, say 'y' here. In this case, the kernel will require
|
||||
external support to redirect the hardware exception vectors to
|
||||
the writable versions located at DRAM_BASE.
|
@ -20,6 +20,11 @@ GZFLAGS :=-9
|
||||
# Select a platform tht is kept up-to-date
|
||||
KBUILD_DEFCONFIG := versatile_defconfig
|
||||
|
||||
# defines filename extension depending memory manement type.
|
||||
ifeq ($(CONFIG_MMU),)
|
||||
MMUEXT := -nommu
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_FRAME_POINTER),y)
|
||||
CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog
|
||||
endif
|
||||
@ -73,7 +78,7 @@ AFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) -msoft-float
|
||||
CHECKFLAGS += -D__arm__
|
||||
|
||||
#Default value
|
||||
head-y := arch/arm/kernel/head.o arch/arm/kernel/init_task.o
|
||||
head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o
|
||||
textofs-y := 0x00008000
|
||||
|
||||
machine-$(CONFIG_ARCH_RPC) := rpc
|
||||
@ -133,7 +138,7 @@ else
|
||||
MACHINE :=
|
||||
endif
|
||||
|
||||
export TEXT_OFFSET GZFLAGS
|
||||
export TEXT_OFFSET GZFLAGS MMUEXT
|
||||
|
||||
# Do we have FASTFPE?
|
||||
FASTFPE :=arch/arm/fastfpe
|
||||
|
@ -2,6 +2,7 @@
|
||||
* linux/arch/arm/boot/compressed/head.S
|
||||
*
|
||||
* Copyright (C) 1996-2002 Russell King
|
||||
* Copyright (C) 2004 Hyok S. Choi (MPU support)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@ -320,6 +321,62 @@ params: ldr r0, =params_phys
|
||||
cache_on: mov r3, #8 @ cache_on function
|
||||
b call_cache_fn
|
||||
|
||||
/*
|
||||
* Initialize the highest priority protection region, PR7
|
||||
* to cover all 32bit address and cacheable and bufferable.
|
||||
*/
|
||||
__armv4_mpu_cache_on:
|
||||
mov r0, #0x3f @ 4G, the whole
|
||||
mcr p15, 0, r0, c6, c7, 0 @ PR7 Area Setting
|
||||
mcr p15, 0, r0, c6, c7, 1
|
||||
|
||||
mov r0, #0x80 @ PR7
|
||||
mcr p15, 0, r0, c2, c0, 0 @ D-cache on
|
||||
mcr p15, 0, r0, c2, c0, 1 @ I-cache on
|
||||
mcr p15, 0, r0, c3, c0, 0 @ write-buffer on
|
||||
|
||||
mov r0, #0xc000
|
||||
mcr p15, 0, r0, c5, c0, 1 @ I-access permission
|
||||
mcr p15, 0, r0, c5, c0, 0 @ D-access permission
|
||||
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
|
||||
mcr p15, 0, r0, c7, c5, 0 @ flush(inval) I-Cache
|
||||
mcr p15, 0, r0, c7, c6, 0 @ flush(inval) D-Cache
|
||||
mrc p15, 0, r0, c1, c0, 0 @ read control reg
|
||||
@ ...I .... ..D. WC.M
|
||||
orr r0, r0, #0x002d @ .... .... ..1. 11.1
|
||||
orr r0, r0, #0x1000 @ ...1 .... .... ....
|
||||
|
||||
mcr p15, 0, r0, c1, c0, 0 @ write control reg
|
||||
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c5, 0 @ flush(inval) I-Cache
|
||||
mcr p15, 0, r0, c7, c6, 0 @ flush(inval) D-Cache
|
||||
mov pc, lr
|
||||
|
||||
__armv3_mpu_cache_on:
|
||||
mov r0, #0x3f @ 4G, the whole
|
||||
mcr p15, 0, r0, c6, c7, 0 @ PR7 Area Setting
|
||||
|
||||
mov r0, #0x80 @ PR7
|
||||
mcr p15, 0, r0, c2, c0, 0 @ cache on
|
||||
mcr p15, 0, r0, c3, c0, 0 @ write-buffer on
|
||||
|
||||
mov r0, #0xc000
|
||||
mcr p15, 0, r0, c5, c0, 0 @ access permission
|
||||
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
|
||||
mrc p15, 0, r0, c1, c0, 0 @ read control reg
|
||||
@ .... .... .... WC.M
|
||||
orr r0, r0, #0x000d @ .... .... .... 11.1
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c1, c0, 0 @ write control reg
|
||||
|
||||
mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
|
||||
mov pc, lr
|
||||
|
||||
__setup_mmu: sub r3, r4, #16384 @ Page directory size
|
||||
bic r3, r3, #0xff @ Align the pointer
|
||||
bic r3, r3, #0x3f00
|
||||
@ -496,6 +553,18 @@ proc_types:
|
||||
b __armv4_mmu_cache_off
|
||||
mov pc, lr
|
||||
|
||||
.word 0x41007400 @ ARM74x
|
||||
.word 0xff00ff00
|
||||
b __armv3_mpu_cache_on
|
||||
b __armv3_mpu_cache_off
|
||||
b __armv3_mpu_cache_flush
|
||||
|
||||
.word 0x41009400 @ ARM94x
|
||||
.word 0xff00ff00
|
||||
b __armv4_mpu_cache_on
|
||||
b __armv4_mpu_cache_off
|
||||
b __armv4_mpu_cache_flush
|
||||
|
||||
.word 0x00007000 @ ARM7 IDs
|
||||
.word 0x0000f000
|
||||
mov pc, lr
|
||||
@ -562,6 +631,24 @@ proc_types:
|
||||
cache_off: mov r3, #12 @ cache_off function
|
||||
b call_cache_fn
|
||||
|
||||
__armv4_mpu_cache_off:
|
||||
mrc p15, 0, r0, c1, c0
|
||||
bic r0, r0, #0x000d
|
||||
mcr p15, 0, r0, c1, c0 @ turn MPU and cache off
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
|
||||
mcr p15, 0, r0, c7, c6, 0 @ flush D-Cache
|
||||
mcr p15, 0, r0, c7, c5, 0 @ flush I-Cache
|
||||
mov pc, lr
|
||||
|
||||
__armv3_mpu_cache_off:
|
||||
mrc p15, 0, r0, c1, c0
|
||||
bic r0, r0, #0x000d
|
||||
mcr p15, 0, r0, c1, c0, 0 @ turn MPU and cache off
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
|
||||
mov pc, lr
|
||||
|
||||
__armv4_mmu_cache_off:
|
||||
mrc p15, 0, r0, c1, c0
|
||||
bic r0, r0, #0x000d
|
||||
@ -601,6 +688,24 @@ cache_clean_flush:
|
||||
mov r3, #16
|
||||
b call_cache_fn
|
||||
|
||||
__armv4_mpu_cache_flush:
|
||||
mov r2, #1
|
||||
mov r3, #0
|
||||
mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
|
||||
mov r1, #7 << 5 @ 8 segments
|
||||
1: orr r3, r1, #63 << 26 @ 64 entries
|
||||
2: mcr p15, 0, r3, c7, c14, 2 @ clean & invalidate D index
|
||||
subs r3, r3, #1 << 26
|
||||
bcs 2b @ entries 63 to 0
|
||||
subs r1, r1, #1 << 5
|
||||
bcs 1b @ segments 7 to 0
|
||||
|
||||
teq r2, #0
|
||||
mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
|
||||
mcr p15, 0, ip, c7, c10, 4 @ drain WB
|
||||
mov pc, lr
|
||||
|
||||
|
||||
__armv6_mmu_cache_flush:
|
||||
mov r1, #0
|
||||
mcr p15, 0, r1, c7, c14, 0 @ clean+invalidate D
|
||||
@ -638,6 +743,7 @@ no_cache_id:
|
||||
mov pc, lr
|
||||
|
||||
__armv3_mmu_cache_flush:
|
||||
__armv3_mpu_cache_flush:
|
||||
mov r1, #0
|
||||
mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
|
||||
mov pc, lr
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/leds.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
@ -75,6 +76,7 @@ static void sharpsl_battery_thread(void *private_);
|
||||
struct sharpsl_pm_status sharpsl_pm;
|
||||
DECLARE_WORK(toggle_charger, sharpsl_charge_toggle, NULL);
|
||||
DECLARE_WORK(sharpsl_bat, sharpsl_battery_thread, NULL);
|
||||
DEFINE_LED_TRIGGER(sharpsl_charge_led_trigger);
|
||||
|
||||
|
||||
static int get_percentage(int voltage)
|
||||
@ -190,10 +192,10 @@ void sharpsl_pm_led(int val)
|
||||
dev_err(sharpsl_pm.dev, "Charging Error!\n");
|
||||
} else if (val == SHARPSL_LED_ON) {
|
||||
dev_dbg(sharpsl_pm.dev, "Charge LED On\n");
|
||||
|
||||
led_trigger_event(sharpsl_charge_led_trigger, LED_FULL);
|
||||
} else {
|
||||
dev_dbg(sharpsl_pm.dev, "Charge LED Off\n");
|
||||
|
||||
led_trigger_event(sharpsl_charge_led_trigger, LED_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
@ -786,6 +788,8 @@ static int __init sharpsl_pm_probe(struct platform_device *pdev)
|
||||
init_timer(&sharpsl_pm.chrg_full_timer);
|
||||
sharpsl_pm.chrg_full_timer.function = sharpsl_chrg_full_timer;
|
||||
|
||||
led_trigger_register_simple("sharpsl-charge", &sharpsl_charge_led_trigger);
|
||||
|
||||
sharpsl_pm.machinfo->init();
|
||||
|
||||
device_create_file(&pdev->dev, &dev_attr_battery_percentage);
|
||||
@ -807,6 +811,8 @@ static int sharpsl_pm_remove(struct platform_device *pdev)
|
||||
device_remove_file(&pdev->dev, &dev_attr_battery_percentage);
|
||||
device_remove_file(&pdev->dev, &dev_attr_battery_voltage);
|
||||
|
||||
led_trigger_unregister_simple(sharpsl_charge_led_trigger);
|
||||
|
||||
sharpsl_pm.machinfo->exit();
|
||||
|
||||
del_timer_sync(&sharpsl_pm.chrg_full_timer);
|
||||
|
@ -379,7 +379,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
|
||||
# CONFIG_MTD_DOC2001 is not set
|
||||
# CONFIG_MTD_DOC2001PLUS is not set
|
||||
CONFIG_MTD_AT91_DATAFLASH=y
|
||||
CONFIG_MTD_AT91_DATAFLASH_CARD=y
|
||||
# CONFIG_MTD_AT91_DATAFLASH_CARD is not set
|
||||
|
||||
#
|
||||
# NAND Flash Device Drivers
|
||||
|
@ -370,7 +370,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
|
||||
# CONFIG_MTD_DOC2001 is not set
|
||||
# CONFIG_MTD_DOC2001PLUS is not set
|
||||
CONFIG_MTD_AT91_DATAFLASH=y
|
||||
CONFIG_MTD_AT91_DATAFLASH_CARD=y
|
||||
# CONFIG_MTD_AT91_DATAFLASH_CARD is not set
|
||||
|
||||
#
|
||||
# NAND Flash Device Drivers
|
||||
|
@ -100,23 +100,12 @@ EXPORT_SYMBOL(__raw_writesl);
|
||||
#endif
|
||||
|
||||
/* string / mem functions */
|
||||
EXPORT_SYMBOL(strcpy);
|
||||
EXPORT_SYMBOL(strncpy);
|
||||
EXPORT_SYMBOL(strcat);
|
||||
EXPORT_SYMBOL(strncat);
|
||||
EXPORT_SYMBOL(strcmp);
|
||||
EXPORT_SYMBOL(strncmp);
|
||||
EXPORT_SYMBOL(strchr);
|
||||
EXPORT_SYMBOL(strlen);
|
||||
EXPORT_SYMBOL(strnlen);
|
||||
EXPORT_SYMBOL(strpbrk);
|
||||
EXPORT_SYMBOL(strrchr);
|
||||
EXPORT_SYMBOL(strstr);
|
||||
EXPORT_SYMBOL(memset);
|
||||
EXPORT_SYMBOL(memcpy);
|
||||
EXPORT_SYMBOL(memmove);
|
||||
EXPORT_SYMBOL(memcmp);
|
||||
EXPORT_SYMBOL(memscan);
|
||||
EXPORT_SYMBOL(memchr);
|
||||
EXPORT_SYMBOL(__memzero);
|
||||
|
||||
@ -190,8 +179,6 @@ EXPORT_SYMBOL(_find_next_bit_be);
|
||||
|
||||
/* syscalls */
|
||||
EXPORT_SYMBOL(sys_write);
|
||||
EXPORT_SYMBOL(sys_read);
|
||||
EXPORT_SYMBOL(sys_lseek);
|
||||
EXPORT_SYMBOL(sys_open);
|
||||
EXPORT_SYMBOL(sys_exit);
|
||||
EXPORT_SYMBOL(sys_wait4);
|
||||
|
@ -666,7 +666,7 @@ __kuser_helper_start:
|
||||
*
|
||||
* #define __kernel_dmb() \
|
||||
* asm volatile ( "mov r0, #0xffff0fff; mov lr, pc; sub pc, r0, #95" \
|
||||
* : : : "lr","cc" )
|
||||
* : : : "r0", "lr","cc" )
|
||||
*/
|
||||
|
||||
__kuser_memory_barrier: @ 0xffff0fa0
|
||||
|
217
arch/arm/kernel/head-common.S
Normal file
217
arch/arm/kernel/head-common.S
Normal file
@ -0,0 +1,217 @@
|
||||
/*
|
||||
* linux/arch/arm/kernel/head-common.S
|
||||
*
|
||||
* Copyright (C) 1994-2002 Russell King
|
||||
* Copyright (c) 2003 ARM Limited
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
.type __switch_data, %object
|
||||
__switch_data:
|
||||
.long __mmap_switched
|
||||
.long __data_loc @ r4
|
||||
.long __data_start @ r5
|
||||
.long __bss_start @ r6
|
||||
.long _end @ r7
|
||||
.long processor_id @ r4
|
||||
.long __machine_arch_type @ r5
|
||||
.long cr_alignment @ r6
|
||||
.long init_thread_union + THREAD_START_SP @ sp
|
||||
|
||||
/*
|
||||
* The following fragment of code is executed with the MMU on in MMU mode,
|
||||
* and uses absolute addresses; this is not position independent.
|
||||
*
|
||||
* r0 = cp#15 control register
|
||||
* r1 = machine ID
|
||||
* r9 = processor ID
|
||||
*/
|
||||
.type __mmap_switched, %function
|
||||
__mmap_switched:
|
||||
adr r3, __switch_data + 4
|
||||
|
||||
ldmia r3!, {r4, r5, r6, r7}
|
||||
cmp r4, r5 @ Copy data segment if needed
|
||||
1: cmpne r5, r6
|
||||
ldrne fp, [r4], #4
|
||||
strne fp, [r5], #4
|
||||
bne 1b
|
||||
|
||||
mov fp, #0 @ Clear BSS (and zero fp)
|
||||
1: cmp r6, r7
|
||||
strcc fp, [r6],#4
|
||||
bcc 1b
|
||||
|
||||
ldmia r3, {r4, r5, r6, sp}
|
||||
str r9, [r4] @ Save processor ID
|
||||
str r1, [r5] @ Save machine type
|
||||
bic r4, r0, #CR_A @ Clear 'A' bit
|
||||
stmia r6, {r0, r4} @ Save control register values
|
||||
b start_kernel
|
||||
|
||||
/*
|
||||
* Exception handling. Something went wrong and we can't proceed. We
|
||||
* ought to tell the user, but since we don't have any guarantee that
|
||||
* we're even running on the right architecture, we do virtually nothing.
|
||||
*
|
||||
* If CONFIG_DEBUG_LL is set we try to print out something about the error
|
||||
* and hope for the best (useful if bootloader fails to pass a proper
|
||||
* machine ID for example).
|
||||
*/
|
||||
|
||||
.type __error_p, %function
|
||||
__error_p:
|
||||
#ifdef CONFIG_DEBUG_LL
|
||||
adr r0, str_p1
|
||||
bl printascii
|
||||
b __error
|
||||
str_p1: .asciz "\nError: unrecognized/unsupported processor variant.\n"
|
||||
.align
|
||||
#endif
|
||||
|
||||
.type __error_a, %function
|
||||
__error_a:
|
||||
#ifdef CONFIG_DEBUG_LL
|
||||
mov r4, r1 @ preserve machine ID
|
||||
adr r0, str_a1
|
||||
bl printascii
|
||||
mov r0, r4
|
||||
bl printhex8
|
||||
adr r0, str_a2
|
||||
bl printascii
|
||||
adr r3, 3f
|
||||
ldmia r3, {r4, r5, r6} @ get machine desc list
|
||||
sub r4, r3, r4 @ get offset between virt&phys
|
||||
add r5, r5, r4 @ convert virt addresses to
|
||||
add r6, r6, r4 @ physical address space
|
||||
1: ldr r0, [r5, #MACHINFO_TYPE] @ get machine type
|
||||
bl printhex8
|
||||
mov r0, #'\t'
|
||||
bl printch
|
||||
ldr r0, [r5, #MACHINFO_NAME] @ get machine name
|
||||
add r0, r0, r4
|
||||
bl printascii
|
||||
mov r0, #'\n'
|
||||
bl printch
|
||||
add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc
|
||||
cmp r5, r6
|
||||
blo 1b
|
||||
adr r0, str_a3
|
||||
bl printascii
|
||||
b __error
|
||||
str_a1: .asciz "\nError: unrecognized/unsupported machine ID (r1 = 0x"
|
||||
str_a2: .asciz ").\n\nAvailable machine support:\n\nID (hex)\tNAME\n"
|
||||
str_a3: .asciz "\nPlease check your kernel config and/or bootloader.\n"
|
||||
.align
|
||||
#endif
|
||||
|
||||
.type __error, %function
|
||||
__error:
|
||||
#ifdef CONFIG_ARCH_RPC
|
||||
/*
|
||||
* Turn the screen red on a error - RiscPC only.
|
||||
*/
|
||||
mov r0, #0x02000000
|
||||
mov r3, #0x11
|
||||
orr r3, r3, r3, lsl #8
|
||||
orr r3, r3, r3, lsl #16
|
||||
str r3, [r0], #4
|
||||
str r3, [r0], #4
|
||||
str r3, [r0], #4
|
||||
str r3, [r0], #4
|
||||
#endif
|
||||
1: mov r0, r0
|
||||
b 1b
|
||||
|
||||
|
||||
/*
|
||||
* Read processor ID register (CP#15, CR0), and look up in the linker-built
|
||||
* supported processor list. Note that we can't use the absolute addresses
|
||||
* for the __proc_info lists since we aren't running with the MMU on
|
||||
* (and therefore, we are not in the correct address space). We have to
|
||||
* calculate the offset.
|
||||
*
|
||||
* r9 = cpuid
|
||||
* Returns:
|
||||
* r3, r4, r6 corrupted
|
||||
* r5 = proc_info pointer in physical address space
|
||||
* r9 = cpuid (preserved)
|
||||
*/
|
||||
.type __lookup_processor_type, %function
|
||||
__lookup_processor_type:
|
||||
adr r3, 3f
|
||||
ldmda r3, {r5 - r7}
|
||||
sub r3, r3, r7 @ get offset between virt&phys
|
||||
add r5, r5, r3 @ convert virt addresses to
|
||||
add r6, r6, r3 @ physical address space
|
||||
1: ldmia r5, {r3, r4} @ value, mask
|
||||
and r4, r4, r9 @ mask wanted bits
|
||||
teq r3, r4
|
||||
beq 2f
|
||||
add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list)
|
||||
cmp r5, r6
|
||||
blo 1b
|
||||
mov r5, #0 @ unknown processor
|
||||
2: mov pc, lr
|
||||
|
||||
/*
|
||||
* This provides a C-API version of the above function.
|
||||
*/
|
||||
ENTRY(lookup_processor_type)
|
||||
stmfd sp!, {r4 - r7, r9, lr}
|
||||
mov r9, r0
|
||||
bl __lookup_processor_type
|
||||
mov r0, r5
|
||||
ldmfd sp!, {r4 - r7, r9, pc}
|
||||
|
||||
/*
|
||||
* Look in include/asm-arm/procinfo.h and arch/arm/kernel/arch.[ch] for
|
||||
* more information about the __proc_info and __arch_info structures.
|
||||
*/
|
||||
.long __proc_info_begin
|
||||
.long __proc_info_end
|
||||
3: .long .
|
||||
.long __arch_info_begin
|
||||
.long __arch_info_end
|
||||
|
||||
/*
|
||||
* Lookup machine architecture in the linker-build list of architectures.
|
||||
* Note that we can't use the absolute addresses for the __arch_info
|
||||
* lists since we aren't running with the MMU on (and therefore, we are
|
||||
* not in the correct address space). We have to calculate the offset.
|
||||
*
|
||||
* r1 = machine architecture number
|
||||
* Returns:
|
||||
* r3, r4, r6 corrupted
|
||||
* r5 = mach_info pointer in physical address space
|
||||
*/
|
||||
.type __lookup_machine_type, %function
|
||||
__lookup_machine_type:
|
||||
adr r3, 3b
|
||||
ldmia r3, {r4, r5, r6}
|
||||
sub r3, r3, r4 @ get offset between virt&phys
|
||||
add r5, r5, r3 @ convert virt addresses to
|
||||
add r6, r6, r3 @ physical address space
|
||||
1: ldr r3, [r5, #MACHINFO_TYPE] @ get machine type
|
||||
teq r3, r1 @ matches loader number?
|
||||
beq 2f @ found
|
||||
add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc
|
||||
cmp r5, r6
|
||||
blo 1b
|
||||
mov r5, #0 @ unknown machine
|
||||
2: mov pc, lr
|
||||
|
||||
/*
|
||||
* This provides a C-API version of the above function.
|
||||
*/
|
||||
ENTRY(lookup_machine_type)
|
||||
stmfd sp!, {r4 - r6, lr}
|
||||
mov r1, r0
|
||||
bl __lookup_machine_type
|
||||
mov r0, r5
|
||||
ldmfd sp!, {r4 - r6, pc}
|
83
arch/arm/kernel/head-nommu.S
Normal file
83
arch/arm/kernel/head-nommu.S
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* linux/arch/arm/kernel/head-nommu.S
|
||||
*
|
||||
* Copyright (C) 1994-2002 Russell King
|
||||
* Copyright (C) 2003-2006 Hyok S. Choi
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Common kernel startup code (non-paged MM)
|
||||
* for 32-bit CPUs which has a process ID register(CP15).
|
||||
*
|
||||
*/
|
||||
#include <linux/config.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <asm/assembler.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/procinfo.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/constants.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
#define PROCINFO_INITFUNC 12
|
||||
|
||||
/*
|
||||
* Kernel startup entry point.
|
||||
* ---------------------------
|
||||
*
|
||||
* This is normally called from the decompressor code. The requirements
|
||||
* are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,
|
||||
* r1 = machine nr.
|
||||
*
|
||||
* See linux/arch/arm/tools/mach-types for the complete list of machine
|
||||
* numbers for r1.
|
||||
*
|
||||
*/
|
||||
__INIT
|
||||
.type stext, %function
|
||||
ENTRY(stext)
|
||||
msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | MODE_SVC @ ensure svc mode
|
||||
@ and irqs disabled
|
||||
mrc p15, 0, r9, c0, c0 @ get processor id
|
||||
bl __lookup_processor_type @ r5=procinfo r9=cpuid
|
||||
movs r10, r5 @ invalid processor (r5=0)?
|
||||
beq __error_p @ yes, error 'p'
|
||||
bl __lookup_machine_type @ r5=machinfo
|
||||
movs r8, r5 @ invalid machine (r5=0)?
|
||||
beq __error_a @ yes, error 'a'
|
||||
|
||||
ldr r13, __switch_data @ address to jump to after
|
||||
@ the initialization is done
|
||||
adr lr, __after_proc_init @ return (PIC) address
|
||||
add pc, r10, #PROCINFO_INITFUNC
|
||||
|
||||
/*
|
||||
* Set the Control Register and Read the process ID.
|
||||
*/
|
||||
.type __after_proc_init, %function
|
||||
__after_proc_init:
|
||||
mrc p15, 0, r0, c1, c0, 0 @ read control reg
|
||||
#ifdef CONFIG_ALIGNMENT_TRAP
|
||||
orr r0, r0, #CR_A
|
||||
#else
|
||||
bic r0, r0, #CR_A
|
||||
#endif
|
||||
#ifdef CONFIG_CPU_DCACHE_DISABLE
|
||||
bic r0, r0, #CR_C
|
||||
#endif
|
||||
#ifdef CONFIG_CPU_BPREDICT_DISABLE
|
||||
bic r0, r0, #CR_Z
|
||||
#endif
|
||||
#ifdef CONFIG_CPU_ICACHE_DISABLE
|
||||
bic r0, r0, #CR_I
|
||||
#endif
|
||||
mcr p15, 0, r0, c1, c0, 0 @ write control reg
|
||||
|
||||
mov pc, r13 @ clear the BSS and jump
|
||||
@ to start_kernel
|
||||
|
||||
#include "head-common.S"
|
@ -102,49 +102,6 @@ ENTRY(stext)
|
||||
adr lr, __enable_mmu @ return (PIC) address
|
||||
add pc, r10, #PROCINFO_INITFUNC
|
||||
|
||||
.type __switch_data, %object
|
||||
__switch_data:
|
||||
.long __mmap_switched
|
||||
.long __data_loc @ r4
|
||||
.long __data_start @ r5
|
||||
.long __bss_start @ r6
|
||||
.long _end @ r7
|
||||
.long processor_id @ r4
|
||||
.long __machine_arch_type @ r5
|
||||
.long cr_alignment @ r6
|
||||
.long init_thread_union + THREAD_START_SP @ sp
|
||||
|
||||
/*
|
||||
* The following fragment of code is executed with the MMU on, and uses
|
||||
* absolute addresses; this is not position independent.
|
||||
*
|
||||
* r0 = cp#15 control register
|
||||
* r1 = machine ID
|
||||
* r9 = processor ID
|
||||
*/
|
||||
.type __mmap_switched, %function
|
||||
__mmap_switched:
|
||||
adr r3, __switch_data + 4
|
||||
|
||||
ldmia r3!, {r4, r5, r6, r7}
|
||||
cmp r4, r5 @ Copy data segment if needed
|
||||
1: cmpne r5, r6
|
||||
ldrne fp, [r4], #4
|
||||
strne fp, [r5], #4
|
||||
bne 1b
|
||||
|
||||
mov fp, #0 @ Clear BSS (and zero fp)
|
||||
1: cmp r6, r7
|
||||
strcc fp, [r6],#4
|
||||
bcc 1b
|
||||
|
||||
ldmia r3, {r4, r5, r6, sp}
|
||||
str r9, [r4] @ Save processor ID
|
||||
str r1, [r5] @ Save machine type
|
||||
bic r4, r0, #CR_A @ Clear 'A' bit
|
||||
stmia r6, {r0, r4} @ Save control register values
|
||||
b start_kernel
|
||||
|
||||
#if defined(CONFIG_SMP)
|
||||
.type secondary_startup, #function
|
||||
ENTRY(secondary_startup)
|
||||
@ -367,166 +324,4 @@ __create_page_tables:
|
||||
mov pc, lr
|
||||
.ltorg
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Exception handling. Something went wrong and we can't proceed. We
|
||||
* ought to tell the user, but since we don't have any guarantee that
|
||||
* we're even running on the right architecture, we do virtually nothing.
|
||||
*
|
||||
* If CONFIG_DEBUG_LL is set we try to print out something about the error
|
||||
* and hope for the best (useful if bootloader fails to pass a proper
|
||||
* machine ID for example).
|
||||
*/
|
||||
|
||||
.type __error_p, %function
|
||||
__error_p:
|
||||
#ifdef CONFIG_DEBUG_LL
|
||||
adr r0, str_p1
|
||||
bl printascii
|
||||
b __error
|
||||
str_p1: .asciz "\nError: unrecognized/unsupported processor variant.\n"
|
||||
.align
|
||||
#endif
|
||||
|
||||
.type __error_a, %function
|
||||
__error_a:
|
||||
#ifdef CONFIG_DEBUG_LL
|
||||
mov r4, r1 @ preserve machine ID
|
||||
adr r0, str_a1
|
||||
bl printascii
|
||||
mov r0, r4
|
||||
bl printhex8
|
||||
adr r0, str_a2
|
||||
bl printascii
|
||||
adr r3, 3f
|
||||
ldmia r3, {r4, r5, r6} @ get machine desc list
|
||||
sub r4, r3, r4 @ get offset between virt&phys
|
||||
add r5, r5, r4 @ convert virt addresses to
|
||||
add r6, r6, r4 @ physical address space
|
||||
1: ldr r0, [r5, #MACHINFO_TYPE] @ get machine type
|
||||
bl printhex8
|
||||
mov r0, #'\t'
|
||||
bl printch
|
||||
ldr r0, [r5, #MACHINFO_NAME] @ get machine name
|
||||
add r0, r0, r4
|
||||
bl printascii
|
||||
mov r0, #'\n'
|
||||
bl printch
|
||||
add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc
|
||||
cmp r5, r6
|
||||
blo 1b
|
||||
adr r0, str_a3
|
||||
bl printascii
|
||||
b __error
|
||||
str_a1: .asciz "\nError: unrecognized/unsupported machine ID (r1 = 0x"
|
||||
str_a2: .asciz ").\n\nAvailable machine support:\n\nID (hex)\tNAME\n"
|
||||
str_a3: .asciz "\nPlease check your kernel config and/or bootloader.\n"
|
||||
.align
|
||||
#endif
|
||||
|
||||
.type __error, %function
|
||||
__error:
|
||||
#ifdef CONFIG_ARCH_RPC
|
||||
/*
|
||||
* Turn the screen red on a error - RiscPC only.
|
||||
*/
|
||||
mov r0, #0x02000000
|
||||
mov r3, #0x11
|
||||
orr r3, r3, r3, lsl #8
|
||||
orr r3, r3, r3, lsl #16
|
||||
str r3, [r0], #4
|
||||
str r3, [r0], #4
|
||||
str r3, [r0], #4
|
||||
str r3, [r0], #4
|
||||
#endif
|
||||
1: mov r0, r0
|
||||
b 1b
|
||||
|
||||
|
||||
/*
|
||||
* Read processor ID register (CP#15, CR0), and look up in the linker-built
|
||||
* supported processor list. Note that we can't use the absolute addresses
|
||||
* for the __proc_info lists since we aren't running with the MMU on
|
||||
* (and therefore, we are not in the correct address space). We have to
|
||||
* calculate the offset.
|
||||
*
|
||||
* r9 = cpuid
|
||||
* Returns:
|
||||
* r3, r4, r6 corrupted
|
||||
* r5 = proc_info pointer in physical address space
|
||||
* r9 = cpuid (preserved)
|
||||
*/
|
||||
.type __lookup_processor_type, %function
|
||||
__lookup_processor_type:
|
||||
adr r3, 3f
|
||||
ldmda r3, {r5 - r7}
|
||||
sub r3, r3, r7 @ get offset between virt&phys
|
||||
add r5, r5, r3 @ convert virt addresses to
|
||||
add r6, r6, r3 @ physical address space
|
||||
1: ldmia r5, {r3, r4} @ value, mask
|
||||
and r4, r4, r9 @ mask wanted bits
|
||||
teq r3, r4
|
||||
beq 2f
|
||||
add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list)
|
||||
cmp r5, r6
|
||||
blo 1b
|
||||
mov r5, #0 @ unknown processor
|
||||
2: mov pc, lr
|
||||
|
||||
/*
|
||||
* This provides a C-API version of the above function.
|
||||
*/
|
||||
ENTRY(lookup_processor_type)
|
||||
stmfd sp!, {r4 - r7, r9, lr}
|
||||
mov r9, r0
|
||||
bl __lookup_processor_type
|
||||
mov r0, r5
|
||||
ldmfd sp!, {r4 - r7, r9, pc}
|
||||
|
||||
/*
|
||||
* Look in include/asm-arm/procinfo.h and arch/arm/kernel/arch.[ch] for
|
||||
* more information about the __proc_info and __arch_info structures.
|
||||
*/
|
||||
.long __proc_info_begin
|
||||
.long __proc_info_end
|
||||
3: .long .
|
||||
.long __arch_info_begin
|
||||
.long __arch_info_end
|
||||
|
||||
/*
|
||||
* Lookup machine architecture in the linker-build list of architectures.
|
||||
* Note that we can't use the absolute addresses for the __arch_info
|
||||
* lists since we aren't running with the MMU on (and therefore, we are
|
||||
* not in the correct address space). We have to calculate the offset.
|
||||
*
|
||||
* r1 = machine architecture number
|
||||
* Returns:
|
||||
* r3, r4, r6 corrupted
|
||||
* r5 = mach_info pointer in physical address space
|
||||
*/
|
||||
.type __lookup_machine_type, %function
|
||||
__lookup_machine_type:
|
||||
adr r3, 3b
|
||||
ldmia r3, {r4, r5, r6}
|
||||
sub r3, r3, r4 @ get offset between virt&phys
|
||||
add r5, r5, r3 @ convert virt addresses to
|
||||
add r6, r6, r3 @ physical address space
|
||||
1: ldr r3, [r5, #MACHINFO_TYPE] @ get machine type
|
||||
teq r3, r1 @ matches loader number?
|
||||
beq 2f @ found
|
||||
add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc
|
||||
cmp r5, r6
|
||||
blo 1b
|
||||
mov r5, #0 @ unknown machine
|
||||
2: mov pc, lr
|
||||
|
||||
/*
|
||||
* This provides a C-API version of the above function.
|
||||
*/
|
||||
ENTRY(lookup_machine_type)
|
||||
stmfd sp!, {r4 - r6, lr}
|
||||
mov r1, r0
|
||||
bl __lookup_machine_type
|
||||
mov r0, r5
|
||||
ldmfd sp!, {r4 - r6, pc}
|
||||
#include "head-common.S"
|
||||
|
@ -474,4 +474,3 @@ unsigned long get_wchan(struct task_struct *p)
|
||||
} while (count ++ < 16);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(get_wchan);
|
||||
|
@ -252,6 +252,9 @@ static void __init dump_cpu_info(int cpu)
|
||||
dump_cache("cache", cpu, CACHE_ISIZE(info));
|
||||
}
|
||||
}
|
||||
|
||||
if (arch_is_coherent())
|
||||
printk("Cache coherency enabled\n");
|
||||
}
|
||||
|
||||
int cpu_architecture(void)
|
||||
|
@ -7,6 +7,6 @@
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#define KERN_SIGRETURN_CODE 0xffff0500
|
||||
#define KERN_SIGRETURN_CODE (CONFIG_VECTORS_BASE + 0x00000500)
|
||||
|
||||
extern const unsigned long sigreturn_codes[7];
|
||||
|
@ -688,6 +688,7 @@ EXPORT_SYMBOL(abort);
|
||||
|
||||
void __init trap_init(void)
|
||||
{
|
||||
unsigned long vectors = CONFIG_VECTORS_BASE;
|
||||
extern char __stubs_start[], __stubs_end[];
|
||||
extern char __vectors_start[], __vectors_end[];
|
||||
extern char __kuser_helper_start[], __kuser_helper_end[];
|
||||
@ -698,9 +699,9 @@ void __init trap_init(void)
|
||||
* into the vector page, mapped at 0xffff0000, and ensure these
|
||||
* are visible to the instruction stream.
|
||||
*/
|
||||
memcpy((void *)0xffff0000, __vectors_start, __vectors_end - __vectors_start);
|
||||
memcpy((void *)0xffff0200, __stubs_start, __stubs_end - __stubs_start);
|
||||
memcpy((void *)0xffff1000 - kuser_sz, __kuser_helper_start, kuser_sz);
|
||||
memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);
|
||||
memcpy((void *)vectors + 0x200, __stubs_start, __stubs_end - __stubs_start);
|
||||
memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz);
|
||||
|
||||
/*
|
||||
* Copy signal return handlers into the vector page, and
|
||||
@ -709,6 +710,6 @@ void __init trap_init(void)
|
||||
memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes,
|
||||
sizeof(sigreturn_codes));
|
||||
|
||||
flush_icache_range(0xffff0000, 0xffff0000 + PAGE_SIZE);
|
||||
flush_icache_range(vectors, vectors + PAGE_SIZE);
|
||||
modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
|
||||
}
|
||||
|
@ -16,11 +16,12 @@ obj-$(CONFIG_MACH_CSB637) += board-csb637.o
|
||||
#obj-$(CONFIG_MACH_KB9200) += board-kb9202.o
|
||||
|
||||
# LEDs support
|
||||
#led-$(CONFIG_ARCH_AT91RM9200DK) += leds.o
|
||||
#led-$(CONFIG_MACH_AT91RM9200EK) += leds.o
|
||||
#led-$(CONFIG_MACH_CSB337) += leds.o
|
||||
#led-$(CONFIG_MACH_CSB637) += leds.o
|
||||
led-$(CONFIG_ARCH_AT91RM9200DK) += leds.o
|
||||
led-$(CONFIG_MACH_AT91RM9200EK) += leds.o
|
||||
led-$(CONFIG_MACH_CSB337) += leds.o
|
||||
led-$(CONFIG_MACH_CSB637) += leds.o
|
||||
#led-$(CONFIG_MACH_KB9200) += leds.o
|
||||
#led-$(CONFIG_MACH_KAFA) += leds.o
|
||||
obj-$(CONFIG_LEDS) += $(led-y)
|
||||
|
||||
# VGA support
|
||||
|
@ -67,6 +67,9 @@ static void __init csb337_map_io(void)
|
||||
/* Initialize clocks: 3.6864 MHz crystal */
|
||||
at91_clock_init(3686400);
|
||||
|
||||
/* Setup the LEDs */
|
||||
at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2);
|
||||
|
||||
#ifdef CONFIG_SERIAL_AT91
|
||||
at91_console_port = CSB337_SERIAL_CONSOLE;
|
||||
memcpy(at91_serial_map, serial, sizeof(serial));
|
||||
|
@ -67,6 +67,9 @@ static void __init csb637_map_io(void)
|
||||
/* Initialize clocks: 3.6864 MHz crystal */
|
||||
at91_clock_init(3686400);
|
||||
|
||||
/* Setup the LEDs */
|
||||
at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2);
|
||||
|
||||
#ifdef CONFIG_SERIAL_AT91
|
||||
at91_console_port = CSB637_SERIAL_CONSOLE;
|
||||
memcpy(at91_serial_map, serial, sizeof(serial));
|
||||
|
@ -70,6 +70,9 @@ static void __init dk_map_io(void)
|
||||
/* Initialize clocks: 18.432 MHz crystal */
|
||||
at91_clock_init(18432000);
|
||||
|
||||
/* Setup the LEDs */
|
||||
at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2);
|
||||
|
||||
#ifdef CONFIG_SERIAL_AT91
|
||||
at91_console_port = DK_SERIAL_CONSOLE;
|
||||
memcpy(at91_serial_map, serial, sizeof(serial));
|
||||
@ -118,9 +121,14 @@ static void __init dk_board_init(void)
|
||||
at91_add_device_udc(&dk_udc_data);
|
||||
/* Compact Flash */
|
||||
at91_add_device_cf(&dk_cf_data);
|
||||
#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
|
||||
/* DataFlash card */
|
||||
at91_set_gpio_output(AT91_PIN_PB7, 0);
|
||||
#else
|
||||
/* MMC */
|
||||
at91_set_gpio_output(AT91_PIN_PB7, 1); /* this MMC card slot can optionally use SPI signaling (CS3). default: MMC */
|
||||
at91_set_gpio_output(AT91_PIN_PB7, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */
|
||||
at91_add_device_mmc(&dk_mmc_data);
|
||||
#endif
|
||||
/* VGA */
|
||||
// dk_add_device_video();
|
||||
}
|
||||
|
@ -70,6 +70,9 @@ static void __init ek_map_io(void)
|
||||
/* Initialize clocks: 18.432 MHz crystal */
|
||||
at91_clock_init(18432000);
|
||||
|
||||
/* Setup the LEDs */
|
||||
at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2);
|
||||
|
||||
#ifdef CONFIG_SERIAL_AT91
|
||||
at91_console_port = EK_SERIAL_CONSOLE;
|
||||
memcpy(at91_serial_map, serial, sizeof(serial));
|
||||
@ -111,9 +114,14 @@ static void __init ek_board_init(void)
|
||||
at91_add_device_usbh(&ek_usbh_data);
|
||||
/* USB Device */
|
||||
at91_add_device_udc(&ek_udc_data);
|
||||
#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
|
||||
/* DataFlash card */
|
||||
at91_set_gpio_output(AT91_PIN_PB22, 0);
|
||||
#else
|
||||
/* MMC */
|
||||
at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). default: MMC */
|
||||
at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */
|
||||
at91_add_device_mmc(&ek_mmc_data);
|
||||
#endif
|
||||
/* VGA */
|
||||
// ek_add_device_video();
|
||||
}
|
||||
|
@ -28,10 +28,10 @@
|
||||
static u64 ohci_dmamask = 0xffffffffUL;
|
||||
static struct at91_usbh_data usbh_data;
|
||||
|
||||
static struct resource at91rm9200_usbh_resource[] = {
|
||||
static struct resource at91_usbh_resource[] = {
|
||||
[0] = {
|
||||
.start = AT91_UHP_BASE,
|
||||
.end = AT91_UHP_BASE + SZ_1M -1,
|
||||
.end = AT91_UHP_BASE + SZ_1M - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
@ -49,8 +49,8 @@ static struct platform_device at91rm9200_usbh_device = {
|
||||
.coherent_dma_mask = 0xffffffff,
|
||||
.platform_data = &usbh_data,
|
||||
},
|
||||
.resource = at91rm9200_usbh_resource,
|
||||
.num_resources = ARRAY_SIZE(at91rm9200_usbh_resource),
|
||||
.resource = at91_usbh_resource,
|
||||
.num_resources = ARRAY_SIZE(at91_usbh_resource),
|
||||
};
|
||||
|
||||
void __init at91_add_device_usbh(struct at91_usbh_data *data)
|
||||
@ -121,6 +121,19 @@ void __init at91_add_device_udc(struct at91_udc_data *data) {}
|
||||
static u64 eth_dmamask = 0xffffffffUL;
|
||||
static struct at91_eth_data eth_data;
|
||||
|
||||
static struct resource at91_eth_resources[] = {
|
||||
[0] = {
|
||||
.start = AT91_BASE_EMAC,
|
||||
.end = AT91_BASE_EMAC + SZ_16K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = AT91_ID_EMAC,
|
||||
.end = AT91_ID_EMAC,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device at91rm9200_eth_device = {
|
||||
.name = "at91_ether",
|
||||
.id = -1,
|
||||
@ -129,7 +142,8 @@ static struct platform_device at91rm9200_eth_device = {
|
||||
.coherent_dma_mask = 0xffffffff,
|
||||
.platform_data = ð_data,
|
||||
},
|
||||
.num_resources = 0,
|
||||
.resource = at91_eth_resources,
|
||||
.num_resources = ARRAY_SIZE(at91_eth_resources),
|
||||
};
|
||||
|
||||
void __init at91_add_device_eth(struct at91_eth_data *data)
|
||||
@ -224,15 +238,20 @@ static u64 mmc_dmamask = 0xffffffffUL;
|
||||
static struct at91_mmc_data mmc_data;
|
||||
|
||||
static struct resource at91_mmc_resources[] = {
|
||||
{
|
||||
[0] = {
|
||||
.start = AT91_BASE_MCI,
|
||||
.end = AT91_BASE_MCI + SZ_16K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.start = AT91_ID_MCI,
|
||||
.end = AT91_ID_MCI,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device at91rm9200_mmc_device = {
|
||||
.name = "at91rm9200_mci",
|
||||
.name = "at91_mci",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.dma_mask = &mmc_dmamask,
|
||||
@ -290,4 +309,123 @@ void __init at91_add_device_mmc(struct at91_mmc_data *data)
|
||||
void __init at91_add_device_mmc(struct at91_mmc_data *data) {}
|
||||
#endif
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* NAND / SmartMedia
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE)
|
||||
static struct at91_nand_data nand_data;
|
||||
|
||||
static struct resource at91_nand_resources[] = {
|
||||
{
|
||||
.start = AT91_SMARTMEDIA_BASE,
|
||||
.end = AT91_SMARTMEDIA_BASE + SZ_8M - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device at91_nand_device = {
|
||||
.name = "at91_nand",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &nand_data,
|
||||
},
|
||||
.resource = at91_nand_resources,
|
||||
.num_resources = ARRAY_SIZE(at91_nand_resources),
|
||||
};
|
||||
|
||||
void __init at91_add_device_nand(struct at91_nand_data *data)
|
||||
{
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
/* enable pin */
|
||||
if (data->enable_pin)
|
||||
at91_set_gpio_output(data->enable_pin, 1);
|
||||
|
||||
/* ready/busy pin */
|
||||
if (data->rdy_pin)
|
||||
at91_set_gpio_input(data->rdy_pin, 1);
|
||||
|
||||
/* card detect pin */
|
||||
if (data->det_pin)
|
||||
at91_set_gpio_input(data->det_pin, 1);
|
||||
|
||||
at91_set_A_periph(AT91_PIN_PC1, 0); /* SMOE */
|
||||
at91_set_A_periph(AT91_PIN_PC3, 0); /* SMWE */
|
||||
|
||||
nand_data = *data;
|
||||
platform_device_register(&at91_nand_device);
|
||||
}
|
||||
#else
|
||||
void __init at91_add_device_nand(struct at91_nand_data *data) {}
|
||||
#endif
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* TWI (i2c)
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
|
||||
static struct platform_device at91rm9200_twi_device = {
|
||||
.name = "at91_i2c",
|
||||
.id = -1,
|
||||
.num_resources = 0,
|
||||
};
|
||||
|
||||
void __init at91_add_device_i2c(void)
|
||||
{
|
||||
/* pins used for TWI interface */
|
||||
at91_set_A_periph(AT91_PIN_PA25, 0); /* TWD */
|
||||
at91_set_multi_drive(AT91_PIN_PA25, 1);
|
||||
|
||||
at91_set_A_periph(AT91_PIN_PA26, 0); /* TWCK */
|
||||
at91_set_multi_drive(AT91_PIN_PA26, 1);
|
||||
|
||||
platform_device_register(&at91rm9200_twi_device);
|
||||
}
|
||||
#else
|
||||
void __init at91_add_device_i2c(void) {}
|
||||
#endif
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* RTC
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#if defined(CONFIG_AT91_RTC) || defined(CONFIG_AT91_RTC_MODULE)
|
||||
static struct platform_device at91rm9200_rtc_device = {
|
||||
.name = "at91_rtc",
|
||||
.id = -1,
|
||||
.num_resources = 0,
|
||||
};
|
||||
|
||||
void __init at91_add_device_rtc(void)
|
||||
{
|
||||
platform_device_register(&at91rm9200_rtc_device);
|
||||
}
|
||||
#else
|
||||
void __init at91_add_device_rtc(void) {}
|
||||
#endif
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* LEDs
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#if defined(CONFIG_LEDS)
|
||||
u8 at91_leds_cpu;
|
||||
u8 at91_leds_timer;
|
||||
|
||||
void __init at91_init_leds(u8 cpu_led, u8 timer_led)
|
||||
{
|
||||
at91_leds_cpu = cpu_led;
|
||||
at91_leds_timer = timer_led;
|
||||
}
|
||||
|
||||
#else
|
||||
void __init at91_init_leds(u8 cpu_led, u8 timer_led) {}
|
||||
#endif
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
100
arch/arm/mach-at91rm9200/leds.c
Normal file
100
arch/arm/mach-at91rm9200/leds.c
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* LED driver for Atmel AT91-based boards.
|
||||
*
|
||||
* Copyright (C) SAN People (Pty) Ltd
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/leds.h>
|
||||
#include <asm/arch/board.h>
|
||||
#include <asm/arch/gpio.h>
|
||||
|
||||
|
||||
static inline void at91_led_on(unsigned int led)
|
||||
{
|
||||
at91_set_gpio_value(led, 0);
|
||||
}
|
||||
|
||||
static inline void at91_led_off(unsigned int led)
|
||||
{
|
||||
at91_set_gpio_value(led, 1);
|
||||
}
|
||||
|
||||
static inline void at91_led_toggle(unsigned int led)
|
||||
{
|
||||
unsigned long is_off = at91_get_gpio_value(led);
|
||||
if (is_off)
|
||||
at91_led_on(led);
|
||||
else
|
||||
at91_led_off(led);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Handle LED events.
|
||||
*/
|
||||
static void at91_leds_event(led_event_t evt)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
switch(evt) {
|
||||
case led_start: /* System startup */
|
||||
at91_led_on(at91_leds_cpu);
|
||||
break;
|
||||
|
||||
case led_stop: /* System stop / suspend */
|
||||
at91_led_off(at91_leds_cpu);
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_LEDS_TIMER
|
||||
case led_timer: /* Every 50 timer ticks */
|
||||
at91_led_toggle(at91_leds_timer);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LEDS_CPU
|
||||
case led_idle_start: /* Entering idle state */
|
||||
at91_led_off(at91_leds_cpu);
|
||||
break;
|
||||
|
||||
case led_idle_end: /* Exit idle state */
|
||||
at91_led_on(at91_leds_cpu);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
|
||||
static int __init leds_init(void)
|
||||
{
|
||||
if (!at91_leds_timer || !at91_leds_cpu)
|
||||
return -ENODEV;
|
||||
|
||||
/* Enable PIO to access the LEDs */
|
||||
at91_set_gpio_output(at91_leds_timer, 1);
|
||||
at91_set_gpio_output(at91_leds_cpu, 1);
|
||||
|
||||
leds_event = at91_leds_event;
|
||||
|
||||
leds_event(led_start);
|
||||
return 0;
|
||||
}
|
||||
|
||||
__initcall(leds_init);
|
@ -424,6 +424,14 @@ static struct amba_device uart3_device = {
|
||||
.periphid = 0x00041010,
|
||||
};
|
||||
|
||||
|
||||
static struct platform_device ep93xx_rtc_device = {
|
||||
.name = "ep93xx-rtc",
|
||||
.id = -1,
|
||||
.num_resources = 0,
|
||||
};
|
||||
|
||||
|
||||
void __init ep93xx_init_devices(void)
|
||||
{
|
||||
unsigned int v;
|
||||
@ -439,4 +447,6 @@ void __init ep93xx_init_devices(void)
|
||||
amba_device_register(&uart1_device, &iomem_resource);
|
||||
amba_device_register(&uart2_device, &iomem_resource);
|
||||
amba_device_register(&uart3_device, &iomem_resource);
|
||||
|
||||
platform_device_register(&ep93xx_rtc_device);
|
||||
}
|
||||
|
@ -17,6 +17,8 @@
|
||||
#include <linux/sched.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mtd/physmap.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/m48t86.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
@ -39,6 +41,16 @@ static struct map_desc ts72xx_io_desc[] __initdata = {
|
||||
.pfn = __phys_to_pfn(TS72XX_OPTIONS2_PHYS_BASE),
|
||||
.length = TS72XX_OPTIONS2_SIZE,
|
||||
.type = MT_DEVICE,
|
||||
}, {
|
||||
.virtual = TS72XX_RTC_INDEX_VIRT_BASE,
|
||||
.pfn = __phys_to_pfn(TS72XX_RTC_INDEX_PHYS_BASE),
|
||||
.length = TS72XX_RTC_INDEX_SIZE,
|
||||
.type = MT_DEVICE,
|
||||
}, {
|
||||
.virtual = TS72XX_RTC_DATA_VIRT_BASE,
|
||||
.pfn = __phys_to_pfn(TS72XX_RTC_DATA_PHYS_BASE),
|
||||
.length = TS72XX_RTC_DATA_SIZE,
|
||||
.type = MT_DEVICE,
|
||||
}
|
||||
};
|
||||
|
||||
@ -99,11 +111,38 @@ static void __init ts72xx_map_io(void)
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned char ts72xx_rtc_readb(unsigned long addr)
|
||||
{
|
||||
__raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE);
|
||||
return __raw_readb(TS72XX_RTC_DATA_VIRT_BASE);
|
||||
}
|
||||
|
||||
static void ts72xx_rtc_writeb(unsigned char value, unsigned long addr)
|
||||
{
|
||||
__raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE);
|
||||
__raw_writeb(value, TS72XX_RTC_DATA_VIRT_BASE);
|
||||
}
|
||||
|
||||
static struct m48t86_ops ts72xx_rtc_ops = {
|
||||
.readb = ts72xx_rtc_readb,
|
||||
.writeb = ts72xx_rtc_writeb,
|
||||
};
|
||||
|
||||
static struct platform_device ts72xx_rtc_device = {
|
||||
.name = "rtc-m48t86",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &ts72xx_rtc_ops,
|
||||
},
|
||||
.num_resources = 0,
|
||||
};
|
||||
|
||||
static void __init ts72xx_init_machine(void)
|
||||
{
|
||||
ep93xx_init_devices();
|
||||
if (board_is_ts7200())
|
||||
physmap_configure(TS72XX_NOR_PHYS_BASE, 0x01000000, 1, NULL);
|
||||
platform_device_register(&ts72xx_rtc_device);
|
||||
}
|
||||
|
||||
MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC")
|
||||
|
@ -7,11 +7,18 @@
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* 03/03/2004 Sascha Hauer <sascha@saschahauer.de>
|
||||
* 2004-03-03 Sascha Hauer <sascha@saschahauer.de>
|
||||
* initial version heavily inspired by
|
||||
* linux/arch/arm/mach-pxa/dma.c
|
||||
*
|
||||
* 2005-04-17 Pavel Pisa <pisa@cmp.felk.cvut.cz>
|
||||
* Changed to support scatter gather DMA
|
||||
* by taking Russell's code from RiscPC
|
||||
*
|
||||
*/
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
@ -22,69 +29,368 @@
|
||||
#include <asm/irq.h>
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/arch/imx-dma.h>
|
||||
|
||||
static struct dma_channel {
|
||||
char *name;
|
||||
void (*irq_handler) (int, void *, struct pt_regs *);
|
||||
void (*err_handler) (int, void *, struct pt_regs *);
|
||||
void *data;
|
||||
} dma_channels[11];
|
||||
struct imx_dma_channel imx_dma_channels[IMX_DMA_CHANNELS];
|
||||
|
||||
/* set err_handler to NULL to have the standard info-only error handler */
|
||||
int
|
||||
imx_request_dma(char *name, imx_dma_prio prio,
|
||||
void (*irq_handler) (int, void *, struct pt_regs *),
|
||||
void (*err_handler) (int, void *, struct pt_regs *), void *data)
|
||||
/*
|
||||
* imx_dma_sg_next - prepare next chunk for scatter-gather DMA emulation
|
||||
* @dma_ch: i.MX DMA channel number
|
||||
* @lastcount: number of bytes transferred during last transfer
|
||||
*
|
||||
* Functions prepares DMA controller for next sg data chunk transfer.
|
||||
* The @lastcount argument informs function about number of bytes transferred
|
||||
* during last block. Zero value can be used for @lastcount to setup DMA
|
||||
* for the first chunk.
|
||||
*/
|
||||
static inline int imx_dma_sg_next(imx_dmach_t dma_ch, unsigned int lastcount)
|
||||
{
|
||||
unsigned long flags;
|
||||
int i, found = 0;
|
||||
struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
|
||||
unsigned int nextcount;
|
||||
unsigned int nextaddr;
|
||||
|
||||
/* basic sanity checks */
|
||||
if (!name || !irq_handler)
|
||||
return -EINVAL;
|
||||
if (!imxdma->name) {
|
||||
printk(KERN_CRIT "%s: called for not allocated channel %d\n",
|
||||
__FUNCTION__, dma_ch);
|
||||
return 0;
|
||||
}
|
||||
|
||||
local_irq_save(flags);
|
||||
imxdma->resbytes -= lastcount;
|
||||
|
||||
/* try grabbing a DMA channel with the requested priority */
|
||||
for (i = prio; i < prio + (prio == DMA_PRIO_LOW) ? 8 : 4; i++) {
|
||||
if (!dma_channels[i].name) {
|
||||
found = 1;
|
||||
break;
|
||||
if (!imxdma->sg) {
|
||||
pr_debug("imxdma%d: no sg data\n", dma_ch);
|
||||
return 0;
|
||||
}
|
||||
|
||||
imxdma->sgbc += lastcount;
|
||||
if ((imxdma->sgbc >= imxdma->sg->length) || !imxdma->resbytes) {
|
||||
if ((imxdma->sgcount <= 1) || !imxdma->resbytes) {
|
||||
pr_debug("imxdma%d: sg transfer limit reached\n",
|
||||
dma_ch);
|
||||
imxdma->sgcount=0;
|
||||
imxdma->sg = NULL;
|
||||
return 0;
|
||||
} else {
|
||||
imxdma->sgcount--;
|
||||
imxdma->sg++;
|
||||
imxdma->sgbc = 0;
|
||||
}
|
||||
}
|
||||
nextcount = imxdma->sg->length - imxdma->sgbc;
|
||||
nextaddr = imxdma->sg->dma_address + imxdma->sgbc;
|
||||
|
||||
if (!found) {
|
||||
/* requested prio group is full, try hier priorities */
|
||||
for (i = prio - 1; i >= 0; i--) {
|
||||
if (!dma_channels[i].name) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(imxdma->resbytes < nextcount)
|
||||
nextcount = imxdma->resbytes;
|
||||
|
||||
if (found) {
|
||||
DIMR &= ~(1 << i);
|
||||
dma_channels[i].name = name;
|
||||
dma_channels[i].irq_handler = irq_handler;
|
||||
dma_channels[i].err_handler = err_handler;
|
||||
dma_channels[i].data = data;
|
||||
} else {
|
||||
printk(KERN_WARNING "No more available DMA channels for %s\n",
|
||||
name);
|
||||
i = -ENODEV;
|
||||
}
|
||||
if ((imxdma->dma_mode & DMA_MODE_MASK) == DMA_MODE_READ)
|
||||
DAR(dma_ch) = nextaddr;
|
||||
else
|
||||
SAR(dma_ch) = nextaddr;
|
||||
|
||||
local_irq_restore(flags);
|
||||
return i;
|
||||
CNTR(dma_ch) = nextcount;
|
||||
pr_debug("imxdma%d: next sg chunk dst 0x%08x, src 0x%08x, size 0x%08x\n",
|
||||
dma_ch, DAR(dma_ch), SAR(dma_ch), CNTR(dma_ch));
|
||||
|
||||
return nextcount;
|
||||
}
|
||||
|
||||
void
|
||||
imx_free_dma(int dma_ch)
|
||||
/*
|
||||
* imx_dma_setup_sg_base - scatter-gather DMA emulation
|
||||
* @dma_ch: i.MX DMA channel number
|
||||
* @sg: pointer to the scatter-gather list/vector
|
||||
* @sgcount: scatter-gather list hungs count
|
||||
*
|
||||
* Functions sets up i.MX DMA state for emulated scatter-gather transfer
|
||||
* and sets up channel registers to be ready for the first chunk
|
||||
*/
|
||||
static int
|
||||
imx_dma_setup_sg_base(imx_dmach_t dma_ch,
|
||||
struct scatterlist *sg, unsigned int sgcount)
|
||||
{
|
||||
struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
|
||||
|
||||
imxdma->sg = sg;
|
||||
imxdma->sgcount = sgcount;
|
||||
imxdma->sgbc = 0;
|
||||
return imx_dma_sg_next(dma_ch, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* imx_dma_setup_single - setup i.MX DMA channel for linear memory to/from device transfer
|
||||
* @dma_ch: i.MX DMA channel number
|
||||
* @dma_address: the DMA/physical memory address of the linear data block
|
||||
* to transfer
|
||||
* @dma_length: length of the data block in bytes
|
||||
* @dev_addr: physical device port address
|
||||
* @dmamode: DMA transfer mode, %DMA_MODE_READ from the device to the memory
|
||||
* or %DMA_MODE_WRITE from memory to the device
|
||||
*
|
||||
* The function setups DMA channel source and destination addresses for transfer
|
||||
* specified by provided parameters. The scatter-gather emulation is disabled,
|
||||
* because linear data block
|
||||
* form the physical address range is transfered.
|
||||
* Return value: if incorrect parameters are provided -%EINVAL.
|
||||
* Zero indicates success.
|
||||
*/
|
||||
int
|
||||
imx_dma_setup_single(imx_dmach_t dma_ch, dma_addr_t dma_address,
|
||||
unsigned int dma_length, unsigned int dev_addr,
|
||||
dmamode_t dmamode)
|
||||
{
|
||||
struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
|
||||
|
||||
imxdma->sg = NULL;
|
||||
imxdma->sgcount = 0;
|
||||
imxdma->dma_mode = dmamode;
|
||||
imxdma->resbytes = dma_length;
|
||||
|
||||
if (!dma_address) {
|
||||
printk(KERN_ERR "imxdma%d: imx_dma_setup_single null address\n",
|
||||
dma_ch);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!dma_length) {
|
||||
printk(KERN_ERR "imxdma%d: imx_dma_setup_single zero length\n",
|
||||
dma_ch);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((dmamode & DMA_MODE_MASK) == DMA_MODE_READ) {
|
||||
pr_debug("imxdma%d: mx_dma_setup_single2dev dma_addressg=0x%08x dma_length=%d dev_addr=0x%08x for read\n",
|
||||
dma_ch, (unsigned int)dma_address, dma_length,
|
||||
dev_addr);
|
||||
SAR(dma_ch) = dev_addr;
|
||||
DAR(dma_ch) = (unsigned int)dma_address;
|
||||
} else if ((dmamode & DMA_MODE_MASK) == DMA_MODE_WRITE) {
|
||||
pr_debug("imxdma%d: mx_dma_setup_single2dev dma_addressg=0x%08x dma_length=%d dev_addr=0x%08x for write\n",
|
||||
dma_ch, (unsigned int)dma_address, dma_length,
|
||||
dev_addr);
|
||||
SAR(dma_ch) = (unsigned int)dma_address;
|
||||
DAR(dma_ch) = dev_addr;
|
||||
} else {
|
||||
printk(KERN_ERR "imxdma%d: imx_dma_setup_single bad dmamode\n",
|
||||
dma_ch);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
CNTR(dma_ch) = dma_length;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* imx_dma_setup_sg - setup i.MX DMA channel SG list to/from device transfer
|
||||
* @dma_ch: i.MX DMA channel number
|
||||
* @sg: pointer to the scatter-gather list/vector
|
||||
* @sgcount: scatter-gather list hungs count
|
||||
* @dma_length: total length of the transfer request in bytes
|
||||
* @dev_addr: physical device port address
|
||||
* @dmamode: DMA transfer mode, %DMA_MODE_READ from the device to the memory
|
||||
* or %DMA_MODE_WRITE from memory to the device
|
||||
*
|
||||
* The function setups DMA channel state and registers to be ready for transfer
|
||||
* specified by provided parameters. The scatter-gather emulation is set up
|
||||
* according to the parameters.
|
||||
*
|
||||
* The full preparation of the transfer requires setup of more register
|
||||
* by the caller before imx_dma_enable() can be called.
|
||||
*
|
||||
* %BLR(dma_ch) holds transfer burst length in bytes, 0 means 64 bytes
|
||||
*
|
||||
* %RSSR(dma_ch) has to be set to the DMA request line source %DMA_REQ_xxx
|
||||
*
|
||||
* %CCR(dma_ch) has to specify transfer parameters, the next settings is typical
|
||||
* for linear or simple scatter-gather transfers if %DMA_MODE_READ is specified
|
||||
*
|
||||
* %CCR_DMOD_LINEAR | %CCR_DSIZ_32 | %CCR_SMOD_FIFO | %CCR_SSIZ_x
|
||||
*
|
||||
* The typical setup for %DMA_MODE_WRITE is specified by next options combination
|
||||
*
|
||||
* %CCR_SMOD_LINEAR | %CCR_SSIZ_32 | %CCR_DMOD_FIFO | %CCR_DSIZ_x
|
||||
*
|
||||
* Be carefull there and do not mistakenly mix source and target device
|
||||
* port sizes constants, they are really different:
|
||||
* %CCR_SSIZ_8, %CCR_SSIZ_16, %CCR_SSIZ_32,
|
||||
* %CCR_DSIZ_8, %CCR_DSIZ_16, %CCR_DSIZ_32
|
||||
*
|
||||
* Return value: if incorrect parameters are provided -%EINVAL.
|
||||
* Zero indicates success.
|
||||
*/
|
||||
int
|
||||
imx_dma_setup_sg(imx_dmach_t dma_ch,
|
||||
struct scatterlist *sg, unsigned int sgcount, unsigned int dma_length,
|
||||
unsigned int dev_addr, dmamode_t dmamode)
|
||||
{
|
||||
int res;
|
||||
struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
|
||||
|
||||
imxdma->sg = NULL;
|
||||
imxdma->sgcount = 0;
|
||||
imxdma->dma_mode = dmamode;
|
||||
imxdma->resbytes = dma_length;
|
||||
|
||||
if (!sg || !sgcount) {
|
||||
printk(KERN_ERR "imxdma%d: imx_dma_setup_sg epty sg list\n",
|
||||
dma_ch);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!sg->length) {
|
||||
printk(KERN_ERR "imxdma%d: imx_dma_setup_sg zero length\n",
|
||||
dma_ch);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((dmamode & DMA_MODE_MASK) == DMA_MODE_READ) {
|
||||
pr_debug("imxdma%d: mx_dma_setup_sg2dev sg=%p sgcount=%d total length=%d dev_addr=0x%08x for read\n",
|
||||
dma_ch, sg, sgcount, dma_length, dev_addr);
|
||||
SAR(dma_ch) = dev_addr;
|
||||
} else if ((dmamode & DMA_MODE_MASK) == DMA_MODE_WRITE) {
|
||||
pr_debug("imxdma%d: mx_dma_setup_sg2dev sg=%p sgcount=%d total length=%d dev_addr=0x%08x for write\n",
|
||||
dma_ch, sg, sgcount, dma_length, dev_addr);
|
||||
DAR(dma_ch) = dev_addr;
|
||||
} else {
|
||||
printk(KERN_ERR "imxdma%d: imx_dma_setup_sg bad dmamode\n",
|
||||
dma_ch);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
res = imx_dma_setup_sg_base(dma_ch, sg, sgcount);
|
||||
if (res <= 0) {
|
||||
printk(KERN_ERR "imxdma%d: no sg chunk ready\n", dma_ch);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* imx_dma_setup_handlers - setup i.MX DMA channel end and error notification handlers
|
||||
* @dma_ch: i.MX DMA channel number
|
||||
* @irq_handler: the pointer to the function called if the transfer
|
||||
* ends successfully
|
||||
* @err_handler: the pointer to the function called if the premature
|
||||
* end caused by error occurs
|
||||
* @data: user specified value to be passed to the handlers
|
||||
*/
|
||||
int
|
||||
imx_dma_setup_handlers(imx_dmach_t dma_ch,
|
||||
void (*irq_handler) (int, void *, struct pt_regs *),
|
||||
void (*err_handler) (int, void *, struct pt_regs *),
|
||||
void *data)
|
||||
{
|
||||
struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
|
||||
unsigned long flags;
|
||||
|
||||
if (!imxdma->name) {
|
||||
printk(KERN_CRIT "%s: called for not allocated channel %d\n",
|
||||
__FUNCTION__, dma_ch);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
local_irq_save(flags);
|
||||
DISR = (1 << dma_ch);
|
||||
imxdma->irq_handler = irq_handler;
|
||||
imxdma->err_handler = err_handler;
|
||||
imxdma->data = data;
|
||||
local_irq_restore(flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* imx_dma_enable - function to start i.MX DMA channel operation
|
||||
* @dma_ch: i.MX DMA channel number
|
||||
*
|
||||
* The channel has to be allocated by driver through imx_dma_request()
|
||||
* or imx_dma_request_by_prio() function.
|
||||
* The transfer parameters has to be set to the channel registers through
|
||||
* call of the imx_dma_setup_single() or imx_dma_setup_sg() function
|
||||
* and registers %BLR(dma_ch), %RSSR(dma_ch) and %CCR(dma_ch) has to
|
||||
* be set prior this function call by the channel user.
|
||||
*/
|
||||
void imx_dma_enable(imx_dmach_t dma_ch)
|
||||
{
|
||||
struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
|
||||
unsigned long flags;
|
||||
|
||||
pr_debug("imxdma%d: imx_dma_enable\n", dma_ch);
|
||||
|
||||
if (!imxdma->name) {
|
||||
printk(KERN_CRIT "%s: called for not allocated channel %d\n",
|
||||
__FUNCTION__, dma_ch);
|
||||
return;
|
||||
}
|
||||
|
||||
local_irq_save(flags);
|
||||
DISR = (1 << dma_ch);
|
||||
DIMR &= ~(1 << dma_ch);
|
||||
CCR(dma_ch) |= CCR_CEN;
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* imx_dma_disable - stop, finish i.MX DMA channel operatin
|
||||
* @dma_ch: i.MX DMA channel number
|
||||
*/
|
||||
void imx_dma_disable(imx_dmach_t dma_ch)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (!dma_channels[dma_ch].name) {
|
||||
pr_debug("imxdma%d: imx_dma_disable\n", dma_ch);
|
||||
|
||||
local_irq_save(flags);
|
||||
DIMR |= (1 << dma_ch);
|
||||
CCR(dma_ch) &= ~CCR_CEN;
|
||||
DISR = (1 << dma_ch);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* imx_dma_request - request/allocate specified channel number
|
||||
* @dma_ch: i.MX DMA channel number
|
||||
* @name: the driver/caller own non-%NULL identification
|
||||
*/
|
||||
int imx_dma_request(imx_dmach_t dma_ch, const char *name)
|
||||
{
|
||||
struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
|
||||
unsigned long flags;
|
||||
|
||||
/* basic sanity checks */
|
||||
if (!name)
|
||||
return -EINVAL;
|
||||
|
||||
if (dma_ch >= IMX_DMA_CHANNELS) {
|
||||
printk(KERN_CRIT "%s: called for non-existed channel %d\n",
|
||||
__FUNCTION__, dma_ch);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
local_irq_save(flags);
|
||||
if (imxdma->name) {
|
||||
local_irq_restore(flags);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
imxdma->name = name;
|
||||
imxdma->irq_handler = NULL;
|
||||
imxdma->err_handler = NULL;
|
||||
imxdma->data = NULL;
|
||||
imxdma->sg = NULL;
|
||||
local_irq_restore(flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* imx_dma_free - release previously acquired channel
|
||||
* @dma_ch: i.MX DMA channel number
|
||||
*/
|
||||
void imx_dma_free(imx_dmach_t dma_ch)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
|
||||
|
||||
if (!imxdma->name) {
|
||||
printk(KERN_CRIT
|
||||
"%s: trying to free channel %d which is already freed\n",
|
||||
__FUNCTION__, dma_ch);
|
||||
@ -92,27 +398,84 @@ imx_free_dma(int dma_ch)
|
||||
}
|
||||
|
||||
local_irq_save(flags);
|
||||
DIMR &= ~(1 << dma_ch);
|
||||
dma_channels[dma_ch].name = NULL;
|
||||
/* Disable interrupts */
|
||||
DIMR |= (1 << dma_ch);
|
||||
CCR(dma_ch) &= ~CCR_CEN;
|
||||
imxdma->name = NULL;
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
static irqreturn_t
|
||||
dma_err_handler(int irq, void *dev_id, struct pt_regs *regs)
|
||||
/**
|
||||
* imx_dma_request_by_prio - find and request some of free channels best suiting requested priority
|
||||
* @dma_ch: i.MX DMA channel number
|
||||
* @name: the driver/caller own non-%NULL identification
|
||||
* @prio: one of the hardware distinguished priority level:
|
||||
* %DMA_PRIO_HIGH, %DMA_PRIO_MEDIUM, %DMA_PRIO_LOW
|
||||
*
|
||||
* This function tries to find free channel in the specified priority group
|
||||
* if the priority cannot be achieved it tries to look for free channel
|
||||
* in the higher and then even lower priority groups.
|
||||
*
|
||||
* Return value: If there is no free channel to allocate, -%ENODEV is returned.
|
||||
* Zero value indicates successful channel allocation.
|
||||
*/
|
||||
int
|
||||
imx_dma_request_by_prio(imx_dmach_t * pdma_ch, const char *name,
|
||||
imx_dma_prio prio)
|
||||
{
|
||||
int i;
|
||||
int best;
|
||||
|
||||
switch (prio) {
|
||||
case (DMA_PRIO_HIGH):
|
||||
best = 8;
|
||||
break;
|
||||
case (DMA_PRIO_MEDIUM):
|
||||
best = 4;
|
||||
break;
|
||||
case (DMA_PRIO_LOW):
|
||||
default:
|
||||
best = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = best; i < IMX_DMA_CHANNELS; i++) {
|
||||
if (!imx_dma_request(i, name)) {
|
||||
*pdma_ch = i;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = best - 1; i >= 0; i--) {
|
||||
if (!imx_dma_request(i, name)) {
|
||||
*pdma_ch = i;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
printk(KERN_ERR "%s: no free DMA channel found\n", __FUNCTION__);
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static irqreturn_t dma_err_handler(int irq, void *dev_id, struct pt_regs *regs)
|
||||
{
|
||||
int i, disr = DISR;
|
||||
struct dma_channel *channel;
|
||||
struct imx_dma_channel *channel;
|
||||
unsigned int err_mask = DBTOSR | DRTOSR | DSESR | DBOSR;
|
||||
|
||||
DISR = disr;
|
||||
for (i = 0; i < 11; i++) {
|
||||
channel = &dma_channels[i];
|
||||
for (i = 0; i < IMX_DMA_CHANNELS; i++) {
|
||||
channel = &imx_dma_channels[i];
|
||||
|
||||
if ( (err_mask & 1<<i) && channel->name && channel->err_handler) {
|
||||
if ((err_mask & 1 << i) && channel->name
|
||||
&& channel->err_handler) {
|
||||
channel->err_handler(i, channel->data, regs);
|
||||
continue;
|
||||
}
|
||||
|
||||
imx_dma_channels[i].sg = NULL;
|
||||
|
||||
if (DBTOSR & (1 << i)) {
|
||||
printk(KERN_WARNING
|
||||
"Burst timeout on channel %d (%s)\n",
|
||||
@ -141,17 +504,27 @@ dma_err_handler(int irq, void *dev_id, struct pt_regs *regs)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t
|
||||
dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
|
||||
static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
|
||||
{
|
||||
int i, disr = DISR;
|
||||
|
||||
pr_debug("imxdma: dma_irq_handler called, disr=0x%08x\n",
|
||||
disr);
|
||||
|
||||
DISR = disr;
|
||||
for (i = 0; i < 11; i++) {
|
||||
for (i = 0; i < IMX_DMA_CHANNELS; i++) {
|
||||
if (disr & (1 << i)) {
|
||||
struct dma_channel *channel = &dma_channels[i];
|
||||
if (channel->name && channel->irq_handler) {
|
||||
channel->irq_handler(i, channel->data, regs);
|
||||
struct imx_dma_channel *channel = &imx_dma_channels[i];
|
||||
if (channel->name) {
|
||||
if (imx_dma_sg_next(i, CNTR(i))) {
|
||||
CCR(i) &= ~CCR_CEN;
|
||||
mb();
|
||||
CCR(i) |= CCR_CEN;
|
||||
} else {
|
||||
if (channel->irq_handler)
|
||||
channel->irq_handler(i,
|
||||
channel->data, regs);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* IRQ for an unregistered DMA channel:
|
||||
@ -165,10 +538,10 @@ dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int __init
|
||||
imx_dma_init(void)
|
||||
static int __init imx_dma_init(void)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
/* reset DMA module */
|
||||
DCR = DCR_DRST;
|
||||
@ -189,15 +562,27 @@ imx_dma_init(void)
|
||||
DCR = DCR_DEN;
|
||||
|
||||
/* clear all interrupts */
|
||||
DISR = 0x3ff;
|
||||
DISR = (1 << IMX_DMA_CHANNELS) - 1;
|
||||
|
||||
/* enable interrupts */
|
||||
DIMR = 0;
|
||||
DIMR = (1 << IMX_DMA_CHANNELS) - 1;
|
||||
|
||||
for (i = 0; i < IMX_DMA_CHANNELS; i++) {
|
||||
imx_dma_channels[i].sg = NULL;
|
||||
imx_dma_channels[i].dma_num = i;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
arch_initcall(imx_dma_init);
|
||||
|
||||
EXPORT_SYMBOL(imx_request_dma);
|
||||
EXPORT_SYMBOL(imx_free_dma);
|
||||
EXPORT_SYMBOL(imx_dma_setup_single);
|
||||
EXPORT_SYMBOL(imx_dma_setup_sg);
|
||||
EXPORT_SYMBOL(imx_dma_setup_handlers);
|
||||
EXPORT_SYMBOL(imx_dma_enable);
|
||||
EXPORT_SYMBOL(imx_dma_disable);
|
||||
EXPORT_SYMBOL(imx_dma_request);
|
||||
EXPORT_SYMBOL(imx_dma_free);
|
||||
EXPORT_SYMBOL(imx_dma_request_by_prio);
|
||||
EXPORT_SYMBOL(imx_dma_channels);
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <asm/arch/imx-regs.h>
|
||||
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/arch/mmc.h>
|
||||
|
||||
void imx_gpio_mode(int gpio_mode)
|
||||
{
|
||||
@ -175,13 +176,25 @@ static struct resource imx_mmc_resources[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static u64 imxmmmc_dmamask = 0xffffffffUL;
|
||||
|
||||
static struct platform_device imx_mmc_device = {
|
||||
.name = "imx-mmc",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.dma_mask = &imxmmmc_dmamask,
|
||||
.coherent_dma_mask = 0xffffffff,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(imx_mmc_resources),
|
||||
.resource = imx_mmc_resources,
|
||||
};
|
||||
|
||||
void __init imx_set_mmc_info(struct imxmmc_platform_data *info)
|
||||
{
|
||||
imx_mmc_device.dev.platform_data = info;
|
||||
}
|
||||
EXPORT_SYMBOL(imx_set_mmc_info);
|
||||
|
||||
static struct resource imx_uart1_resources[] = {
|
||||
[0] = {
|
||||
.start = 0x00206000,
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/arch/mmc.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include "generic.h"
|
||||
|
||||
@ -51,11 +52,28 @@ static struct platform_device *devices[] __initdata = {
|
||||
&cs89x0_device,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MMC_IMX
|
||||
static int mx1ads_mmc_card_present(void)
|
||||
{
|
||||
/* MMC/SD Card Detect is PB 20 on MX1ADS V1.0.7 */
|
||||
return (SSR(1) & (1 << 20) ? 0 : 1);
|
||||
}
|
||||
|
||||
static struct imxmmc_platform_data mx1ads_mmc_info = {
|
||||
.card_present = mx1ads_mmc_card_present,
|
||||
};
|
||||
#endif
|
||||
|
||||
static void __init
|
||||
mx1ads_init(void)
|
||||
{
|
||||
#ifdef CONFIG_LEDS
|
||||
imx_gpio_mode(GPIO_PORTA | GPIO_OUT | 2);
|
||||
#endif
|
||||
#ifdef CONFIG_MMC_IMX
|
||||
/* SD/MMC card detect */
|
||||
imx_gpio_mode(GPIO_PORTB | GPIO_GIUS | GPIO_IN | 20);
|
||||
imx_set_mmc_info(&mx1ads_mmc_info);
|
||||
#endif
|
||||
platform_add_devices(devices, ARRAY_SIZE(devices));
|
||||
}
|
||||
|
@ -44,6 +44,15 @@
|
||||
#include <asm/mach/irq.h>
|
||||
#include <asm/mach/pci.h>
|
||||
|
||||
static int __init espresso_pci_init(void)
|
||||
{
|
||||
if (machine_is_espresso())
|
||||
ixp23xx_pci_slave_init();
|
||||
|
||||
return 0;
|
||||
};
|
||||
subsys_initcall(espresso_pci_init);
|
||||
|
||||
static void __init espresso_init(void)
|
||||
{
|
||||
physmap_configure(0x90000000, 0x02000000, 2, NULL);
|
||||
|
@ -201,7 +201,7 @@ int clear_master_aborts(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __init ixp23xx_pci_preinit(void)
|
||||
static void __init ixp23xx_pci_common_init(void)
|
||||
{
|
||||
#ifdef __ARMEB__
|
||||
*IXP23XX_PCI_CONTROL |= 0x20000; /* set I/O swapping */
|
||||
@ -219,7 +219,18 @@ void __init ixp23xx_pci_preinit(void)
|
||||
*IXP23XX_PCI_CPP_ADDR_BITS &= ~(1 << 1);
|
||||
} else {
|
||||
*IXP23XX_PCI_CPP_ADDR_BITS |= (1 << 1);
|
||||
|
||||
/*
|
||||
* Enable coherency on A2 silicon.
|
||||
*/
|
||||
if (arch_is_coherent())
|
||||
*IXP23XX_CPP2XSI_CURR_XFER_REG3 &= ~IXP23XX_CPP2XSI_COH_OFF;
|
||||
}
|
||||
}
|
||||
|
||||
void __init ixp23xx_pci_preinit(void)
|
||||
{
|
||||
ixp23xx_pci_common_init();
|
||||
|
||||
hook_fault_code(16+6, ixp23xx_pci_abort_handler, SIGBUS,
|
||||
"PCI config cycle to non-existent device");
|
||||
@ -273,3 +284,8 @@ int ixp23xx_pci_setup(int nr, struct pci_sys_data *sys)
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ixp23xx_pci_slave_init(void)
|
||||
{
|
||||
ixp23xx_pci_common_init();
|
||||
}
|
||||
|
@ -69,12 +69,6 @@ config MACH_VOICEBLUE
|
||||
Support for Voiceblue GSM/VoIP gateway. Say Y here if you have
|
||||
such a board.
|
||||
|
||||
config MACH_NETSTAR
|
||||
bool "NetStar"
|
||||
depends on ARCH_OMAP1 && ARCH_OMAP15XX
|
||||
help
|
||||
Support for NetStar PBX. Say Y here if you have such a board.
|
||||
|
||||
config MACH_OMAP_PALMTE
|
||||
bool "Palm Tungsten E"
|
||||
depends on ARCH_OMAP1 && ARCH_OMAP15XX
|
||||
@ -85,6 +79,20 @@ config MACH_OMAP_PALMTE
|
||||
informations.
|
||||
Say Y here if you have such a PDA, say NO otherwise.
|
||||
|
||||
config MACH_NOKIA770
|
||||
bool "Nokia 770"
|
||||
depends on ARCH_OMAP1 && ARCH_OMAP16XX
|
||||
help
|
||||
Support for the Nokia 770 Internet Tablet. Say Y here if you
|
||||
have such a device.
|
||||
|
||||
config MACH_AMS_DELTA
|
||||
bool "Amstrad E3 (Delta)"
|
||||
depends on ARCH_OMAP1 && ARCH_OMAP15XX
|
||||
help
|
||||
Support for the Amstrad E3 (codename Delta) videophone. Say Y here
|
||||
if you have such a device.
|
||||
|
||||
config MACH_OMAP_GENERIC
|
||||
bool "Generic OMAP board"
|
||||
depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX)
|
||||
|
@ -3,7 +3,13 @@
|
||||
#
|
||||
|
||||
# Common support
|
||||
obj-y := io.o id.o clock.o irq.o time.o mux.o serial.o devices.o
|
||||
obj-y := io.o id.o clock.o irq.o mux.o serial.o devices.o
|
||||
|
||||
obj-$(CONFIG_OMAP_MPU_TIMER) += time.o
|
||||
|
||||
# Power Management
|
||||
obj-$(CONFIG_PM) += pm.o sleep.o
|
||||
|
||||
led-y := leds.o
|
||||
|
||||
# Specific board support
|
||||
@ -14,8 +20,9 @@ obj-$(CONFIG_MACH_OMAP_PERSEUS2) += board-perseus2.o
|
||||
obj-$(CONFIG_MACH_OMAP_OSK) += board-osk.o
|
||||
obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o
|
||||
obj-$(CONFIG_MACH_VOICEBLUE) += board-voiceblue.o
|
||||
obj-$(CONFIG_MACH_NETSTAR) += board-netstar.o
|
||||
obj-$(CONFIG_MACH_OMAP_PALMTE) += board-palmte.o
|
||||
obj-$(CONFIG_MACH_NOKIA770) += board-nokia770.o
|
||||
obj-$(CONFIG_MACH_AMS_DELTA) += board-ams-delta.o
|
||||
|
||||
ifeq ($(CONFIG_ARCH_OMAP15XX),y)
|
||||
# Innovator-1510 FPGA
|
||||
|
116
arch/arm/mach-omap1/board-ams-delta.c
Normal file
116
arch/arm/mach-omap1/board-ams-delta.c
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap1/board-ams-delta.c
|
||||
*
|
||||
* Modified from board-generic.c
|
||||
*
|
||||
* Board specific inits for the Amstrad E3 (codename Delta) videophone
|
||||
*
|
||||
* Copyright (C) 2006 Jonathan McDowell <noodles@earth.li>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
|
||||
#include <asm/arch/board-ams-delta.h>
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/usb.h>
|
||||
#include <asm/arch/board.h>
|
||||
#include <asm/arch/common.h>
|
||||
|
||||
static u8 ams_delta_latch1_reg;
|
||||
static u16 ams_delta_latch2_reg;
|
||||
|
||||
void ams_delta_latch1_write(u8 mask, u8 value)
|
||||
{
|
||||
ams_delta_latch1_reg &= ~mask;
|
||||
ams_delta_latch1_reg |= value;
|
||||
*(volatile __u8 *) AMS_DELTA_LATCH1_VIRT = ams_delta_latch1_reg;
|
||||
}
|
||||
|
||||
void ams_delta_latch2_write(u16 mask, u16 value)
|
||||
{
|
||||
ams_delta_latch2_reg &= ~mask;
|
||||
ams_delta_latch2_reg |= value;
|
||||
*(volatile __u16 *) AMS_DELTA_LATCH2_VIRT = ams_delta_latch2_reg;
|
||||
}
|
||||
|
||||
static void __init ams_delta_init_irq(void)
|
||||
{
|
||||
omap1_init_common_hw();
|
||||
omap_init_irq();
|
||||
omap_gpio_init();
|
||||
}
|
||||
|
||||
static struct map_desc ams_delta_io_desc[] __initdata = {
|
||||
// AMS_DELTA_LATCH1
|
||||
{
|
||||
.virtual = AMS_DELTA_LATCH1_VIRT,
|
||||
.pfn = __phys_to_pfn(AMS_DELTA_LATCH1_PHYS),
|
||||
.length = 0x01000000,
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
// AMS_DELTA_LATCH2
|
||||
{
|
||||
.virtual = AMS_DELTA_LATCH2_VIRT,
|
||||
.pfn = __phys_to_pfn(AMS_DELTA_LATCH2_PHYS),
|
||||
.length = 0x01000000,
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
// AMS_DELTA_MODEM
|
||||
{
|
||||
.virtual = AMS_DELTA_MODEM_VIRT,
|
||||
.pfn = __phys_to_pfn(AMS_DELTA_MODEM_PHYS),
|
||||
.length = 0x01000000,
|
||||
.type = MT_DEVICE
|
||||
}
|
||||
};
|
||||
|
||||
static struct omap_uart_config ams_delta_uart_config __initdata = {
|
||||
.enabled_uarts = 1,
|
||||
};
|
||||
|
||||
static struct omap_board_config_kernel ams_delta_config[] = {
|
||||
{ OMAP_TAG_UART, &ams_delta_uart_config },
|
||||
};
|
||||
|
||||
static void __init ams_delta_init(void)
|
||||
{
|
||||
iotable_init(ams_delta_io_desc, ARRAY_SIZE(ams_delta_io_desc));
|
||||
|
||||
omap_board_config = ams_delta_config;
|
||||
omap_board_config_size = ARRAY_SIZE(ams_delta_config);
|
||||
omap_serial_init();
|
||||
|
||||
/* Clear latch2 (NAND, LCD, modem enable) */
|
||||
ams_delta_latch2_write(~0, 0);
|
||||
}
|
||||
|
||||
static void __init ams_delta_map_io(void)
|
||||
{
|
||||
omap1_map_common_io();
|
||||
}
|
||||
|
||||
MACHINE_START(AMS_DELTA, "Amstrad E3 (Delta)")
|
||||
/* Maintainer: Jonathan McDowell <noodles@earth.li> */
|
||||
.phys_io = 0xfff00000,
|
||||
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x10000100,
|
||||
.map_io = ams_delta_map_io,
|
||||
.init_irq = ams_delta_init_irq,
|
||||
.init_machine = ams_delta_init,
|
||||
.timer = &omap_timer,
|
||||
MACHINE_END
|
||||
|
||||
EXPORT_SYMBOL(ams_delta_latch1_write);
|
||||
EXPORT_SYMBOL(ams_delta_latch2_write);
|
@ -88,7 +88,7 @@ static struct omap_board_config_kernel generic_config[] = {
|
||||
static void __init omap_generic_init(void)
|
||||
{
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
if (cpu_is_omap1510()) {
|
||||
if (cpu_is_omap15xx()) {
|
||||
generic_config[0].data = &generic1510_usb_config;
|
||||
}
|
||||
#endif
|
||||
|
@ -24,7 +24,9 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/nand.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
@ -35,12 +37,55 @@
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/tc.h>
|
||||
#include <asm/arch/irda.h>
|
||||
#include <asm/arch/usb.h>
|
||||
#include <asm/arch/keypad.h>
|
||||
#include <asm/arch/common.h>
|
||||
#include <asm/arch/mcbsp.h>
|
||||
#include <asm/arch/omap-alsa.h>
|
||||
|
||||
extern int omap_gpio_init(void);
|
||||
|
||||
static struct mtd_partition h2_partitions[] = {
|
||||
static int h2_keymap[] = {
|
||||
KEY(0, 0, KEY_LEFT),
|
||||
KEY(0, 1, KEY_RIGHT),
|
||||
KEY(0, 2, KEY_3),
|
||||
KEY(0, 3, KEY_F10),
|
||||
KEY(0, 4, KEY_F5),
|
||||
KEY(0, 5, KEY_9),
|
||||
KEY(1, 0, KEY_DOWN),
|
||||
KEY(1, 1, KEY_UP),
|
||||
KEY(1, 2, KEY_2),
|
||||
KEY(1, 3, KEY_F9),
|
||||
KEY(1, 4, KEY_F7),
|
||||
KEY(1, 5, KEY_0),
|
||||
KEY(2, 0, KEY_ENTER),
|
||||
KEY(2, 1, KEY_6),
|
||||
KEY(2, 2, KEY_1),
|
||||
KEY(2, 3, KEY_F2),
|
||||
KEY(2, 4, KEY_F6),
|
||||
KEY(2, 5, KEY_HOME),
|
||||
KEY(3, 0, KEY_8),
|
||||
KEY(3, 1, KEY_5),
|
||||
KEY(3, 2, KEY_F12),
|
||||
KEY(3, 3, KEY_F3),
|
||||
KEY(3, 4, KEY_F8),
|
||||
KEY(3, 5, KEY_END),
|
||||
KEY(4, 0, KEY_7),
|
||||
KEY(4, 1, KEY_4),
|
||||
KEY(4, 2, KEY_F11),
|
||||
KEY(4, 3, KEY_F1),
|
||||
KEY(4, 4, KEY_F4),
|
||||
KEY(4, 5, KEY_ESC),
|
||||
KEY(5, 0, KEY_F13),
|
||||
KEY(5, 1, KEY_F14),
|
||||
KEY(5, 2, KEY_F15),
|
||||
KEY(5, 3, KEY_F16),
|
||||
KEY(5, 4, KEY_SLEEP),
|
||||
0
|
||||
};
|
||||
|
||||
static struct mtd_partition h2_nor_partitions[] = {
|
||||
/* bootloader (U-Boot, etc) in first sector */
|
||||
{
|
||||
.name = "bootloader",
|
||||
@ -71,26 +116,26 @@ static struct mtd_partition h2_partitions[] = {
|
||||
}
|
||||
};
|
||||
|
||||
static struct flash_platform_data h2_flash_data = {
|
||||
static struct flash_platform_data h2_nor_data = {
|
||||
.map_name = "cfi_probe",
|
||||
.width = 2,
|
||||
.parts = h2_partitions,
|
||||
.nr_parts = ARRAY_SIZE(h2_partitions),
|
||||
.parts = h2_nor_partitions,
|
||||
.nr_parts = ARRAY_SIZE(h2_nor_partitions),
|
||||
};
|
||||
|
||||
static struct resource h2_flash_resource = {
|
||||
static struct resource h2_nor_resource = {
|
||||
/* This is on CS3, wherever it's mapped */
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct platform_device h2_flash_device = {
|
||||
static struct platform_device h2_nor_device = {
|
||||
.name = "omapflash",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &h2_flash_data,
|
||||
.platform_data = &h2_nor_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &h2_flash_resource,
|
||||
.resource = &h2_nor_resource,
|
||||
};
|
||||
|
||||
static struct resource h2_smc91x_resources[] = {
|
||||
@ -113,9 +158,119 @@ static struct platform_device h2_smc91x_device = {
|
||||
.resource = h2_smc91x_resources,
|
||||
};
|
||||
|
||||
static struct resource h2_kp_resources[] = {
|
||||
[0] = {
|
||||
.start = INT_KEYBOARD,
|
||||
.end = INT_KEYBOARD,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct omap_kp_platform_data h2_kp_data = {
|
||||
.rows = 8,
|
||||
.cols = 8,
|
||||
.keymap = h2_keymap,
|
||||
.rep = 1,
|
||||
};
|
||||
|
||||
static struct platform_device h2_kp_device = {
|
||||
.name = "omap-keypad",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &h2_kp_data,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(h2_kp_resources),
|
||||
.resource = h2_kp_resources,
|
||||
};
|
||||
|
||||
#define H2_IRDA_FIRSEL_GPIO_PIN 17
|
||||
|
||||
#if defined(CONFIG_OMAP_IR) || defined(CONFIG_OMAP_IR_MODULE)
|
||||
static int h2_transceiver_mode(struct device *dev, int state)
|
||||
{
|
||||
if (state & IR_SIRMODE)
|
||||
omap_set_gpio_dataout(H2_IRDA_FIRSEL_GPIO_PIN, 0);
|
||||
else /* MIR/FIR */
|
||||
omap_set_gpio_dataout(H2_IRDA_FIRSEL_GPIO_PIN, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct omap_irda_config h2_irda_data = {
|
||||
.transceiver_cap = IR_SIRMODE | IR_MIRMODE | IR_FIRMODE,
|
||||
.rx_channel = OMAP_DMA_UART3_RX,
|
||||
.tx_channel = OMAP_DMA_UART3_TX,
|
||||
.dest_start = UART3_THR,
|
||||
.src_start = UART3_RHR,
|
||||
.tx_trigger = 0,
|
||||
.rx_trigger = 0,
|
||||
};
|
||||
|
||||
static struct resource h2_irda_resources[] = {
|
||||
[0] = {
|
||||
.start = INT_UART3,
|
||||
.end = INT_UART3,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
static struct platform_device h2_irda_device = {
|
||||
.name = "omapirda",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &h2_irda_data,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(h2_irda_resources),
|
||||
.resource = h2_irda_resources,
|
||||
};
|
||||
|
||||
static struct platform_device h2_lcd_device = {
|
||||
.name = "lcd_h2",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static struct omap_mcbsp_reg_cfg mcbsp_regs = {
|
||||
.spcr2 = FREE | FRST | GRST | XRST | XINTM(3),
|
||||
.spcr1 = RINTM(3) | RRST,
|
||||
.rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) |
|
||||
RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(1),
|
||||
.rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16),
|
||||
.xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) |
|
||||
XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(1) | XFIG,
|
||||
.xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16),
|
||||
.srgr1 = FWID(15),
|
||||
.srgr2 = GSYNC | CLKSP | FSGM | FPER(31),
|
||||
|
||||
.pcr0 = CLKXM | CLKRM | FSXP | FSRP | CLKXP | CLKRP,
|
||||
//.pcr0 = CLKXP | CLKRP, /* mcbsp: slave */
|
||||
};
|
||||
|
||||
static struct omap_alsa_codec_config alsa_config = {
|
||||
.name = "H2 TSC2101",
|
||||
.mcbsp_regs_alsa = &mcbsp_regs,
|
||||
.codec_configure_dev = NULL, // tsc2101_configure,
|
||||
.codec_set_samplerate = NULL, // tsc2101_set_samplerate,
|
||||
.codec_clock_setup = NULL, // tsc2101_clock_setup,
|
||||
.codec_clock_on = NULL, // tsc2101_clock_on,
|
||||
.codec_clock_off = NULL, // tsc2101_clock_off,
|
||||
.get_default_samplerate = NULL, // tsc2101_get_default_samplerate,
|
||||
};
|
||||
|
||||
static struct platform_device h2_mcbsp1_device = {
|
||||
.name = "omap_alsa_mcbsp",
|
||||
.id = 1,
|
||||
.dev = {
|
||||
.platform_data = &alsa_config,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device *h2_devices[] __initdata = {
|
||||
&h2_flash_device,
|
||||
&h2_nor_device,
|
||||
&h2_smc91x_device,
|
||||
&h2_irda_device,
|
||||
&h2_kp_device,
|
||||
&h2_lcd_device,
|
||||
&h2_mcbsp1_device,
|
||||
};
|
||||
|
||||
static void __init h2_init_smc91x(void)
|
||||
@ -164,7 +319,6 @@ static struct omap_uart_config h2_uart_config __initdata = {
|
||||
};
|
||||
|
||||
static struct omap_lcd_config h2_lcd_config __initdata = {
|
||||
.panel_name = "h2",
|
||||
.ctrl_name = "internal",
|
||||
};
|
||||
|
||||
@ -177,16 +331,34 @@ static struct omap_board_config_kernel h2_config[] = {
|
||||
|
||||
static void __init h2_init(void)
|
||||
{
|
||||
/* NOTE: revC boards support NAND-boot, which can put NOR on CS2B
|
||||
* and NAND (either 16bit or 8bit) on CS3.
|
||||
/* Here we assume the NOR boot config: NOR on CS3 (possibly swapped
|
||||
* to address 0 by a dip switch), NAND on CS2B. The NAND driver will
|
||||
* notice whether a NAND chip is enabled at probe time.
|
||||
*
|
||||
* FIXME revC boards (and H3) support NAND-boot, with a dip switch to
|
||||
* put NOR on CS2B and NAND (which on H2 may be 16bit) on CS3. Try
|
||||
* detecting that in code here, to avoid probing every possible flash
|
||||
* configuration...
|
||||
*/
|
||||
h2_flash_resource.end = h2_flash_resource.start = omap_cs3_phys();
|
||||
h2_flash_resource.end += SZ_32M - 1;
|
||||
h2_nor_resource.end = h2_nor_resource.start = omap_cs3_phys();
|
||||
h2_nor_resource.end += SZ_32M - 1;
|
||||
|
||||
omap_cfg_reg(L3_1610_FLASH_CS2B_OE);
|
||||
omap_cfg_reg(M8_1610_FLASH_CS2B_WE);
|
||||
|
||||
/* MMC: card detect and WP */
|
||||
// omap_cfg_reg(U19_ARMIO1); /* CD */
|
||||
omap_cfg_reg(BALLOUT_V8_ARMIO3); /* WP */
|
||||
|
||||
/* Irda */
|
||||
#if defined(CONFIG_OMAP_IR) || defined(CONFIG_OMAP_IR_MODULE)
|
||||
omap_writel(omap_readl(FUNC_MUX_CTRL_A) | 7, FUNC_MUX_CTRL_A);
|
||||
if (!(omap_request_gpio(H2_IRDA_FIRSEL_GPIO_PIN))) {
|
||||
omap_set_gpio_direction(H2_IRDA_FIRSEL_GPIO_PIN, 0);
|
||||
h2_irda_data.transceiver_mode = h2_transceiver_mode;
|
||||
}
|
||||
#endif
|
||||
|
||||
platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices));
|
||||
omap_board_config = h2_config;
|
||||
omap_board_config_size = ARRAY_SIZE(h2_config);
|
||||
|
@ -21,8 +21,11 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/nand.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/page.h>
|
||||
@ -33,15 +36,59 @@
|
||||
#include <asm/mach/map.h>
|
||||
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/arch/gpioexpander.h>
|
||||
#include <asm/arch/irqs.h>
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/tc.h>
|
||||
#include <asm/arch/irda.h>
|
||||
#include <asm/arch/usb.h>
|
||||
#include <asm/arch/keypad.h>
|
||||
#include <asm/arch/dma.h>
|
||||
#include <asm/arch/common.h>
|
||||
|
||||
extern int omap_gpio_init(void);
|
||||
|
||||
static struct mtd_partition h3_partitions[] = {
|
||||
static int h3_keymap[] = {
|
||||
KEY(0, 0, KEY_LEFT),
|
||||
KEY(0, 1, KEY_RIGHT),
|
||||
KEY(0, 2, KEY_3),
|
||||
KEY(0, 3, KEY_F10),
|
||||
KEY(0, 4, KEY_F5),
|
||||
KEY(0, 5, KEY_9),
|
||||
KEY(1, 0, KEY_DOWN),
|
||||
KEY(1, 1, KEY_UP),
|
||||
KEY(1, 2, KEY_2),
|
||||
KEY(1, 3, KEY_F9),
|
||||
KEY(1, 4, KEY_F7),
|
||||
KEY(1, 5, KEY_0),
|
||||
KEY(2, 0, KEY_ENTER),
|
||||
KEY(2, 1, KEY_6),
|
||||
KEY(2, 2, KEY_1),
|
||||
KEY(2, 3, KEY_F2),
|
||||
KEY(2, 4, KEY_F6),
|
||||
KEY(2, 5, KEY_HOME),
|
||||
KEY(3, 0, KEY_8),
|
||||
KEY(3, 1, KEY_5),
|
||||
KEY(3, 2, KEY_F12),
|
||||
KEY(3, 3, KEY_F3),
|
||||
KEY(3, 4, KEY_F8),
|
||||
KEY(3, 5, KEY_END),
|
||||
KEY(4, 0, KEY_7),
|
||||
KEY(4, 1, KEY_4),
|
||||
KEY(4, 2, KEY_F11),
|
||||
KEY(4, 3, KEY_F1),
|
||||
KEY(4, 4, KEY_F4),
|
||||
KEY(4, 5, KEY_ESC),
|
||||
KEY(5, 0, KEY_F13),
|
||||
KEY(5, 1, KEY_F14),
|
||||
KEY(5, 2, KEY_F15),
|
||||
KEY(5, 3, KEY_F16),
|
||||
KEY(5, 4, KEY_SLEEP),
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
static struct mtd_partition nor_partitions[] = {
|
||||
/* bootloader (U-Boot, etc) in first sector */
|
||||
{
|
||||
.name = "bootloader",
|
||||
@ -72,26 +119,80 @@ static struct mtd_partition h3_partitions[] = {
|
||||
}
|
||||
};
|
||||
|
||||
static struct flash_platform_data h3_flash_data = {
|
||||
static struct flash_platform_data nor_data = {
|
||||
.map_name = "cfi_probe",
|
||||
.width = 2,
|
||||
.parts = h3_partitions,
|
||||
.nr_parts = ARRAY_SIZE(h3_partitions),
|
||||
.parts = nor_partitions,
|
||||
.nr_parts = ARRAY_SIZE(nor_partitions),
|
||||
};
|
||||
|
||||
static struct resource h3_flash_resource = {
|
||||
static struct resource nor_resource = {
|
||||
/* This is on CS3, wherever it's mapped */
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct platform_device flash_device = {
|
||||
static struct platform_device nor_device = {
|
||||
.name = "omapflash",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &h3_flash_data,
|
||||
.platform_data = &nor_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &h3_flash_resource,
|
||||
.resource = &nor_resource,
|
||||
};
|
||||
|
||||
static struct mtd_partition nand_partitions[] = {
|
||||
#if 0
|
||||
/* REVISIT: enable these partitions if you make NAND BOOT work */
|
||||
{
|
||||
.name = "xloader",
|
||||
.offset = 0,
|
||||
.size = 64 * 1024,
|
||||
.mask_flags = MTD_WRITEABLE, /* force read-only */
|
||||
},
|
||||
{
|
||||
.name = "bootloader",
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.size = 256 * 1024,
|
||||
.mask_flags = MTD_WRITEABLE, /* force read-only */
|
||||
},
|
||||
{
|
||||
.name = "params",
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.size = 192 * 1024,
|
||||
},
|
||||
{
|
||||
.name = "kernel",
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.size = 2 * SZ_1M,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.name = "filesystem",
|
||||
.size = MTDPART_SIZ_FULL,
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
},
|
||||
};
|
||||
|
||||
/* dip switches control NAND chip access: 8 bit, 16 bit, or neither */
|
||||
static struct nand_platform_data nand_data = {
|
||||
.options = NAND_SAMSUNG_LP_OPTIONS,
|
||||
.parts = nand_partitions,
|
||||
.nr_parts = ARRAY_SIZE(nand_partitions),
|
||||
};
|
||||
|
||||
static struct resource nand_resource = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct platform_device nand_device = {
|
||||
.name = "omapnand",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &nand_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &nand_resource,
|
||||
};
|
||||
|
||||
static struct resource smc91x_resources[] = {
|
||||
@ -138,10 +239,136 @@ static struct platform_device intlat_device = {
|
||||
.resource = intlat_resources,
|
||||
};
|
||||
|
||||
static struct resource h3_kp_resources[] = {
|
||||
[0] = {
|
||||
.start = INT_KEYBOARD,
|
||||
.end = INT_KEYBOARD,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct omap_kp_platform_data h3_kp_data = {
|
||||
.rows = 8,
|
||||
.cols = 8,
|
||||
.keymap = h3_keymap,
|
||||
.rep = 1,
|
||||
};
|
||||
|
||||
static struct platform_device h3_kp_device = {
|
||||
.name = "omap-keypad",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &h3_kp_data,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(h3_kp_resources),
|
||||
.resource = h3_kp_resources,
|
||||
};
|
||||
|
||||
|
||||
/* Select between the IrDA and aGPS module
|
||||
*/
|
||||
static int h3_select_irda(struct device *dev, int state)
|
||||
{
|
||||
unsigned char expa;
|
||||
int err = 0;
|
||||
|
||||
if ((err = read_gpio_expa(&expa, 0x26))) {
|
||||
printk(KERN_ERR "Error reading from I/O EXPANDER \n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* 'P6' enable/disable IRDA_TX and IRDA_RX */
|
||||
if (state & IR_SEL) { /* IrDA */
|
||||
if ((err = write_gpio_expa(expa | 0x40, 0x26))) {
|
||||
printk(KERN_ERR "Error writing to I/O EXPANDER \n");
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
if ((err = write_gpio_expa(expa & ~0x40, 0x26))) {
|
||||
printk(KERN_ERR "Error writing to I/O EXPANDER \n");
|
||||
return err;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static void set_trans_mode(void *data)
|
||||
{
|
||||
int *mode = data;
|
||||
unsigned char expa;
|
||||
int err = 0;
|
||||
|
||||
if ((err = read_gpio_expa(&expa, 0x27)) != 0) {
|
||||
printk(KERN_ERR "Error reading from I/O expander\n");
|
||||
}
|
||||
|
||||
expa &= ~0x03;
|
||||
|
||||
if (*mode & IR_SIRMODE) {
|
||||
expa |= 0x01;
|
||||
} else { /* MIR/FIR */
|
||||
expa |= 0x03;
|
||||
}
|
||||
|
||||
if ((err = write_gpio_expa(expa, 0x27)) != 0) {
|
||||
printk(KERN_ERR "Error writing to I/O expander\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int h3_transceiver_mode(struct device *dev, int mode)
|
||||
{
|
||||
struct omap_irda_config *irda_config = dev->platform_data;
|
||||
|
||||
cancel_delayed_work(&irda_config->gpio_expa);
|
||||
PREPARE_WORK(&irda_config->gpio_expa, set_trans_mode, &mode);
|
||||
schedule_work(&irda_config->gpio_expa);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct omap_irda_config h3_irda_data = {
|
||||
.transceiver_cap = IR_SIRMODE | IR_MIRMODE | IR_FIRMODE,
|
||||
.transceiver_mode = h3_transceiver_mode,
|
||||
.select_irda = h3_select_irda,
|
||||
.rx_channel = OMAP_DMA_UART3_RX,
|
||||
.tx_channel = OMAP_DMA_UART3_TX,
|
||||
.dest_start = UART3_THR,
|
||||
.src_start = UART3_RHR,
|
||||
.tx_trigger = 0,
|
||||
.rx_trigger = 0,
|
||||
};
|
||||
|
||||
static struct resource h3_irda_resources[] = {
|
||||
[0] = {
|
||||
.start = INT_UART3,
|
||||
.end = INT_UART3,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device h3_irda_device = {
|
||||
.name = "omapirda",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &h3_irda_data,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(h3_irda_resources),
|
||||
.resource = h3_irda_resources,
|
||||
};
|
||||
|
||||
static struct platform_device h3_lcd_device = {
|
||||
.name = "lcd_h3",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static struct platform_device *devices[] __initdata = {
|
||||
&flash_device,
|
||||
&nor_device,
|
||||
&nand_device,
|
||||
&smc91x_device,
|
||||
&intlat_device,
|
||||
&h3_irda_device,
|
||||
&h3_kp_device,
|
||||
&h3_lcd_device,
|
||||
};
|
||||
|
||||
static struct omap_usb_config h3_usb_config __initdata = {
|
||||
@ -171,7 +398,6 @@ static struct omap_uart_config h3_uart_config __initdata = {
|
||||
};
|
||||
|
||||
static struct omap_lcd_config h3_lcd_config __initdata = {
|
||||
.panel_name = "h3",
|
||||
.ctrl_name = "internal",
|
||||
};
|
||||
|
||||
@ -182,11 +408,36 @@ static struct omap_board_config_kernel h3_config[] = {
|
||||
{ OMAP_TAG_LCD, &h3_lcd_config },
|
||||
};
|
||||
|
||||
#define H3_NAND_RB_GPIO_PIN 10
|
||||
|
||||
static int nand_dev_ready(struct nand_platform_data *data)
|
||||
{
|
||||
return omap_get_gpio_datain(H3_NAND_RB_GPIO_PIN);
|
||||
}
|
||||
|
||||
static void __init h3_init(void)
|
||||
{
|
||||
h3_flash_resource.end = h3_flash_resource.start = omap_cs3_phys();
|
||||
h3_flash_resource.end += OMAP_CS3_SIZE - 1;
|
||||
(void) platform_add_devices(devices, ARRAY_SIZE(devices));
|
||||
/* Here we assume the NOR boot config: NOR on CS3 (possibly swapped
|
||||
* to address 0 by a dip switch), NAND on CS2B. The NAND driver will
|
||||
* notice whether a NAND chip is enabled at probe time.
|
||||
*
|
||||
* H3 support NAND-boot, with a dip switch to put NOR on CS2B and NAND
|
||||
* (which on H2 may be 16bit) on CS3. Try detecting that in code here,
|
||||
* to avoid probing every possible flash configuration...
|
||||
*/
|
||||
nor_resource.end = nor_resource.start = omap_cs3_phys();
|
||||
nor_resource.end += SZ_32M - 1;
|
||||
|
||||
nand_resource.end = nand_resource.start = OMAP_CS2B_PHYS;
|
||||
nand_resource.end += SZ_4K - 1;
|
||||
if (!(omap_request_gpio(H3_NAND_RB_GPIO_PIN)))
|
||||
nand_data.dev_ready = nand_dev_ready;
|
||||
|
||||
/* GPIO10 Func_MUX_CTRL reg bit 29:27, Configure V2 to mode1 as GPIO */
|
||||
/* GPIO10 pullup/down register, Enable pullup on GPIO10 */
|
||||
omap_cfg_reg(V2_1710_GPIO10);
|
||||
|
||||
platform_add_devices(devices, ARRAY_SIZE(devices));
|
||||
omap_board_config = h3_config;
|
||||
omap_board_config_size = ARRAY_SIZE(h3_config);
|
||||
omap_serial_init();
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
@ -34,8 +35,22 @@
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/arch/tc.h>
|
||||
#include <asm/arch/usb.h>
|
||||
#include <asm/arch/keypad.h>
|
||||
#include <asm/arch/common.h>
|
||||
|
||||
static int innovator_keymap[] = {
|
||||
KEY(0, 0, KEY_F1),
|
||||
KEY(0, 3, KEY_DOWN),
|
||||
KEY(1, 1, KEY_F2),
|
||||
KEY(1, 2, KEY_RIGHT),
|
||||
KEY(2, 0, KEY_F3),
|
||||
KEY(2, 1, KEY_F4),
|
||||
KEY(2, 2, KEY_UP),
|
||||
KEY(3, 2, KEY_ENTER),
|
||||
KEY(3, 3, KEY_LEFT),
|
||||
0
|
||||
};
|
||||
|
||||
static struct mtd_partition innovator_partitions[] = {
|
||||
/* bootloader (U-Boot, etc) in first sector */
|
||||
{
|
||||
@ -97,6 +112,31 @@ static struct platform_device innovator_flash_device = {
|
||||
.resource = &innovator_flash_resource,
|
||||
};
|
||||
|
||||
static struct resource innovator_kp_resources[] = {
|
||||
[0] = {
|
||||
.start = INT_KEYBOARD,
|
||||
.end = INT_KEYBOARD,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct omap_kp_platform_data innovator_kp_data = {
|
||||
.rows = 8,
|
||||
.cols = 8,
|
||||
.keymap = innovator_keymap,
|
||||
};
|
||||
|
||||
static struct platform_device innovator_kp_device = {
|
||||
.name = "omap-keypad",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &innovator_kp_data,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(innovator_kp_resources),
|
||||
.resource = innovator_kp_resources,
|
||||
};
|
||||
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
|
||||
/* Only FPGA needs to be mapped here. All others are done with ioremap */
|
||||
@ -129,9 +169,16 @@ static struct platform_device innovator1510_smc91x_device = {
|
||||
.resource = innovator1510_smc91x_resources,
|
||||
};
|
||||
|
||||
static struct platform_device innovator1510_lcd_device = {
|
||||
.name = "lcd_inn1510",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static struct platform_device *innovator1510_devices[] __initdata = {
|
||||
&innovator_flash_device,
|
||||
&innovator1510_smc91x_device,
|
||||
&innovator_kp_device,
|
||||
&innovator1510_lcd_device,
|
||||
};
|
||||
|
||||
#endif /* CONFIG_ARCH_OMAP15XX */
|
||||
@ -158,9 +205,16 @@ static struct platform_device innovator1610_smc91x_device = {
|
||||
.resource = innovator1610_smc91x_resources,
|
||||
};
|
||||
|
||||
static struct platform_device innovator1610_lcd_device = {
|
||||
.name = "inn1610_lcd",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static struct platform_device *innovator1610_devices[] __initdata = {
|
||||
&innovator_flash_device,
|
||||
&innovator1610_smc91x_device,
|
||||
&innovator_kp_device,
|
||||
&innovator1610_lcd_device,
|
||||
};
|
||||
|
||||
#endif /* CONFIG_ARCH_OMAP16XX */
|
||||
@ -206,7 +260,6 @@ static struct omap_usb_config innovator1510_usb_config __initdata = {
|
||||
};
|
||||
|
||||
static struct omap_lcd_config innovator1510_lcd_config __initdata = {
|
||||
.panel_name = "inn1510",
|
||||
.ctrl_name = "internal",
|
||||
};
|
||||
#endif
|
||||
@ -228,7 +281,6 @@ static struct omap_usb_config h2_usb_config __initdata = {
|
||||
};
|
||||
|
||||
static struct omap_lcd_config innovator1610_lcd_config __initdata = {
|
||||
.panel_name = "inn1610",
|
||||
.ctrl_name = "internal",
|
||||
};
|
||||
#endif
|
||||
|
@ -1,160 +0,0 @@
|
||||
/*
|
||||
* Modified from board-generic.c
|
||||
*
|
||||
* Copyright (C) 2004 2N Telekomunikace, Ladislav Michl <michl@2n.cz>
|
||||
*
|
||||
* Code for Netstar OMAP board.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/reboot.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/usb.h>
|
||||
#include <asm/arch/common.h>
|
||||
|
||||
extern void __init omap_init_time(void);
|
||||
extern int omap_gpio_init(void);
|
||||
|
||||
static struct resource netstar_smc91x_resources[] = {
|
||||
[0] = {
|
||||
.start = OMAP_CS1_PHYS + 0x300,
|
||||
.end = OMAP_CS1_PHYS + 0x300 + 16,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = OMAP_GPIO_IRQ(8),
|
||||
.end = OMAP_GPIO_IRQ(8),
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device netstar_smc91x_device = {
|
||||
.name = "smc91x",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(netstar_smc91x_resources),
|
||||
.resource = netstar_smc91x_resources,
|
||||
};
|
||||
|
||||
static struct platform_device *netstar_devices[] __initdata = {
|
||||
&netstar_smc91x_device,
|
||||
};
|
||||
|
||||
static struct omap_uart_config netstar_uart_config __initdata = {
|
||||
.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
|
||||
};
|
||||
|
||||
static struct omap_board_config_kernel netstar_config[] = {
|
||||
{ OMAP_TAG_UART, &netstar_uart_config },
|
||||
};
|
||||
|
||||
static void __init netstar_init_irq(void)
|
||||
{
|
||||
omap1_init_common_hw();
|
||||
omap_init_irq();
|
||||
omap_gpio_init();
|
||||
}
|
||||
|
||||
static void __init netstar_init(void)
|
||||
{
|
||||
/* green LED */
|
||||
omap_request_gpio(4);
|
||||
omap_set_gpio_direction(4, 0);
|
||||
/* smc91x reset */
|
||||
omap_request_gpio(7);
|
||||
omap_set_gpio_direction(7, 0);
|
||||
omap_set_gpio_dataout(7, 1);
|
||||
udelay(2); /* wait at least 100ns */
|
||||
omap_set_gpio_dataout(7, 0);
|
||||
mdelay(50); /* 50ms until PHY ready */
|
||||
/* smc91x interrupt pin */
|
||||
omap_request_gpio(8);
|
||||
|
||||
omap_request_gpio(12);
|
||||
omap_request_gpio(13);
|
||||
omap_request_gpio(14);
|
||||
omap_request_gpio(15);
|
||||
set_irq_type(OMAP_GPIO_IRQ(12), IRQT_FALLING);
|
||||
set_irq_type(OMAP_GPIO_IRQ(13), IRQT_FALLING);
|
||||
set_irq_type(OMAP_GPIO_IRQ(14), IRQT_FALLING);
|
||||
set_irq_type(OMAP_GPIO_IRQ(15), IRQT_FALLING);
|
||||
|
||||
platform_add_devices(netstar_devices, ARRAY_SIZE(netstar_devices));
|
||||
|
||||
/* Switch on green LED */
|
||||
omap_set_gpio_dataout(4, 0);
|
||||
/* Switch off red LED */
|
||||
omap_writeb(0x00, OMAP_LPG1_PMR); /* Disable clock */
|
||||
omap_writeb(0x80, OMAP_LPG1_LCR);
|
||||
|
||||
omap_board_config = netstar_config;
|
||||
omap_board_config_size = ARRAY_SIZE(netstar_config);
|
||||
omap_serial_init();
|
||||
}
|
||||
|
||||
static void __init netstar_map_io(void)
|
||||
{
|
||||
omap1_map_common_io();
|
||||
}
|
||||
|
||||
#define MACHINE_PANICED 1
|
||||
#define MACHINE_REBOOTING 2
|
||||
#define MACHINE_REBOOT 4
|
||||
static unsigned long machine_state;
|
||||
|
||||
static int panic_event(struct notifier_block *this, unsigned long event,
|
||||
void *ptr)
|
||||
{
|
||||
if (test_and_set_bit(MACHINE_PANICED, &machine_state))
|
||||
return NOTIFY_DONE;
|
||||
|
||||
/* Switch off green LED */
|
||||
omap_set_gpio_dataout(4, 1);
|
||||
/* Flash red LED */
|
||||
omap_writeb(0x78, OMAP_LPG1_LCR);
|
||||
omap_writeb(0x01, OMAP_LPG1_PMR); /* Enable clock */
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static struct notifier_block panic_block = {
|
||||
.notifier_call = panic_event,
|
||||
};
|
||||
|
||||
static int __init netstar_late_init(void)
|
||||
{
|
||||
/* TODO: Setup front panel switch here */
|
||||
|
||||
/* Setup panic notifier */
|
||||
atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
postcore_initcall(netstar_late_init);
|
||||
|
||||
MACHINE_START(NETSTAR, "NetStar OMAP5910")
|
||||
/* Maintainer: Ladislav Michl <michl@2n.cz> */
|
||||
.phys_io = 0xfff00000,
|
||||
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x10000100,
|
||||
.map_io = netstar_map_io,
|
||||
.init_irq = netstar_init_irq,
|
||||
.init_machine = netstar_init,
|
||||
.timer = &omap_timer,
|
||||
MACHINE_END
|
268
arch/arm/mach-omap1/board-nokia770.c
Normal file
268
arch/arm/mach-omap1/board-nokia770.c
Normal file
@ -0,0 +1,268 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap1/board-nokia770.c
|
||||
*
|
||||
* Modified from board-generic.c
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/ads7846.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/usb.h>
|
||||
#include <asm/arch/board.h>
|
||||
#include <asm/arch/keypad.h>
|
||||
#include <asm/arch/common.h>
|
||||
#include <asm/arch/dsp_common.h>
|
||||
#include <asm/arch/aic23.h>
|
||||
#include <asm/arch/gpio.h>
|
||||
|
||||
static void __init omap_nokia770_init_irq(void)
|
||||
{
|
||||
/* On Nokia 770, the SleepX signal is masked with an
|
||||
* MPUIO line by default. It has to be unmasked for it
|
||||
* to become functional */
|
||||
|
||||
/* SleepX mask direction */
|
||||
omap_writew((omap_readw(0xfffb5008) & ~2), 0xfffb5008);
|
||||
/* Unmask SleepX signal */
|
||||
omap_writew((omap_readw(0xfffb5004) & ~2), 0xfffb5004);
|
||||
|
||||
omap1_init_common_hw();
|
||||
omap_init_irq();
|
||||
}
|
||||
|
||||
static int nokia770_keymap[] = {
|
||||
KEY(0, 1, GROUP_0 | KEY_UP),
|
||||
KEY(0, 2, GROUP_1 | KEY_F5),
|
||||
KEY(1, 0, GROUP_0 | KEY_LEFT),
|
||||
KEY(1, 1, GROUP_0 | KEY_ENTER),
|
||||
KEY(1, 2, GROUP_0 | KEY_RIGHT),
|
||||
KEY(2, 0, GROUP_1 | KEY_ESC),
|
||||
KEY(2, 1, GROUP_0 | KEY_DOWN),
|
||||
KEY(2, 2, GROUP_1 | KEY_F4),
|
||||
KEY(3, 0, GROUP_2 | KEY_F7),
|
||||
KEY(3, 1, GROUP_2 | KEY_F8),
|
||||
KEY(3, 2, GROUP_2 | KEY_F6),
|
||||
0
|
||||
};
|
||||
|
||||
static struct resource nokia770_kp_resources[] = {
|
||||
[0] = {
|
||||
.start = INT_KEYBOARD,
|
||||
.end = INT_KEYBOARD,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct omap_kp_platform_data nokia770_kp_data = {
|
||||
.rows = 8,
|
||||
.cols = 8,
|
||||
.keymap = nokia770_keymap
|
||||
};
|
||||
|
||||
static struct platform_device nokia770_kp_device = {
|
||||
.name = "omap-keypad",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &nokia770_kp_data,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(nokia770_kp_resources),
|
||||
.resource = nokia770_kp_resources,
|
||||
};
|
||||
|
||||
static struct platform_device *nokia770_devices[] __initdata = {
|
||||
&nokia770_kp_device,
|
||||
};
|
||||
|
||||
static struct ads7846_platform_data nokia770_ads7846_platform_data __initdata = {
|
||||
.x_max = 0x0fff,
|
||||
.y_max = 0x0fff,
|
||||
.x_plate_ohms = 180,
|
||||
.pressure_max = 255,
|
||||
.debounce_max = 10,
|
||||
.debounce_tol = 3,
|
||||
};
|
||||
|
||||
static struct spi_board_info nokia770_spi_board_info[] __initdata = {
|
||||
[0] = {
|
||||
.modalias = "lcd_lph8923",
|
||||
.bus_num = 2,
|
||||
.chip_select = 3,
|
||||
.max_speed_hz = 12000000,
|
||||
},
|
||||
[1] = {
|
||||
.modalias = "ads7846",
|
||||
.bus_num = 2,
|
||||
.chip_select = 0,
|
||||
.max_speed_hz = 2500000,
|
||||
.irq = OMAP_GPIO_IRQ(15),
|
||||
.platform_data = &nokia770_ads7846_platform_data,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
/* assume no Mini-AB port */
|
||||
|
||||
static struct omap_usb_config nokia770_usb_config __initdata = {
|
||||
.otg = 1,
|
||||
.register_host = 1,
|
||||
.register_dev = 1,
|
||||
.hmc_mode = 16,
|
||||
.pins[0] = 6,
|
||||
};
|
||||
|
||||
static struct omap_mmc_config nokia770_mmc_config __initdata = {
|
||||
.mmc[0] = {
|
||||
.enabled = 0,
|
||||
.wire4 = 0,
|
||||
.wp_pin = -1,
|
||||
.power_pin = -1,
|
||||
.switch_pin = -1,
|
||||
},
|
||||
.mmc[1] = {
|
||||
.enabled = 0,
|
||||
.wire4 = 0,
|
||||
.wp_pin = -1,
|
||||
.power_pin = -1,
|
||||
.switch_pin = -1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct omap_board_config_kernel nokia770_config[] = {
|
||||
{ OMAP_TAG_USB, NULL },
|
||||
{ OMAP_TAG_MMC, &nokia770_mmc_config },
|
||||
};
|
||||
|
||||
/*
|
||||
* audio power control
|
||||
*/
|
||||
#define HEADPHONE_GPIO 14
|
||||
#define AMPLIFIER_CTRL_GPIO 58
|
||||
|
||||
static struct clk *dspxor_ck;
|
||||
static DECLARE_MUTEX(audio_pwr_sem);
|
||||
/*
|
||||
* audio_pwr_state
|
||||
* +--+-------------------------+---------------------------------------+
|
||||
* |-1|down |power-up request -> 0 |
|
||||
* +--+-------------------------+---------------------------------------+
|
||||
* | 0|up |power-down(1) request -> 1 |
|
||||
* | | |power-down(2) request -> (ignore) |
|
||||
* +--+-------------------------+---------------------------------------+
|
||||
* | 1|up, |power-up request -> 0 |
|
||||
* | |received down(1) request |power-down(2) request -> -1 |
|
||||
* +--+-------------------------+---------------------------------------+
|
||||
*/
|
||||
static int audio_pwr_state = -1;
|
||||
|
||||
/*
|
||||
* audio_pwr_up / down should be called under audio_pwr_sem
|
||||
*/
|
||||
static void nokia770_audio_pwr_up(void)
|
||||
{
|
||||
clk_enable(dspxor_ck);
|
||||
|
||||
/* Turn on codec */
|
||||
tlv320aic23_power_up();
|
||||
|
||||
if (omap_get_gpio_datain(HEADPHONE_GPIO))
|
||||
/* HP not connected, turn on amplifier */
|
||||
omap_set_gpio_dataout(AMPLIFIER_CTRL_GPIO, 1);
|
||||
else
|
||||
/* HP connected, do not turn on amplifier */
|
||||
printk("HP connected\n");
|
||||
}
|
||||
|
||||
static void codec_delayed_power_down(void *arg)
|
||||
{
|
||||
down(&audio_pwr_sem);
|
||||
if (audio_pwr_state == -1)
|
||||
tlv320aic23_power_down();
|
||||
clk_disable(dspxor_ck);
|
||||
up(&audio_pwr_sem);
|
||||
}
|
||||
|
||||
static DECLARE_WORK(codec_power_down_work, codec_delayed_power_down, NULL);
|
||||
|
||||
static void nokia770_audio_pwr_down(void)
|
||||
{
|
||||
/* Turn off amplifier */
|
||||
omap_set_gpio_dataout(AMPLIFIER_CTRL_GPIO, 0);
|
||||
|
||||
/* Turn off codec: schedule delayed work */
|
||||
schedule_delayed_work(&codec_power_down_work, HZ / 20); /* 50ms */
|
||||
}
|
||||
|
||||
void nokia770_audio_pwr_up_request(int stage)
|
||||
{
|
||||
down(&audio_pwr_sem);
|
||||
if (audio_pwr_state == -1)
|
||||
nokia770_audio_pwr_up();
|
||||
/* force audio_pwr_state = 0, even if it was 1. */
|
||||
audio_pwr_state = 0;
|
||||
up(&audio_pwr_sem);
|
||||
}
|
||||
|
||||
void nokia770_audio_pwr_down_request(int stage)
|
||||
{
|
||||
down(&audio_pwr_sem);
|
||||
switch (stage) {
|
||||
case 1:
|
||||
if (audio_pwr_state == 0)
|
||||
audio_pwr_state = 1;
|
||||
break;
|
||||
case 2:
|
||||
if (audio_pwr_state == 1) {
|
||||
nokia770_audio_pwr_down();
|
||||
audio_pwr_state = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
up(&audio_pwr_sem);
|
||||
}
|
||||
|
||||
static void __init omap_nokia770_init(void)
|
||||
{
|
||||
nokia770_config[0].data = &nokia770_usb_config;
|
||||
|
||||
platform_add_devices(nokia770_devices, ARRAY_SIZE(nokia770_devices));
|
||||
spi_register_board_info(nokia770_spi_board_info,
|
||||
ARRAY_SIZE(nokia770_spi_board_info));
|
||||
omap_board_config = nokia770_config;
|
||||
omap_board_config_size = ARRAY_SIZE(nokia770_config);
|
||||
omap_serial_init();
|
||||
omap_dsp_audio_pwr_up_request = nokia770_audio_pwr_up_request;
|
||||
omap_dsp_audio_pwr_down_request = nokia770_audio_pwr_down_request;
|
||||
dspxor_ck = clk_get(0, "dspxor_ck");
|
||||
}
|
||||
|
||||
static void __init omap_nokia770_map_io(void)
|
||||
{
|
||||
omap1_map_common_io();
|
||||
}
|
||||
|
||||
MACHINE_START(NOKIA770, "Nokia 770")
|
||||
.phys_io = 0xfff00000,
|
||||
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x10000100,
|
||||
.map_io = omap_nokia770_map_io,
|
||||
.init_irq = omap_nokia770_init_irq,
|
||||
.init_machine = omap_nokia770_init,
|
||||
.timer = &omap_timer,
|
||||
MACHINE_END
|
@ -33,6 +33,7 @@
|
||||
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
@ -44,7 +45,24 @@
|
||||
#include <asm/arch/usb.h>
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/tc.h>
|
||||
#include <asm/arch/keypad.h>
|
||||
#include <asm/arch/common.h>
|
||||
#include <asm/arch/mcbsp.h>
|
||||
#include <asm/arch/omap-alsa.h>
|
||||
|
||||
static int osk_keymap[] = {
|
||||
KEY(0, 0, KEY_F1),
|
||||
KEY(0, 3, KEY_UP),
|
||||
KEY(1, 1, KEY_LEFTCTRL),
|
||||
KEY(1, 2, KEY_LEFT),
|
||||
KEY(2, 0, KEY_SPACE),
|
||||
KEY(2, 1, KEY_ESC),
|
||||
KEY(2, 2, KEY_DOWN),
|
||||
KEY(3, 2, KEY_ENTER),
|
||||
KEY(3, 3, KEY_RIGHT),
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
static struct mtd_partition osk_partitions[] = {
|
||||
/* bootloader (U-Boot, etc) in first sector */
|
||||
@ -133,9 +151,69 @@ static struct platform_device osk5912_cf_device = {
|
||||
.resource = osk5912_cf_resources,
|
||||
};
|
||||
|
||||
#define DEFAULT_BITPERSAMPLE 16
|
||||
|
||||
static struct omap_mcbsp_reg_cfg mcbsp_regs = {
|
||||
.spcr2 = FREE | FRST | GRST | XRST | XINTM(3),
|
||||
.spcr1 = RINTM(3) | RRST,
|
||||
.rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) |
|
||||
RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(0),
|
||||
.rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16),
|
||||
.xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) |
|
||||
XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(0) | XFIG,
|
||||
.xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16),
|
||||
.srgr1 = FWID(DEFAULT_BITPERSAMPLE - 1),
|
||||
.srgr2 = GSYNC | CLKSP | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1),
|
||||
/*.pcr0 = FSXM | FSRM | CLKXM | CLKRM | CLKXP | CLKRP,*/ /* mcbsp: master */
|
||||
.pcr0 = CLKXP | CLKRP, /* mcbsp: slave */
|
||||
};
|
||||
|
||||
static struct omap_alsa_codec_config alsa_config = {
|
||||
.name = "OSK AIC23",
|
||||
.mcbsp_regs_alsa = &mcbsp_regs,
|
||||
.codec_configure_dev = NULL, // aic23_configure,
|
||||
.codec_set_samplerate = NULL, // aic23_set_samplerate,
|
||||
.codec_clock_setup = NULL, // aic23_clock_setup,
|
||||
.codec_clock_on = NULL, // aic23_clock_on,
|
||||
.codec_clock_off = NULL, // aic23_clock_off,
|
||||
.get_default_samplerate = NULL, // aic23_get_default_samplerate,
|
||||
};
|
||||
|
||||
static struct platform_device osk5912_mcbsp1_device = {
|
||||
.name = "omap_mcbsp",
|
||||
.id = 1,
|
||||
.name = "omap_alsa_mcbsp",
|
||||
.id = 1,
|
||||
.dev = {
|
||||
.platform_data = &alsa_config,
|
||||
},
|
||||
};
|
||||
|
||||
static struct resource osk5912_kp_resources[] = {
|
||||
[0] = {
|
||||
.start = INT_KEYBOARD,
|
||||
.end = INT_KEYBOARD,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct omap_kp_platform_data osk_kp_data = {
|
||||
.rows = 8,
|
||||
.cols = 8,
|
||||
.keymap = osk_keymap,
|
||||
};
|
||||
|
||||
static struct platform_device osk5912_kp_device = {
|
||||
.name = "omap-keypad",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &osk_kp_data,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(osk5912_kp_resources),
|
||||
.resource = osk5912_kp_resources,
|
||||
};
|
||||
|
||||
static struct platform_device osk5912_lcd_device = {
|
||||
.name = "lcd_osk",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static struct platform_device *osk5912_devices[] __initdata = {
|
||||
@ -143,6 +221,8 @@ static struct platform_device *osk5912_devices[] __initdata = {
|
||||
&osk5912_smc91x_device,
|
||||
&osk5912_cf_device,
|
||||
&osk5912_mcbsp1_device,
|
||||
&osk5912_kp_device,
|
||||
&osk5912_lcd_device,
|
||||
};
|
||||
|
||||
static void __init osk_init_smc91x(void)
|
||||
@ -197,7 +277,6 @@ static struct omap_uart_config osk_uart_config __initdata = {
|
||||
};
|
||||
|
||||
static struct omap_lcd_config osk_lcd_config __initdata = {
|
||||
.panel_name = "osk",
|
||||
.ctrl_name = "internal",
|
||||
};
|
||||
|
||||
@ -255,8 +334,18 @@ static void __init osk_mistral_init(void)
|
||||
static void __init osk_mistral_init(void) { }
|
||||
#endif
|
||||
|
||||
#define EMIFS_CS3_VAL (0x88013141)
|
||||
|
||||
static void __init osk_init(void)
|
||||
{
|
||||
/* Workaround for wrong CS3 (NOR flash) timing
|
||||
* There are some U-Boot versions out there which configure
|
||||
* wrong CS3 memory timings. This mainly leads to CRC
|
||||
* or similiar errors if you use NOR flash (e.g. with JFFS2)
|
||||
*/
|
||||
if (EMIFS_CCS(3) != EMIFS_CS3_VAL)
|
||||
EMIFS_CCS(3) = EMIFS_CS3_VAL;
|
||||
|
||||
osk_flash_resource.end = osk_flash_resource.start = omap_cs3_phys();
|
||||
osk_flash_resource.end += SZ_32M - 1;
|
||||
platform_add_devices(osk5912_devices, ARRAY_SIZE(osk5912_devices));
|
||||
|
@ -38,6 +38,15 @@ static void __init omap_generic_init_irq(void)
|
||||
omap_init_irq();
|
||||
}
|
||||
|
||||
static struct platform_device palmte_lcd_device = {
|
||||
.name = "lcd_palmte",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static struct platform_device *devices[] __initdata = {
|
||||
&palmte_lcd_device,
|
||||
};
|
||||
|
||||
static struct omap_usb_config palmte_usb_config __initdata = {
|
||||
.register_dev = 1,
|
||||
.hmc_mode = 0,
|
||||
@ -55,7 +64,6 @@ static struct omap_mmc_config palmte_mmc_config __initdata = {
|
||||
};
|
||||
|
||||
static struct omap_lcd_config palmte_lcd_config __initdata = {
|
||||
.panel_name = "palmte",
|
||||
.ctrl_name = "internal",
|
||||
};
|
||||
|
||||
@ -69,6 +77,8 @@ static void __init omap_generic_init(void)
|
||||
{
|
||||
omap_board_config = palmte_config;
|
||||
omap_board_config_size = ARRAY_SIZE(palmte_config);
|
||||
|
||||
platform_add_devices(devices, ARRAY_SIZE(devices));
|
||||
}
|
||||
|
||||
static void __init omap_generic_map_io(void)
|
||||
|
@ -16,7 +16,9 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/nand.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
@ -28,9 +30,44 @@
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/fpga.h>
|
||||
#include <asm/arch/keypad.h>
|
||||
#include <asm/arch/common.h>
|
||||
#include <asm/arch/board.h>
|
||||
|
||||
static int p2_keymap[] = {
|
||||
KEY(0,0,KEY_UP),
|
||||
KEY(0,1,KEY_RIGHT),
|
||||
KEY(0,2,KEY_LEFT),
|
||||
KEY(0,3,KEY_DOWN),
|
||||
KEY(0,4,KEY_CENTER),
|
||||
KEY(0,5,KEY_0_5),
|
||||
KEY(1,0,KEY_SOFT2),
|
||||
KEY(1,1,KEY_SEND),
|
||||
KEY(1,2,KEY_END),
|
||||
KEY(1,3,KEY_VOLUMEDOWN),
|
||||
KEY(1,4,KEY_VOLUMEUP),
|
||||
KEY(1,5,KEY_RECORD),
|
||||
KEY(2,0,KEY_SOFT1),
|
||||
KEY(2,1,KEY_3),
|
||||
KEY(2,2,KEY_6),
|
||||
KEY(2,3,KEY_9),
|
||||
KEY(2,4,KEY_SHARP),
|
||||
KEY(2,5,KEY_2_5),
|
||||
KEY(3,0,KEY_BACK),
|
||||
KEY(3,1,KEY_2),
|
||||
KEY(3,2,KEY_5),
|
||||
KEY(3,3,KEY_8),
|
||||
KEY(3,4,KEY_0),
|
||||
KEY(3,5,KEY_HEADSETHOOK),
|
||||
KEY(4,0,KEY_HOME),
|
||||
KEY(4,1,KEY_1),
|
||||
KEY(4,2,KEY_4),
|
||||
KEY(4,3,KEY_7),
|
||||
KEY(4,4,KEY_STAR),
|
||||
KEY(4,5,KEY_POWER),
|
||||
0
|
||||
};
|
||||
|
||||
static struct resource smc91x_resources[] = {
|
||||
[0] = {
|
||||
.start = H2P2_DBG_FPGA_ETHR_START, /* Physical */
|
||||
@ -44,7 +81,7 @@ static struct resource smc91x_resources[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct mtd_partition p2_partitions[] = {
|
||||
static struct mtd_partition nor_partitions[] = {
|
||||
/* bootloader (U-Boot, etc) in first sector */
|
||||
{
|
||||
.name = "bootloader",
|
||||
@ -75,27 +112,47 @@ static struct mtd_partition p2_partitions[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct flash_platform_data p2_flash_data = {
|
||||
static struct flash_platform_data nor_data = {
|
||||
.map_name = "cfi_probe",
|
||||
.width = 2,
|
||||
.parts = p2_partitions,
|
||||
.nr_parts = ARRAY_SIZE(p2_partitions),
|
||||
.parts = nor_partitions,
|
||||
.nr_parts = ARRAY_SIZE(nor_partitions),
|
||||
};
|
||||
|
||||
static struct resource p2_flash_resource = {
|
||||
static struct resource nor_resource = {
|
||||
.start = OMAP_CS0_PHYS,
|
||||
.end = OMAP_CS0_PHYS + SZ_32M - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct platform_device p2_flash_device = {
|
||||
static struct platform_device nor_device = {
|
||||
.name = "omapflash",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &p2_flash_data,
|
||||
.platform_data = &nor_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &p2_flash_resource,
|
||||
.resource = &nor_resource,
|
||||
};
|
||||
|
||||
static struct nand_platform_data nand_data = {
|
||||
.options = NAND_SAMSUNG_LP_OPTIONS,
|
||||
};
|
||||
|
||||
static struct resource nand_resource = {
|
||||
.start = OMAP_CS3_PHYS,
|
||||
.end = OMAP_CS3_PHYS + SZ_4K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct platform_device nand_device = {
|
||||
.name = "omapnand",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &nand_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &nand_resource,
|
||||
};
|
||||
|
||||
static struct platform_device smc91x_device = {
|
||||
@ -105,17 +162,55 @@ static struct platform_device smc91x_device = {
|
||||
.resource = smc91x_resources,
|
||||
};
|
||||
|
||||
static struct platform_device *devices[] __initdata = {
|
||||
&p2_flash_device,
|
||||
&smc91x_device,
|
||||
static struct resource kp_resources[] = {
|
||||
[0] = {
|
||||
.start = INT_730_MPUIO_KEYPAD,
|
||||
.end = INT_730_MPUIO_KEYPAD,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct omap_kp_platform_data kp_data = {
|
||||
.rows = 8,
|
||||
.cols = 8,
|
||||
.keymap = p2_keymap,
|
||||
};
|
||||
|
||||
static struct platform_device kp_device = {
|
||||
.name = "omap-keypad",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &kp_data,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(kp_resources),
|
||||
.resource = kp_resources,
|
||||
};
|
||||
|
||||
static struct platform_device lcd_device = {
|
||||
.name = "lcd_p2",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static struct platform_device *devices[] __initdata = {
|
||||
&nor_device,
|
||||
&nand_device,
|
||||
&smc91x_device,
|
||||
&kp_device,
|
||||
&lcd_device,
|
||||
};
|
||||
|
||||
#define P2_NAND_RB_GPIO_PIN 62
|
||||
|
||||
static int nand_dev_ready(struct nand_platform_data *data)
|
||||
{
|
||||
return omap_get_gpio_datain(P2_NAND_RB_GPIO_PIN);
|
||||
}
|
||||
|
||||
static struct omap_uart_config perseus2_uart_config __initdata = {
|
||||
.enabled_uarts = ((1 << 0) | (1 << 1)),
|
||||
};
|
||||
|
||||
static struct omap_lcd_config perseus2_lcd_config __initdata = {
|
||||
.panel_name = "p2",
|
||||
.ctrl_name = "internal",
|
||||
};
|
||||
|
||||
@ -126,7 +221,13 @@ static struct omap_board_config_kernel perseus2_config[] = {
|
||||
|
||||
static void __init omap_perseus2_init(void)
|
||||
{
|
||||
(void) platform_add_devices(devices, ARRAY_SIZE(devices));
|
||||
if (!(omap_request_gpio(P2_NAND_RB_GPIO_PIN)))
|
||||
nand_data.dev_ready = nand_dev_ready;
|
||||
|
||||
omap_cfg_reg(L3_1610_FLASH_CS2B_OE);
|
||||
omap_cfg_reg(M8_1610_FLASH_CS2B_WE);
|
||||
|
||||
platform_add_devices(devices, ARRAY_SIZE(devices));
|
||||
|
||||
omap_board_config = perseus2_config;
|
||||
omap_board_config_size = ARRAY_SIZE(perseus2_config);
|
||||
|
@ -155,9 +155,9 @@ static struct omap_uart_config voiceblue_uart_config __initdata = {
|
||||
};
|
||||
|
||||
static struct omap_board_config_kernel voiceblue_config[] = {
|
||||
{ OMAP_TAG_USB, &voiceblue_usb_config },
|
||||
{ OMAP_TAG_MMC, &voiceblue_mmc_config },
|
||||
{ OMAP_TAG_UART, &voiceblue_uart_config },
|
||||
{ OMAP_TAG_USB, &voiceblue_usb_config },
|
||||
{ OMAP_TAG_MMC, &voiceblue_mmc_config },
|
||||
{ OMAP_TAG_UART, &voiceblue_uart_config },
|
||||
};
|
||||
|
||||
static void __init voiceblue_init_irq(void)
|
||||
@ -235,7 +235,7 @@ static struct notifier_block panic_block = {
|
||||
static int __init voiceblue_setup(void)
|
||||
{
|
||||
/* Setup panic notifier */
|
||||
atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
|
||||
notifier_chain_register(&panic_notifier_list, &panic_block);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -345,7 +345,7 @@ static unsigned calc_ext_dsor(unsigned long rate)
|
||||
*/
|
||||
for (dsor = 2; dsor < 96; ++dsor) {
|
||||
if ((dsor & 1) && dsor > 8)
|
||||
continue;
|
||||
continue;
|
||||
if (rate >= 96000000 / dsor)
|
||||
break;
|
||||
}
|
||||
@ -687,6 +687,11 @@ int __init omap1_clk_init(void)
|
||||
clk_register(*clkp);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (((*clkp)->flags &CLOCK_IN_OMAP310) && cpu_is_omap310()) {
|
||||
clk_register(*clkp);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config);
|
||||
@ -784,7 +789,7 @@ int __init omap1_clk_init(void)
|
||||
clk_enable(&armxor_ck.clk);
|
||||
clk_enable(&armtim_ck.clk); /* This should be done by timer code */
|
||||
|
||||
if (cpu_is_omap1510())
|
||||
if (cpu_is_omap15xx())
|
||||
clk_enable(&arm_gpio_ck);
|
||||
|
||||
return 0;
|
||||
|
@ -151,7 +151,7 @@ static struct clk ck_ref = {
|
||||
.name = "ck_ref",
|
||||
.rate = 12000000,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
ALWAYS_ENABLED,
|
||||
CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
|
||||
.enable = &omap1_clk_enable_generic,
|
||||
.disable = &omap1_clk_disable_generic,
|
||||
};
|
||||
@ -160,7 +160,7 @@ static struct clk ck_dpll1 = {
|
||||
.name = "ck_dpll1",
|
||||
.parent = &ck_ref,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
RATE_PROPAGATES | ALWAYS_ENABLED,
|
||||
CLOCK_IN_OMAP310 | RATE_PROPAGATES | ALWAYS_ENABLED,
|
||||
.enable = &omap1_clk_enable_generic,
|
||||
.disable = &omap1_clk_disable_generic,
|
||||
};
|
||||
@ -183,7 +183,8 @@ static struct clk arm_ck = {
|
||||
.name = "arm_ck",
|
||||
.parent = &ck_dpll1,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED,
|
||||
CLOCK_IN_OMAP310 | RATE_CKCTL | RATE_PROPAGATES |
|
||||
ALWAYS_ENABLED,
|
||||
.rate_offset = CKCTL_ARMDIV_OFFSET,
|
||||
.recalc = &omap1_ckctl_recalc,
|
||||
.enable = &omap1_clk_enable_generic,
|
||||
@ -195,7 +196,8 @@ static struct arm_idlect1_clk armper_ck = {
|
||||
.name = "armper_ck",
|
||||
.parent = &ck_dpll1,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
RATE_CKCTL | CLOCK_IDLE_CONTROL,
|
||||
CLOCK_IN_OMAP310 | RATE_CKCTL |
|
||||
CLOCK_IDLE_CONTROL,
|
||||
.enable_reg = (void __iomem *)ARM_IDLECT2,
|
||||
.enable_bit = EN_PERCK,
|
||||
.rate_offset = CKCTL_PERDIV_OFFSET,
|
||||
@ -209,7 +211,7 @@ static struct arm_idlect1_clk armper_ck = {
|
||||
static struct clk arm_gpio_ck = {
|
||||
.name = "arm_gpio_ck",
|
||||
.parent = &ck_dpll1,
|
||||
.flags = CLOCK_IN_OMAP1510,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
|
||||
.enable_reg = (void __iomem *)ARM_IDLECT2,
|
||||
.enable_bit = EN_GPIOCK,
|
||||
.recalc = &followparent_recalc,
|
||||
@ -222,7 +224,7 @@ static struct arm_idlect1_clk armxor_ck = {
|
||||
.name = "armxor_ck",
|
||||
.parent = &ck_ref,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
CLOCK_IDLE_CONTROL,
|
||||
CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
|
||||
.enable_reg = (void __iomem *)ARM_IDLECT2,
|
||||
.enable_bit = EN_XORPCK,
|
||||
.recalc = &followparent_recalc,
|
||||
@ -237,7 +239,7 @@ static struct arm_idlect1_clk armtim_ck = {
|
||||
.name = "armtim_ck",
|
||||
.parent = &ck_ref,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
CLOCK_IDLE_CONTROL,
|
||||
CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
|
||||
.enable_reg = (void __iomem *)ARM_IDLECT2,
|
||||
.enable_bit = EN_TIMCK,
|
||||
.recalc = &followparent_recalc,
|
||||
@ -252,7 +254,7 @@ static struct arm_idlect1_clk armwdt_ck = {
|
||||
.name = "armwdt_ck",
|
||||
.parent = &ck_ref,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
CLOCK_IDLE_CONTROL,
|
||||
CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
|
||||
.enable_reg = (void __iomem *)ARM_IDLECT2,
|
||||
.enable_bit = EN_WDTCK,
|
||||
.recalc = &omap1_watchdog_recalc,
|
||||
@ -344,9 +346,9 @@ static struct arm_idlect1_clk tc_ck = {
|
||||
.name = "tc_ck",
|
||||
.parent = &ck_dpll1,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
CLOCK_IN_OMAP730 | RATE_CKCTL |
|
||||
RATE_PROPAGATES | ALWAYS_ENABLED |
|
||||
CLOCK_IDLE_CONTROL,
|
||||
CLOCK_IN_OMAP730 | CLOCK_IN_OMAP310 |
|
||||
RATE_CKCTL | RATE_PROPAGATES |
|
||||
ALWAYS_ENABLED | CLOCK_IDLE_CONTROL,
|
||||
.rate_offset = CKCTL_TCDIV_OFFSET,
|
||||
.recalc = &omap1_ckctl_recalc,
|
||||
.enable = &omap1_clk_enable_generic,
|
||||
@ -358,7 +360,8 @@ static struct arm_idlect1_clk tc_ck = {
|
||||
static struct clk arminth_ck1510 = {
|
||||
.name = "arminth_ck",
|
||||
.parent = &tc_ck.clk,
|
||||
.flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
|
||||
ALWAYS_ENABLED,
|
||||
.recalc = &followparent_recalc,
|
||||
/* Note: On 1510 the frequency follows TC_CK
|
||||
*
|
||||
@ -372,7 +375,8 @@ static struct clk tipb_ck = {
|
||||
/* No-idle controlled by "tc_ck" */
|
||||
.name = "tibp_ck",
|
||||
.parent = &tc_ck.clk,
|
||||
.flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
|
||||
ALWAYS_ENABLED,
|
||||
.recalc = &followparent_recalc,
|
||||
.enable = &omap1_clk_enable_generic,
|
||||
.disable = &omap1_clk_disable_generic,
|
||||
@ -417,7 +421,7 @@ static struct clk dma_ck = {
|
||||
.name = "dma_ck",
|
||||
.parent = &tc_ck.clk,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
ALWAYS_ENABLED,
|
||||
CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
|
||||
.recalc = &followparent_recalc,
|
||||
.enable = &omap1_clk_enable_generic,
|
||||
.disable = &omap1_clk_disable_generic,
|
||||
@ -437,7 +441,7 @@ static struct arm_idlect1_clk api_ck = {
|
||||
.name = "api_ck",
|
||||
.parent = &tc_ck.clk,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
CLOCK_IDLE_CONTROL,
|
||||
CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
|
||||
.enable_reg = (void __iomem *)ARM_IDLECT2,
|
||||
.enable_bit = EN_APICK,
|
||||
.recalc = &followparent_recalc,
|
||||
@ -451,7 +455,8 @@ static struct arm_idlect1_clk lb_ck = {
|
||||
.clk = {
|
||||
.name = "lb_ck",
|
||||
.parent = &tc_ck.clk,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IDLE_CONTROL,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
|
||||
CLOCK_IDLE_CONTROL,
|
||||
.enable_reg = (void __iomem *)ARM_IDLECT2,
|
||||
.enable_bit = EN_LBCK,
|
||||
.recalc = &followparent_recalc,
|
||||
@ -495,8 +500,8 @@ static struct arm_idlect1_clk lcd_ck_1510 = {
|
||||
.clk = {
|
||||
.name = "lcd_ck",
|
||||
.parent = &ck_dpll1,
|
||||
.flags = CLOCK_IN_OMAP1510 | RATE_CKCTL |
|
||||
CLOCK_IDLE_CONTROL,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
|
||||
RATE_CKCTL | CLOCK_IDLE_CONTROL,
|
||||
.enable_reg = (void __iomem *)ARM_IDLECT2,
|
||||
.enable_bit = EN_LCDCK,
|
||||
.rate_offset = CKCTL_LCDDIV_OFFSET,
|
||||
@ -512,8 +517,9 @@ static struct clk uart1_1510 = {
|
||||
/* Direct from ULPD, no real parent */
|
||||
.parent = &armper_ck.clk,
|
||||
.rate = 12000000,
|
||||
.flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT |
|
||||
ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
|
||||
ENABLE_REG_32BIT | ALWAYS_ENABLED |
|
||||
CLOCK_NO_IDLE_PARENT,
|
||||
.enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
|
||||
.enable_bit = 29, /* Chooses between 12MHz and 48MHz */
|
||||
.set_rate = &omap1_set_uart_rate,
|
||||
@ -544,8 +550,8 @@ static struct clk uart2_ck = {
|
||||
.parent = &armper_ck.clk,
|
||||
.rate = 12000000,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
ENABLE_REG_32BIT | ALWAYS_ENABLED |
|
||||
CLOCK_NO_IDLE_PARENT,
|
||||
CLOCK_IN_OMAP310 | ENABLE_REG_32BIT |
|
||||
ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT,
|
||||
.enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
|
||||
.enable_bit = 30, /* Chooses between 12MHz and 48MHz */
|
||||
.set_rate = &omap1_set_uart_rate,
|
||||
@ -559,8 +565,9 @@ static struct clk uart3_1510 = {
|
||||
/* Direct from ULPD, no real parent */
|
||||
.parent = &armper_ck.clk,
|
||||
.rate = 12000000,
|
||||
.flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT |
|
||||
ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
|
||||
ENABLE_REG_32BIT | ALWAYS_ENABLED |
|
||||
CLOCK_NO_IDLE_PARENT,
|
||||
.enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
|
||||
.enable_bit = 31, /* Chooses between 12MHz and 48MHz */
|
||||
.set_rate = &omap1_set_uart_rate,
|
||||
@ -590,7 +597,7 @@ static struct clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */
|
||||
/* Direct from ULPD, no parent */
|
||||
.rate = 6000000,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
RATE_FIXED | ENABLE_REG_32BIT,
|
||||
CLOCK_IN_OMAP310 | RATE_FIXED | ENABLE_REG_32BIT,
|
||||
.enable_reg = (void __iomem *)ULPD_CLOCK_CTRL,
|
||||
.enable_bit = USB_MCLK_EN_BIT,
|
||||
.enable = &omap1_clk_enable_generic,
|
||||
@ -601,7 +608,7 @@ static struct clk usb_hhc_ck1510 = {
|
||||
.name = "usb_hhc_ck",
|
||||
/* Direct from ULPD, no parent */
|
||||
.rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
|
||||
.flags = CLOCK_IN_OMAP1510 |
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
|
||||
RATE_FIXED | ENABLE_REG_32BIT,
|
||||
.enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
|
||||
.enable_bit = USB_HOST_HHC_UHOST_EN,
|
||||
@ -637,7 +644,9 @@ static struct clk mclk_1510 = {
|
||||
.name = "mclk",
|
||||
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
|
||||
.rate = 12000000,
|
||||
.flags = CLOCK_IN_OMAP1510 | RATE_FIXED,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | RATE_FIXED,
|
||||
.enable_reg = (void __iomem *)SOFT_REQ_REG,
|
||||
.enable_bit = 6,
|
||||
.enable = &omap1_clk_enable_generic,
|
||||
.disable = &omap1_clk_disable_generic,
|
||||
};
|
||||
@ -659,7 +668,7 @@ static struct clk bclk_1510 = {
|
||||
.name = "bclk",
|
||||
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
|
||||
.rate = 12000000,
|
||||
.flags = CLOCK_IN_OMAP1510 | RATE_FIXED,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | RATE_FIXED,
|
||||
.enable = &omap1_clk_enable_generic,
|
||||
.disable = &omap1_clk_disable_generic,
|
||||
};
|
||||
@ -678,12 +687,14 @@ static struct clk bclk_16xx = {
|
||||
};
|
||||
|
||||
static struct clk mmc1_ck = {
|
||||
.name = "mmc1_ck",
|
||||
.name = "mmc_ck",
|
||||
.id = 1,
|
||||
/* Functional clock is direct from ULPD, interface clock is ARMPER */
|
||||
.parent = &armper_ck.clk,
|
||||
.rate = 48000000,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
|
||||
CLOCK_IN_OMAP310 | RATE_FIXED | ENABLE_REG_32BIT |
|
||||
CLOCK_NO_IDLE_PARENT,
|
||||
.enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
|
||||
.enable_bit = 23,
|
||||
.enable = &omap1_clk_enable_generic,
|
||||
@ -691,7 +702,8 @@ static struct clk mmc1_ck = {
|
||||
};
|
||||
|
||||
static struct clk mmc2_ck = {
|
||||
.name = "mmc2_ck",
|
||||
.name = "mmc_ck",
|
||||
.id = 2,
|
||||
/* Functional clock is direct from ULPD, interface clock is ARMPER */
|
||||
.parent = &armper_ck.clk,
|
||||
.rate = 48000000,
|
||||
@ -706,7 +718,7 @@ static struct clk mmc2_ck = {
|
||||
static struct clk virtual_ck_mpu = {
|
||||
.name = "mpu",
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
VIRTUAL_CLOCK | ALWAYS_ENABLED,
|
||||
CLOCK_IN_OMAP310 | VIRTUAL_CLOCK | ALWAYS_ENABLED,
|
||||
.parent = &arm_ck, /* Is smarter alias for */
|
||||
.recalc = &followparent_recalc,
|
||||
.set_rate = &omap1_select_table_rate,
|
||||
@ -715,6 +727,20 @@ static struct clk virtual_ck_mpu = {
|
||||
.disable = &omap1_clk_disable_generic,
|
||||
};
|
||||
|
||||
/* virtual functional clock domain for I2C. Just for making sure that ARMXOR_CK
|
||||
remains active during MPU idle whenever this is enabled */
|
||||
static struct clk i2c_fck = {
|
||||
.name = "i2c_fck",
|
||||
.id = 1,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
VIRTUAL_CLOCK | CLOCK_NO_IDLE_PARENT |
|
||||
ALWAYS_ENABLED,
|
||||
.parent = &armxor_ck.clk,
|
||||
.recalc = &followparent_recalc,
|
||||
.enable = &omap1_clk_enable_generic,
|
||||
.disable = &omap1_clk_disable_generic,
|
||||
};
|
||||
|
||||
static struct clk * onchip_clks[] = {
|
||||
/* non-ULPD clocks */
|
||||
&ck_ref,
|
||||
@ -763,6 +789,7 @@ static struct clk * onchip_clks[] = {
|
||||
&mmc2_ck,
|
||||
/* Virtual clocks */
|
||||
&virtual_ck_mpu,
|
||||
&i2c_fck,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -99,6 +99,45 @@ static void omap_init_rtc(void)
|
||||
static inline void omap_init_rtc(void) {}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_OMAP_STI)
|
||||
|
||||
#define OMAP1_STI_BASE IO_ADDRESS(0xfffea000)
|
||||
#define OMAP1_STI_CHANNEL_BASE (OMAP1_STI_BASE + 0x400)
|
||||
|
||||
static struct resource sti_resources[] = {
|
||||
{
|
||||
.start = OMAP1_STI_BASE,
|
||||
.end = OMAP1_STI_BASE + SZ_1K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = OMAP1_STI_CHANNEL_BASE,
|
||||
.end = OMAP1_STI_CHANNEL_BASE + SZ_1K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = INT_1610_STI,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device sti_device = {
|
||||
.name = "sti",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.release = omap_nop_release,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(sti_resources),
|
||||
.resource = sti_resources,
|
||||
};
|
||||
|
||||
static inline void omap_init_sti(void)
|
||||
{
|
||||
platform_device_register(&sti_device);
|
||||
}
|
||||
#else
|
||||
static inline void omap_init_sti(void) {}
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
@ -129,6 +168,7 @@ static int __init omap1_init_devices(void)
|
||||
*/
|
||||
omap_init_irda();
|
||||
omap_init_rtc();
|
||||
omap_init_sti();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/tc.h>
|
||||
#include <asm/arch/omapfb.h>
|
||||
|
||||
extern int omap1_clk_init(void);
|
||||
extern void omap_check_revision(void);
|
||||
@ -110,7 +111,7 @@ void __init omap1_map_common_io(void)
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
if (cpu_is_omap1510()) {
|
||||
if (cpu_is_omap15xx()) {
|
||||
iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc));
|
||||
}
|
||||
#endif
|
||||
@ -121,6 +122,7 @@ void __init omap1_map_common_io(void)
|
||||
#endif
|
||||
|
||||
omap_sram_init();
|
||||
omapfb_reserve_mem();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -60,7 +60,7 @@ struct omap_irq_bank {
|
||||
unsigned long wake_enable;
|
||||
};
|
||||
|
||||
static unsigned int irq_bank_count = 0;
|
||||
static unsigned int irq_bank_count;
|
||||
static struct omap_irq_bank *irq_banks;
|
||||
|
||||
static inline unsigned int irq_bank_readl(int bank, int offset)
|
||||
@ -142,28 +142,28 @@ static void omap_irq_set_cfg(int irq, int fiq, int priority, int trigger)
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP730
|
||||
static struct omap_irq_bank omap730_irq_banks[] = {
|
||||
{ .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3f8e22f },
|
||||
{ .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb9c1f2 },
|
||||
{ .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3f8e22f },
|
||||
{ .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb9c1f2 },
|
||||
{ .base_reg = OMAP_IH2_BASE + 0x100, .trigger_map = 0x800040f3 },
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
static struct omap_irq_bank omap1510_irq_banks[] = {
|
||||
{ .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3febfff },
|
||||
{ .base_reg = OMAP_IH2_BASE, .trigger_map = 0xffbfffed },
|
||||
{ .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3febfff },
|
||||
{ .base_reg = OMAP_IH2_BASE, .trigger_map = 0xffbfffed },
|
||||
};
|
||||
static struct omap_irq_bank omap310_irq_banks[] = {
|
||||
{ .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3faefc3 },
|
||||
{ .base_reg = OMAP_IH2_BASE, .trigger_map = 0x65b3c061 },
|
||||
{ .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3faefc3 },
|
||||
{ .base_reg = OMAP_IH2_BASE, .trigger_map = 0x65b3c061 },
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP16XX)
|
||||
|
||||
static struct omap_irq_bank omap1610_irq_banks[] = {
|
||||
{ .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3fefe8f },
|
||||
{ .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb7c1fd },
|
||||
{ .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3fefe8f },
|
||||
{ .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb7c1fd },
|
||||
{ .base_reg = OMAP_IH2_BASE + 0x100, .trigger_map = 0xffffb7ff },
|
||||
{ .base_reg = OMAP_IH2_BASE + 0x200, .trigger_map = 0xffffffff },
|
||||
};
|
||||
|
@ -35,16 +35,20 @@
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP730
|
||||
struct pin_config __initdata_or_module omap730_pins[] = {
|
||||
MUX_CFG_730("E2_730_KBR0", 12, 21, 0, 0, 20, 1, NA, 0, 0)
|
||||
MUX_CFG_730("J7_730_KBR1", 12, 25, 0, 0, 24, 1, NA, 0, 0)
|
||||
MUX_CFG_730("E1_730_KBR2", 12, 29, 0, 0, 28, 1, NA, 0, 0)
|
||||
MUX_CFG_730("F3_730_KBR3", 13, 1, 0, 0, 0, 1, NA, 0, 0)
|
||||
MUX_CFG_730("D2_730_KBR4", 13, 5, 0, 0, 4, 1, NA, 0, 0)
|
||||
MUX_CFG_730("C2_730_KBC0", 13, 9, 0, 0, 8, 1, NA, 0, 0)
|
||||
MUX_CFG_730("D3_730_KBC1", 13, 13, 0, 0, 12, 1, NA, 0, 0)
|
||||
MUX_CFG_730("E4_730_KBC2", 13, 17, 0, 0, 16, 1, NA, 0, 0)
|
||||
MUX_CFG_730("F4_730_KBC3", 13, 21, 0, 0, 20, 1, NA, 0, 0)
|
||||
MUX_CFG_730("E3_730_KBC4", 13, 25, 0, 0, 24, 1, NA, 0, 0)
|
||||
MUX_CFG_730("E2_730_KBR0", 12, 21, 0, 20, 1, 0)
|
||||
MUX_CFG_730("J7_730_KBR1", 12, 25, 0, 24, 1, 0)
|
||||
MUX_CFG_730("E1_730_KBR2", 12, 29, 0, 28, 1, 0)
|
||||
MUX_CFG_730("F3_730_KBR3", 13, 1, 0, 0, 1, 0)
|
||||
MUX_CFG_730("D2_730_KBR4", 13, 5, 0, 4, 1, 0)
|
||||
MUX_CFG_730("C2_730_KBC0", 13, 9, 0, 8, 1, 0)
|
||||
MUX_CFG_730("D3_730_KBC1", 13, 13, 0, 12, 1, 0)
|
||||
MUX_CFG_730("E4_730_KBC2", 13, 17, 0, 16, 1, 0)
|
||||
MUX_CFG_730("F4_730_KBC3", 13, 21, 0, 20, 1, 0)
|
||||
MUX_CFG_730("E3_730_KBC4", 13, 25, 0, 24, 1, 0)
|
||||
|
||||
MUX_CFG_730("AA17_730_USB_DM", 2, 21, 0, 20, 0, 0)
|
||||
MUX_CFG_730("W16_730_USB_PU_EN", 2, 25, 0, 24, 0, 0)
|
||||
MUX_CFG_730("W17_730_USB_VBUSI", 2, 29, 0, 28, 0, 0)
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -73,8 +77,8 @@ MUX_CFG("UART3_BCLK", A, 0, 0, 2, 6, 0, NA, 0, 0)
|
||||
MUX_CFG("Y15_1610_UART3_RTS", A, 0, 1, 2, 6, 0, NA, 0, 0)
|
||||
|
||||
/* PWT & PWL, conflicts with UART3 */
|
||||
MUX_CFG("PWT", 6, 0, 2, 0, 30, 0, NA, 0, 0)
|
||||
MUX_CFG("PWL", 6, 3, 1, 0, 31, 1, NA, 0, 0)
|
||||
MUX_CFG("PWT", 6, 0, 2, 0, 30, 0, NA, 0, 0)
|
||||
MUX_CFG("PWL", 6, 3, 1, 0, 31, 1, NA, 0, 0)
|
||||
|
||||
/* USB internal master generic */
|
||||
MUX_CFG("R18_USB_VBUS", 7, 9, 2, 1, 11, 0, NA, 0, 1)
|
||||
@ -151,7 +155,7 @@ MUX_CFG("MCBSP3_CLKX", 9, 3, 1, 1, 29, 0, NA, 0, 1)
|
||||
|
||||
/* Misc ballouts */
|
||||
MUX_CFG("BALLOUT_V8_ARMIO3", B, 18, 0, 2, 25, 1, NA, 0, 1)
|
||||
MUX_CFG("N20_HDQ", 6, 18, 1, 1, 4, 0, 1, 4, 0)
|
||||
MUX_CFG("N20_HDQ", 6, 18, 1, 1, 4, 0, 1, 4, 0)
|
||||
|
||||
/* OMAP-1610 MMC2 */
|
||||
MUX_CFG("W8_1610_MMC2_DAT0", B, 21, 6, 2, 23, 1, 2, 1, 1)
|
||||
|
770
arch/arm/mach-omap1/pm.c
Normal file
770
arch/arm/mach-omap1/pm.c
Normal file
@ -0,0 +1,770 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap1/pm.c
|
||||
*
|
||||
* OMAP Power Management Routines
|
||||
*
|
||||
* Original code for the SA11x0:
|
||||
* Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
|
||||
*
|
||||
* Modified for the PXA250 by Nicolas Pitre:
|
||||
* Copyright (c) 2002 Monta Vista Software, Inc.
|
||||
*
|
||||
* Modified for the OMAP1510 by David Singleton:
|
||||
* Copyright (c) 2002 Monta Vista Software, Inc.
|
||||
*
|
||||
* Cleanup 2004 for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.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
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/pm.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/mach/time.h>
|
||||
#include <asm/mach/irq.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include <asm/arch/irqs.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/sram.h>
|
||||
#include <asm/arch/tc.h>
|
||||
#include <asm/arch/pm.h>
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/tps65010.h>
|
||||
#include <asm/arch/dma.h>
|
||||
#include <asm/arch/dsp_common.h>
|
||||
#include <asm/arch/dmtimer.h>
|
||||
|
||||
static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE];
|
||||
static unsigned short dsp_sleep_save[DSP_SLEEP_SAVE_SIZE];
|
||||
static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE];
|
||||
static unsigned int mpui730_sleep_save[MPUI730_SLEEP_SAVE_SIZE];
|
||||
static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE];
|
||||
static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
|
||||
|
||||
static unsigned short enable_dyn_sleep = 1;
|
||||
|
||||
static ssize_t omap_pm_sleep_while_idle_show(struct subsystem * subsys, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%hu\n", enable_dyn_sleep);
|
||||
}
|
||||
|
||||
static ssize_t omap_pm_sleep_while_idle_store(struct subsystem * subsys,
|
||||
const char * buf,
|
||||
size_t n)
|
||||
{
|
||||
unsigned short value;
|
||||
if (sscanf(buf, "%hu", &value) != 1 ||
|
||||
(value != 0 && value != 1)) {
|
||||
printk(KERN_ERR "idle_sleep_store: Invalid value\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
enable_dyn_sleep = value;
|
||||
return n;
|
||||
}
|
||||
|
||||
static struct subsys_attribute sleep_while_idle_attr = {
|
||||
.attr = {
|
||||
.name = __stringify(sleep_while_idle),
|
||||
.mode = 0644,
|
||||
},
|
||||
.show = omap_pm_sleep_while_idle_show,
|
||||
.store = omap_pm_sleep_while_idle_store,
|
||||
};
|
||||
|
||||
extern struct subsystem power_subsys;
|
||||
static void (*omap_sram_idle)(void) = NULL;
|
||||
static void (*omap_sram_suspend)(unsigned long r0, unsigned long r1) = NULL;
|
||||
|
||||
/*
|
||||
* Let's power down on idle, but only if we are really
|
||||
* idle, because once we start down the path of
|
||||
* going idle we continue to do idle even if we get
|
||||
* a clock tick interrupt . .
|
||||
*/
|
||||
void omap_pm_idle(void)
|
||||
{
|
||||
extern __u32 arm_idlect1_mask;
|
||||
__u32 use_idlect1 = arm_idlect1_mask;
|
||||
#ifndef CONFIG_OMAP_MPU_TIMER
|
||||
int do_sleep;
|
||||
#endif
|
||||
|
||||
local_irq_disable();
|
||||
local_fiq_disable();
|
||||
if (need_resched()) {
|
||||
local_fiq_enable();
|
||||
local_irq_enable();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Since an interrupt may set up a timer, we don't want to
|
||||
* reprogram the hardware timer with interrupts enabled.
|
||||
* Re-enable interrupts only after returning from idle.
|
||||
*/
|
||||
timer_dyn_reprogram();
|
||||
|
||||
#ifdef CONFIG_OMAP_MPU_TIMER
|
||||
#warning Enable 32kHz OS timer in order to allow sleep states in idle
|
||||
use_idlect1 = use_idlect1 & ~(1 << 9);
|
||||
#else
|
||||
|
||||
do_sleep = 0;
|
||||
while (enable_dyn_sleep) {
|
||||
|
||||
#ifdef CONFIG_CBUS_TAHVO_USB
|
||||
extern int vbus_active;
|
||||
/* Clock requirements? */
|
||||
if (vbus_active)
|
||||
break;
|
||||
#endif
|
||||
do_sleep = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OMAP_DM_TIMER
|
||||
use_idlect1 = omap_dm_timer_modify_idlect_mask(use_idlect1);
|
||||
#endif
|
||||
|
||||
if (omap_dma_running()) {
|
||||
use_idlect1 &= ~(1 << 6);
|
||||
if (omap_lcd_dma_ext_running())
|
||||
use_idlect1 &= ~(1 << 12);
|
||||
}
|
||||
|
||||
/* We should be able to remove the do_sleep variable and multiple
|
||||
* tests above as soon as drivers, timer and DMA code have been fixed.
|
||||
* Even the sleep block count should become obsolete. */
|
||||
if ((use_idlect1 != ~0) || !do_sleep) {
|
||||
|
||||
__u32 saved_idlect1 = omap_readl(ARM_IDLECT1);
|
||||
if (cpu_is_omap15xx())
|
||||
use_idlect1 &= OMAP1510_BIG_SLEEP_REQUEST;
|
||||
else
|
||||
use_idlect1 &= OMAP1610_IDLECT1_SLEEP_VAL;
|
||||
omap_writel(use_idlect1, ARM_IDLECT1);
|
||||
__asm__ volatile ("mcr p15, 0, r0, c7, c0, 4");
|
||||
omap_writel(saved_idlect1, ARM_IDLECT1);
|
||||
|
||||
local_fiq_enable();
|
||||
local_irq_enable();
|
||||
return;
|
||||
}
|
||||
omap_sram_suspend(omap_readl(ARM_IDLECT1),
|
||||
omap_readl(ARM_IDLECT2));
|
||||
#endif
|
||||
|
||||
local_fiq_enable();
|
||||
local_irq_enable();
|
||||
}
|
||||
|
||||
/*
|
||||
* Configuration of the wakeup event is board specific. For the
|
||||
* moment we put it into this helper function. Later it may move
|
||||
* to board specific files.
|
||||
*/
|
||||
static void omap_pm_wakeup_setup(void)
|
||||
{
|
||||
u32 level1_wake = 0;
|
||||
u32 level2_wake = OMAP_IRQ_BIT(INT_UART2);
|
||||
|
||||
/*
|
||||
* Turn off all interrupts except GPIO bank 1, L1-2nd level cascade,
|
||||
* and the L2 wakeup interrupts: keypad and UART2. Note that the
|
||||
* drivers must still separately call omap_set_gpio_wakeup() to
|
||||
* wake up to a GPIO interrupt.
|
||||
*/
|
||||
if (cpu_is_omap730())
|
||||
level1_wake = OMAP_IRQ_BIT(INT_730_GPIO_BANK1) |
|
||||
OMAP_IRQ_BIT(INT_730_IH2_IRQ);
|
||||
else if (cpu_is_omap15xx())
|
||||
level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
|
||||
OMAP_IRQ_BIT(INT_1510_IH2_IRQ);
|
||||
else if (cpu_is_omap16xx())
|
||||
level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
|
||||
OMAP_IRQ_BIT(INT_1610_IH2_IRQ);
|
||||
|
||||
omap_writel(~level1_wake, OMAP_IH1_MIR);
|
||||
|
||||
if (cpu_is_omap730()) {
|
||||
omap_writel(~level2_wake, OMAP_IH2_0_MIR);
|
||||
omap_writel(~(OMAP_IRQ_BIT(INT_730_WAKE_UP_REQ) |
|
||||
OMAP_IRQ_BIT(INT_730_MPUIO_KEYPAD)),
|
||||
OMAP_IH2_1_MIR);
|
||||
} else if (cpu_is_omap15xx()) {
|
||||
level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
|
||||
omap_writel(~level2_wake, OMAP_IH2_MIR);
|
||||
} else if (cpu_is_omap16xx()) {
|
||||
level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
|
||||
omap_writel(~level2_wake, OMAP_IH2_0_MIR);
|
||||
|
||||
/* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */
|
||||
omap_writel(~OMAP_IRQ_BIT(INT_1610_WAKE_UP_REQ),
|
||||
OMAP_IH2_1_MIR);
|
||||
omap_writel(~0x0, OMAP_IH2_2_MIR);
|
||||
omap_writel(~0x0, OMAP_IH2_3_MIR);
|
||||
}
|
||||
|
||||
/* New IRQ agreement, recalculate in cascade order */
|
||||
omap_writel(1, OMAP_IH2_CONTROL);
|
||||
omap_writel(1, OMAP_IH1_CONTROL);
|
||||
}
|
||||
|
||||
#define EN_DSPCK 13 /* ARM_CKCTL */
|
||||
#define EN_APICK 6 /* ARM_IDLECT2 */
|
||||
#define DSP_EN 1 /* ARM_RSTCT1 */
|
||||
|
||||
void omap_pm_suspend(void)
|
||||
{
|
||||
unsigned long arg0 = 0, arg1 = 0;
|
||||
|
||||
printk("PM: OMAP%x is trying to enter deep sleep...\n", system_rev);
|
||||
|
||||
omap_serial_wake_trigger(1);
|
||||
|
||||
if (machine_is_omap_osk()) {
|
||||
/* Stop LED1 (D9) blink */
|
||||
tps65010_set_led(LED1, OFF);
|
||||
}
|
||||
|
||||
omap_writew(0xffff, ULPD_SOFT_DISABLE_REQ_REG);
|
||||
|
||||
/*
|
||||
* Step 1: turn off interrupts (FIXME: NOTE: already disabled)
|
||||
*/
|
||||
|
||||
local_irq_disable();
|
||||
local_fiq_disable();
|
||||
|
||||
/*
|
||||
* Step 2: save registers
|
||||
*
|
||||
* The omap is a strange/beautiful device. The caches, memory
|
||||
* and register state are preserved across power saves.
|
||||
* We have to save and restore very little register state to
|
||||
* idle the omap.
|
||||
*
|
||||
* Save interrupt, MPUI, ARM and UPLD control registers.
|
||||
*/
|
||||
|
||||
if (cpu_is_omap730()) {
|
||||
MPUI730_SAVE(OMAP_IH1_MIR);
|
||||
MPUI730_SAVE(OMAP_IH2_0_MIR);
|
||||
MPUI730_SAVE(OMAP_IH2_1_MIR);
|
||||
MPUI730_SAVE(MPUI_CTRL);
|
||||
MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG);
|
||||
MPUI730_SAVE(MPUI_DSP_API_CONFIG);
|
||||
MPUI730_SAVE(EMIFS_CONFIG);
|
||||
MPUI730_SAVE(EMIFF_SDRAM_CONFIG);
|
||||
|
||||
} else if (cpu_is_omap15xx()) {
|
||||
MPUI1510_SAVE(OMAP_IH1_MIR);
|
||||
MPUI1510_SAVE(OMAP_IH2_MIR);
|
||||
MPUI1510_SAVE(MPUI_CTRL);
|
||||
MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
|
||||
MPUI1510_SAVE(MPUI_DSP_API_CONFIG);
|
||||
MPUI1510_SAVE(EMIFS_CONFIG);
|
||||
MPUI1510_SAVE(EMIFF_SDRAM_CONFIG);
|
||||
} else if (cpu_is_omap16xx()) {
|
||||
MPUI1610_SAVE(OMAP_IH1_MIR);
|
||||
MPUI1610_SAVE(OMAP_IH2_0_MIR);
|
||||
MPUI1610_SAVE(OMAP_IH2_1_MIR);
|
||||
MPUI1610_SAVE(OMAP_IH2_2_MIR);
|
||||
MPUI1610_SAVE(OMAP_IH2_3_MIR);
|
||||
MPUI1610_SAVE(MPUI_CTRL);
|
||||
MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG);
|
||||
MPUI1610_SAVE(MPUI_DSP_API_CONFIG);
|
||||
MPUI1610_SAVE(EMIFS_CONFIG);
|
||||
MPUI1610_SAVE(EMIFF_SDRAM_CONFIG);
|
||||
}
|
||||
|
||||
ARM_SAVE(ARM_CKCTL);
|
||||
ARM_SAVE(ARM_IDLECT1);
|
||||
ARM_SAVE(ARM_IDLECT2);
|
||||
if (!(cpu_is_omap15xx()))
|
||||
ARM_SAVE(ARM_IDLECT3);
|
||||
ARM_SAVE(ARM_EWUPCT);
|
||||
ARM_SAVE(ARM_RSTCT1);
|
||||
ARM_SAVE(ARM_RSTCT2);
|
||||
ARM_SAVE(ARM_SYSST);
|
||||
ULPD_SAVE(ULPD_CLOCK_CTRL);
|
||||
ULPD_SAVE(ULPD_STATUS_REQ);
|
||||
|
||||
/* (Step 3 removed - we now allow deep sleep by default) */
|
||||
|
||||
/*
|
||||
* Step 4: OMAP DSP Shutdown
|
||||
*/
|
||||
|
||||
/* stop DSP */
|
||||
omap_writew(omap_readw(ARM_RSTCT1) & ~(1 << DSP_EN), ARM_RSTCT1);
|
||||
|
||||
/* shut down dsp_ck */
|
||||
omap_writew(omap_readw(ARM_CKCTL) & ~(1 << EN_DSPCK), ARM_CKCTL);
|
||||
|
||||
/* temporarily enabling api_ck to access DSP registers */
|
||||
omap_writew(omap_readw(ARM_IDLECT2) | 1 << EN_APICK, ARM_IDLECT2);
|
||||
|
||||
/* save DSP registers */
|
||||
DSP_SAVE(DSP_IDLECT2);
|
||||
|
||||
/* Stop all DSP domain clocks */
|
||||
__raw_writew(0, DSP_IDLECT2);
|
||||
|
||||
/*
|
||||
* Step 5: Wakeup Event Setup
|
||||
*/
|
||||
|
||||
omap_pm_wakeup_setup();
|
||||
|
||||
/*
|
||||
* Step 6: ARM and Traffic controller shutdown
|
||||
*/
|
||||
|
||||
/* disable ARM watchdog */
|
||||
omap_writel(0x00F5, OMAP_WDT_TIMER_MODE);
|
||||
omap_writel(0x00A0, OMAP_WDT_TIMER_MODE);
|
||||
|
||||
/*
|
||||
* Step 6b: ARM and Traffic controller shutdown
|
||||
*
|
||||
* Step 6 continues here. Prepare jump to power management
|
||||
* assembly code in internal SRAM.
|
||||
*
|
||||
* Since the omap_cpu_suspend routine has been copied to
|
||||
* SRAM, we'll do an indirect procedure call to it and pass the
|
||||
* contents of arm_idlect1 and arm_idlect2 so it can restore
|
||||
* them when it wakes up and it will return.
|
||||
*/
|
||||
|
||||
arg0 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT1];
|
||||
arg1 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT2];
|
||||
|
||||
/*
|
||||
* Step 6c: ARM and Traffic controller shutdown
|
||||
*
|
||||
* Jump to assembly code. The processor will stay there
|
||||
* until wake up.
|
||||
*/
|
||||
omap_sram_suspend(arg0, arg1);
|
||||
|
||||
/*
|
||||
* If we are here, processor is woken up!
|
||||
*/
|
||||
|
||||
/*
|
||||
* Restore DSP clocks
|
||||
*/
|
||||
|
||||
/* again temporarily enabling api_ck to access DSP registers */
|
||||
omap_writew(omap_readw(ARM_IDLECT2) | 1 << EN_APICK, ARM_IDLECT2);
|
||||
|
||||
/* Restore DSP domain clocks */
|
||||
DSP_RESTORE(DSP_IDLECT2);
|
||||
|
||||
/*
|
||||
* Restore ARM state, except ARM_IDLECT1/2 which omap_cpu_suspend did
|
||||
*/
|
||||
|
||||
if (!(cpu_is_omap15xx()))
|
||||
ARM_RESTORE(ARM_IDLECT3);
|
||||
ARM_RESTORE(ARM_CKCTL);
|
||||
ARM_RESTORE(ARM_EWUPCT);
|
||||
ARM_RESTORE(ARM_RSTCT1);
|
||||
ARM_RESTORE(ARM_RSTCT2);
|
||||
ARM_RESTORE(ARM_SYSST);
|
||||
ULPD_RESTORE(ULPD_CLOCK_CTRL);
|
||||
ULPD_RESTORE(ULPD_STATUS_REQ);
|
||||
|
||||
if (cpu_is_omap730()) {
|
||||
MPUI730_RESTORE(EMIFS_CONFIG);
|
||||
MPUI730_RESTORE(EMIFF_SDRAM_CONFIG);
|
||||
MPUI730_RESTORE(OMAP_IH1_MIR);
|
||||
MPUI730_RESTORE(OMAP_IH2_0_MIR);
|
||||
MPUI730_RESTORE(OMAP_IH2_1_MIR);
|
||||
} else if (cpu_is_omap15xx()) {
|
||||
MPUI1510_RESTORE(MPUI_CTRL);
|
||||
MPUI1510_RESTORE(MPUI_DSP_BOOT_CONFIG);
|
||||
MPUI1510_RESTORE(MPUI_DSP_API_CONFIG);
|
||||
MPUI1510_RESTORE(EMIFS_CONFIG);
|
||||
MPUI1510_RESTORE(EMIFF_SDRAM_CONFIG);
|
||||
MPUI1510_RESTORE(OMAP_IH1_MIR);
|
||||
MPUI1510_RESTORE(OMAP_IH2_MIR);
|
||||
} else if (cpu_is_omap16xx()) {
|
||||
MPUI1610_RESTORE(MPUI_CTRL);
|
||||
MPUI1610_RESTORE(MPUI_DSP_BOOT_CONFIG);
|
||||
MPUI1610_RESTORE(MPUI_DSP_API_CONFIG);
|
||||
MPUI1610_RESTORE(EMIFS_CONFIG);
|
||||
MPUI1610_RESTORE(EMIFF_SDRAM_CONFIG);
|
||||
|
||||
MPUI1610_RESTORE(OMAP_IH1_MIR);
|
||||
MPUI1610_RESTORE(OMAP_IH2_0_MIR);
|
||||
MPUI1610_RESTORE(OMAP_IH2_1_MIR);
|
||||
MPUI1610_RESTORE(OMAP_IH2_2_MIR);
|
||||
MPUI1610_RESTORE(OMAP_IH2_3_MIR);
|
||||
}
|
||||
|
||||
omap_writew(0, ULPD_SOFT_DISABLE_REQ_REG);
|
||||
|
||||
/*
|
||||
* Reenable interrupts
|
||||
*/
|
||||
|
||||
local_irq_enable();
|
||||
local_fiq_enable();
|
||||
|
||||
omap_serial_wake_trigger(0);
|
||||
|
||||
printk("PM: OMAP%x is re-starting from deep sleep...\n", system_rev);
|
||||
|
||||
if (machine_is_omap_osk()) {
|
||||
/* Let LED1 (D9) blink again */
|
||||
tps65010_set_led(LED1, BLINK);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(DEBUG) && defined(CONFIG_PROC_FS)
|
||||
static int g_read_completed;
|
||||
|
||||
/*
|
||||
* Read system PM registers for debugging
|
||||
*/
|
||||
static int omap_pm_read_proc(
|
||||
char *page_buffer,
|
||||
char **my_first_byte,
|
||||
off_t virtual_start,
|
||||
int length,
|
||||
int *eof,
|
||||
void *data)
|
||||
{
|
||||
int my_buffer_offset = 0;
|
||||
char * const my_base = page_buffer;
|
||||
|
||||
ARM_SAVE(ARM_CKCTL);
|
||||
ARM_SAVE(ARM_IDLECT1);
|
||||
ARM_SAVE(ARM_IDLECT2);
|
||||
if (!(cpu_is_omap15xx()))
|
||||
ARM_SAVE(ARM_IDLECT3);
|
||||
ARM_SAVE(ARM_EWUPCT);
|
||||
ARM_SAVE(ARM_RSTCT1);
|
||||
ARM_SAVE(ARM_RSTCT2);
|
||||
ARM_SAVE(ARM_SYSST);
|
||||
|
||||
ULPD_SAVE(ULPD_IT_STATUS);
|
||||
ULPD_SAVE(ULPD_CLOCK_CTRL);
|
||||
ULPD_SAVE(ULPD_SOFT_REQ);
|
||||
ULPD_SAVE(ULPD_STATUS_REQ);
|
||||
ULPD_SAVE(ULPD_DPLL_CTRL);
|
||||
ULPD_SAVE(ULPD_POWER_CTRL);
|
||||
|
||||
if (cpu_is_omap730()) {
|
||||
MPUI730_SAVE(MPUI_CTRL);
|
||||
MPUI730_SAVE(MPUI_DSP_STATUS);
|
||||
MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG);
|
||||
MPUI730_SAVE(MPUI_DSP_API_CONFIG);
|
||||
MPUI730_SAVE(EMIFF_SDRAM_CONFIG);
|
||||
MPUI730_SAVE(EMIFS_CONFIG);
|
||||
} else if (cpu_is_omap15xx()) {
|
||||
MPUI1510_SAVE(MPUI_CTRL);
|
||||
MPUI1510_SAVE(MPUI_DSP_STATUS);
|
||||
MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
|
||||
MPUI1510_SAVE(MPUI_DSP_API_CONFIG);
|
||||
MPUI1510_SAVE(EMIFF_SDRAM_CONFIG);
|
||||
MPUI1510_SAVE(EMIFS_CONFIG);
|
||||
} else if (cpu_is_omap16xx()) {
|
||||
MPUI1610_SAVE(MPUI_CTRL);
|
||||
MPUI1610_SAVE(MPUI_DSP_STATUS);
|
||||
MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG);
|
||||
MPUI1610_SAVE(MPUI_DSP_API_CONFIG);
|
||||
MPUI1610_SAVE(EMIFF_SDRAM_CONFIG);
|
||||
MPUI1610_SAVE(EMIFS_CONFIG);
|
||||
}
|
||||
|
||||
if (virtual_start == 0) {
|
||||
g_read_completed = 0;
|
||||
|
||||
my_buffer_offset += sprintf(my_base + my_buffer_offset,
|
||||
"ARM_CKCTL_REG: 0x%-8x \n"
|
||||
"ARM_IDLECT1_REG: 0x%-8x \n"
|
||||
"ARM_IDLECT2_REG: 0x%-8x \n"
|
||||
"ARM_IDLECT3_REG: 0x%-8x \n"
|
||||
"ARM_EWUPCT_REG: 0x%-8x \n"
|
||||
"ARM_RSTCT1_REG: 0x%-8x \n"
|
||||
"ARM_RSTCT2_REG: 0x%-8x \n"
|
||||
"ARM_SYSST_REG: 0x%-8x \n"
|
||||
"ULPD_IT_STATUS_REG: 0x%-4x \n"
|
||||
"ULPD_CLOCK_CTRL_REG: 0x%-4x \n"
|
||||
"ULPD_SOFT_REQ_REG: 0x%-4x \n"
|
||||
"ULPD_DPLL_CTRL_REG: 0x%-4x \n"
|
||||
"ULPD_STATUS_REQ_REG: 0x%-4x \n"
|
||||
"ULPD_POWER_CTRL_REG: 0x%-4x \n",
|
||||
ARM_SHOW(ARM_CKCTL),
|
||||
ARM_SHOW(ARM_IDLECT1),
|
||||
ARM_SHOW(ARM_IDLECT2),
|
||||
ARM_SHOW(ARM_IDLECT3),
|
||||
ARM_SHOW(ARM_EWUPCT),
|
||||
ARM_SHOW(ARM_RSTCT1),
|
||||
ARM_SHOW(ARM_RSTCT2),
|
||||
ARM_SHOW(ARM_SYSST),
|
||||
ULPD_SHOW(ULPD_IT_STATUS),
|
||||
ULPD_SHOW(ULPD_CLOCK_CTRL),
|
||||
ULPD_SHOW(ULPD_SOFT_REQ),
|
||||
ULPD_SHOW(ULPD_DPLL_CTRL),
|
||||
ULPD_SHOW(ULPD_STATUS_REQ),
|
||||
ULPD_SHOW(ULPD_POWER_CTRL));
|
||||
|
||||
if (cpu_is_omap730()) {
|
||||
my_buffer_offset += sprintf(my_base + my_buffer_offset,
|
||||
"MPUI730_CTRL_REG 0x%-8x \n"
|
||||
"MPUI730_DSP_STATUS_REG: 0x%-8x \n"
|
||||
"MPUI730_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
|
||||
"MPUI730_DSP_API_CONFIG_REG: 0x%-8x \n"
|
||||
"MPUI730_SDRAM_CONFIG_REG: 0x%-8x \n"
|
||||
"MPUI730_EMIFS_CONFIG_REG: 0x%-8x \n",
|
||||
MPUI730_SHOW(MPUI_CTRL),
|
||||
MPUI730_SHOW(MPUI_DSP_STATUS),
|
||||
MPUI730_SHOW(MPUI_DSP_BOOT_CONFIG),
|
||||
MPUI730_SHOW(MPUI_DSP_API_CONFIG),
|
||||
MPUI730_SHOW(EMIFF_SDRAM_CONFIG),
|
||||
MPUI730_SHOW(EMIFS_CONFIG));
|
||||
} else if (cpu_is_omap15xx()) {
|
||||
my_buffer_offset += sprintf(my_base + my_buffer_offset,
|
||||
"MPUI1510_CTRL_REG 0x%-8x \n"
|
||||
"MPUI1510_DSP_STATUS_REG: 0x%-8x \n"
|
||||
"MPUI1510_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
|
||||
"MPUI1510_DSP_API_CONFIG_REG: 0x%-8x \n"
|
||||
"MPUI1510_SDRAM_CONFIG_REG: 0x%-8x \n"
|
||||
"MPUI1510_EMIFS_CONFIG_REG: 0x%-8x \n",
|
||||
MPUI1510_SHOW(MPUI_CTRL),
|
||||
MPUI1510_SHOW(MPUI_DSP_STATUS),
|
||||
MPUI1510_SHOW(MPUI_DSP_BOOT_CONFIG),
|
||||
MPUI1510_SHOW(MPUI_DSP_API_CONFIG),
|
||||
MPUI1510_SHOW(EMIFF_SDRAM_CONFIG),
|
||||
MPUI1510_SHOW(EMIFS_CONFIG));
|
||||
} else if (cpu_is_omap16xx()) {
|
||||
my_buffer_offset += sprintf(my_base + my_buffer_offset,
|
||||
"MPUI1610_CTRL_REG 0x%-8x \n"
|
||||
"MPUI1610_DSP_STATUS_REG: 0x%-8x \n"
|
||||
"MPUI1610_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
|
||||
"MPUI1610_DSP_API_CONFIG_REG: 0x%-8x \n"
|
||||
"MPUI1610_SDRAM_CONFIG_REG: 0x%-8x \n"
|
||||
"MPUI1610_EMIFS_CONFIG_REG: 0x%-8x \n",
|
||||
MPUI1610_SHOW(MPUI_CTRL),
|
||||
MPUI1610_SHOW(MPUI_DSP_STATUS),
|
||||
MPUI1610_SHOW(MPUI_DSP_BOOT_CONFIG),
|
||||
MPUI1610_SHOW(MPUI_DSP_API_CONFIG),
|
||||
MPUI1610_SHOW(EMIFF_SDRAM_CONFIG),
|
||||
MPUI1610_SHOW(EMIFS_CONFIG));
|
||||
}
|
||||
|
||||
g_read_completed++;
|
||||
} else if (g_read_completed >= 1) {
|
||||
*eof = 1;
|
||||
return 0;
|
||||
}
|
||||
g_read_completed++;
|
||||
|
||||
*my_first_byte = page_buffer;
|
||||
return my_buffer_offset;
|
||||
}
|
||||
|
||||
static void omap_pm_init_proc(void)
|
||||
{
|
||||
struct proc_dir_entry *entry;
|
||||
|
||||
entry = create_proc_read_entry("driver/omap_pm",
|
||||
S_IWUSR | S_IRUGO, NULL,
|
||||
omap_pm_read_proc, NULL);
|
||||
}
|
||||
|
||||
#endif /* DEBUG && CONFIG_PROC_FS */
|
||||
|
||||
static void (*saved_idle)(void) = NULL;
|
||||
|
||||
/*
|
||||
* omap_pm_prepare - Do preliminary suspend work.
|
||||
* @state: suspend state we're entering.
|
||||
*
|
||||
*/
|
||||
static int omap_pm_prepare(suspend_state_t state)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
/* We cannot sleep in idle until we have resumed */
|
||||
saved_idle = pm_idle;
|
||||
pm_idle = NULL;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case PM_SUSPEND_STANDBY:
|
||||
case PM_SUSPEND_MEM:
|
||||
break;
|
||||
|
||||
case PM_SUSPEND_DISK:
|
||||
return -ENOTSUPP;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* omap_pm_enter - Actually enter a sleep state.
|
||||
* @state: State we're entering.
|
||||
*
|
||||
*/
|
||||
|
||||
static int omap_pm_enter(suspend_state_t state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case PM_SUSPEND_STANDBY:
|
||||
case PM_SUSPEND_MEM:
|
||||
omap_pm_suspend();
|
||||
break;
|
||||
|
||||
case PM_SUSPEND_DISK:
|
||||
return -ENOTSUPP;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* omap_pm_finish - Finish up suspend sequence.
|
||||
* @state: State we're coming out of.
|
||||
*
|
||||
* This is called after we wake back up (or if entering the sleep state
|
||||
* failed).
|
||||
*/
|
||||
|
||||
static int omap_pm_finish(suspend_state_t state)
|
||||
{
|
||||
pm_idle = saved_idle;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static irqreturn_t omap_wakeup_interrupt(int irq, void * dev,
|
||||
struct pt_regs * regs)
|
||||
{
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction omap_wakeup_irq = {
|
||||
.name = "peripheral wakeup",
|
||||
.flags = SA_INTERRUPT,
|
||||
.handler = omap_wakeup_interrupt
|
||||
};
|
||||
|
||||
|
||||
|
||||
static struct pm_ops omap_pm_ops ={
|
||||
.pm_disk_mode = 0,
|
||||
.prepare = omap_pm_prepare,
|
||||
.enter = omap_pm_enter,
|
||||
.finish = omap_pm_finish,
|
||||
};
|
||||
|
||||
static int __init omap_pm_init(void)
|
||||
{
|
||||
printk("Power Management for TI OMAP.\n");
|
||||
|
||||
/*
|
||||
* We copy the assembler sleep/wakeup routines to SRAM.
|
||||
* These routines need to be in SRAM as that's the only
|
||||
* memory the MPU can see when it wakes up.
|
||||
*/
|
||||
if (cpu_is_omap730()) {
|
||||
omap_sram_idle = omap_sram_push(omap730_idle_loop_suspend,
|
||||
omap730_idle_loop_suspend_sz);
|
||||
omap_sram_suspend = omap_sram_push(omap730_cpu_suspend,
|
||||
omap730_cpu_suspend_sz);
|
||||
} else if (cpu_is_omap15xx()) {
|
||||
omap_sram_idle = omap_sram_push(omap1510_idle_loop_suspend,
|
||||
omap1510_idle_loop_suspend_sz);
|
||||
omap_sram_suspend = omap_sram_push(omap1510_cpu_suspend,
|
||||
omap1510_cpu_suspend_sz);
|
||||
} else if (cpu_is_omap16xx()) {
|
||||
omap_sram_idle = omap_sram_push(omap1610_idle_loop_suspend,
|
||||
omap1610_idle_loop_suspend_sz);
|
||||
omap_sram_suspend = omap_sram_push(omap1610_cpu_suspend,
|
||||
omap1610_cpu_suspend_sz);
|
||||
}
|
||||
|
||||
if (omap_sram_idle == NULL || omap_sram_suspend == NULL) {
|
||||
printk(KERN_ERR "PM not initialized: Missing SRAM support\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
pm_idle = omap_pm_idle;
|
||||
|
||||
if (cpu_is_omap730())
|
||||
setup_irq(INT_730_WAKE_UP_REQ, &omap_wakeup_irq);
|
||||
else if (cpu_is_omap16xx())
|
||||
setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq);
|
||||
|
||||
/* Program new power ramp-up time
|
||||
* (0 for most boards since we don't lower voltage when in deep sleep)
|
||||
*/
|
||||
omap_writew(ULPD_SETUP_ANALOG_CELL_3_VAL, ULPD_SETUP_ANALOG_CELL_3);
|
||||
|
||||
/* Setup ULPD POWER_CTRL_REG - enter deep sleep whenever possible */
|
||||
omap_writew(ULPD_POWER_CTRL_REG_VAL, ULPD_POWER_CTRL);
|
||||
|
||||
/* Configure IDLECT3 */
|
||||
if (cpu_is_omap730())
|
||||
omap_writel(OMAP730_IDLECT3_VAL, OMAP730_IDLECT3);
|
||||
else if (cpu_is_omap16xx())
|
||||
omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3);
|
||||
|
||||
pm_set_ops(&omap_pm_ops);
|
||||
|
||||
#if defined(DEBUG) && defined(CONFIG_PROC_FS)
|
||||
omap_pm_init_proc();
|
||||
#endif
|
||||
|
||||
subsys_create_file(&power_subsys, &sleep_while_idle_attr);
|
||||
|
||||
if (cpu_is_omap16xx()) {
|
||||
/* configure LOW_PWR pin */
|
||||
omap_cfg_reg(T20_1610_LOW_PWR);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
__initcall(omap_pm_init);
|
@ -30,9 +30,9 @@
|
||||
#include <asm/arch/pm.h>
|
||||
#endif
|
||||
|
||||
static struct clk * uart1_ck = NULL;
|
||||
static struct clk * uart2_ck = NULL;
|
||||
static struct clk * uart3_ck = NULL;
|
||||
static struct clk * uart1_ck;
|
||||
static struct clk * uart2_ck;
|
||||
static struct clk * uart3_ck;
|
||||
|
||||
static inline unsigned int omap_serial_in(struct plat_serial8250_port *up,
|
||||
int offset)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* linux/arch/arm/plat-omap/sleep.S
|
||||
* linux/arch/arm/mach-omap1/sleep.S
|
||||
*
|
||||
* Low-level OMAP730/1510/1610 sleep/wakeUp support
|
||||
*
|
||||
@ -383,60 +383,133 @@ ENTRY(omap1610_cpu_suspend)
|
||||
mcr p15, 0, r0, c7, c10, 4
|
||||
nop
|
||||
|
||||
@ load base address of Traffic Controller
|
||||
@ Load base address of Traffic Controller
|
||||
mov r6, #TCMIF_ASM_BASE & 0xff000000
|
||||
orr r6, r6, #TCMIF_ASM_BASE & 0x00ff0000
|
||||
orr r6, r6, #TCMIF_ASM_BASE & 0x0000ff00
|
||||
|
||||
@ prepare to put SDRAM into self-refresh manually
|
||||
@ Prepare to put SDRAM into self-refresh manually
|
||||
ldr r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
|
||||
orr r9, r7, #SELF_REFRESH_MODE & 0xff000000
|
||||
orr r9, r9, #SELF_REFRESH_MODE & 0x000000ff
|
||||
str r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
|
||||
|
||||
@ prepare to put EMIFS to Sleep
|
||||
@ Prepare to put EMIFS to Sleep
|
||||
ldr r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
|
||||
orr r9, r8, #IDLE_EMIFS_REQUEST & 0xff
|
||||
str r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
|
||||
|
||||
@ load base address of ARM_IDLECT1 and ARM_IDLECT2
|
||||
@ Load base address of ARM_IDLECT1 and ARM_IDLECT2
|
||||
mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000
|
||||
orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
|
||||
orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
|
||||
|
||||
@ turn off clock domains
|
||||
@ do not disable PERCK (0x04)
|
||||
@ Turn off clock domains
|
||||
@ Do not disable PERCK (0x04)
|
||||
mov r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff
|
||||
orr r5, r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff00
|
||||
strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
|
||||
|
||||
@ request ARM idle
|
||||
@ Request ARM idle
|
||||
mov r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff
|
||||
orr r3, r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff00
|
||||
strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
|
||||
|
||||
@ disable instruction cache
|
||||
mrc p15, 0, r9, c1, c0, 0
|
||||
bic r2, r9, #0x1000
|
||||
mcr p15, 0, r2, c1, c0, 0
|
||||
nop
|
||||
|
||||
/*
|
||||
* Let's wait for the next wake up event to wake us up. r0 can't be
|
||||
* used here because r0 holds ARM_IDLECT1
|
||||
*/
|
||||
mov r2, #0
|
||||
mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt
|
||||
|
||||
@ Errata (HEL3SU467, section 1.4.4) specifies nop-instructions
|
||||
@ according to this formula:
|
||||
@ 2 + (4*DPLL_MULT)/DPLL_DIV/ARMDIV
|
||||
@ Max DPLL_MULT = 18
|
||||
@ DPLL_DIV = 1
|
||||
@ ARMDIV = 1
|
||||
@ => 74 nop-instructions
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop @10
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop @20
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop @30
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop @40
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop @50
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop @60
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop @70
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop @74
|
||||
/*
|
||||
* omap1610_cpu_suspend()'s resume point.
|
||||
*
|
||||
* It will just start executing here, so we'll restore stuff from the
|
||||
* stack.
|
||||
*/
|
||||
@ re-enable Icache
|
||||
mcr p15, 0, r9, c1, c0, 0
|
||||
|
||||
@ reset the ARM_IDLECT1 and ARM_IDLECT2.
|
||||
@ Restore the ARM_IDLECT1 and ARM_IDLECT2.
|
||||
strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
|
||||
strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
|
||||
|
||||
@ -444,7 +517,7 @@ ENTRY(omap1610_cpu_suspend)
|
||||
str r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
|
||||
str r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
|
||||
|
||||
@ restore regs and return
|
||||
@ Restore regs and return
|
||||
ldmfd sp!, {r0 - r12, pc}
|
||||
|
||||
ENTRY(omap1610_cpu_suspend_sz)
|
@ -51,8 +51,6 @@
|
||||
|
||||
struct sys_timer omap_timer;
|
||||
|
||||
#ifdef CONFIG_OMAP_MPU_TIMER
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* MPU timer
|
||||
@ -222,195 +220,6 @@ unsigned long long sched_clock(void)
|
||||
|
||||
return cycles_2_ns(ticks64);
|
||||
}
|
||||
#endif /* CONFIG_OMAP_MPU_TIMER */
|
||||
|
||||
#ifdef CONFIG_OMAP_32K_TIMER
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
#error OMAP 32KHz timer does not currently work on 15XX!
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* 32KHz OS timer
|
||||
*
|
||||
* This currently works only on 16xx, as 1510 does not have the continuous
|
||||
* 32KHz synchronous timer. The 32KHz synchronous timer is used to keep track
|
||||
* of time in addition to the 32KHz OS timer. Using only the 32KHz OS timer
|
||||
* on 1510 would be possible, but the timer would not be as accurate as
|
||||
* with the 32KHz synchronized timer.
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
#define OMAP_32K_TIMER_BASE 0xfffb9000
|
||||
#define OMAP_32K_TIMER_CR 0x08
|
||||
#define OMAP_32K_TIMER_TVR 0x00
|
||||
#define OMAP_32K_TIMER_TCR 0x04
|
||||
|
||||
#define OMAP_32K_TICKS_PER_HZ (32768 / HZ)
|
||||
|
||||
/*
|
||||
* TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1
|
||||
* so with HZ = 100, TVR = 327.68.
|
||||
*/
|
||||
#define OMAP_32K_TIMER_TICK_PERIOD ((32768 / HZ) - 1)
|
||||
#define TIMER_32K_SYNCHRONIZED 0xfffbc410
|
||||
|
||||
#define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate) \
|
||||
(((nr_jiffies) * (clock_rate)) / HZ)
|
||||
|
||||
static inline void omap_32k_timer_write(int val, int reg)
|
||||
{
|
||||
omap_writew(val, reg + OMAP_32K_TIMER_BASE);
|
||||
}
|
||||
|
||||
static inline unsigned long omap_32k_timer_read(int reg)
|
||||
{
|
||||
return omap_readl(reg + OMAP_32K_TIMER_BASE) & 0xffffff;
|
||||
}
|
||||
|
||||
/*
|
||||
* The 32KHz synchronized timer is an additional timer on 16xx.
|
||||
* It is always running.
|
||||
*/
|
||||
static inline unsigned long omap_32k_sync_timer_read(void)
|
||||
{
|
||||
return omap_readl(TIMER_32K_SYNCHRONIZED);
|
||||
}
|
||||
|
||||
static inline void omap_32k_timer_start(unsigned long load_val)
|
||||
{
|
||||
omap_32k_timer_write(load_val, OMAP_32K_TIMER_TVR);
|
||||
omap_32k_timer_write(0x0f, OMAP_32K_TIMER_CR);
|
||||
}
|
||||
|
||||
static inline void omap_32k_timer_stop(void)
|
||||
{
|
||||
omap_32k_timer_write(0x0, OMAP_32K_TIMER_CR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Rounds down to nearest usec. Note that this will overflow for larger values.
|
||||
*/
|
||||
static inline unsigned long omap_32k_ticks_to_usecs(unsigned long ticks_32k)
|
||||
{
|
||||
return (ticks_32k * 5*5*5*5*5*5) >> 9;
|
||||
}
|
||||
|
||||
/*
|
||||
* Rounds down to nearest nsec.
|
||||
*/
|
||||
static inline unsigned long long
|
||||
omap_32k_ticks_to_nsecs(unsigned long ticks_32k)
|
||||
{
|
||||
return (unsigned long long) ticks_32k * 1000 * 5*5*5*5*5*5 >> 9;
|
||||
}
|
||||
|
||||
static unsigned long omap_32k_last_tick = 0;
|
||||
|
||||
/*
|
||||
* Returns elapsed usecs since last 32k timer interrupt
|
||||
*/
|
||||
static unsigned long omap_32k_timer_gettimeoffset(void)
|
||||
{
|
||||
unsigned long now = omap_32k_sync_timer_read();
|
||||
return omap_32k_ticks_to_usecs(now - omap_32k_last_tick);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns current time from boot in nsecs. It's OK for this to wrap
|
||||
* around for now, as it's just a relative time stamp.
|
||||
*/
|
||||
unsigned long long sched_clock(void)
|
||||
{
|
||||
return omap_32k_ticks_to_nsecs(omap_32k_sync_timer_read());
|
||||
}
|
||||
|
||||
/*
|
||||
* Timer interrupt for 32KHz timer. When dynamic tick is enabled, this
|
||||
* function is also called from other interrupts to remove latency
|
||||
* issues with dynamic tick. In the dynamic tick case, we need to lock
|
||||
* with irqsave.
|
||||
*/
|
||||
static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long now;
|
||||
|
||||
write_seqlock_irqsave(&xtime_lock, flags);
|
||||
now = omap_32k_sync_timer_read();
|
||||
|
||||
while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) {
|
||||
omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ;
|
||||
timer_tick(regs);
|
||||
}
|
||||
|
||||
/* Restart timer so we don't drift off due to modulo or dynamic tick.
|
||||
* By default we program the next timer to be continuous to avoid
|
||||
* latencies during high system load. During dynamic tick operation the
|
||||
* continuous timer can be overridden from pm_idle to be longer.
|
||||
*/
|
||||
omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now);
|
||||
write_sequnlock_irqrestore(&xtime_lock, flags);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NO_IDLE_HZ
|
||||
/*
|
||||
* Programs the next timer interrupt needed. Called when dynamic tick is
|
||||
* enabled, and to reprogram the ticks to skip from pm_idle. Note that
|
||||
* we can keep the timer continuous, and don't need to set it to run in
|
||||
* one-shot mode. This is because the timer will get reprogrammed again
|
||||
* after next interrupt.
|
||||
*/
|
||||
void omap_32k_timer_reprogram(unsigned long next_tick)
|
||||
{
|
||||
omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1);
|
||||
}
|
||||
|
||||
static struct irqaction omap_32k_timer_irq;
|
||||
extern struct timer_update_handler timer_update;
|
||||
|
||||
static int omap_32k_timer_enable_dyn_tick(void)
|
||||
{
|
||||
/* No need to reprogram timer, just use the next interrupt */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap_32k_timer_disable_dyn_tick(void)
|
||||
{
|
||||
omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dyn_tick_timer omap_dyn_tick_timer = {
|
||||
.enable = omap_32k_timer_enable_dyn_tick,
|
||||
.disable = omap_32k_timer_disable_dyn_tick,
|
||||
.reprogram = omap_32k_timer_reprogram,
|
||||
.handler = omap_32k_timer_interrupt,
|
||||
};
|
||||
#endif /* CONFIG_NO_IDLE_HZ */
|
||||
|
||||
static struct irqaction omap_32k_timer_irq = {
|
||||
.name = "32KHz timer",
|
||||
.flags = SA_INTERRUPT | SA_TIMER,
|
||||
.handler = omap_32k_timer_interrupt,
|
||||
};
|
||||
|
||||
static __init void omap_init_32k_timer(void)
|
||||
{
|
||||
|
||||
#ifdef CONFIG_NO_IDLE_HZ
|
||||
omap_timer.dyn_tick = &omap_dyn_tick_timer;
|
||||
#endif
|
||||
|
||||
setup_irq(INT_OS_TIMER, &omap_32k_timer_irq);
|
||||
omap_timer.offset = omap_32k_timer_gettimeoffset;
|
||||
omap_32k_last_tick = omap_32k_sync_timer_read();
|
||||
omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
|
||||
}
|
||||
#endif /* CONFIG_OMAP_32K_TIMER */
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
@ -419,13 +228,7 @@ static __init void omap_init_32k_timer(void)
|
||||
*/
|
||||
static void __init omap_timer_init(void)
|
||||
{
|
||||
#if defined(CONFIG_OMAP_MPU_TIMER)
|
||||
omap_init_mpu_timer();
|
||||
#elif defined(CONFIG_OMAP_32K_TIMER)
|
||||
omap_init_32k_timer();
|
||||
#else
|
||||
#error No system timer selected in Kconfig!
|
||||
#endif
|
||||
}
|
||||
|
||||
struct sys_timer omap_timer = {
|
||||
|
@ -20,3 +20,6 @@ config MACH_OMAP_H4
|
||||
bool "OMAP 2420 H4 board"
|
||||
depends on ARCH_OMAP2 && ARCH_OMAP24XX
|
||||
|
||||
config MACH_OMAP_APOLLON
|
||||
bool "OMAP 2420 Apollon board"
|
||||
depends on ARCH_OMAP2 && ARCH_OMAP24XX
|
||||
|
@ -3,11 +3,15 @@
|
||||
#
|
||||
|
||||
# Common support
|
||||
obj-y := irq.o id.o io.o sram-fn.o clock.o mux.o devices.o serial.o
|
||||
obj-y := irq.o id.o io.o sram-fn.o memory.o prcm.o clock.o mux.o devices.o serial.o
|
||||
|
||||
obj-$(CONFIG_OMAP_MPU_TIMER) += timer-gp.o
|
||||
|
||||
# Power Management
|
||||
obj-$(CONFIG_PM) += pm.o sleep.o
|
||||
|
||||
# Specific board support
|
||||
obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o
|
||||
obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o
|
||||
obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o
|
||||
|
||||
|
285
arch/arm/mach-omap2/board-apollon.c
Normal file
285
arch/arm/mach-omap2/board-apollon.c
Normal file
@ -0,0 +1,285 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap/omap2/board-apollon.c
|
||||
*
|
||||
* Copyright (C) 2005,2006 Samsung Electronics
|
||||
* Author: Kyungmin Park <kyungmin.park@samsung.com>
|
||||
*
|
||||
* Modified from mach-omap/omap2/board-h4.c
|
||||
*
|
||||
* Code for apollon OMAP2 board. Should work on many OMAP2 systems where
|
||||
* the bootloader passes the board-specific data to the kernel.
|
||||
* Do not put any board specific code to this file; create a new machine
|
||||
* type if you need custom low-level initializations.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/mtd/onenand.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/flash.h>
|
||||
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/usb.h>
|
||||
#include <asm/arch/board.h>
|
||||
#include <asm/arch/common.h>
|
||||
#include "prcm-regs.h"
|
||||
|
||||
/* LED & Switch macros */
|
||||
#define LED0_GPIO13 13
|
||||
#define LED1_GPIO14 14
|
||||
#define LED2_GPIO15 15
|
||||
#define SW_ENTER_GPIO16 16
|
||||
#define SW_UP_GPIO17 17
|
||||
#define SW_DOWN_GPIO58 58
|
||||
|
||||
static struct mtd_partition apollon_partitions[] = {
|
||||
{
|
||||
.name = "X-Loader + U-Boot",
|
||||
.offset = 0,
|
||||
.size = SZ_128K,
|
||||
.mask_flags = MTD_WRITEABLE,
|
||||
},
|
||||
{
|
||||
.name = "params",
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.size = SZ_128K,
|
||||
},
|
||||
{
|
||||
.name = "kernel",
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.size = SZ_2M,
|
||||
},
|
||||
{
|
||||
.name = "rootfs",
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.size = SZ_16M,
|
||||
},
|
||||
{
|
||||
.name = "filesystem00",
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.size = SZ_32M,
|
||||
},
|
||||
{
|
||||
.name = "filesystem01",
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.size = MTDPART_SIZ_FULL,
|
||||
},
|
||||
};
|
||||
|
||||
static struct flash_platform_data apollon_flash_data = {
|
||||
.parts = apollon_partitions,
|
||||
.nr_parts = ARRAY_SIZE(apollon_partitions),
|
||||
};
|
||||
|
||||
static struct resource apollon_flash_resource = {
|
||||
.start = APOLLON_CS0_BASE,
|
||||
.end = APOLLON_CS0_BASE + SZ_128K,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct platform_device apollon_onenand_device = {
|
||||
.name = "onenand",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &apollon_flash_data,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(&apollon_flash_resource),
|
||||
.resource = &apollon_flash_resource,
|
||||
};
|
||||
|
||||
static struct resource apollon_smc91x_resources[] = {
|
||||
[0] = {
|
||||
.start = APOLLON_ETHR_START, /* Physical */
|
||||
.end = APOLLON_ETHR_START + 0xf,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ),
|
||||
.end = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ),
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device apollon_smc91x_device = {
|
||||
.name = "smc91x",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(apollon_smc91x_resources),
|
||||
.resource = apollon_smc91x_resources,
|
||||
};
|
||||
|
||||
static struct platform_device apollon_lcd_device = {
|
||||
.name = "apollon_lcd",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static struct platform_device *apollon_devices[] __initdata = {
|
||||
&apollon_onenand_device,
|
||||
&apollon_smc91x_device,
|
||||
&apollon_lcd_device,
|
||||
};
|
||||
|
||||
static inline void __init apollon_init_smc91x(void)
|
||||
{
|
||||
/* Make sure CS1 timings are correct */
|
||||
GPMC_CONFIG1_1 = 0x00011203;
|
||||
GPMC_CONFIG2_1 = 0x001f1f01;
|
||||
GPMC_CONFIG3_1 = 0x00080803;
|
||||
GPMC_CONFIG4_1 = 0x1c091c09;
|
||||
GPMC_CONFIG5_1 = 0x041f1f1f;
|
||||
GPMC_CONFIG6_1 = 0x000004c4;
|
||||
GPMC_CONFIG7_1 = 0x00000f40 | (APOLLON_CS1_BASE >> 24);
|
||||
udelay(100);
|
||||
|
||||
omap_cfg_reg(W4__24XX_GPIO74);
|
||||
if (omap_request_gpio(APOLLON_ETHR_GPIO_IRQ) < 0) {
|
||||
printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
|
||||
APOLLON_ETHR_GPIO_IRQ);
|
||||
return;
|
||||
}
|
||||
omap_set_gpio_direction(APOLLON_ETHR_GPIO_IRQ, 1);
|
||||
}
|
||||
|
||||
static void __init omap_apollon_init_irq(void)
|
||||
{
|
||||
omap2_init_common_hw();
|
||||
omap_init_irq();
|
||||
omap_gpio_init();
|
||||
apollon_init_smc91x();
|
||||
}
|
||||
|
||||
static struct omap_uart_config apollon_uart_config __initdata = {
|
||||
.enabled_uarts = (1 << 0) | (0 << 1) | (0 << 2),
|
||||
};
|
||||
|
||||
static struct omap_mmc_config apollon_mmc_config __initdata = {
|
||||
.mmc [0] = {
|
||||
.enabled = 0,
|
||||
.wire4 = 0,
|
||||
.wp_pin = -1,
|
||||
.power_pin = -1,
|
||||
.switch_pin = -1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct omap_lcd_config apollon_lcd_config __initdata = {
|
||||
.ctrl_name = "internal",
|
||||
};
|
||||
|
||||
static struct omap_board_config_kernel apollon_config[] = {
|
||||
{ OMAP_TAG_UART, &apollon_uart_config },
|
||||
{ OMAP_TAG_MMC, &apollon_mmc_config },
|
||||
{ OMAP_TAG_LCD, &apollon_lcd_config },
|
||||
};
|
||||
|
||||
static void __init apollon_led_init(void)
|
||||
{
|
||||
/* LED0 - AA10 */
|
||||
omap_cfg_reg(AA10_242X_GPIO13);
|
||||
omap_request_gpio(LED0_GPIO13);
|
||||
omap_set_gpio_direction(LED0_GPIO13, 0);
|
||||
omap_set_gpio_dataout(LED0_GPIO13, 0);
|
||||
/* LED1 - AA6 */
|
||||
omap_cfg_reg(AA6_242X_GPIO14);
|
||||
omap_request_gpio(LED1_GPIO14);
|
||||
omap_set_gpio_direction(LED1_GPIO14, 0);
|
||||
omap_set_gpio_dataout(LED1_GPIO14, 0);
|
||||
/* LED2 - AA4 */
|
||||
omap_cfg_reg(AA4_242X_GPIO15);
|
||||
omap_request_gpio(LED2_GPIO15);
|
||||
omap_set_gpio_direction(LED2_GPIO15, 0);
|
||||
omap_set_gpio_dataout(LED2_GPIO15, 0);
|
||||
}
|
||||
|
||||
static irqreturn_t apollon_sw_interrupt(int irq, void *ignored, struct pt_regs *regs)
|
||||
{
|
||||
static unsigned int led0, led1, led2;
|
||||
|
||||
if (irq == OMAP_GPIO_IRQ(SW_ENTER_GPIO16))
|
||||
omap_set_gpio_dataout(LED0_GPIO13, led0 ^= 1);
|
||||
else if (irq == OMAP_GPIO_IRQ(SW_UP_GPIO17))
|
||||
omap_set_gpio_dataout(LED1_GPIO14, led1 ^= 1);
|
||||
else if (irq == OMAP_GPIO_IRQ(SW_DOWN_GPIO58))
|
||||
omap_set_gpio_dataout(LED2_GPIO15, led2 ^= 1);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void __init apollon_sw_init(void)
|
||||
{
|
||||
/* Enter SW - Y11 */
|
||||
omap_cfg_reg(Y11_242X_GPIO16);
|
||||
omap_request_gpio(SW_ENTER_GPIO16);
|
||||
omap_set_gpio_direction(SW_ENTER_GPIO16, 1);
|
||||
/* Up SW - AA12 */
|
||||
omap_cfg_reg(AA12_242X_GPIO17);
|
||||
omap_request_gpio(SW_UP_GPIO17);
|
||||
omap_set_gpio_direction(SW_UP_GPIO17, 1);
|
||||
/* Down SW - AA8 */
|
||||
omap_cfg_reg(AA8_242X_GPIO58);
|
||||
omap_request_gpio(SW_DOWN_GPIO58);
|
||||
omap_set_gpio_direction(SW_DOWN_GPIO58, 1);
|
||||
|
||||
set_irq_type(OMAP_GPIO_IRQ(SW_ENTER_GPIO16), IRQT_RISING);
|
||||
if (request_irq(OMAP_GPIO_IRQ(SW_ENTER_GPIO16), &apollon_sw_interrupt,
|
||||
SA_SHIRQ, "enter sw",
|
||||
&apollon_sw_interrupt))
|
||||
return;
|
||||
set_irq_type(OMAP_GPIO_IRQ(SW_UP_GPIO17), IRQT_RISING);
|
||||
if (request_irq(OMAP_GPIO_IRQ(SW_UP_GPIO17), &apollon_sw_interrupt,
|
||||
SA_SHIRQ, "up sw",
|
||||
&apollon_sw_interrupt))
|
||||
return;
|
||||
set_irq_type(OMAP_GPIO_IRQ(SW_DOWN_GPIO58), IRQT_RISING);
|
||||
if (request_irq(OMAP_GPIO_IRQ(SW_DOWN_GPIO58), &apollon_sw_interrupt,
|
||||
SA_SHIRQ, "down sw",
|
||||
&apollon_sw_interrupt))
|
||||
return;
|
||||
}
|
||||
|
||||
static void __init omap_apollon_init(void)
|
||||
{
|
||||
apollon_led_init();
|
||||
apollon_sw_init();
|
||||
|
||||
/* REVISIT: where's the correct place */
|
||||
omap_cfg_reg(W19_24XX_SYS_NIRQ);
|
||||
|
||||
/*
|
||||
* Make sure the serial ports are muxed on at this point.
|
||||
* You have to mux them off in device drivers later on
|
||||
* if not needed.
|
||||
*/
|
||||
platform_add_devices(apollon_devices, ARRAY_SIZE(apollon_devices));
|
||||
omap_board_config = apollon_config;
|
||||
omap_board_config_size = ARRAY_SIZE(apollon_config);
|
||||
omap_serial_init();
|
||||
}
|
||||
|
||||
static void __init omap_apollon_map_io(void)
|
||||
{
|
||||
omap2_map_common_io();
|
||||
}
|
||||
|
||||
MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon")
|
||||
/* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
|
||||
.phys_io = 0x48000000,
|
||||
.io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x80000100,
|
||||
.map_io = omap_apollon_map_io,
|
||||
.init_irq = omap_apollon_init_irq,
|
||||
.init_machine = omap_apollon_init,
|
||||
.timer = &omap_timer,
|
||||
MACHINE_END
|
@ -17,6 +17,8 @@
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
@ -25,15 +27,57 @@
|
||||
#include <asm/mach/flash.h>
|
||||
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/arch/gpioexpander.h>
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/usb.h>
|
||||
#include <asm/arch/irda.h>
|
||||
#include <asm/arch/board.h>
|
||||
#include <asm/arch/common.h>
|
||||
#include <asm/arch/prcm.h>
|
||||
#include <asm/arch/keypad.h>
|
||||
#include <asm/arch/menelaus.h>
|
||||
#include <asm/arch/dma.h>
|
||||
#include "prcm-regs.h"
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/delay.h>
|
||||
|
||||
static unsigned int row_gpios[6] = { 88, 89, 124, 11, 6, 96 };
|
||||
static unsigned int col_gpios[7] = { 90, 91, 100, 36, 12, 97, 98 };
|
||||
|
||||
static int h4_keymap[] = {
|
||||
KEY(0, 0, KEY_LEFT),
|
||||
KEY(0, 1, KEY_RIGHT),
|
||||
KEY(0, 2, KEY_A),
|
||||
KEY(0, 3, KEY_B),
|
||||
KEY(0, 4, KEY_C),
|
||||
KEY(1, 0, KEY_DOWN),
|
||||
KEY(1, 1, KEY_UP),
|
||||
KEY(1, 2, KEY_E),
|
||||
KEY(1, 3, KEY_F),
|
||||
KEY(1, 4, KEY_G),
|
||||
KEY(2, 0, KEY_ENTER),
|
||||
KEY(2, 1, KEY_I),
|
||||
KEY(2, 2, KEY_J),
|
||||
KEY(2, 3, KEY_K),
|
||||
KEY(2, 4, KEY_3),
|
||||
KEY(3, 0, KEY_M),
|
||||
KEY(3, 1, KEY_N),
|
||||
KEY(3, 2, KEY_O),
|
||||
KEY(3, 3, KEY_P),
|
||||
KEY(3, 4, KEY_Q),
|
||||
KEY(4, 0, KEY_R),
|
||||
KEY(4, 1, KEY_4),
|
||||
KEY(4, 2, KEY_T),
|
||||
KEY(4, 3, KEY_U),
|
||||
KEY(4, 4, KEY_ENTER),
|
||||
KEY(5, 0, KEY_V),
|
||||
KEY(5, 1, KEY_W),
|
||||
KEY(5, 2, KEY_L),
|
||||
KEY(5, 3, KEY_S),
|
||||
KEY(5, 4, KEY_ENTER),
|
||||
0
|
||||
};
|
||||
|
||||
static struct mtd_partition h4_partitions[] = {
|
||||
/* bootloader (U-Boot, etc) in first sector */
|
||||
{
|
||||
@ -108,9 +152,123 @@ static struct platform_device h4_smc91x_device = {
|
||||
.resource = h4_smc91x_resources,
|
||||
};
|
||||
|
||||
/* Select between the IrDA and aGPS module
|
||||
*/
|
||||
static int h4_select_irda(struct device *dev, int state)
|
||||
{
|
||||
unsigned char expa;
|
||||
int err = 0;
|
||||
|
||||
if ((err = read_gpio_expa(&expa, 0x21))) {
|
||||
printk(KERN_ERR "Error reading from I/O expander\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* 'P6' enable/disable IRDA_TX and IRDA_RX */
|
||||
if (state & IR_SEL) { /* IrDa */
|
||||
if ((err = write_gpio_expa(expa | 0x01, 0x21))) {
|
||||
printk(KERN_ERR "Error writing to I/O expander\n");
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
if ((err = write_gpio_expa(expa & ~0x01, 0x21))) {
|
||||
printk(KERN_ERR "Error writing to I/O expander\n");
|
||||
return err;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static void set_trans_mode(void *data)
|
||||
{
|
||||
int *mode = data;
|
||||
unsigned char expa;
|
||||
int err = 0;
|
||||
|
||||
if ((err = read_gpio_expa(&expa, 0x20)) != 0) {
|
||||
printk(KERN_ERR "Error reading from I/O expander\n");
|
||||
}
|
||||
|
||||
expa &= ~0x01;
|
||||
|
||||
if (!(*mode & IR_SIRMODE)) { /* MIR/FIR */
|
||||
expa |= 0x01;
|
||||
}
|
||||
|
||||
if ((err = write_gpio_expa(expa, 0x20)) != 0) {
|
||||
printk(KERN_ERR "Error writing to I/O expander\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int h4_transceiver_mode(struct device *dev, int mode)
|
||||
{
|
||||
struct omap_irda_config *irda_config = dev->platform_data;
|
||||
|
||||
cancel_delayed_work(&irda_config->gpio_expa);
|
||||
PREPARE_WORK(&irda_config->gpio_expa, set_trans_mode, &mode);
|
||||
schedule_work(&irda_config->gpio_expa);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct omap_irda_config h4_irda_data = {
|
||||
.transceiver_cap = IR_SIRMODE | IR_MIRMODE | IR_FIRMODE,
|
||||
.transceiver_mode = h4_transceiver_mode,
|
||||
.select_irda = h4_select_irda,
|
||||
.rx_channel = OMAP24XX_DMA_UART3_RX,
|
||||
.tx_channel = OMAP24XX_DMA_UART3_TX,
|
||||
.dest_start = OMAP_UART3_BASE,
|
||||
.src_start = OMAP_UART3_BASE,
|
||||
.tx_trigger = OMAP24XX_DMA_UART3_TX,
|
||||
.rx_trigger = OMAP24XX_DMA_UART3_RX,
|
||||
};
|
||||
|
||||
static struct resource h4_irda_resources[] = {
|
||||
[0] = {
|
||||
.start = INT_24XX_UART3_IRQ,
|
||||
.end = INT_24XX_UART3_IRQ,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device h4_irda_device = {
|
||||
.name = "omapirda",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &h4_irda_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = h4_irda_resources,
|
||||
};
|
||||
|
||||
static struct omap_kp_platform_data h4_kp_data = {
|
||||
.rows = 6,
|
||||
.cols = 7,
|
||||
.keymap = h4_keymap,
|
||||
.rep = 1,
|
||||
.row_gpios = row_gpios,
|
||||
.col_gpios = col_gpios,
|
||||
};
|
||||
|
||||
static struct platform_device h4_kp_device = {
|
||||
.name = "omap-keypad",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &h4_kp_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device h4_lcd_device = {
|
||||
.name = "lcd_h4",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static struct platform_device *h4_devices[] __initdata = {
|
||||
&h4_smc91x_device,
|
||||
&h4_flash_device,
|
||||
&h4_irda_device,
|
||||
&h4_kp_device,
|
||||
&h4_lcd_device,
|
||||
};
|
||||
|
||||
static inline void __init h4_init_smc91x(void)
|
||||
@ -157,7 +315,6 @@ static struct omap_mmc_config h4_mmc_config __initdata = {
|
||||
};
|
||||
|
||||
static struct omap_lcd_config h4_lcd_config __initdata = {
|
||||
.panel_name = "h4",
|
||||
.ctrl_name = "internal",
|
||||
};
|
||||
|
||||
@ -174,6 +331,19 @@ static void __init omap_h4_init(void)
|
||||
* You have to mux them off in device drivers later on
|
||||
* if not needed.
|
||||
*/
|
||||
#if defined(CONFIG_OMAP_IR) || defined(CONFIG_OMAP_IR_MODULE)
|
||||
omap_cfg_reg(K15_24XX_UART3_TX);
|
||||
omap_cfg_reg(K14_24XX_UART3_RX);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_KEYBOARD_OMAP) || defined(CONFIG_KEYBOARD_OMAP_MODULE)
|
||||
if (omap_has_menelaus()) {
|
||||
row_gpios[5] = 0;
|
||||
col_gpios[2] = 15;
|
||||
col_gpios[6] = 18;
|
||||
}
|
||||
#endif
|
||||
|
||||
platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices));
|
||||
omap_board_config = h4_config;
|
||||
omap_board_config_size = ARRAY_SIZE(h4_config);
|
||||
|
@ -28,14 +28,14 @@
|
||||
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/sram.h>
|
||||
#include <asm/arch/prcm.h>
|
||||
|
||||
#include "prcm-regs.h"
|
||||
#include "memory.h"
|
||||
#include "clock.h"
|
||||
|
||||
//#define DOWN_VARIABLE_DPLL 1 /* Experimental */
|
||||
|
||||
static struct prcm_config *curr_prcm_set;
|
||||
static struct memory_timings mem_timings;
|
||||
static u32 curr_perf_level = PRCM_FULL_SPEED;
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -54,11 +54,13 @@ static void omap2_sys_clk_recalc(struct clk * clk)
|
||||
|
||||
static u32 omap2_get_dpll_rate(struct clk * tclk)
|
||||
{
|
||||
int dpll_clk, dpll_mult, dpll_div, amult;
|
||||
long long dpll_clk;
|
||||
int dpll_mult, dpll_div, amult;
|
||||
|
||||
dpll_mult = (CM_CLKSEL1_PLL >> 12) & 0x03ff; /* 10 bits */
|
||||
dpll_div = (CM_CLKSEL1_PLL >> 8) & 0x0f; /* 4 bits */
|
||||
dpll_clk = (tclk->parent->rate * dpll_mult) / (dpll_div + 1);
|
||||
dpll_clk = (long long)tclk->parent->rate * dpll_mult;
|
||||
do_div(dpll_clk, dpll_div + 1);
|
||||
amult = CM_CLKSEL2_PLL & 0x3;
|
||||
dpll_clk *= amult;
|
||||
|
||||
@ -385,75 +387,23 @@ static u32 omap2_dll_force_needed(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void omap2_init_memory_params(u32 force_lock_to_unlock_mode)
|
||||
{
|
||||
unsigned long dll_cnt;
|
||||
u32 fast_dll = 0;
|
||||
|
||||
mem_timings.m_type = !((SDRC_MR_0 & 0x3) == 0x1); /* DDR = 1, SDR = 0 */
|
||||
|
||||
/* 2422 es2.05 and beyond has a single SIP DDR instead of 2 like others.
|
||||
* In the case of 2422, its ok to use CS1 instead of CS0.
|
||||
*/
|
||||
|
||||
#if 0 /* FIXME: Enable after 24xx cpu detection works */
|
||||
ctype = get_cpu_type();
|
||||
if (cpu_is_omap2422())
|
||||
mem_timings.base_cs = 1;
|
||||
else
|
||||
#endif
|
||||
mem_timings.base_cs = 0;
|
||||
|
||||
if (mem_timings.m_type != M_DDR)
|
||||
return;
|
||||
|
||||
/* With DDR we need to determine the low frequency DLL value */
|
||||
if (((mem_timings.fast_dll_ctrl & (1 << 2)) == M_LOCK_CTRL))
|
||||
mem_timings.dll_mode = M_UNLOCK;
|
||||
else
|
||||
mem_timings.dll_mode = M_LOCK;
|
||||
|
||||
if (mem_timings.base_cs == 0) {
|
||||
fast_dll = SDRC_DLLA_CTRL;
|
||||
dll_cnt = SDRC_DLLA_STATUS & 0xff00;
|
||||
} else {
|
||||
fast_dll = SDRC_DLLB_CTRL;
|
||||
dll_cnt = SDRC_DLLB_STATUS & 0xff00;
|
||||
}
|
||||
if (force_lock_to_unlock_mode) {
|
||||
fast_dll &= ~0xff00;
|
||||
fast_dll |= dll_cnt; /* Current lock mode */
|
||||
}
|
||||
mem_timings.fast_dll_ctrl = fast_dll;
|
||||
|
||||
/* No disruptions, DDR will be offline & C-ABI not followed */
|
||||
omap2_sram_ddr_init(&mem_timings.slow_dll_ctrl,
|
||||
mem_timings.fast_dll_ctrl,
|
||||
mem_timings.base_cs,
|
||||
force_lock_to_unlock_mode);
|
||||
mem_timings.slow_dll_ctrl &= 0xff00; /* Keep lock value */
|
||||
|
||||
/* Turn status into unlock ctrl */
|
||||
mem_timings.slow_dll_ctrl |=
|
||||
((mem_timings.fast_dll_ctrl & 0xF) | (1 << 2));
|
||||
|
||||
/* 90 degree phase for anything below 133Mhz */
|
||||
mem_timings.slow_dll_ctrl |= (1 << 1);
|
||||
}
|
||||
|
||||
static u32 omap2_reprogram_sdrc(u32 level, u32 force)
|
||||
{
|
||||
u32 slow_dll_ctrl, fast_dll_ctrl, m_type;
|
||||
u32 prev = curr_perf_level, flags;
|
||||
|
||||
if ((curr_perf_level == level) && !force)
|
||||
return prev;
|
||||
|
||||
m_type = omap2_memory_get_type();
|
||||
slow_dll_ctrl = omap2_memory_get_slow_dll_ctrl();
|
||||
fast_dll_ctrl = omap2_memory_get_fast_dll_ctrl();
|
||||
|
||||
if (level == PRCM_HALF_SPEED) {
|
||||
local_irq_save(flags);
|
||||
PRCM_VOLTSETUP = 0xffff;
|
||||
omap2_sram_reprogram_sdrc(PRCM_HALF_SPEED,
|
||||
mem_timings.slow_dll_ctrl,
|
||||
mem_timings.m_type);
|
||||
slow_dll_ctrl, m_type);
|
||||
curr_perf_level = PRCM_HALF_SPEED;
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
@ -461,8 +411,7 @@ static u32 omap2_reprogram_sdrc(u32 level, u32 force)
|
||||
local_irq_save(flags);
|
||||
PRCM_VOLTSETUP = 0xffff;
|
||||
omap2_sram_reprogram_sdrc(PRCM_FULL_SPEED,
|
||||
mem_timings.fast_dll_ctrl,
|
||||
mem_timings.m_type);
|
||||
fast_dll_ctrl, m_type);
|
||||
curr_perf_level = PRCM_FULL_SPEED;
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
@ -650,7 +599,7 @@ static u32 omap2_get_clksel(u32 *div_sel, u32 *field_mask,
|
||||
case 13: /* dss2 */
|
||||
mask = 0x1; break;
|
||||
case 25: /* usb */
|
||||
mask = 0xf; break;
|
||||
mask = 0x7; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,20 +33,6 @@ static u32 omap2_clksel_get_divisor(struct clk *clk);
|
||||
#define RATE_IN_242X (1 << 0)
|
||||
#define RATE_IN_243X (1 << 1)
|
||||
|
||||
/* Memory timings */
|
||||
#define M_DDR 1
|
||||
#define M_LOCK_CTRL (1 << 2)
|
||||
#define M_UNLOCK 0
|
||||
#define M_LOCK 1
|
||||
|
||||
struct memory_timings {
|
||||
u32 m_type; /* ddr = 1, sdr = 0 */
|
||||
u32 dll_mode; /* use lock mode = 1, unlock mode = 0 */
|
||||
u32 slow_dll_ctrl; /* unlock mode, dll value for slow speed */
|
||||
u32 fast_dll_ctrl; /* unlock mode, dll value for fast speed */
|
||||
u32 base_cs; /* base chip select to use for calculations */
|
||||
};
|
||||
|
||||
/* Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated.
|
||||
* xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,CM_CLKSEL_DSP
|
||||
* CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL CM_CLKSEL2_PLL, CM_CLKSEL_MDM
|
||||
@ -731,6 +717,16 @@ static struct clk sys_clkout2 = {
|
||||
.recalc = &omap2_clksel_recalc,
|
||||
};
|
||||
|
||||
static struct clk emul_ck = {
|
||||
.name = "emul_ck",
|
||||
.parent = &func_54m_ck,
|
||||
.flags = CLOCK_IN_OMAP242X,
|
||||
.enable_reg = (void __iomem *)&PRCM_CLKEMUL_CTRL,
|
||||
.enable_bit = 0,
|
||||
.recalc = &omap2_propagate_rate,
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* MPU clock domain
|
||||
* Clocks:
|
||||
@ -1702,7 +1698,8 @@ static struct clk hdq_fck = {
|
||||
};
|
||||
|
||||
static struct clk i2c2_ick = {
|
||||
.name = "i2c2_ick",
|
||||
.name = "i2c_ick",
|
||||
.id = 2,
|
||||
.parent = &l4_ck,
|
||||
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
|
||||
.enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
|
||||
@ -1711,7 +1708,8 @@ static struct clk i2c2_ick = {
|
||||
};
|
||||
|
||||
static struct clk i2c2_fck = {
|
||||
.name = "i2c2_fck",
|
||||
.name = "i2c_fck",
|
||||
.id = 2,
|
||||
.parent = &func_12m_ck,
|
||||
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
|
||||
.enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
|
||||
@ -1729,7 +1727,8 @@ static struct clk i2chs2_fck = {
|
||||
};
|
||||
|
||||
static struct clk i2c1_ick = {
|
||||
.name = "i2c1_ick",
|
||||
.name = "i2c_ick",
|
||||
.id = 1,
|
||||
.parent = &l4_ck,
|
||||
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
|
||||
.enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
|
||||
@ -1738,7 +1737,8 @@ static struct clk i2c1_ick = {
|
||||
};
|
||||
|
||||
static struct clk i2c1_fck = {
|
||||
.name = "i2c1_fck",
|
||||
.name = "i2c_fck",
|
||||
.id = 1,
|
||||
.parent = &func_12m_ck,
|
||||
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
|
||||
.enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
|
||||
@ -1971,6 +1971,7 @@ static struct clk *onchip_clks[] = {
|
||||
&wdt1_osc_ck,
|
||||
&sys_clkout,
|
||||
&sys_clkout2,
|
||||
&emul_ck,
|
||||
/* mpu domain clocks */
|
||||
&mpu_ck,
|
||||
/* dsp domain clocks */
|
||||
|
@ -74,6 +74,47 @@ static void omap_init_i2c(void) {}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_OMAP_STI)
|
||||
|
||||
#define OMAP2_STI_BASE IO_ADDRESS(0x48068000)
|
||||
#define OMAP2_STI_CHANNEL_BASE 0x54000000
|
||||
#define OMAP2_STI_IRQ 4
|
||||
|
||||
static struct resource sti_resources[] = {
|
||||
{
|
||||
.start = OMAP2_STI_BASE,
|
||||
.end = OMAP2_STI_BASE + 0x7ff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = OMAP2_STI_CHANNEL_BASE,
|
||||
.end = OMAP2_STI_CHANNEL_BASE + SZ_64K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = OMAP2_STI_IRQ,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device sti_device = {
|
||||
.name = "sti",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.release = omap_nop_release,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(sti_resources),
|
||||
.resource = sti_resources,
|
||||
};
|
||||
|
||||
static inline void omap_init_sti(void)
|
||||
{
|
||||
platform_device_register(&sti_device);
|
||||
}
|
||||
#else
|
||||
static inline void omap_init_sti(void) {}
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static int __init omap2_init_devices(void)
|
||||
@ -82,6 +123,7 @@ static int __init omap2_init_devices(void)
|
||||
* in alphabetical order so they're easier to sort through.
|
||||
*/
|
||||
omap_init_i2c();
|
||||
omap_init_sti();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -16,9 +16,13 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/tlb.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include <asm/mach/map.h>
|
||||
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/omapfb.h>
|
||||
|
||||
extern void omap_sram_init(void);
|
||||
extern int omap2_clk_init(void);
|
||||
@ -43,11 +47,24 @@ static struct map_desc omap2_io_desc[] __initdata = {
|
||||
}
|
||||
};
|
||||
|
||||
void __init omap_map_common_io(void)
|
||||
void __init omap2_map_common_io(void)
|
||||
{
|
||||
iotable_init(omap2_io_desc, ARRAY_SIZE(omap2_io_desc));
|
||||
|
||||
/* Normally devicemaps_init() would flush caches and tlb after
|
||||
* mdesc->map_io(), but we must also do it here because of the CPU
|
||||
* revision check below.
|
||||
*/
|
||||
local_flush_tlb_all();
|
||||
flush_cache_all();
|
||||
|
||||
omap2_check_revision();
|
||||
omap_sram_init();
|
||||
omapfb_reserve_mem();
|
||||
}
|
||||
|
||||
void __init omap2_init_common_hw(void)
|
||||
{
|
||||
omap2_mux_init();
|
||||
omap2_clk_init();
|
||||
}
|
||||
|
102
arch/arm/mach-omap2/memory.c
Normal file
102
arch/arm/mach-omap2/memory.c
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap2/memory.c
|
||||
*
|
||||
* Memory timing related functions for OMAP24XX
|
||||
*
|
||||
* Copyright (C) 2005 Texas Instruments Inc.
|
||||
* Richard Woodruff <r-woodruff2@ti.com>
|
||||
*
|
||||
* Copyright (C) 2005 Nokia Corporation
|
||||
* Tony Lindgren <tony@atomide.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/sram.h>
|
||||
|
||||
#include "prcm-regs.h"
|
||||
#include "memory.h"
|
||||
|
||||
static struct memory_timings mem_timings;
|
||||
|
||||
u32 omap2_memory_get_slow_dll_ctrl(void)
|
||||
{
|
||||
return mem_timings.slow_dll_ctrl;
|
||||
}
|
||||
|
||||
u32 omap2_memory_get_fast_dll_ctrl(void)
|
||||
{
|
||||
return mem_timings.fast_dll_ctrl;
|
||||
}
|
||||
|
||||
u32 omap2_memory_get_type(void)
|
||||
{
|
||||
return mem_timings.m_type;
|
||||
}
|
||||
|
||||
void omap2_init_memory_params(u32 force_lock_to_unlock_mode)
|
||||
{
|
||||
unsigned long dll_cnt;
|
||||
u32 fast_dll = 0;
|
||||
|
||||
mem_timings.m_type = !((SDRC_MR_0 & 0x3) == 0x1); /* DDR = 1, SDR = 0 */
|
||||
|
||||
/* 2422 es2.05 and beyond has a single SIP DDR instead of 2 like others.
|
||||
* In the case of 2422, its ok to use CS1 instead of CS0.
|
||||
*/
|
||||
if (cpu_is_omap2422())
|
||||
mem_timings.base_cs = 1;
|
||||
else
|
||||
mem_timings.base_cs = 0;
|
||||
|
||||
if (mem_timings.m_type != M_DDR)
|
||||
return;
|
||||
|
||||
/* With DDR we need to determine the low frequency DLL value */
|
||||
if (((mem_timings.fast_dll_ctrl & (1 << 2)) == M_LOCK_CTRL))
|
||||
mem_timings.dll_mode = M_UNLOCK;
|
||||
else
|
||||
mem_timings.dll_mode = M_LOCK;
|
||||
|
||||
if (mem_timings.base_cs == 0) {
|
||||
fast_dll = SDRC_DLLA_CTRL;
|
||||
dll_cnt = SDRC_DLLA_STATUS & 0xff00;
|
||||
} else {
|
||||
fast_dll = SDRC_DLLB_CTRL;
|
||||
dll_cnt = SDRC_DLLB_STATUS & 0xff00;
|
||||
}
|
||||
if (force_lock_to_unlock_mode) {
|
||||
fast_dll &= ~0xff00;
|
||||
fast_dll |= dll_cnt; /* Current lock mode */
|
||||
}
|
||||
/* set fast timings with DLL filter disabled */
|
||||
mem_timings.fast_dll_ctrl = (fast_dll | (3 << 8));
|
||||
|
||||
/* No disruptions, DDR will be offline & C-ABI not followed */
|
||||
omap2_sram_ddr_init(&mem_timings.slow_dll_ctrl,
|
||||
mem_timings.fast_dll_ctrl,
|
||||
mem_timings.base_cs,
|
||||
force_lock_to_unlock_mode);
|
||||
mem_timings.slow_dll_ctrl &= 0xff00; /* Keep lock value */
|
||||
|
||||
/* Turn status into unlock ctrl */
|
||||
mem_timings.slow_dll_ctrl |=
|
||||
((mem_timings.fast_dll_ctrl & 0xF) | (1 << 2));
|
||||
|
||||
/* 90 degree phase for anything below 133Mhz + disable DLL filter */
|
||||
mem_timings.slow_dll_ctrl |= ((1 << 1) | (3 << 8));
|
||||
}
|
34
arch/arm/mach-omap2/memory.h
Normal file
34
arch/arm/mach-omap2/memory.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap2/memory.h
|
||||
*
|
||||
* Interface for memory timing related functions for OMAP24XX
|
||||
*
|
||||
* Copyright (C) 2005 Texas Instruments Inc.
|
||||
* Richard Woodruff <r-woodruff2@ti.com>
|
||||
*
|
||||
* Copyright (C) 2005 Nokia Corporation
|
||||
* Tony Lindgren <tony@atomide.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
/* Memory timings */
|
||||
#define M_DDR 1
|
||||
#define M_LOCK_CTRL (1 << 2)
|
||||
#define M_UNLOCK 0
|
||||
#define M_LOCK 1
|
||||
|
||||
struct memory_timings {
|
||||
u32 m_type; /* ddr = 1, sdr = 0 */
|
||||
u32 dll_mode; /* use lock mode = 1, unlock mode = 0 */
|
||||
u32 slow_dll_ctrl; /* unlock mode, dll value for slow speed */
|
||||
u32 fast_dll_ctrl; /* unlock mode, dll value for fast speed */
|
||||
u32 base_cs; /* base chip select to use for calculations */
|
||||
};
|
||||
|
||||
extern void omap2_init_memory_params(u32 force_lock_to_unlock_mode);
|
||||
extern u32 omap2_memory_get_slow_dll_ctrl(void);
|
||||
extern u32 omap2_memory_get_fast_dll_ctrl(void);
|
||||
extern u32 omap2_memory_get_type(void);
|
@ -50,9 +50,54 @@ MUX_CFG_24XX("H19_24XX_I2C2_SDA", 0x114, 0, 0, 0, 1)
|
||||
/* Menelaus interrupt */
|
||||
MUX_CFG_24XX("W19_24XX_SYS_NIRQ", 0x12c, 0, 1, 1, 1)
|
||||
|
||||
/* 24xx clocks */
|
||||
MUX_CFG_24XX("W14_24XX_SYS_CLKOUT", 0x137, 0, 1, 1, 1)
|
||||
|
||||
/* 24xx McBSP */
|
||||
MUX_CFG_24XX("Y15_24XX_MCBSP2_CLKX", 0x124, 1, 1, 0, 1)
|
||||
MUX_CFG_24XX("R14_24XX_MCBSP2_FSX", 0x125, 1, 1, 0, 1)
|
||||
MUX_CFG_24XX("W15_24XX_MCBSP2_DR", 0x126, 1, 1, 0, 1)
|
||||
MUX_CFG_24XX("V15_24XX_MCBSP2_DX", 0x127, 1, 1, 0, 1)
|
||||
|
||||
/* 24xx GPIO */
|
||||
MUX_CFG_24XX("M21_242X_GPIO11", 0x0c9, 3, 1, 1, 1)
|
||||
MUX_CFG_24XX("AA10_242X_GPIO13", 0x0e5, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("AA6_242X_GPIO14", 0x0e6, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("AA4_242X_GPIO15", 0x0e7, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("Y11_242X_GPIO16", 0x0e8, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("AA12_242X_GPIO17", 0x0e9, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("AA8_242X_GPIO58", 0x0ea, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("Y20_24XX_GPIO60", 0x12c, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("W4__24XX_GPIO74", 0x0f2, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("M15_24XX_GPIO92", 0x10a, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("V14_24XX_GPIO117", 0x128, 3, 1, 0, 1)
|
||||
|
||||
/* TSC IRQ */
|
||||
MUX_CFG_24XX("P20_24XX_TSC_IRQ", 0x108, 0, 0, 0, 1)
|
||||
|
||||
/* UART3 */
|
||||
MUX_CFG_24XX("K15_24XX_UART3_TX", 0x118, 0, 0, 0, 1)
|
||||
MUX_CFG_24XX("K14_24XX_UART3_RX", 0x119, 0, 0, 0, 1)
|
||||
|
||||
/* Keypad GPIO*/
|
||||
MUX_CFG_24XX("T19_24XX_KBR0", 0x106, 3, 1, 1, 1)
|
||||
MUX_CFG_24XX("R19_24XX_KBR1", 0x107, 3, 1, 1, 1)
|
||||
MUX_CFG_24XX("V18_24XX_KBR2", 0x139, 3, 1, 1, 1)
|
||||
MUX_CFG_24XX("M21_24XX_KBR3", 0xc9, 3, 1, 1, 1)
|
||||
MUX_CFG_24XX("E5__24XX_KBR4", 0x138, 3, 1, 1, 1)
|
||||
MUX_CFG_24XX("M18_24XX_KBR5", 0x10e, 3, 1, 1, 1)
|
||||
MUX_CFG_24XX("R20_24XX_KBC0", 0x108, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("M14_24XX_KBC1", 0x109, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("H19_24XX_KBC2", 0x114, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("V17_24XX_KBC3", 0x135, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("P21_24XX_KBC4", 0xca, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("L14_24XX_KBC5", 0x10f, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("N19_24XX_KBC6", 0x110, 3, 0, 0, 1)
|
||||
|
||||
/* 24xx Menelaus Keypad GPIO */
|
||||
MUX_CFG_24XX("B3__24XX_KBR5", 0x30, 3, 1, 1, 1)
|
||||
MUX_CFG_24XX("AA4_24XX_KBC2", 0xe7, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("B13_24XX_KBC6", 0x110, 3, 0, 0, 1)
|
||||
|
||||
};
|
||||
|
||||
|
149
arch/arm/mach-omap2/pm.c
Normal file
149
arch/arm/mach-omap2/pm.c
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap2/pm.c
|
||||
*
|
||||
* OMAP2 Power Management Routines
|
||||
*
|
||||
* Copyright (C) 2006 Nokia Corporation
|
||||
* Tony Lindgren <tony@atomide.com>
|
||||
*
|
||||
* Copyright (C) 2005 Texas Instruments, Inc.
|
||||
* Richard Woodruff <r-woodruff2@ti.com>
|
||||
*
|
||||
* Based on pm.c for omap1
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/pm.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/mach/time.h>
|
||||
#include <asm/mach/irq.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include <asm/arch/irqs.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/sram.h>
|
||||
#include <asm/arch/pm.h>
|
||||
|
||||
static struct clk *vclk;
|
||||
static void (*omap2_sram_idle)(void);
|
||||
static void (*omap2_sram_suspend)(int dllctrl, int cpu_rev);
|
||||
static void (*saved_idle)(void);
|
||||
|
||||
void omap2_pm_idle(void)
|
||||
{
|
||||
local_irq_disable();
|
||||
local_fiq_disable();
|
||||
if (need_resched()) {
|
||||
local_fiq_enable();
|
||||
local_irq_enable();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Since an interrupt may set up a timer, we don't want to
|
||||
* reprogram the hardware timer with interrupts enabled.
|
||||
* Re-enable interrupts only after returning from idle.
|
||||
*/
|
||||
timer_dyn_reprogram();
|
||||
|
||||
omap2_sram_idle();
|
||||
local_fiq_enable();
|
||||
local_irq_enable();
|
||||
}
|
||||
|
||||
static int omap2_pm_prepare(suspend_state_t state)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
/* We cannot sleep in idle until we have resumed */
|
||||
saved_idle = pm_idle;
|
||||
pm_idle = NULL;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case PM_SUSPEND_STANDBY:
|
||||
case PM_SUSPEND_MEM:
|
||||
break;
|
||||
|
||||
case PM_SUSPEND_DISK:
|
||||
return -ENOTSUPP;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int omap2_pm_enter(suspend_state_t state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case PM_SUSPEND_STANDBY:
|
||||
case PM_SUSPEND_MEM:
|
||||
/* FIXME: Add suspend */
|
||||
break;
|
||||
|
||||
case PM_SUSPEND_DISK:
|
||||
return -ENOTSUPP;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap2_pm_finish(suspend_state_t state)
|
||||
{
|
||||
pm_idle = saved_idle;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct pm_ops omap_pm_ops = {
|
||||
.pm_disk_mode = 0,
|
||||
.prepare = omap2_pm_prepare,
|
||||
.enter = omap2_pm_enter,
|
||||
.finish = omap2_pm_finish,
|
||||
};
|
||||
|
||||
int __init omap2_pm_init(void)
|
||||
{
|
||||
printk("Power Management for TI OMAP.\n");
|
||||
|
||||
vclk = clk_get(NULL, "virt_prcm_set");
|
||||
if (IS_ERR(vclk)) {
|
||||
printk(KERN_ERR "Could not get PM vclk\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/*
|
||||
* We copy the assembler sleep/wakeup routines to SRAM.
|
||||
* These routines need to be in SRAM as that's the only
|
||||
* memory the MPU can see when it wakes up.
|
||||
*/
|
||||
omap2_sram_idle = omap_sram_push(omap24xx_idle_loop_suspend,
|
||||
omap24xx_idle_loop_suspend_sz);
|
||||
|
||||
omap2_sram_suspend = omap_sram_push(omap24xx_cpu_suspend,
|
||||
omap24xx_cpu_suspend_sz);
|
||||
|
||||
pm_set_ops(&omap_pm_ops);
|
||||
pm_idle = omap2_pm_idle;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__initcall(omap2_pm_init);
|
@ -1,5 +1,7 @@
|
||||
/*
|
||||
* prcm.h - Access definations for use in OMAP24XX clock and power management
|
||||
* linux/arch/arm/mach-omap2/prcm-reg.h
|
||||
*
|
||||
* OMAP24XX Power Reset and Clock Management (PRCM) registers
|
||||
*
|
||||
* Copyright (C) 2005 Texas Instruments, Inc.
|
||||
*
|
||||
@ -18,8 +20,8 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __ASM_ARM_ARCH_DPM_PRCM_H
|
||||
#define __ASM_ARM_ARCH_DPM_PRCM_H
|
||||
#ifndef __ARCH_ARM_MACH_OMAP2_PRCM_H
|
||||
#define __ARCH_ARM_MACH_OMAP2_PRCM_H
|
||||
|
||||
/* SET_PERFORMANCE_LEVEL PARAMETERS */
|
||||
#define PRCM_HALF_SPEED 1
|
||||
@ -159,54 +161,63 @@
|
||||
#define CM_FCLKEN_MDM PRCM_REG32(0xC00)
|
||||
#define CM_ICLKEN_MDM PRCM_REG32(0xC10)
|
||||
#define CM_IDLEST_MDM PRCM_REG32(0xC20)
|
||||
#define CM_AUTOIDLE_MDM PRCM_REG32(0xC30)
|
||||
#define CM_CLKSEL_MDM PRCM_REG32(0xC40)
|
||||
#define CM_CLKSTCTRL_MDM PRCM_REG32(0xC48)
|
||||
#define RM_RSTCTRL_MDM PRCM_REG32(0xC50)
|
||||
#define RM_RSTST_MDM PRCM_REG32(0xC58)
|
||||
#define PM_WKEN_MDM PRCM_REG32(0xCA0)
|
||||
#define PM_WKST_MDM PRCM_REG32(0xCB0)
|
||||
#define PM_WKDEP_MDM PRCM_REG32(0xCC8)
|
||||
#define PM_PWSTCTRL_MDM PRCM_REG32(0xCE0)
|
||||
#define PM_PWSTST_MDM PRCM_REG32(0xCE4)
|
||||
|
||||
/* FIXME: Move to header for 2430 */
|
||||
#define DISP_BASE (OMAP24XX_L4_IO_BASE+0x50000)
|
||||
#define OMAP24XX_L4_IO_BASE 0x48000000
|
||||
|
||||
#define DISP_BASE (OMAP24XX_L4_IO_BASE + 0x50000)
|
||||
#define DISP_REG32(offset) __REG32(DISP_BASE + (offset))
|
||||
|
||||
#define GPMC_BASE (OMAP24XX_GPMC_BASE)
|
||||
#define GPMC_REG32(offset) __REG32(GPMC_BASE + (offset))
|
||||
#define OMAP24XX_GPMC_BASE (L3_24XX_BASE + 0xa000)
|
||||
#define GPMC_REG32(offset) __REG32(OMAP24XX_GPMC_BASE + (offset))
|
||||
|
||||
#define GPT1_BASE (OMAP24XX_GPT1)
|
||||
/* FIXME: Move these to timer code */
|
||||
#define GPT1_BASE (0x48028000)
|
||||
#define GPT1_REG32(offset) __REG32(GPT1_BASE + (offset))
|
||||
|
||||
/* Misc sysconfig */
|
||||
#define DISPC_SYSCONFIG DISP_REG32(0x410)
|
||||
#define SPI_BASE (OMAP24XX_L4_IO_BASE+0x98000)
|
||||
#define SPI_BASE (OMAP24XX_L4_IO_BASE + 0x98000)
|
||||
#define MCSPI1_SYSCONFIG __REG32(SPI_BASE + 0x10)
|
||||
#define MCSPI2_SYSCONFIG __REG32(SPI_BASE+0x2000 + 0x10)
|
||||
#define MCSPI2_SYSCONFIG __REG32(SPI_BASE + 0x2000 + 0x10)
|
||||
#define MCSPI3_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE + 0xb8010)
|
||||
|
||||
//#define DSP_MMU_SYSCONFIG 0x5A000010
|
||||
#define CAMERA_MMU_SYSCONFIG __REG32(DISP_BASE+0x2C10)
|
||||
//#define IVA_MMU_SYSCONFIG 0x5D000010
|
||||
//#define DSP_DMA_SYSCONFIG 0x00FCC02C
|
||||
#define CAMERA_DMA_SYSCONFIG __REG32(DISP_BASE+0x282C)
|
||||
#define SYSTEM_DMA_SYSCONFIG __REG32(DISP_BASE+0x602C)
|
||||
#define CAMERA_MMU_SYSCONFIG __REG32(DISP_BASE + 0x2C10)
|
||||
#define CAMERA_DMA_SYSCONFIG __REG32(DISP_BASE + 0x282C)
|
||||
#define SYSTEM_DMA_SYSCONFIG __REG32(DISP_BASE + 0x602C)
|
||||
#define GPMC_SYSCONFIG GPMC_REG32(0x010)
|
||||
#define MAILBOXES_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x94010)
|
||||
#define UART1_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6A054)
|
||||
#define UART2_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6C054)
|
||||
#define UART3_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6E054)
|
||||
//#define IVA_SYSCONFIG 0x5C060010
|
||||
#define SDRC_SYSCONFIG __REG32(OMAP24XX_SDRC_BASE+0x10)
|
||||
#define SMS_SYSCONFIG __REG32(OMAP24XX_SMS_BASE+0x10)
|
||||
#define SSI_SYSCONFIG __REG32(DISP_BASE+0x8010)
|
||||
//#define VLYNQ_SYSCONFIG 0x67FFFE10
|
||||
#define MAILBOXES_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE + 0x94010)
|
||||
#define UART1_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE + 0x6A054)
|
||||
#define UART2_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE + 0x6C054)
|
||||
#define UART3_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE + 0x6E054)
|
||||
#define SDRC_SYSCONFIG __REG32(OMAP24XX_SDRC_BASE + 0x10)
|
||||
#define OMAP24XX_SMS_BASE (L3_24XX_BASE + 0x8000)
|
||||
#define SMS_SYSCONFIG __REG32(OMAP24XX_SMS_BASE + 0x10)
|
||||
#define SSI_SYSCONFIG __REG32(DISP_BASE + 0x8010)
|
||||
|
||||
/* rkw - good cannidates for PM_ to start what nm was trying */
|
||||
#define OMAP24XX_GPT2 (OMAP24XX_L4_IO_BASE+0x2A000)
|
||||
#define OMAP24XX_GPT3 (OMAP24XX_L4_IO_BASE+0x78000)
|
||||
#define OMAP24XX_GPT4 (OMAP24XX_L4_IO_BASE+0x7A000)
|
||||
#define OMAP24XX_GPT5 (OMAP24XX_L4_IO_BASE+0x7C000)
|
||||
#define OMAP24XX_GPT6 (OMAP24XX_L4_IO_BASE+0x7E000)
|
||||
#define OMAP24XX_GPT7 (OMAP24XX_L4_IO_BASE+0x80000)
|
||||
#define OMAP24XX_GPT8 (OMAP24XX_L4_IO_BASE+0x82000)
|
||||
#define OMAP24XX_GPT9 (OMAP24XX_L4_IO_BASE+0x84000)
|
||||
#define OMAP24XX_GPT10 (OMAP24XX_L4_IO_BASE+0x86000)
|
||||
#define OMAP24XX_GPT11 (OMAP24XX_L4_IO_BASE+0x88000)
|
||||
#define OMAP24XX_GPT12 (OMAP24XX_L4_IO_BASE+0x8A000)
|
||||
#define OMAP24XX_GPT2 (OMAP24XX_L4_IO_BASE + 0x2A000)
|
||||
#define OMAP24XX_GPT3 (OMAP24XX_L4_IO_BASE + 0x78000)
|
||||
#define OMAP24XX_GPT4 (OMAP24XX_L4_IO_BASE + 0x7A000)
|
||||
#define OMAP24XX_GPT5 (OMAP24XX_L4_IO_BASE + 0x7C000)
|
||||
#define OMAP24XX_GPT6 (OMAP24XX_L4_IO_BASE + 0x7E000)
|
||||
#define OMAP24XX_GPT7 (OMAP24XX_L4_IO_BASE + 0x80000)
|
||||
#define OMAP24XX_GPT8 (OMAP24XX_L4_IO_BASE + 0x82000)
|
||||
#define OMAP24XX_GPT9 (OMAP24XX_L4_IO_BASE + 0x84000)
|
||||
#define OMAP24XX_GPT10 (OMAP24XX_L4_IO_BASE + 0x86000)
|
||||
#define OMAP24XX_GPT11 (OMAP24XX_L4_IO_BASE + 0x88000)
|
||||
#define OMAP24XX_GPT12 (OMAP24XX_L4_IO_BASE + 0x8A000)
|
||||
|
||||
/* FIXME: Move these to timer code */
|
||||
#define GPTIMER1_SYSCONFIG GPT1_REG32(0x010)
|
||||
#define GPTIMER2_SYSCONFIG __REG32(OMAP24XX_GPT2 + 0x10)
|
||||
#define GPTIMER3_SYSCONFIG __REG32(OMAP24XX_GPT3 + 0x10)
|
||||
@ -220,12 +231,18 @@
|
||||
#define GPTIMER11_SYSCONFIG __REG32(OMAP24XX_GPT11 + 0x10)
|
||||
#define GPTIMER12_SYSCONFIG __REG32(OMAP24XX_GPT12 + 0x10)
|
||||
|
||||
#define GPIOX_BASE(X) (OMAP24XX_GPIO_BASE+(0x2000*((X)-1)))
|
||||
/* FIXME: Move these to gpio code */
|
||||
#define OMAP24XX_GPIO_BASE 0x48018000
|
||||
#define GPIOX_BASE(X) (OMAP24XX_GPIO_BASE + (0x2000 * ((X) - 1)))
|
||||
|
||||
#define GPIO1_SYSCONFIG __REG32((GPIOX_BASE(1)+0x10))
|
||||
#define GPIO2_SYSCONFIG __REG32((GPIOX_BASE(2)+0x10))
|
||||
#define GPIO3_SYSCONFIG __REG32((GPIOX_BASE(3)+0x10))
|
||||
#define GPIO4_SYSCONFIG __REG32((GPIOX_BASE(4)+0x10))
|
||||
#define GPIO1_SYSCONFIG __REG32((GPIOX_BASE(1) + 0x10))
|
||||
#define GPIO2_SYSCONFIG __REG32((GPIOX_BASE(2) + 0x10))
|
||||
#define GPIO3_SYSCONFIG __REG32((GPIOX_BASE(3) + 0x10))
|
||||
#define GPIO4_SYSCONFIG __REG32((GPIOX_BASE(4) + 0x10))
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP243X)
|
||||
#define GPIO5_SYSCONFIG __REG32((OMAP24XX_GPIO5_BASE + 0x10))
|
||||
#endif
|
||||
|
||||
/* GP TIMER 1 */
|
||||
#define GPTIMER1_TISTAT GPT1_REG32(0x014)
|
||||
@ -243,15 +260,15 @@
|
||||
#define GPTIMER1_TCAR2 GPT1_REG32(0x044)
|
||||
|
||||
/* rkw -- base fix up please... */
|
||||
#define GPTIMER3_TISR __REG32(OMAP24XX_L4_IO_BASE+0x78018)
|
||||
#define GPTIMER3_TISR __REG32(OMAP24XX_L4_IO_BASE + 0x78018)
|
||||
|
||||
/* SDRC */
|
||||
#define SDRC_DLLA_CTRL __REG32(OMAP24XX_SDRC_BASE+0x060)
|
||||
#define SDRC_DLLA_STATUS __REG32(OMAP24XX_SDRC_BASE+0x064)
|
||||
#define SDRC_DLLB_CTRL __REG32(OMAP24XX_SDRC_BASE+0x068)
|
||||
#define SDRC_DLLB_STATUS __REG32(OMAP24XX_SDRC_BASE+0x06C)
|
||||
#define SDRC_POWER __REG32(OMAP24XX_SDRC_BASE+0x070)
|
||||
#define SDRC_MR_0 __REG32(OMAP24XX_SDRC_BASE+0x084)
|
||||
#define SDRC_DLLA_CTRL __REG32(OMAP24XX_SDRC_BASE + 0x060)
|
||||
#define SDRC_DLLA_STATUS __REG32(OMAP24XX_SDRC_BASE + 0x064)
|
||||
#define SDRC_DLLB_CTRL __REG32(OMAP24XX_SDRC_BASE + 0x068)
|
||||
#define SDRC_DLLB_STATUS __REG32(OMAP24XX_SDRC_BASE + 0x06C)
|
||||
#define SDRC_POWER __REG32(OMAP24XX_SDRC_BASE + 0x070)
|
||||
#define SDRC_MR_0 __REG32(OMAP24XX_SDRC_BASE + 0x084)
|
||||
|
||||
/* GPIO 1 */
|
||||
#define GPIO1_BASE GPIOX_BASE(1)
|
||||
@ -278,6 +295,8 @@
|
||||
#define GPIO2_DATAIN GPIO2_REG32(0x038)
|
||||
#define GPIO2_OE GPIO2_REG32(0x034)
|
||||
#define GPIO2_DATAOUT GPIO2_REG32(0x03C)
|
||||
#define GPIO2_DEBOUNCENABLE GPIO2_REG32(0x050)
|
||||
#define GPIO2_DEBOUNCINGTIME GPIO2_REG32(0x054)
|
||||
|
||||
/* GPIO 3 */
|
||||
#define GPIO3_BASE GPIOX_BASE(3)
|
||||
@ -294,6 +313,8 @@
|
||||
#define GPIO3_DATAOUT GPIO3_REG32(0x03C)
|
||||
#define GPIO3_DEBOUNCENABLE GPIO3_REG32(0x050)
|
||||
#define GPIO3_DEBOUNCINGTIME GPIO3_REG32(0x054)
|
||||
#define GPIO3_DEBOUNCENABLE GPIO3_REG32(0x050)
|
||||
#define GPIO3_DEBOUNCINGTIME GPIO3_REG32(0x054)
|
||||
|
||||
/* GPIO 4 */
|
||||
#define GPIO4_BASE GPIOX_BASE(4)
|
||||
@ -311,10 +332,26 @@
|
||||
#define GPIO4_DEBOUNCENABLE GPIO4_REG32(0x050)
|
||||
#define GPIO4_DEBOUNCINGTIME GPIO4_REG32(0x054)
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP243X)
|
||||
/* GPIO 5 */
|
||||
#define GPIO5_REG32(offset) __REG32((OMAP24XX_GPIO5_BASE + (offset)))
|
||||
#define GPIO5_IRQENABLE1 GPIO5_REG32(0x01C)
|
||||
#define GPIO5_IRQSTATUS1 GPIO5_REG32(0x018)
|
||||
#define GPIO5_IRQENABLE2 GPIO5_REG32(0x02C)
|
||||
#define GPIO5_IRQSTATUS2 GPIO5_REG32(0x028)
|
||||
#define GPIO5_WAKEUPENABLE GPIO5_REG32(0x020)
|
||||
#define GPIO5_RISINGDETECT GPIO5_REG32(0x048)
|
||||
#define GPIO5_FALLINGDETECT GPIO5_REG32(0x04C)
|
||||
#define GPIO5_DATAIN GPIO5_REG32(0x038)
|
||||
#define GPIO5_OE GPIO5_REG32(0x034)
|
||||
#define GPIO5_DATAOUT GPIO5_REG32(0x03C)
|
||||
#define GPIO5_DEBOUNCENABLE GPIO5_REG32(0x050)
|
||||
#define GPIO5_DEBOUNCINGTIME GPIO5_REG32(0x054)
|
||||
#endif
|
||||
|
||||
/* IO CONFIG */
|
||||
#define CONTROL_BASE (OMAP24XX_CTRL_BASE)
|
||||
#define CONTROL_REG32(offset) __REG32(CONTROL_BASE + (offset))
|
||||
#define OMAP24XX_CTRL_BASE (L4_24XX_BASE)
|
||||
#define CONTROL_REG32(offset) __REG32(OMAP24XX_CTRL_BASE + (offset))
|
||||
|
||||
#define CONTROL_PADCONF_SPI1_NCS2 CONTROL_REG32(0x104)
|
||||
#define CONTROL_PADCONF_SYS_XTALOUT CONTROL_REG32(0x134)
|
||||
@ -322,15 +359,18 @@
|
||||
#define CONTROL_PADCONF_MCBSP1_DX CONTROL_REG32(0x10C)
|
||||
#define CONTROL_PADCONF_GPMC_NCS4 CONTROL_REG32(0x090)
|
||||
#define CONTROL_PADCONF_DSS_D5 CONTROL_REG32(0x0B8)
|
||||
#define CONTROL_PADCONF_DSS_D9 CONTROL_REG32(0x0BC)
|
||||
#define CONTROL_PADCONF_DSS_D9 CONTROL_REG32(0x0BC) /* 2420 */
|
||||
#define CONTROL_PADCONF_DSS_D13 CONTROL_REG32(0x0C0)
|
||||
#define CONTROL_PADCONF_DSS_VSYNC CONTROL_REG32(0x0CC)
|
||||
#define CONTROL_PADCONF_SYS_NIRQW0 CONTROL_REG32(0x0BC) /* 2430 */
|
||||
#define CONTROL_PADCONF_SSI1_FLAG_TX CONTROL_REG32(0x108) /* 2430 */
|
||||
|
||||
/* CONTROL */
|
||||
#define CONTROL_DEVCONF CONTROL_REG32(0x274)
|
||||
#define CONTROL_DEVCONF1 CONTROL_REG32(0x2E8)
|
||||
|
||||
/* INTERRUPT CONTROLLER */
|
||||
#define INTC_BASE (OMAP24XX_L4_IO_BASE+0xfe000)
|
||||
#define INTC_BASE ((L4_24XX_BASE) + 0xfe000)
|
||||
#define INTC_REG32(offset) __REG32(INTC_BASE + (offset))
|
||||
|
||||
#define INTC1_U_BASE INTC_REG32(0x000)
|
||||
@ -348,10 +388,12 @@
|
||||
#define INTC_ISR_CLEAR2 INTC_REG32(0x0D4)
|
||||
#define INTC_SIR_IRQ INTC_REG32(0x040)
|
||||
#define INTC_CONTROL INTC_REG32(0x048)
|
||||
#define INTC_ILR11 INTC_REG32(0x12C)
|
||||
#define INTC_ILR11 INTC_REG32(0x12C) /* PRCM on MPU PIC */
|
||||
#define INTC_ILR30 INTC_REG32(0x178)
|
||||
#define INTC_ILR31 INTC_REG32(0x17C)
|
||||
#define INTC_ILR32 INTC_REG32(0x180)
|
||||
#define INTC_ILR37 INTC_REG32(0x194)
|
||||
#define INTC_SYSCONFIG INTC_REG32(0x010)
|
||||
#define INTC_ILR37 INTC_REG32(0x194) /* GPIO4 on MPU PIC */
|
||||
#define INTC_SYSCONFIG INTC_REG32(0x010) /* GPT1 on MPU PIC */
|
||||
|
||||
/* RAM FIREWALL */
|
||||
#define RAMFW_BASE (0x68005000)
|
||||
@ -373,6 +415,24 @@
|
||||
#define GPMC_CONFIG6_0 GPMC_REG32(0x074)
|
||||
#define GPMC_CONFIG7_0 GPMC_REG32(0x078)
|
||||
|
||||
/* GPMC CS1 */
|
||||
#define GPMC_CONFIG1_1 GPMC_REG32(0x090)
|
||||
#define GPMC_CONFIG2_1 GPMC_REG32(0x094)
|
||||
#define GPMC_CONFIG3_1 GPMC_REG32(0x098)
|
||||
#define GPMC_CONFIG4_1 GPMC_REG32(0x09C)
|
||||
#define GPMC_CONFIG5_1 GPMC_REG32(0x0a0)
|
||||
#define GPMC_CONFIG6_1 GPMC_REG32(0x0a4)
|
||||
#define GPMC_CONFIG7_1 GPMC_REG32(0x0a8)
|
||||
|
||||
/* GPMC CS3 */
|
||||
#define GPMC_CONFIG1_3 GPMC_REG32(0x0F0)
|
||||
#define GPMC_CONFIG2_3 GPMC_REG32(0x0F4)
|
||||
#define GPMC_CONFIG3_3 GPMC_REG32(0x0F8)
|
||||
#define GPMC_CONFIG4_3 GPMC_REG32(0x0FC)
|
||||
#define GPMC_CONFIG5_3 GPMC_REG32(0x100)
|
||||
#define GPMC_CONFIG6_3 GPMC_REG32(0x104)
|
||||
#define GPMC_CONFIG7_3 GPMC_REG32(0x108)
|
||||
|
||||
/* DSS */
|
||||
#define DSS_CONTROL DISP_REG32(0x040)
|
||||
#define DISPC_CONTROL DISP_REG32(0x440)
|
||||
@ -405,11 +465,15 @@
|
||||
#define DISPC_DATA_CYCLE2 DISP_REG32(0x5D8)
|
||||
#define DISPC_DATA_CYCLE3 DISP_REG32(0x5DC)
|
||||
|
||||
/* Wake up define for board */
|
||||
#define GPIO97 (1 << 1)
|
||||
#define GPIO88 (1 << 24)
|
||||
/* HSUSB Suspend */
|
||||
#define HSUSB_CTRL __REG8(0x480AC001)
|
||||
#define USBOTG_POWER __REG32(0x480AC000)
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
/* HS MMC */
|
||||
#define MMCHS1_SYSCONFIG __REG32(0x4809C010)
|
||||
#define MMCHS2_SYSCONFIG __REG32(0x480b4010)
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
#endif
|
||||
|
40
arch/arm/mach-omap2/prcm.c
Normal file
40
arch/arm/mach-omap2/prcm.c
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap2/prcm.c
|
||||
*
|
||||
* OMAP 24xx Power Reset and Clock Management (PRCM) functions
|
||||
*
|
||||
* Copyright (C) 2005 Nokia Corporation
|
||||
*
|
||||
* Written by Tony Lindgren <tony.lindgren@nokia.com>
|
||||
*
|
||||
* Some pieces of code Copyright (C) 2005 Texas Instruments, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
#include "prcm-regs.h"
|
||||
|
||||
u32 omap_prcm_get_reset_sources(void)
|
||||
{
|
||||
return RM_RSTST_WKUP & 0x7f;
|
||||
}
|
||||
EXPORT_SYMBOL(omap_prcm_get_reset_sources);
|
||||
|
||||
/* Resets clock rates and reboots the system. Only called from system.h */
|
||||
void omap_prcm_arch_reset(char mode)
|
||||
{
|
||||
u32 rate;
|
||||
struct clk *vclk, *sclk;
|
||||
|
||||
vclk = clk_get(NULL, "virt_prcm_set");
|
||||
sclk = clk_get(NULL, "sys_ck");
|
||||
rate = clk_get_rate(sclk);
|
||||
clk_set_rate(vclk, rate); /* go to bypass for OMAP limitation */
|
||||
RM_RSTCTRL_WKUP |= 2;
|
||||
}
|
144
arch/arm/mach-omap2/sleep.S
Normal file
144
arch/arm/mach-omap2/sleep.S
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap2/sleep.S
|
||||
*
|
||||
* (C) Copyright 2004
|
||||
* Texas Instruments, <www.ti.com>
|
||||
* Richard Woodruff <r-woodruff2@ti.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 Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/assembler.h>
|
||||
#include <asm/arch/io.h>
|
||||
#include <asm/arch/pm.h>
|
||||
|
||||
#define A_32KSYNC_CR_V IO_ADDRESS(OMAP_TIMER32K_BASE+0x10)
|
||||
#define A_PRCM_VOLTCTRL_V IO_ADDRESS(OMAP24XX_PRCM_BASE+0x50)
|
||||
#define A_PRCM_CLKCFG_CTRL_V IO_ADDRESS(OMAP24XX_PRCM_BASE+0x80)
|
||||
#define A_CM_CLKEN_PLL_V IO_ADDRESS(OMAP24XX_PRCM_BASE+0x500)
|
||||
#define A_CM_IDLEST_CKGEN_V IO_ADDRESS(OMAP24XX_PRCM_BASE+0x520)
|
||||
#define A_CM_CLKSEL1_PLL_V IO_ADDRESS(OMAP24XX_PRCM_BASE+0x540)
|
||||
#define A_CM_CLKSEL2_PLL_V IO_ADDRESS(OMAP24XX_PRCM_BASE+0x544)
|
||||
|
||||
#define A_SDRC_DLLA_CTRL_V IO_ADDRESS(OMAP24XX_SDRC_BASE+0x60)
|
||||
#define A_SDRC_POWER_V IO_ADDRESS(OMAP24XX_SDRC_BASE+0x70)
|
||||
#define A_SDRC_RFR_CTRL_V IO_ADDRESS(OMAP24XX_SDRC_BASE+0xA4)
|
||||
#define A_SDRC0_V (0xC0000000)
|
||||
#define A_SDRC_MANUAL_V IO_ADDRESS(OMAP24XX_SDRC_BASE+0xA8)
|
||||
|
||||
.text
|
||||
|
||||
/*
|
||||
* Forces OMAP into idle state
|
||||
*
|
||||
* omap24xx_idle_loop_suspend() - This bit of code just executes the WFI
|
||||
* for normal idles.
|
||||
*
|
||||
* Note: This code get's copied to internal SRAM at boot. When the OMAP
|
||||
* wakes up it continues execution at the point it went to sleep.
|
||||
*/
|
||||
ENTRY(omap24xx_idle_loop_suspend)
|
||||
stmfd sp!, {r0, lr} @ save registers on stack
|
||||
mov r0, #0 @ clear for mcr setup
|
||||
mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt
|
||||
ldmfd sp!, {r0, pc} @ restore regs and return
|
||||
|
||||
ENTRY(omap24xx_idle_loop_suspend_sz)
|
||||
.word . - omap24xx_idle_loop_suspend
|
||||
|
||||
/*
|
||||
* omap242x_cpu_suspend() - Forces OMAP into deep sleep state by completing
|
||||
* SDRC shutdown then ARM shutdown. Upon wake MPU is back on so just restore
|
||||
* SDRC.
|
||||
*
|
||||
* Input:
|
||||
* R0 : DLL ctrl value pre-Sleep
|
||||
* R1 : Processor+Revision
|
||||
* 2420: 0x21 = 242xES1, 0x26 = 242xES2.2
|
||||
* 2430: 0x31 = 2430ES1, 0x32 = 2430ES2
|
||||
*
|
||||
* The if the DPLL is going to AutoIdle. It seems like the DPLL may be back on
|
||||
* when we get called, but the DLL probably isn't. We will wait a bit more in
|
||||
* case the DPLL isn't quite there yet. The code will wait on DLL for DDR even
|
||||
* if in unlocked mode.
|
||||
*
|
||||
* For less than 242x-ES2.2 upon wake from a sleep mode where the external
|
||||
* oscillator was stopped, a timing bug exists where a non-stabilized 12MHz
|
||||
* clock can pass into the PRCM can cause problems at DSP and IVA.
|
||||
* To work around this the code will switch to the 32kHz source prior to sleep.
|
||||
* Post sleep we will shift back to using the DPLL. Apparently,
|
||||
* CM_IDLEST_CLKGEN does not reflect the full clock change so you need to wait
|
||||
* 3x12MHz + 3x32kHz clocks for a full switch.
|
||||
*
|
||||
* The DLL load value is not kept in RETENTION or OFF. It needs to be restored
|
||||
* at wake
|
||||
*/
|
||||
ENTRY(omap24xx_cpu_suspend)
|
||||
stmfd sp!, {r0 - r12, lr} @ save registers on stack
|
||||
mov r3, #0x0 @ clear for mrc call
|
||||
mcr p15, 0, r3, c7, c10, 4 @ memory barrier, hope SDR/DDR finished
|
||||
nop
|
||||
nop
|
||||
ldr r3, A_SDRC_POWER @ addr of sdrc power
|
||||
ldr r4, [r3] @ value of sdrc power
|
||||
orr r4, r4, #0x40 @ enable self refresh on idle req
|
||||
mov r5, #0x2000 @ set delay (DPLL relock + DLL relock)
|
||||
str r4, [r3] @ make it so
|
||||
mov r2, #0
|
||||
nop
|
||||
mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt
|
||||
nop
|
||||
loop:
|
||||
subs r5, r5, #0x1 @ awake, wait just a bit
|
||||
bne loop
|
||||
|
||||
/* The DPLL has on before we take the DDR out of self refresh */
|
||||
bic r4, r4, #0x40 @ now clear self refresh bit.
|
||||
str r4, [r3] @ put vlaue back.
|
||||
ldr r4, A_SDRC0 @ make a clock happen
|
||||
ldr r4, [r4]
|
||||
nop @ start auto refresh only after clk ok
|
||||
movs r0, r0 @ see if DDR or SDR
|
||||
ldrne r1, A_SDRC_DLLA_CTRL_S @ get addr of DLL ctrl
|
||||
strne r0, [r1] @ rewrite DLLA to force DLL reload
|
||||
addne r1, r1, #0x8 @ move to DLLB
|
||||
strne r0, [r1] @ rewrite DLLB to force DLL reload
|
||||
|
||||
mov r5, #0x1000
|
||||
loop2:
|
||||
subs r5, r5, #0x1
|
||||
bne loop2
|
||||
/* resume*/
|
||||
ldmfd sp!, {r0 - r12, pc} @ restore regs and return
|
||||
|
||||
A_SDRC_POWER:
|
||||
.word A_SDRC_POWER_V
|
||||
A_SDRC0:
|
||||
.word A_SDRC0_V
|
||||
A_CM_CLKSEL2_PLL_S:
|
||||
.word A_CM_CLKSEL2_PLL_V
|
||||
A_CM_CLKEN_PLL:
|
||||
.word A_CM_CLKEN_PLL_V
|
||||
A_SDRC_DLLA_CTRL_S:
|
||||
.word A_SDRC_DLLA_CTRL_V
|
||||
A_SDRC_MANUAL_S:
|
||||
.word A_SDRC_MANUAL_V
|
||||
|
||||
ENTRY(omap24xx_cpu_suspend_sz)
|
||||
.word . - omap24xx_cpu_suspend
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap1/sram.S
|
||||
* linux/arch/arm/mach-omap2/sram.S
|
||||
*
|
||||
* Omap2 specific functions that need to be run in internal SRAM
|
||||
*
|
||||
@ -28,7 +28,7 @@
|
||||
#include <asm/arch/io.h>
|
||||
#include <asm/hardware.h>
|
||||
|
||||
#include <asm/arch/prcm.h>
|
||||
#include "prcm-regs.h"
|
||||
|
||||
#define TIMER_32KSYNCT_CR_V IO_ADDRESS(OMAP24XX_32KSYNCT_BASE + 0x010)
|
||||
|
||||
|
@ -141,6 +141,8 @@ struct corgissp_machinfo corgi_ssp_machinfo = {
|
||||
*/
|
||||
static struct corgibl_machinfo corgi_bl_machinfo = {
|
||||
.max_intensity = 0x2f,
|
||||
.default_intensity = 0x1f,
|
||||
.limit_mask = 0x0b,
|
||||
.set_bl_intensity = corgi_bl_set_intensity,
|
||||
};
|
||||
|
||||
@ -163,6 +165,14 @@ static struct platform_device corgikbd_device = {
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Corgi LEDs
|
||||
*/
|
||||
static struct platform_device corgiled_device = {
|
||||
.name = "corgi-led",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
/*
|
||||
* Corgi Touch Screen Device
|
||||
*/
|
||||
@ -297,6 +307,7 @@ static struct platform_device *devices[] __initdata = {
|
||||
&corgikbd_device,
|
||||
&corgibl_device,
|
||||
&corgits_device,
|
||||
&corgiled_device,
|
||||
};
|
||||
|
||||
static void __init corgi_init(void)
|
||||
|
@ -307,6 +307,10 @@ static void __init fixup_poodle(struct machine_desc *desc,
|
||||
struct tag *tags, char **cmdline, struct meminfo *mi)
|
||||
{
|
||||
sharpsl_save_param();
|
||||
mi->nr_banks=1;
|
||||
mi->bank[0].start = 0xa0000000;
|
||||
mi->bank[0].node = 0;
|
||||
mi->bank[0].size = (32*1024*1024);
|
||||
}
|
||||
|
||||
MACHINE_START(POODLE, "SHARP Poodle")
|
||||
|
@ -220,6 +220,8 @@ struct corgissp_machinfo spitz_ssp_machinfo = {
|
||||
* Spitz Backlight Device
|
||||
*/
|
||||
static struct corgibl_machinfo spitz_bl_machinfo = {
|
||||
.default_intensity = 0x1f,
|
||||
.limit_mask = 0x0b,
|
||||
.max_intensity = 0x2f,
|
||||
};
|
||||
|
||||
@ -241,6 +243,14 @@ static struct platform_device spitzkbd_device = {
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Spitz LEDs
|
||||
*/
|
||||
static struct platform_device spitzled_device = {
|
||||
.name = "spitz-led",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
/*
|
||||
* Spitz Touch Screen Device
|
||||
*/
|
||||
@ -418,6 +428,7 @@ static struct platform_device *devices[] __initdata = {
|
||||
&spitzkbd_device,
|
||||
&spitzts_device,
|
||||
&spitzbl_device,
|
||||
&spitzled_device,
|
||||
};
|
||||
|
||||
static void __init common_init(void)
|
||||
|
@ -251,10 +251,19 @@ static struct platform_device tosakbd_device = {
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
/*
|
||||
* Tosa LEDs
|
||||
*/
|
||||
static struct platform_device tosaled_device = {
|
||||
.name = "tosa-led",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static struct platform_device *devices[] __initdata = {
|
||||
&tosascoop_device,
|
||||
&tosascoop_jc_device,
|
||||
&tosakbd_device,
|
||||
&tosaled_device,
|
||||
};
|
||||
|
||||
static void __init tosa_init(void)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user