1
0
Fork 0

Merge branch 'for-rmk-devel' of git://git.pengutronix.de/git/imx/linux-2.6 into devel

Conflicts:
	arch/arm/Kconfig
	arch/arm/Makefile
hifive-unleashed-5.1
Russell King 2009-05-23 20:57:31 +01:00 committed by Russell King
commit a2ab67fae1
551 changed files with 18218 additions and 16913 deletions

View File

@ -143,7 +143,8 @@ quiet_cmd_db2pdf = PDF $@
$(call cmd,db2pdf)
main_idx = Documentation/DocBook/index.html
index = index.html
main_idx = Documentation/DocBook/$(index)
build_main_index = rm -rf $(main_idx) && \
echo '<h1>Linux Kernel HTML Documentation</h1>' >> $(main_idx) && \
echo '<h2>Kernel Version: $(KERNELVERSION)</h2>' >> $(main_idx) && \
@ -232,7 +233,7 @@ clean-files := $(DOCBOOKS) \
$(patsubst %.xml, %.pdf, $(DOCBOOKS)) \
$(patsubst %.xml, %.html, $(DOCBOOKS)) \
$(patsubst %.xml, %.9, $(DOCBOOKS)) \
$(C-procfs-example)
$(C-procfs-example) $(index)
clean-dirs := $(patsubst %.xml,%,$(DOCBOOKS)) man

View File

@ -190,16 +190,20 @@ X!Ekernel/module.c
!Edrivers/pci/pci.c
!Edrivers/pci/pci-driver.c
!Edrivers/pci/remove.c
!Edrivers/pci/pci-acpi.c
!Edrivers/pci/search.c
!Edrivers/pci/msi.c
!Edrivers/pci/bus.c
!Edrivers/pci/access.c
!Edrivers/pci/irq.c
!Edrivers/pci/htirq.c
<!-- FIXME: Removed for now since no structured comments in source
X!Edrivers/pci/hotplug.c
-->
!Edrivers/pci/probe.c
!Edrivers/pci/slot.c
!Edrivers/pci/rom.c
!Edrivers/pci/iov.c
!Idrivers/pci/pci-sysfs.c
</sect1>
<sect1><title>PCI Hotplug Support Library</title>
!Edrivers/pci/hotplug/pci_hotplug_core.c

View File

@ -512,16 +512,24 @@ locking rules:
BKL mmap_sem PageLocked(page)
open: no yes
close: no yes
fault: no yes
page_mkwrite: no yes no
fault: no yes can return with page locked
page_mkwrite: no yes can return with page locked
access: no yes
->page_mkwrite() is called when a previously read-only page is
about to become writeable. The file system is responsible for
protecting against truncate races. Once appropriate action has been
taking to lock out truncate, the page range should be verified to be
within i_size. The page mapping should also be checked that it is not
NULL.
->fault() is called when a previously not present pte is about
to be faulted in. The filesystem must find and return the page associated
with the passed in "pgoff" in the vm_fault structure. If it is possible that
the page may be truncated and/or invalidated, then the filesystem must lock
the page, then ensure it is not already truncated (the page lock will block
subsequent truncate), and then return with VM_FAULT_LOCKED, and the page
locked. The VM will unlock the page.
->page_mkwrite() is called when a previously read-only pte is
about to become writeable. The filesystem again must ensure that there are
no truncate/invalidate races, and then return with the page locked. If
the page has been truncated, the filesystem should not look up a new page
like the ->fault() handler, but simply return with VM_FAULT_NOPAGE, which
will cause the VM to retry the fault.
->access() is called when get_user_pages() fails in
acces_process_vm(), typically used to debug a process through

View File

@ -0,0 +1,65 @@
BCM5974 Driver (bcm5974)
------------------------
Copyright (C) 2008-2009 Henrik Rydberg <rydberg@euromail.se>
The USB initialization and package decoding was made by Scott Shawcroft as
part of the touchd user-space driver project:
Copyright (C) 2008 Scott Shawcroft (scott.shawcroft@gmail.com)
The BCM5974 driver is based on the appletouch driver:
Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
Copyright (C) 2005 Johannes Berg (johannes@sipsolutions.net)
Copyright (C) 2005 Stelian Pop (stelian@popies.net)
Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de)
Copyright (C) 2005 Peter Osterlund (petero2@telia.com)
Copyright (C) 2005 Michael Hanselmann (linux-kernel@hansmi.ch)
Copyright (C) 2006 Nicolas Boichat (nicolas@boichat.ch)
This driver adds support for the multi-touch trackpad on the new Apple
Macbook Air and Macbook Pro laptops. It replaces the appletouch driver on
those computers, and integrates well with the synaptics driver of the Xorg
system.
Known to work on Macbook Air, Macbook Pro Penryn and the new unibody
Macbook 5 and Macbook Pro 5.
Usage
-----
The driver loads automatically for the supported usb device ids, and
becomes available both as an event device (/dev/input/event*) and as a
mouse via the mousedev driver (/dev/input/mice).
USB Race
--------
The Apple multi-touch trackpads report both mouse and keyboard events via
different interfaces of the same usb device. This creates a race condition
with the HID driver, which, if not told otherwise, will find the standard
HID mouse and keyboard, and claim the whole device. To remedy, the usb
product id must be listed in the mouse_ignore list of the hid driver.
Debug output
------------
To ease the development for new hardware version, verbose packet output can
be switched on with the debug kernel module parameter. The range [1-9]
yields different levels of verbosity. Example (as root):
echo -n 9 > /sys/module/bcm5974/parameters/debug
tail -f /var/log/debug
echo -n 0 > /sys/module/bcm5974/parameters/debug
Trivia
------
The driver was developed at the ubuntu forums in June 2008 [1], and now has
a more permanent home at bitmath.org [2].
Links
-----
[1] http://ubuntuforums.org/showthread.php?t=840040
[2] http://http://bitmath.org/code/

View File

@ -0,0 +1,140 @@
Multi-touch (MT) Protocol
-------------------------
Copyright (C) 2009 Henrik Rydberg <rydberg@euromail.se>
Introduction
------------
In order to utilize the full power of the new multi-touch devices, a way to
report detailed finger data to user space is needed. This document
describes the multi-touch (MT) protocol which allows kernel drivers to
report details for an arbitrary number of fingers.
Usage
-----
Anonymous finger details are sent sequentially as separate packets of ABS
events. Only the ABS_MT events are recognized as part of a finger
packet. The end of a packet is marked by calling the input_mt_sync()
function, which generates a SYN_MT_REPORT event. The end of multi-touch
transfer is marked by calling the usual input_sync() function.
A set of ABS_MT events with the desired properties is defined. The events
are divided into categories, to allow for partial implementation. The
minimum set consists of ABS_MT_TOUCH_MAJOR, ABS_MT_POSITION_X and
ABS_MT_POSITION_Y, which allows for multiple fingers to be tracked. If the
device supports it, the ABS_MT_WIDTH_MAJOR may be used to provide the size
of the approaching finger. Anisotropy and direction may be specified with
ABS_MT_TOUCH_MINOR, ABS_MT_WIDTH_MINOR and ABS_MT_ORIENTATION. Devices with
more granular information may specify general shapes as blobs, i.e., as a
sequence of rectangular shapes grouped together by an
ABS_MT_BLOB_ID. Finally, the ABS_MT_TOOL_TYPE may be used to specify
whether the touching tool is a finger or a pen or something else.
Event Semantics
---------------
The word "contact" is used to describe a tool which is in direct contact
with the surface. A finger, a pen or a rubber all classify as contacts.
ABS_MT_TOUCH_MAJOR
The length of the major axis of the contact. The length should be given in
surface units. If the surface has an X times Y resolution, the largest
possible value of ABS_MT_TOUCH_MAJOR is sqrt(X^2 + Y^2), the diagonal.
ABS_MT_TOUCH_MINOR
The length, in surface units, of the minor axis of the contact. If the
contact is circular, this event can be omitted.
ABS_MT_WIDTH_MAJOR
The length, in surface units, of the major axis of the approaching
tool. This should be understood as the size of the tool itself. The
orientation of the contact and the approaching tool are assumed to be the
same.
ABS_MT_WIDTH_MINOR
The length, in surface units, of the minor axis of the approaching
tool. Omit if circular.
The above four values can be used to derive additional information about
the contact. The ratio ABS_MT_TOUCH_MAJOR / ABS_MT_WIDTH_MAJOR approximates
the notion of pressure. The fingers of the hand and the palm all have
different characteristic widths [1].
ABS_MT_ORIENTATION
The orientation of the ellipse. The value should describe half a revolution
clockwise around the touch center. The scale of the value is arbitrary, but
zero should be returned for an ellipse aligned along the Y axis of the
surface. As an example, an index finger placed straight onto the axis could
return zero orientation, something negative when twisted to the left, and
something positive when twisted to the right. This value can be omitted if
the touching object is circular, or if the information is not available in
the kernel driver.
ABS_MT_POSITION_X
The surface X coordinate of the center of the touching ellipse.
ABS_MT_POSITION_Y
The surface Y coordinate of the center of the touching ellipse.
ABS_MT_TOOL_TYPE
The type of approaching tool. A lot of kernel drivers cannot distinguish
between different tool types, such as a finger or a pen. In such cases, the
event should be omitted. The protocol currently supports MT_TOOL_FINGER and
MT_TOOL_PEN [2].
ABS_MT_BLOB_ID
The BLOB_ID groups several packets together into one arbitrarily shaped
contact. This is a low-level anonymous grouping, and should not be confused
with the high-level contactID, explained below. Most kernel drivers will
not have this capability, and can safely omit the event.
Finger Tracking
---------------
The kernel driver should generate an arbitrary enumeration of the set of
anonymous contacts currently on the surface. The order in which the packets
appear in the event stream is not important.
The process of finger tracking, i.e., to assign a unique contactID to each
initiated contact on the surface, is left to user space; preferably the
multi-touch X driver [3]. In that driver, the contactID stays the same and
unique until the contact vanishes (when the finger leaves the surface). The
problem of assigning a set of anonymous fingers to a set of identified
fingers is a euclidian bipartite matching problem at each event update, and
relies on a sufficiently rapid update rate.
Notes
-----
In order to stay compatible with existing applications, the data
reported in a finger packet must not be recognized as single-touch
events. In addition, all finger data must bypass input filtering,
since subsequent events of the same type refer to different fingers.
The first kernel driver to utilize the MT protocol is the bcm5974 driver,
where examples can be found.
[1] With the extension ABS_MT_APPROACH_X and ABS_MT_APPROACH_Y, the
difference between the contact position and the approaching tool position
could be used to derive tilt.
[2] The list can of course be extended.
[3] The multi-touch X driver is currently in the prototyping stage. At the
time of writing (April 2009), the MT protocol is not yet merged, and the
prototype implements finger matching, basic mouse support and two-finger
scrolling. The project aims at improving the quality of current multi-touch
functionality available in the synaptics X driver, and in addition
implement more advanced gestures.

View File

@ -2,8 +2,14 @@
- this file (info on ISDN implementation for Linux)
CREDITS
- list of the kind folks that brought you this stuff.
HiSax.cert
- information about the ITU approval certification of the HiSax driver.
INTERFACE
- description of Linklevel and Hardwarelevel ISDN interface.
- description of isdn4linux Link Level and Hardware Level interfaces.
INTERFACE.fax
- description of the fax subinterface of isdn4linux.
INTERFACE.CAPI
- description of kernel CAPI Link Level to Hardware Level interface.
README
- general info on what you need and what to do for Linux ISDN.
README.FAQ
@ -12,6 +18,8 @@ README.audio
- info for running audio over ISDN.
README.fax
- info for using Fax over ISDN.
README.gigaset
- info on the drivers for Siemens Gigaset ISDN adapters.
README.icn
- info on the ICN-ISDN-card and its driver.
README.HiSax
@ -37,7 +45,8 @@ README.diversion
README.sc
- info on driver for Spellcaster cards.
README.x25
_ info for running X.25 over ISDN.
- info for running X.25 over ISDN.
README.hysdn
- info on driver for Hypercope active HYSDN cards
- info on driver for Hypercope active HYSDN cards
README.mISDN
- info on the Modular ISDN subsystem (mISDN).

View File

@ -0,0 +1,213 @@
Kernel CAPI Interface to Hardware Drivers
-----------------------------------------
1. Overview
From the CAPI 2.0 specification:
COMMON-ISDN-API (CAPI) is an application programming interface standard used
to access ISDN equipment connected to basic rate interfaces (BRI) and primary
rate interfaces (PRI).
Kernel CAPI operates as a dispatching layer between CAPI applications and CAPI
hardware drivers. Hardware drivers register ISDN devices (controllers, in CAPI
lingo) with Kernel CAPI to indicate their readiness to provide their service
to CAPI applications. CAPI applications also register with Kernel CAPI,
requesting association with a CAPI device. Kernel CAPI then dispatches the
application registration to an available device, forwarding it to the
corresponding hardware driver. Kernel CAPI then forwards CAPI messages in both
directions between the application and the hardware driver.
Format and semantics of CAPI messages are specified in the CAPI 2.0 standard.
This standard is freely available from http://www.capi.org.
2. Driver and Device Registration
CAPI drivers optionally register themselves with Kernel CAPI by calling the
Kernel CAPI function register_capi_driver() with a pointer to a struct
capi_driver. This structure must be filled with the name and revision of the
driver, and optionally a pointer to a callback function, add_card(). The
registration can be revoked by calling the function unregister_capi_driver()
with a pointer to the same struct capi_driver.
CAPI drivers must register each of the ISDN devices they control with Kernel
CAPI by calling the Kernel CAPI function attach_capi_ctr() with a pointer to a
struct capi_ctr before they can be used. This structure must be filled with
the names of the driver and controller, and a number of callback function
pointers which are subsequently used by Kernel CAPI for communicating with the
driver. The registration can be revoked by calling the function
detach_capi_ctr() with a pointer to the same struct capi_ctr.
Before the device can be actually used, the driver must fill in the device
information fields 'manu', 'version', 'profile' and 'serial' in the capi_ctr
structure of the device, and signal its readiness by calling capi_ctr_ready().
From then on, Kernel CAPI may call the registered callback functions for the
device.
If the device becomes unusable for any reason (shutdown, disconnect ...), the
driver has to call capi_ctr_reseted(). This will prevent further calls to the
callback functions by Kernel CAPI.
3. Application Registration and Communication
Kernel CAPI forwards registration requests from applications (calls to CAPI
operation CAPI_REGISTER) to an appropriate hardware driver by calling its
register_appl() callback function. A unique Application ID (ApplID, u16) is
allocated by Kernel CAPI and passed to register_appl() along with the
parameter structure provided by the application. This is analogous to the
open() operation on regular files or character devices.
After a successful return from register_appl(), CAPI messages from the
application may be passed to the driver for the device via calls to the
send_message() callback function. The CAPI message to send is stored in the
data portion of an skb. Conversely, the driver may call Kernel CAPI's
capi_ctr_handle_message() function to pass a received CAPI message to Kernel
CAPI for forwarding to an application, specifying its ApplID.
Deregistration requests (CAPI operation CAPI_RELEASE) from applications are
forwarded as calls to the release_appl() callback function, passing the same
ApplID as with register_appl(). After return from release_appl(), no CAPI
messages for that application may be passed to or from the device anymore.
4. Data Structures
4.1 struct capi_driver
This structure describes a Kernel CAPI driver itself. It is used in the
register_capi_driver() and unregister_capi_driver() functions, and contains
the following non-private fields, all to be set by the driver before calling
register_capi_driver():
char name[32]
the name of the driver, as a zero-terminated ASCII string
char revision[32]
the revision number of the driver, as a zero-terminated ASCII string
int (*add_card)(struct capi_driver *driver, capicardparams *data)
a callback function pointer (may be NULL)
4.2 struct capi_ctr
This structure describes an ISDN device (controller) handled by a Kernel CAPI
driver. After registration via the attach_capi_ctr() function it is passed to
all controller specific lower layer interface and callback functions to
identify the controller to operate on.
It contains the following non-private fields:
- to be set by the driver before calling attach_capi_ctr():
struct module *owner
pointer to the driver module owning the device
void *driverdata
an opaque pointer to driver specific data, not touched by Kernel CAPI
char name[32]
the name of the controller, as a zero-terminated ASCII string
char *driver_name
the name of the driver, as a zero-terminated ASCII string
int (*load_firmware)(struct capi_ctr *ctrlr, capiloaddata *ldata)
(optional) pointer to a callback function for sending firmware and
configuration data to the device
void (*reset_ctr)(struct capi_ctr *ctrlr)
pointer to a callback function for performing a reset on the device,
releasing all registered applications
void (*register_appl)(struct capi_ctr *ctrlr, u16 applid,
capi_register_params *rparam)
void (*release_appl)(struct capi_ctr *ctrlr, u16 applid)
pointers to callback functions for registration and deregistration of
applications with the device
u16 (*send_message)(struct capi_ctr *ctrlr, struct sk_buff *skb)
pointer to a callback function for sending a CAPI message to the
device
char *(*procinfo)(struct capi_ctr *ctrlr)
pointer to a callback function returning the entry for the device in
the CAPI controller info table, /proc/capi/controller
read_proc_t *ctr_read_proc
pointer to the read_proc callback function for the device's proc file
system entry, /proc/capi/controllers/<n>; will be called with a
pointer to the device's capi_ctr structure as the last (data) argument
- to be filled in before calling capi_ctr_ready():
u8 manu[CAPI_MANUFACTURER_LEN]
value to return for CAPI_GET_MANUFACTURER
capi_version version
value to return for CAPI_GET_VERSION
capi_profile profile
value to return for CAPI_GET_PROFILE
u8 serial[CAPI_SERIAL_LEN]
value to return for CAPI_GET_SERIAL
5. Lower Layer Interface Functions
(declared in <linux/isdn/capilli.h>)
void register_capi_driver(struct capi_driver *drvr)
void unregister_capi_driver(struct capi_driver *drvr)
register/unregister a driver with Kernel CAPI
int attach_capi_ctr(struct capi_ctr *ctrlr)
int detach_capi_ctr(struct capi_ctr *ctrlr)
register/unregister a device (controller) with Kernel CAPI
void capi_ctr_ready(struct capi_ctr *ctrlr)
void capi_ctr_reseted(struct capi_ctr *ctrlr)
signal controller ready/not ready
void capi_ctr_suspend_output(struct capi_ctr *ctrlr)
void capi_ctr_resume_output(struct capi_ctr *ctrlr)
signal suspend/resume
void capi_ctr_handle_message(struct capi_ctr * ctrlr, u16 applid,
struct sk_buff *skb)
pass a received CAPI message to Kernel CAPI
for forwarding to the specified application
6. Helper Functions and Macros
Library functions (from <linux/isdn/capilli.h>):
void capilib_new_ncci(struct list_head *head, u16 applid,
u32 ncci, u32 winsize)
void capilib_free_ncci(struct list_head *head, u16 applid, u32 ncci)
void capilib_release_appl(struct list_head *head, u16 applid)
void capilib_release(struct list_head *head)
void capilib_data_b3_conf(struct list_head *head, u16 applid,
u32 ncci, u16 msgid)
u16 capilib_data_b3_req(struct list_head *head, u16 applid,
u32 ncci, u16 msgid)
Macros to extract/set element values from/in a CAPI message header
(from <linux/isdn/capiutil.h>):
Get Macro Set Macro Element (Type)
CAPIMSG_LEN(m) CAPIMSG_SETLEN(m, len) Total Length (u16)
CAPIMSG_APPID(m) CAPIMSG_SETAPPID(m, applid) ApplID (u16)
CAPIMSG_COMMAND(m) CAPIMSG_SETCOMMAND(m,cmd) Command (u8)
CAPIMSG_SUBCOMMAND(m) CAPIMSG_SETSUBCOMMAND(m, cmd) Subcommand (u8)
CAPIMSG_CMD(m) - Command*256
+ Subcommand (u16)
CAPIMSG_MSGID(m) CAPIMSG_SETMSGID(m, msgid) Message Number (u16)
CAPIMSG_CONTROL(m) CAPIMSG_SETCONTROL(m, contr) Controller/PLCI/NCCI
(u32)
CAPIMSG_DATALEN(m) CAPIMSG_SETDATALEN(m, len) Data Length (u16)

View File

@ -269,7 +269,10 @@ Use the argument mechanism to document members or constants.
Inside a struct description, you can use the "private:" and "public:"
comment tags. Structure fields that are inside a "private:" area
are not listed in the generated output documentation.
are not listed in the generated output documentation. The "private:"
and "public:" tags must begin immediately following a "/*" comment
marker. They may optionally include comments between the ":" and the
ending "*/" marker.
Example:
@ -283,7 +286,7 @@ Example:
struct my_struct {
int a;
int b;
/* private: */
/* private: internal use only */
int c;
};

View File

@ -1620,6 +1620,8 @@ and is between 256 and 4096 characters. It is defined in the file
nowb [ARM]
nox2apic [X86-64,APIC] Do not enable x2APIC mode.
nptcg= [IA64] Override max number of concurrent global TLB
purges which is reported from either PAL_VM_SUMMARY or
SAL PALO.

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 303 KiB

View File

@ -1,4 +1,13 @@
Tux is taking a three month sabbatical to work as a barber, so Tuz is
standing in. He's taken pains to ensure you'll hardly notice.
This is the full-colour version of the currently unofficial Linux logo
("currently unofficial" just means that there has been no paperwork and
that I have not really announced it yet). It was created by Larry Ewing,
and is freely usable as long as you acknowledge Larry as the original
artist.
Note that there are black-and-white versions of this available that
scale down to smaller sizes and are better for letterheads or whatever
you want to use it for: for the full range of logos take a look at
Larry's web-page:
http://www.isc.tamu.edu/~lewing/linux/
Image by Andrew McGown and Josh Bush. Image is licensed CC BY-SA.

View File

@ -90,6 +90,10 @@ will itself start writeback.
If dirty_bytes is written, dirty_ratio becomes a function of its value
(dirty_bytes / the amount of dirtyable system memory).
Note: the minimum value allowed for dirty_bytes is two pages (in bytes); any
value lower than this limit will be ignored and the old configuration will be
retained.
==============================================================
dirty_expire_centisecs

View File

@ -3448,7 +3448,7 @@ P: Matt Porter
M: mporter@kernel.crashing.org
W: http://www.penguinppc.org/
L: linuxppc-dev@ozlabs.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jwboyer/powerpc.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jwboyer/powerpc-4xx.git
S: Maintained
LINUX FOR POWERPC EMBEDDED XILINX VIRTEX
@ -4189,7 +4189,7 @@ P: Joel Becker
M: joel.becker@oracle.com
L: ocfs2-devel@oss.oracle.com (moderated for non-subscribers)
W: http://oss.oracle.com/projects/ocfs2/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2.git
S: Supported
F: Documentation/filesystems/ocfs2.txt
F: Documentation/filesystems/dlmfs.txt
@ -4521,6 +4521,19 @@ M: jim@jtan.com
L: cbe-oss-dev@ozlabs.org
S: Maintained
PTRACE SUPPORT
P: Roland McGrath
M: roland@redhat.com
P: Oleg Nesterov
M: oleg@redhat.com
L: linux-kernel@vger.kernel.org
S: Maintained
F: include/asm-generic/syscall.h
F: include/linux/ptrace.h
F: include/linux/regset.h
F: include/linux/tracehook.h
F: kernel/ptrace.c
PVRUSB2 VIDEO4LINUX DRIVER
P: Mike Isely
M: isely@pobox.com
@ -4666,13 +4679,13 @@ F: kernel/rcutorture.c
RDC R-321X SoC
P: Florian Fainelli
M: florian.fainelli@telecomint.eu
M: florian@openwrt.org
L: linux-kernel@vger.kernel.org
S: Maintained
RDC R6040 FAST ETHERNET DRIVER
P: Florian Fainelli
M: florian.fainelli@telecomint.eu
M: florian@openwrt.org
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/r6040.c

View File

@ -1,8 +1,8 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 30
EXTRAVERSION = -rc3
NAME = Temporary Tasmanian Devil
EXTRAVERSION = -rc4
NAME = Vindictive Armadillo
# *DOCUMENTATION*
# To see a list of typical targets execute "make help"
@ -1293,7 +1293,7 @@ help:
@echo ' dir/ - Build all files in dir and below'
@echo ' dir/file.[ois] - Build specified target only'
@echo ' dir/file.ko - Build module including final link'
@echo ' prepare - Set up for building external modules'
@echo ' modules_prepare - Set up for building external modules'
@echo ' tags/TAGS - Generate tags file for editors'
@echo ' cscope - Generate cscope index'
@echo ' kernelrelease - Output the release version string'
@ -1421,7 +1421,9 @@ $(clean-dirs):
$(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@)
clean: rm-dirs := $(MODVERDIR)
clean: rm-files := $(KBUILD_EXTMOD)/Module.symvers
clean: rm-files := $(KBUILD_EXTMOD)/Module.symvers \
$(KBUILD_EXTMOD)/Module.markers \
$(KBUILD_EXTMOD)/modules.order
clean: $(clean-dirs)
$(call cmd,rmdirs)
$(call cmd,rmfiles)

View File

@ -16,11 +16,13 @@ __asm__ __volatile__("wmb": : :"memory")
__asm__ __volatile__("mb": : :"memory")
#ifdef CONFIG_SMP
#define __ASM_SMP_MB "\tmb\n"
#define smp_mb() mb()
#define smp_rmb() rmb()
#define smp_wmb() wmb()
#define smp_read_barrier_depends() read_barrier_depends()
#else
#define __ASM_SMP_MB
#define smp_mb() barrier()
#define smp_rmb() barrier()
#define smp_wmb() barrier()

View File

@ -1,6 +1,116 @@
#ifndef _ASM_FUTEX_H
#define _ASM_FUTEX_H
#ifndef _ASM_ALPHA_FUTEX_H
#define _ASM_ALPHA_FUTEX_H
#include <asm-generic/futex.h>
#ifdef __KERNEL__
#endif
#include <linux/futex.h>
#include <linux/uaccess.h>
#include <asm/errno.h>
#include <asm/barrier.h>
#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
__asm__ __volatile__( \
__ASM_SMP_MB \
"1: ldl_l %0,0(%2)\n" \
insn \
"2: stl_c %1,0(%2)\n" \
" beq %1,4f\n" \
" mov $31,%1\n" \
"3: .subsection 2\n" \
"4: br 1b\n" \
" .previous\n" \
" .section __ex_table,\"a\"\n" \
" .long 1b-.\n" \
" lda $31,3b-1b(%1)\n" \
" .long 2b-.\n" \
" lda $31,3b-2b(%1)\n" \
" .previous\n" \
: "=&r" (oldval), "=&r"(ret) \
: "r" (uaddr), "r"(oparg) \
: "memory")
static inline int futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
{
int op = (encoded_op >> 28) & 7;
int cmp = (encoded_op >> 24) & 15;
int oparg = (encoded_op << 8) >> 20;
int cmparg = (encoded_op << 20) >> 20;
int oldval = 0, ret;
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
oparg = 1 << oparg;
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
return -EFAULT;
pagefault_disable();
switch (op) {
case FUTEX_OP_SET:
__futex_atomic_op("mov %3,%1\n", ret, oldval, uaddr, oparg);
break;
case FUTEX_OP_ADD:
__futex_atomic_op("addl %0,%3,%1\n", ret, oldval, uaddr, oparg);
break;
case FUTEX_OP_OR:
__futex_atomic_op("or %0,%3,%1\n", ret, oldval, uaddr, oparg);
break;
case FUTEX_OP_ANDN:
__futex_atomic_op("andnot %0,%3,%1\n", ret, oldval, uaddr, oparg);
break;
case FUTEX_OP_XOR:
__futex_atomic_op("xor %0,%3,%1\n", ret, oldval, uaddr, oparg);
break;
default:
ret = -ENOSYS;
}
pagefault_enable();
if (!ret) {
switch (cmp) {
case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
default: ret = -ENOSYS;
}
}
return ret;
}
static inline int
futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
{
int prev, cmp;
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
return -EFAULT;
__asm__ __volatile__ (
__ASM_SMP_MB
"1: ldl_l %0,0(%2)\n"
" cmpeq %0,%3,%1\n"
" beq %1,3f\n"
" mov %4,%1\n"
"2: stl_c %1,0(%2)\n"
" beq %1,4f\n"
"3: .subsection 2\n"
"4: br 1b\n"
" .previous\n"
" .section __ex_table,\"a\"\n"
" .long 1b-.\n"
" lda $31,3b-1b(%0)\n"
" .long 2b-.\n"
" lda $31,3b-2b(%0)\n"
" .previous\n"
: "=&r"(prev), "=&r"(cmp)
: "r"(uaddr), "r"((long)oldval), "r"(newval)
: "memory");
return prev;
}
#endif /* __KERNEL__ */
#endif /* _ASM_ALPHA_FUTEX_H */

View File

@ -507,5 +507,7 @@ struct exception_table_entry
(pc) + (_fixup)->fixup.bits.nextinsn; \
})
#define ARCH_HAS_SORT_EXTABLE
#define ARCH_HAS_SEARCH_EXTABLE
#endif /* __ALPHA_UACCESS_H */

View File

@ -8,7 +8,7 @@ EXTRA_CFLAGS := -Werror -Wno-sign-compare
obj-y := entry.o traps.o process.o init_task.o osf_sys.o irq.o \
irq_alpha.o signal.o setup.o ptrace.o time.o \
alpha_ksyms.o systbls.o err_common.o io.o binfmt_loader.o
alpha_ksyms.o systbls.o err_common.o io.o
obj-$(CONFIG_VGA_HOSE) += console.o
obj-$(CONFIG_SMP) += smp.o
@ -43,6 +43,10 @@ else
# Misc support
obj-$(CONFIG_ALPHA_SRM) += srmcons.o
ifdef CONFIG_BINFMT_AOUT
obj-y += binfmt_loader.o
endif
# Core logic support
obj-$(CONFIG_ALPHA_APECS) += core_apecs.o
obj-$(CONFIG_ALPHA_CIA) += core_cia.o

View File

@ -46,6 +46,6 @@ static struct linux_binfmt loader_format = {
static int __init init_loader_binfmt(void)
{
return register_binfmt(&loader_format);
return insert_binfmt(&loader_format);
}
arch_initcall(init_loader_binfmt);

View File

@ -229,7 +229,7 @@ ev6_process_logout_frame(struct el_common *mchk_header, int print)
}
void
ev6_machine_check(u64 vector, u64 la_ptr)
ev6_machine_check(unsigned long vector, unsigned long la_ptr)
{
struct el_common *mchk_header = (struct el_common *)la_ptr;

View File

@ -117,7 +117,7 @@ ev7_collect_logout_frame_subpackets(struct el_subpacket *el_ptr,
}
void
ev7_machine_check(u64 vector, u64 la_ptr)
ev7_machine_check(unsigned long vector, unsigned long la_ptr)
{
struct el_subpacket *el_ptr = (struct el_subpacket *)la_ptr;
char *saved_err_prefix = err_print_prefix;
@ -246,7 +246,7 @@ ev7_process_pal_subpacket(struct el_subpacket *header)
switch(header->type) {
case EL_TYPE__PAL__LOGOUT_FRAME:
printk("%s*** MCHK occurred on LPID %ld (RBOX %llx)\n",
printk("%s*** MCHK occurred on LPID %lld (RBOX %llx)\n",
err_print_prefix,
packet->by_type.logout.whami,
packet->by_type.logout.rbox_whami);

View File

@ -60,26 +60,26 @@ extern struct ev7_lf_subpackets *
ev7_collect_logout_frame_subpackets(struct el_subpacket *,
struct ev7_lf_subpackets *);
extern void ev7_register_error_handlers(void);
extern void ev7_machine_check(u64, u64);
extern void ev7_machine_check(unsigned long, unsigned long);
/*
* err_ev6.c
*/
extern void ev6_register_error_handlers(void);
extern int ev6_process_logout_frame(struct el_common *, int);
extern void ev6_machine_check(u64, u64);
extern void ev6_machine_check(unsigned long, unsigned long);
/*
* err_marvel.c
*/
extern void marvel_machine_check(u64, u64);
extern void marvel_machine_check(unsigned long, unsigned long);
extern void marvel_register_error_handlers(void);
/*
* err_titan.c
*/
extern int titan_process_logout_frame(struct el_common *, int);
extern void titan_machine_check(u64, u64);
extern void titan_machine_check(unsigned long, unsigned long);
extern void titan_register_error_handlers(void);
extern int privateer_process_logout_frame(struct el_common *, int);
extern void privateer_machine_check(u64, u64);
extern void privateer_machine_check(unsigned long, unsigned long);

View File

@ -1042,7 +1042,7 @@ marvel_process_logout_frame(struct ev7_lf_subpackets *lf_subpackets, int print)
}
void
marvel_machine_check(u64 vector, u64 la_ptr)
marvel_machine_check(unsigned long vector, unsigned long la_ptr)
{
struct el_subpacket *el_ptr = (struct el_subpacket *)la_ptr;
int (*process_frame)(struct ev7_lf_subpackets *, int) = NULL;

View File

@ -380,7 +380,7 @@ titan_process_logout_frame(struct el_common *mchk_header, int print)
}
void
titan_machine_check(u64 vector, u64 la_ptr)
titan_machine_check(unsigned long vector, unsigned long la_ptr)
{
struct el_common *mchk_header = (struct el_common *)la_ptr;
struct el_TITAN_sysdata_mcheck *tmchk =
@ -702,7 +702,7 @@ privateer_process_logout_frame(struct el_common *mchk_header, int print)
}
void
privateer_machine_check(u64 vector, u64 la_ptr)
privateer_machine_check(unsigned long vector, unsigned long la_ptr)
{
struct el_common *mchk_header = (struct el_common *)la_ptr;
struct el_TITAN_sysdata_mcheck *tmchk =

View File

@ -7,10 +7,11 @@
* the kernel global pointer and jump to the kernel entry-point.
*/
#include <linux/init.h>
#include <asm/system.h>
#include <asm/asm-offsets.h>
.section .text.head, "ax"
__HEAD
.globl swapper_pg_dir
.globl _stext
swapper_pg_dir=SWAPPER_PGD

View File

@ -36,7 +36,6 @@ extern void cia_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
extern struct pci_ops irongate_pci_ops;
extern int irongate_pci_clr_err(void);
extern void irongate_init_arch(void);
extern void irongate_machine_check(u64, u64);
#define irongate_pci_tbi ((void *)0)
/* core_lca.c */
@ -49,7 +48,7 @@ extern void lca_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
extern struct pci_ops marvel_pci_ops;
extern void marvel_init_arch(void);
extern void marvel_kill_arch(int);
extern void marvel_machine_check(u64, u64);
extern void marvel_machine_check(unsigned long, unsigned long);
extern void marvel_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
extern int marvel_pa_to_nid(unsigned long);
extern int marvel_cpuid_to_nid(int);
@ -86,7 +85,7 @@ extern void t2_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
extern struct pci_ops titan_pci_ops;
extern void titan_init_arch(void);
extern void titan_kill_arch(int);
extern void titan_machine_check(u64, u64);
extern void titan_machine_check(unsigned long, unsigned long);
extern void titan_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
extern struct _alpha_agp_info *titan_agp_info(void);

View File

@ -16,7 +16,7 @@ SECTIONS
_text = .; /* Text and read-only data */
.text : {
*(.text.head)
HEAD_TEXT
TEXT_TEXT
SCHED_TEXT
LOCK_TEXT

View File

@ -3,11 +3,49 @@
*/
#include <linux/module.h>
#include <linux/sort.h>
#include <asm/uaccess.h>
static inline unsigned long ex_to_addr(const struct exception_table_entry *x)
{
return (unsigned long)&x->insn + x->insn;
}
static void swap_ex(void *a, void *b, int size)
{
struct exception_table_entry *ex_a = a, *ex_b = b;
unsigned long addr_a = ex_to_addr(ex_a), addr_b = ex_to_addr(ex_b);
unsigned int t = ex_a->fixup.unit;
ex_a->fixup.unit = ex_b->fixup.unit;
ex_b->fixup.unit = t;
ex_a->insn = (int)(addr_b - (unsigned long)&ex_a->insn);
ex_b->insn = (int)(addr_a - (unsigned long)&ex_b->insn);
}
/*
* The exception table needs to be sorted so that the binary
* search that we use to find entries in it works properly.
* This is used both for the kernel exception table and for
* the exception tables of modules that get loaded.
*/
static int cmp_ex(const void *a, const void *b)
{
const struct exception_table_entry *x = a, *y = b;
/* avoid overflow */
if (ex_to_addr(x) > ex_to_addr(y))
return 1;
if (ex_to_addr(x) < ex_to_addr(y))
return -1;
return 0;
}
void sort_extable(struct exception_table_entry *start,
struct exception_table_entry *finish)
{
sort(start, finish - start, sizeof(struct exception_table_entry),
cmp_ex, swap_ex);
}
const struct exception_table_entry *
@ -20,7 +58,7 @@ search_extable(const struct exception_table_entry *first,
unsigned long mid_value;
mid = (last - first) / 2 + first;
mid_value = (unsigned long)&mid->insn + mid->insn;
mid_value = ex_to_addr(mid);
if (mid_value == value)
return mid;
else if (mid_value < value)

View File

@ -299,6 +299,7 @@ config ARCH_MXC
select ARCH_MTD_XIP
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
select HAVE_CLK
help
Support for Freescale MXC/iMX-based family of processors
@ -318,15 +319,6 @@ config ARCH_H720X
help
This enables support for systems based on the Hynix HMS720x
config ARCH_IMX
bool "IMX"
select CPU_ARM920T
select GENERIC_GPIO
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
help
Support for Motorola's i.MX family of processors (MX1, MXL).
config ARCH_IOP13XX
bool "IOP13xx-based"
depends on MMU
@ -507,8 +499,6 @@ config ARCH_PXA
select HAVE_CLK
select COMMON_CLKDEV
select ARCH_REQUIRE_GPIOLIB
select HAVE_CLK
select COMMON_CLKDEV
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select TICK_ONESHOT
@ -603,6 +593,8 @@ config ARCH_DAVINCI
select ARCH_REQUIRE_GPIOLIB
select HAVE_CLK
select ZONE_DMA
select HAVE_IDE
select COMMON_CLKDEV
help
Support for TI's DaVinci platform.
@ -681,8 +673,6 @@ endif
source "arch/arm/mach-lh7a40x/Kconfig"
source "arch/arm/mach-imx/Kconfig"
source "arch/arm/mach-h720x/Kconfig"
source "arch/arm/mach-versatile/Kconfig"
@ -740,6 +730,56 @@ if !MMU
source "arch/arm/Kconfig-nommu"
endif
config ARM_ERRATA_411920
bool "ARM errata: Invalidation of the Instruction Cache operation can fail"
depends on CPU_V6 && !SMP
help
Invalidation of the Instruction Cache operation can
fail. This erratum is present in 1136 (before r1p4), 1156 and 1176.
It does not affect the MPCore. This option enables the ARM Ltd.
recommended workaround.
config ARM_ERRATA_430973
bool "ARM errata: Stale prediction on replaced interworking branch"
depends on CPU_V7
help
This option enables the workaround for the 430973 Cortex-A8
(r1p0..r1p2) erratum. If a code sequence containing an ARM/Thumb
interworking branch is replaced with another code sequence at the
same virtual address, whether due to self-modifying code or virtual
to physical address re-mapping, Cortex-A8 does not recover from the
stale interworking branch prediction. This results in Cortex-A8
executing the new code sequence in the incorrect ARM or Thumb state.
The workaround enables the BTB/BTAC operations by setting ACTLR.IBE
and also flushes the branch target cache at every context switch.
Note that setting specific bits in the ACTLR register may not be
available in non-secure mode.
config ARM_ERRATA_458693
bool "ARM errata: Processor deadlock when a false hazard is created"
depends on CPU_V7
help
This option enables the workaround for the 458693 Cortex-A8 (r2p0)
erratum. For very specific sequences of memory operations, it is
possible for a hazard condition intended for a cache line to instead
be incorrectly associated with a different cache line. This false
hazard might then cause a processor deadlock. The workaround enables
the L1 caching of the NEON accesses and disables the PLD instruction
in the ACTLR register. Note that setting specific bits in the ACTLR
register may not be available in non-secure mode.
config ARM_ERRATA_460075
bool "ARM errata: Data written to the L2 cache can be overwritten with stale data"
depends on CPU_V7
help
This option enables the workaround for the 460075 Cortex-A8 (r2p0)
erratum. Any asynchronous access to the L2 cache may encounter a
situation in which recent store transactions to the L2 cache are lost
and overwritten with stale memory contents from external memory. The
workaround disables the write-allocate mode for the L2 cache via the
ACTLR register. Note that setting specific bits in the ACTLR register
may not be available in non-secure mode.
endmenu
source "arch/arm/common/Kconfig"
@ -971,7 +1011,7 @@ source "mm/Kconfig"
config LEDS
bool "Timer and CPU usage LEDs"
depends on ARCH_CDB89712 || ARCH_EBSA110 || \
ARCH_EBSA285 || ARCH_IMX || ARCH_INTEGRATOR || \
ARCH_EBSA285 || ARCH_INTEGRATOR || \
ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_NETWINDER || \
ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \
ARCH_SA1100 || ARCH_SHARK || ARCH_VERSATILE || \
@ -1137,7 +1177,7 @@ endmenu
menu "CPU Power Management"
if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_PXA)
if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_PXA)
source "drivers/cpufreq/Kconfig"
@ -1162,15 +1202,6 @@ config CPU_FREQ_INTEGRATOR
If in doubt, say Y.
config CPU_FREQ_IMX
tristate "CPUfreq driver for i.MX CPUs"
depends on ARCH_IMX && CPU_FREQ
default n
help
This enables the CPUfreq driver for i.MX CPUs.
If in doubt, say N.
config CPU_FREQ_PXA
bool
depends on CPU_FREQ && ARCH_PXA && PXA25x

View File

@ -115,7 +115,6 @@ machine-$(CONFIG_ARCH_EBSA110) := ebsa110
machine-$(CONFIG_ARCH_EP93XX) := ep93xx
machine-$(CONFIG_ARCH_GEMINI) := gemini
machine-$(CONFIG_ARCH_H720X) := h720x
machine-$(CONFIG_ARCH_IMX) := imx
machine-$(CONFIG_ARCH_INTEGRATOR) := integrator
machine-$(CONFIG_ARCH_IOP13XX) := iop13xx
machine-$(CONFIG_ARCH_IOP32X) := iop32x

File diff suppressed because it is too large Load Diff

View File

@ -197,7 +197,7 @@ CONFIG_MXC_PWM=y
#
CONFIG_CPU_32=y
CONFIG_CPU_V6=y
CONFIG_CPU_32v6K=y
# CONFIG_CPU_32v6K is not set
CONFIG_CPU_32v6=y
CONFIG_CPU_ABRT_EV6=y
CONFIG_CPU_PABRT_NOIFAR=y

View File

@ -298,7 +298,6 @@ CONFIG_CPU_FREQ_GOV_POWERSAVE=m
CONFIG_CPU_FREQ_GOV_USERSPACE=m
CONFIG_CPU_FREQ_GOV_ONDEMAND=m
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
CONFIG_CPU_FREQ_PXA=y
#
# Floating point emulation

View File

@ -4,19 +4,56 @@ menu "TI DaVinci Implementations"
comment "DaVinci Core Type"
config ARCH_DAVINCI644x
default y
config ARCH_DAVINCI_DM644x
bool "DaVinci 644x based system"
comment "DaVinci Board Type"
config MACH_DAVINCI_EVM
bool "TI DaVinci EVM"
bool "TI DM644x EVM"
default y
depends on ARCH_DAVINCI644x
depends on ARCH_DAVINCI_DM644x
help
Configure this option to specify the whether the board used
for development is a DaVinci EVM
for development is a DM644x EVM
config DAVINCI_MUX
bool "DAVINCI multiplexing support"
depends on ARCH_DAVINCI
default y
help
Pin multiplexing support for DAVINCI boards. If your bootloader
sets the multiplexing correctly, say N. Otherwise, or if unsure,
say Y.
config DAVINCI_MUX_DEBUG
bool "Multiplexing debug output"
depends on DAVINCI_MUX
help
Makes the multiplexing functions print out a lot of debug info.
This is useful if you want to find out the correct values of the
multiplexing registers.
config DAVINCI_MUX_WARNINGS
bool "Warn about pins the bootloader didn't set up"
depends on DAVINCI_MUX
help
Choose Y here to warn whenever driver initialization logic needs
to change the pin multiplexing setup. When there are no warnings
printed, it's safe to deselect DAVINCI_MUX for your product.
config DAVINCI_RESET_CLOCKS
bool "Reset unused clocks during boot"
depends on ARCH_DAVINCI
help
Say Y if you want to reset unused clocks during boot.
This option saves power, but assumes all drivers are
using the clock framework. Broken drivers that do not
yet use clock framework may not work with this option.
If you are booting from another operating system, you
probably do not want this option enabled until your
device drivers work properly.
endmenu

View File

@ -5,7 +5,12 @@
# Common objects
obj-y := time.o irq.o clock.o serial.o io.o id.o psc.o \
gpio.o mux.o devices.o usb.o
gpio.o devices.o dma.o usb.o
obj-$(CONFIG_DAVINCI_MUX) += mux.o
# Chip specific
obj-$(CONFIG_ARCH_DAVINCI_DM644x) += dm644x.o
# Board specific
obj-$(CONFIG_MACH_DAVINCI_EVM) += board-evm.o
obj-$(CONFIG_MACH_DAVINCI_EVM) += board-dm644x-evm.o

View File

@ -15,15 +15,20 @@
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/leds.h>
#include <linux/memory.h>
#include <linux/etherdevice.h>
#include <linux/i2c.h>
#include <linux/i2c/pcf857x.h>
#include <linux/i2c/at24.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/io.h>
#include <linux/phy.h>
#include <linux/clk.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
@ -32,25 +37,34 @@
#include <asm/mach/map.h>
#include <asm/mach/flash.h>
#include <mach/hardware.h>
#include <mach/dm644x.h>
#include <mach/common.h>
#include <mach/i2c.h>
#include <mach/serial.h>
#include <mach/mux.h>
#include <mach/psc.h>
#include <mach/nand.h>
/* other misc. init functions */
void __init davinci_psc_init(void);
void __init davinci_irq_init(void);
void __init davinci_map_common_io(void);
void __init davinci_init_common_hw(void);
#define DM644X_EVM_PHY_MASK (0x2)
#define DM644X_EVM_MDIO_FREQUENCY (2200000) /* PHY bus frequency */
#if defined(CONFIG_MTD_PHYSMAP) || \
defined(CONFIG_MTD_PHYSMAP_MODULE)
#define DAVINCI_CFC_ATA_BASE 0x01C66000
#define DAVINCI_ASYNC_EMIF_CONTROL_BASE 0x01e00000
#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
#define DAVINCI_ASYNC_EMIF_DATA_CE1_BASE 0x04000000
#define DAVINCI_ASYNC_EMIF_DATA_CE2_BASE 0x06000000
#define DAVINCI_ASYNC_EMIF_DATA_CE3_BASE 0x08000000
#define LXT971_PHY_ID (0x001378e2)
#define LXT971_PHY_MASK (0xfffffff0)
static struct mtd_partition davinci_evm_norflash_partitions[] = {
/* bootloader (U-Boot, etc) in first 4 sectors */
/* bootloader (UBL, U-Boot, etc) in first 5 sectors */
{
.name = "bootloader",
.offset = 0,
.size = 4 * SZ_64K,
.size = 5 * SZ_64K,
.mask_flags = MTD_WRITEABLE, /* force read-only */
},
/* bootloader params in the next 1 sectors */
@ -100,10 +114,89 @@ static struct platform_device davinci_evm_norflash_device = {
.resource = &davinci_evm_norflash_resource,
};
#endif
/* DM644x EVM includes a 64 MByte small-page NAND flash (16K blocks).
* It may used instead of the (default) NOR chip to boot, using TI's
* tools to install the secondary boot loader (UBL) and U-Boot.
*/
struct mtd_partition davinci_evm_nandflash_partition[] = {
/* Bootloader layout depends on whose u-boot is installed, but we
* can hide all the details.
* - block 0 for u-boot environment ... in mainline u-boot
* - block 1 for UBL (plus up to four backup copies in blocks 2..5)
* - blocks 6...? for u-boot
* - blocks 16..23 for u-boot environment ... in TI's u-boot
*/
{
.name = "bootloader",
.offset = 0,
.size = SZ_256K + SZ_128K,
.mask_flags = MTD_WRITEABLE, /* force read-only */
},
/* Kernel */
{
.name = "kernel",
.offset = MTDPART_OFS_APPEND,
.size = SZ_4M,
.mask_flags = 0,
},
/* File system (older GIT kernels started this on the 5MB mark) */
{
.name = "filesystem",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
.mask_flags = 0,
}
/* A few blocks at end hold a flash BBT ... created by TI's CCS
* using flashwriter_nand.out, but ignored by TI's versions of
* Linux and u-boot. We boot faster by using them.
*/
};
#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
static struct davinci_nand_pdata davinci_evm_nandflash_data = {
.parts = davinci_evm_nandflash_partition,
.nr_parts = ARRAY_SIZE(davinci_evm_nandflash_partition),
.ecc_mode = NAND_ECC_HW,
.options = NAND_USE_FLASH_BBT,
};
static struct resource davinci_evm_nandflash_resource[] = {
{
.start = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE,
.end = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1,
.flags = IORESOURCE_MEM,
}, {
.start = DAVINCI_ASYNC_EMIF_CONTROL_BASE,
.end = DAVINCI_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device davinci_evm_nandflash_device = {
.name = "davinci_nand",
.id = 0,
.dev = {
.platform_data = &davinci_evm_nandflash_data,
},
.num_resources = ARRAY_SIZE(davinci_evm_nandflash_resource),
.resource = davinci_evm_nandflash_resource,
};
static u64 davinci_fb_dma_mask = DMA_BIT_MASK(32);
static struct platform_device davinci_fb_device = {
.name = "davincifb",
.id = -1,
.dev = {
.dma_mask = &davinci_fb_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = 0,
};
static struct platform_device rtc_dev = {
.name = "rtc_davinci_evm",
.id = -1,
};
static struct resource ide_resources[] = {
{
@ -118,7 +211,7 @@ static struct resource ide_resources[] = {
},
};
static u64 ide_dma_mask = DMA_BIT_MASK(32);
static u64 ide_dma_mask = DMA_32BIT_MASK;
static struct platform_device ide_dev = {
.name = "palm_bk3710",
@ -127,12 +220,10 @@ static struct platform_device ide_dev = {
.num_resources = ARRAY_SIZE(ide_resources),
.dev = {
.dma_mask = &ide_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.coherent_dma_mask = DMA_32BIT_MASK,
},
};
#endif
/*----------------------------------------------------------------------*/
/*
@ -311,7 +402,9 @@ evm_u35_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
gpio_request(gpio + 7, "nCF_SEL");
gpio_direction_output(gpio + 7, 1);
/* irlml6401 sustains over 3A, switches 5V in under 8 msec */
/* irlml6401 switches over 1A, in under 8 msec;
* now it can be managed by nDRV_VBUS ...
*/
setup_usb(500, 8);
return 0;
@ -343,13 +436,119 @@ static struct pcf857x_platform_data pcf_data_u35 = {
* - 0x0039, 1 byte NTSC vs PAL (bit 0x80 == PAL)
* - ... newer boards may have more
*/
static struct memory_accessor *at24_mem_acc;
static void at24_setup(struct memory_accessor *mem_acc, void *context)
{
DECLARE_MAC_BUF(mac_str);
char mac_addr[6];
at24_mem_acc = mem_acc;
/* Read MAC addr from EEPROM */
if (at24_mem_acc->read(at24_mem_acc, mac_addr, 0x7f00, 6) == 6) {
printk(KERN_INFO "Read MAC addr from EEPROM: %s\n",
print_mac(mac_str, mac_addr));
}
}
static struct at24_platform_data eeprom_info = {
.byte_len = (256*1024) / 8,
.page_size = 64,
.flags = AT24_FLAG_ADDR16,
.setup = at24_setup,
};
int dm6446evm_eeprom_read(void *buf, off_t off, size_t count)
{
if (at24_mem_acc)
return at24_mem_acc->read(at24_mem_acc, buf, off, count);
return -ENODEV;
}
EXPORT_SYMBOL(dm6446evm_eeprom_read);
int dm6446evm_eeprom_write(void *buf, off_t off, size_t count)
{
if (at24_mem_acc)
return at24_mem_acc->write(at24_mem_acc, buf, off, count);
return -ENODEV;
}
EXPORT_SYMBOL(dm6446evm_eeprom_write);
/*
* MSP430 supports RTC, card detection, input from IR remote, and
* a bit more. It triggers interrupts on GPIO(7) from pressing
* buttons on the IR remote, and for card detect switches.
*/
static struct i2c_client *dm6446evm_msp;
static int dm6446evm_msp_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
dm6446evm_msp = client;
return 0;
}
static int dm6446evm_msp_remove(struct i2c_client *client)
{
dm6446evm_msp = NULL;
return 0;
}
static const struct i2c_device_id dm6446evm_msp_ids[] = {
{ "dm6446evm_msp", 0, },
{ /* end of list */ },
};
static struct i2c_driver dm6446evm_msp_driver = {
.driver.name = "dm6446evm_msp",
.id_table = dm6446evm_msp_ids,
.probe = dm6446evm_msp_probe,
.remove = dm6446evm_msp_remove,
};
static int dm6444evm_msp430_get_pins(void)
{
static const char txbuf[2] = { 2, 4, };
char buf[4];
struct i2c_msg msg[2] = {
{
.addr = dm6446evm_msp->addr,
.flags = 0,
.len = 2,
.buf = (void __force *)txbuf,
},
{
.addr = dm6446evm_msp->addr,
.flags = I2C_M_RD,
.len = 4,
.buf = buf,
},
};
int status;
if (!dm6446evm_msp)
return -ENXIO;
/* Command 4 == get input state, returns port 2 and port3 data
* S Addr W [A] len=2 [A] cmd=4 [A]
* RS Addr R [A] [len=4] A [cmd=4] A [port2] A [port3] N P
*/
status = i2c_transfer(dm6446evm_msp->adapter, msg, 2);
if (status < 0)
return status;
dev_dbg(&dm6446evm_msp->dev,
"PINS: %02x %02x %02x %02x\n",
buf[0], buf[1], buf[2], buf[3]);
return (buf[3] << 8) | buf[2];
}
static struct i2c_board_info __initdata i2c_info[] = {
{
I2C_BOARD_INFO("dm6446evm_msp", 0x23),
},
{
I2C_BOARD_INFO("pcf8574", 0x38),
.platform_data = &pcf_data_u2,
@ -368,7 +567,6 @@ static struct i2c_board_info __initdata i2c_info[] = {
},
/* ALSO:
* - tvl320aic33 audio codec (0x1b)
* - msp430 microcontroller (0x23)
* - tvp5146 video decoder (0x5d)
*/
};
@ -384,51 +582,109 @@ static struct davinci_i2c_platform_data i2c_pdata = {
static void __init evm_init_i2c(void)
{
davinci_init_i2c(&i2c_pdata);
i2c_add_driver(&dm6446evm_msp_driver);
i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));
}
static struct platform_device *davinci_evm_devices[] __initdata = {
#if defined(CONFIG_MTD_PHYSMAP) || \
defined(CONFIG_MTD_PHYSMAP_MODULE)
&davinci_evm_norflash_device,
#endif
#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
&ide_dev,
#endif
&davinci_fb_device,
&rtc_dev,
};
static struct davinci_uart_config uart_config __initdata = {
.enabled_uarts = (1 << 0),
};
static void __init
davinci_evm_map_io(void)
{
davinci_map_common_io();
dm644x_init();
}
static __init void davinci_evm_init(void)
static int davinci_phy_fixup(struct phy_device *phydev)
{
davinci_psc_init();
unsigned int control;
/* CRITICAL: Fix for increasing PHY signal drive strength for
* TX lockup issue. On DaVinci EVM, the Intel LXT971 PHY
* signal strength was low causing TX to fail randomly. The
* fix is to Set bit 11 (Increased MII drive strength) of PHY
* register 26 (Digital Config register) on this phy. */
control = phy_read(phydev, 26);
phy_write(phydev, 26, (control | 0x800));
return 0;
}
#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
#define HAS_ATA 1
#else
#define HAS_ATA 0
#endif
#if defined(CONFIG_MTD_PHYSMAP) || \
defined(CONFIG_MTD_PHYSMAP_MODULE)
printk(KERN_WARNING "WARNING: both IDE and NOR flash are enabled, "
"but share pins.\n\t Disable IDE for NOR support.\n");
#define HAS_NOR 1
#else
#define HAS_NOR 0
#endif
#if defined(CONFIG_MTD_NAND_DAVINCI) || \
defined(CONFIG_MTD_NAND_DAVINCI_MODULE)
#define HAS_NAND 1
#else
#define HAS_NAND 0
#endif
static __init void davinci_evm_init(void)
{
struct clk *aemif_clk;
aemif_clk = clk_get(NULL, "aemif");
clk_enable(aemif_clk);
if (HAS_ATA) {
if (HAS_NAND || HAS_NOR)
pr_warning("WARNING: both IDE and Flash are "
"enabled, but they share AEMIF pins.\n"
"\tDisable IDE for NAND/NOR support.\n");
davinci_cfg_reg(DM644X_HPIEN_DISABLE);
davinci_cfg_reg(DM644X_ATAEN);
davinci_cfg_reg(DM644X_HDIREN);
platform_device_register(&ide_dev);
} else if (HAS_NAND || HAS_NOR) {
davinci_cfg_reg(DM644X_HPIEN_DISABLE);
davinci_cfg_reg(DM644X_ATAEN_DISABLE);
/* only one device will be jumpered and detected */
if (HAS_NAND) {
platform_device_register(&davinci_evm_nandflash_device);
evm_leds[7].default_trigger = "nand-disk";
if (HAS_NOR)
pr_warning("WARNING: both NAND and NOR flash "
"are enabled; disable one of them.\n");
} else if (HAS_NOR)
platform_device_register(&davinci_evm_norflash_device);
}
platform_add_devices(davinci_evm_devices,
ARRAY_SIZE(davinci_evm_devices));
evm_init_i2c();
davinci_serial_init(&uart_config);
/* Register the fixup for PHY on DaVinci */
phy_register_fixup_for_uid(LXT971_PHY_ID, LXT971_PHY_MASK,
davinci_phy_fixup);
}
static __init void davinci_evm_irq_init(void)
{
davinci_init_common_hw();
davinci_irq_init();
}
MACHINE_START(DAVINCI_EVM, "DaVinci EVM")
MACHINE_START(DAVINCI_EVM, "DaVinci DM644x EVM")
/* Maintainer: MontaVista Software <source@mvista.com> */
.phys_io = IO_PHYS,
.io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,

View File

@ -1,7 +1,8 @@
/*
* TI DaVinci clock config file
* Clock and PLL control for DaVinci devices
*
* Copyright (C) 2006 Texas Instruments.
* Copyright (C) 2006-2007 Texas Instruments.
* Copyright (C) 2008-2009 Deep Root Systems, LLC
*
* 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
@ -13,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
@ -21,98 +23,50 @@
#include <mach/hardware.h>
#include <mach/psc.h>
#include <mach/cputype.h>
#include "clock.h"
/* PLL/Reset register offsets */
#define PLLM 0x110
static LIST_HEAD(clocks);
static DEFINE_MUTEX(clocks_mutex);
static DEFINE_SPINLOCK(clockfw_lock);
static unsigned int commonrate;
static unsigned int armrate;
static unsigned int fixedrate = 27000000; /* 27 MHZ */
extern void davinci_psc_config(unsigned int domain, unsigned int id, char enable);
/*
* Returns a clock. Note that we first try to use device id on the bus
* and clock name. If this fails, we try to use clock name only.
*/
struct clk *clk_get(struct device *dev, const char *id)
static unsigned psc_domain(struct clk *clk)
{
struct clk *p, *clk = ERR_PTR(-ENOENT);
int idno;
if (dev == NULL || dev->bus != &platform_bus_type)
idno = -1;
else
idno = to_platform_device(dev)->id;
mutex_lock(&clocks_mutex);
list_for_each_entry(p, &clocks, node) {
if (p->id == idno &&
strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
clk = p;
goto found;
}
}
list_for_each_entry(p, &clocks, node) {
if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
clk = p;
break;
}
}
found:
mutex_unlock(&clocks_mutex);
return clk;
return (clk->flags & PSC_DSP)
? DAVINCI_GPSC_DSPDOMAIN
: DAVINCI_GPSC_ARMDOMAIN;
}
EXPORT_SYMBOL(clk_get);
void clk_put(struct clk *clk)
static void __clk_enable(struct clk *clk)
{
if (clk && !IS_ERR(clk))
module_put(clk->owner);
}
EXPORT_SYMBOL(clk_put);
static int __clk_enable(struct clk *clk)
{
if (clk->flags & ALWAYS_ENABLED)
return 0;
davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, clk->lpsc, 1);
return 0;
if (clk->parent)
__clk_enable(clk->parent);
if (clk->usecount++ == 0 && (clk->flags & CLK_PSC))
davinci_psc_config(psc_domain(clk), clk->lpsc, 1);
}
static void __clk_disable(struct clk *clk)
{
if (clk->usecount)
if (WARN_ON(clk->usecount == 0))
return;
davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, clk->lpsc, 0);
if (--clk->usecount == 0 && !(clk->flags & CLK_PLL))
davinci_psc_config(psc_domain(clk), clk->lpsc, 0);
if (clk->parent)
__clk_disable(clk->parent);
}
int clk_enable(struct clk *clk)
{
unsigned long flags;
int ret = 0;
if (clk == NULL || IS_ERR(clk))
return -EINVAL;
if (clk->usecount++ == 0) {
spin_lock_irqsave(&clockfw_lock, flags);
ret = __clk_enable(clk);
spin_unlock_irqrestore(&clockfw_lock, flags);
}
spin_lock_irqsave(&clockfw_lock, flags);
__clk_enable(clk);
spin_unlock_irqrestore(&clockfw_lock, flags);
return ret;
return 0;
}
EXPORT_SYMBOL(clk_enable);
@ -123,11 +77,9 @@ void clk_disable(struct clk *clk)
if (clk == NULL || IS_ERR(clk))
return;
if (clk->usecount > 0 && !(--clk->usecount)) {
spin_lock_irqsave(&clockfw_lock, flags);
__clk_disable(clk);
spin_unlock_irqrestore(&clockfw_lock, flags);
}
spin_lock_irqsave(&clockfw_lock, flags);
__clk_disable(clk);
spin_unlock_irqrestore(&clockfw_lock, flags);
}
EXPORT_SYMBOL(clk_disable);
@ -136,7 +88,7 @@ unsigned long clk_get_rate(struct clk *clk)
if (clk == NULL || IS_ERR(clk))
return -EINVAL;
return *(clk->rate);
return clk->rate;
}
EXPORT_SYMBOL(clk_get_rate);
@ -145,7 +97,7 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
if (clk == NULL || IS_ERR(clk))
return -EINVAL;
return *(clk->rate);
return clk->rate;
}
EXPORT_SYMBOL(clk_round_rate);
@ -164,10 +116,23 @@ int clk_register(struct clk *clk)
if (clk == NULL || IS_ERR(clk))
return -EINVAL;
if (WARN(clk->parent && !clk->parent->rate,
"CLK: %s parent %s has no rate!\n",
clk->name, clk->parent->name))
return -EINVAL;
mutex_lock(&clocks_mutex);
list_add(&clk->node, &clocks);
list_add_tail(&clk->node, &clocks);
mutex_unlock(&clocks_mutex);
/* If rate is already set, use it */
if (clk->rate)
return 0;
/* Otherwise, default to parent rate */
if (clk->parent)
clk->rate = clk->parent->rate;
return 0;
}
EXPORT_SYMBOL(clk_register);
@ -183,84 +148,150 @@ void clk_unregister(struct clk *clk)
}
EXPORT_SYMBOL(clk_unregister);
static struct clk davinci_clks[] = {
{
.name = "ARMCLK",
.rate = &armrate,
.lpsc = -1,
.flags = ALWAYS_ENABLED,
},
{
.name = "UART",
.rate = &fixedrate,
.lpsc = DAVINCI_LPSC_UART0,
},
{
.name = "EMACCLK",
.rate = &commonrate,
.lpsc = DAVINCI_LPSC_EMAC_WRAPPER,
},
{
.name = "I2CCLK",
.rate = &fixedrate,
.lpsc = DAVINCI_LPSC_I2C,
},
{
.name = "IDECLK",
.rate = &commonrate,
.lpsc = DAVINCI_LPSC_ATA,
},
{
.name = "McBSPCLK",
.rate = &commonrate,
.lpsc = DAVINCI_LPSC_McBSP,
},
{
.name = "MMCSDCLK",
.rate = &commonrate,
.lpsc = DAVINCI_LPSC_MMC_SD,
},
{
.name = "SPICLK",
.rate = &commonrate,
.lpsc = DAVINCI_LPSC_SPI,
},
{
.name = "gpio",
.rate = &commonrate,
.lpsc = DAVINCI_LPSC_GPIO,
},
{
.name = "usb",
.rate = &commonrate,
.lpsc = DAVINCI_LPSC_USB,
},
{
.name = "AEMIFCLK",
.rate = &commonrate,
.lpsc = DAVINCI_LPSC_AEMIF,
.usecount = 1,
}
};
int __init davinci_clk_init(void)
#ifdef CONFIG_DAVINCI_RESET_CLOCKS
/*
* Disable any unused clocks left on by the bootloader
*/
static int __init clk_disable_unused(void)
{
struct clk *clkp;
int count = 0;
u32 pll_mult;
struct clk *ck;
pll_mult = davinci_readl(DAVINCI_PLL_CNTRL0_BASE + PLLM);
commonrate = ((pll_mult + 1) * 27000000) / 6;
armrate = ((pll_mult + 1) * 27000000) / 2;
spin_lock_irq(&clockfw_lock);
list_for_each_entry(ck, &clocks, node) {
if (ck->usecount > 0)
continue;
if (!(ck->flags & CLK_PSC))
continue;
for (clkp = davinci_clks; count < ARRAY_SIZE(davinci_clks);
count++, clkp++) {
clk_register(clkp);
/* ignore if in Disabled or SwRstDisable states */
if (!davinci_psc_is_clk_active(ck->lpsc))
continue;
/* Turn on clocks that have been enabled in the
* table above */
if (clkp->usecount)
clk_enable(clkp);
pr_info("Clocks: disable unused %s\n", ck->name);
davinci_psc_config(psc_domain(ck), ck->lpsc, 0);
}
spin_unlock_irq(&clockfw_lock);
return 0;
}
late_initcall(clk_disable_unused);
#endif
static void clk_sysclk_recalc(struct clk *clk)
{
u32 v, plldiv;
struct pll_data *pll;
/* If this is the PLL base clock, no more calculations needed */
if (clk->pll_data)
return;
if (WARN_ON(!clk->parent))
return;
clk->rate = clk->parent->rate;
/* Otherwise, the parent must be a PLL */
if (WARN_ON(!clk->parent->pll_data))
return;
pll = clk->parent->pll_data;
/* If pre-PLL, source clock is before the multiplier and divider(s) */
if (clk->flags & PRE_PLL)
clk->rate = pll->input_rate;
if (!clk->div_reg)
return;
v = __raw_readl(pll->base + clk->div_reg);
if (v & PLLDIV_EN) {
plldiv = (v & PLLDIV_RATIO_MASK) + 1;
if (plldiv)
clk->rate /= plldiv;
}
}
static void __init clk_pll_init(struct clk *clk)
{
u32 ctrl, mult = 1, prediv = 1, postdiv = 1;
u8 bypass;
struct pll_data *pll = clk->pll_data;
pll->base = IO_ADDRESS(pll->phys_base);
ctrl = __raw_readl(pll->base + PLLCTL);
clk->rate = pll->input_rate = clk->parent->rate;
if (ctrl & PLLCTL_PLLEN) {
bypass = 0;
mult = __raw_readl(pll->base + PLLM);
mult = (mult & PLLM_PLLM_MASK) + 1;
} else
bypass = 1;
if (pll->flags & PLL_HAS_PREDIV) {
prediv = __raw_readl(pll->base + PREDIV);
if (prediv & PLLDIV_EN)
prediv = (prediv & PLLDIV_RATIO_MASK) + 1;
else
prediv = 1;
}
/* pre-divider is fixed, but (some?) chips won't report that */
if (cpu_is_davinci_dm355() && pll->num == 1)
prediv = 8;
if (pll->flags & PLL_HAS_POSTDIV) {
postdiv = __raw_readl(pll->base + POSTDIV);
if (postdiv & PLLDIV_EN)
postdiv = (postdiv & PLLDIV_RATIO_MASK) + 1;
else
postdiv = 1;
}
if (!bypass) {
clk->rate /= prediv;
clk->rate *= mult;
clk->rate /= postdiv;
}
pr_debug("PLL%d: input = %lu MHz [ ",
pll->num, clk->parent->rate / 1000000);
if (bypass)
pr_debug("bypass ");
if (prediv > 1)
pr_debug("/ %d ", prediv);
if (mult > 1)
pr_debug("* %d ", mult);
if (postdiv > 1)
pr_debug("/ %d ", postdiv);
pr_debug("] --> %lu MHz output.\n", clk->rate / 1000000);
}
int __init davinci_clk_init(struct davinci_clk *clocks)
{
struct davinci_clk *c;
struct clk *clk;
for (c = clocks; c->lk.clk; c++) {
clk = c->lk.clk;
if (clk->pll_data)
clk_pll_init(clk);
/* Calculate rates for PLL-derived clocks */
else if (clk->flags & CLK_PLL)
clk_sysclk_recalc(clk);
if (clk->lpsc)
clk->flags |= CLK_PSC;
clkdev_add(&c->lk);
clk_register(clk);
/* Turn on clocks that Linux doesn't otherwise manage */
if (clk->flags & ALWAYS_ENABLED)
clk_enable(clk);
}
return 0;
@ -285,12 +316,52 @@ static void davinci_ck_stop(struct seq_file *m, void *v)
{
}
#define CLKNAME_MAX 10 /* longest clock name */
#define NEST_DELTA 2
#define NEST_MAX 4
static void
dump_clock(struct seq_file *s, unsigned nest, struct clk *parent)
{
char *state;
char buf[CLKNAME_MAX + NEST_DELTA * NEST_MAX];
struct clk *clk;
unsigned i;
if (parent->flags & CLK_PLL)
state = "pll";
else if (parent->flags & CLK_PSC)
state = "psc";
else
state = "";
/* <nest spaces> name <pad to end> */
memset(buf, ' ', sizeof(buf) - 1);
buf[sizeof(buf) - 1] = 0;
i = strlen(parent->name);
memcpy(buf + nest, parent->name,
min(i, (unsigned)(sizeof(buf) - 1 - nest)));
seq_printf(s, "%s users=%2d %-3s %9ld Hz\n",
buf, parent->usecount, state, clk_get_rate(parent));
/* REVISIT show device associations too */
/* cost is now small, but not linear... */
list_for_each_entry(clk, &clocks, node) {
if (clk->parent == parent)
dump_clock(s, nest + NEST_DELTA, clk);
}
}
static int davinci_ck_show(struct seq_file *m, void *v)
{
struct clk *cp;
list_for_each_entry(cp, &clocks, node)
seq_printf(m,"%s %d %d\n", cp->name, *(cp->rate), cp->usecount);
/* Show clock tree; we know the main oscillator is first.
* We trust nonzero usecounts equate to PSC enables...
*/
mutex_lock(&clocks_mutex);
if (!list_empty(&clocks))
dump_clock(m, 0, list_first_entry(&clocks, struct clk, node));
mutex_unlock(&clocks_mutex);
return 0;
}
@ -321,4 +392,4 @@ static int __init davinci_ck_proc_init(void)
}
__initcall(davinci_ck_proc_init);
#endif /* CONFIG_DEBUG_PROC_FS */
#endif /* CONFIG_DEBUG_PROC_FS */

View File

@ -1,7 +1,8 @@
/*
* TI DaVinci clock definitions
*
* Copyright (C) 2006 Texas Instruments.
* Copyright (C) 2006-2007 Texas Instruments.
* Copyright (C) 2008-2009 Deep Root Systems, LLC
*
* 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
@ -11,23 +12,85 @@
#ifndef __ARCH_ARM_DAVINCI_CLOCK_H
#define __ARCH_ARM_DAVINCI_CLOCK_H
#include <linux/list.h>
#include <asm/clkdev.h>
#define DAVINCI_PLL1_BASE 0x01c40800
#define DAVINCI_PLL2_BASE 0x01c40c00
#define MAX_PLL 2
/* PLL/Reset register offsets */
#define PLLCTL 0x100
#define PLLCTL_PLLEN BIT(0)
#define PLLCTL_CLKMODE BIT(8)
#define PLLM 0x110
#define PLLM_PLLM_MASK 0xff
#define PREDIV 0x114
#define PLLDIV1 0x118
#define PLLDIV2 0x11c
#define PLLDIV3 0x120
#define POSTDIV 0x128
#define BPDIV 0x12c
#define PLLCMD 0x138
#define PLLSTAT 0x13c
#define PLLALNCTL 0x140
#define PLLDCHANGE 0x144
#define PLLCKEN 0x148
#define PLLCKSTAT 0x14c
#define PLLSYSTAT 0x150
#define PLLDIV4 0x160
#define PLLDIV5 0x164
#define PLLDIV6 0x168
#define PLLDIV7 0x16c
#define PLLDIV8 0x170
#define PLLDIV9 0x174
#define PLLDIV_EN BIT(15)
#define PLLDIV_RATIO_MASK 0x1f
struct pll_data {
u32 phys_base;
void __iomem *base;
u32 num;
u32 flags;
u32 input_rate;
};
#define PLL_HAS_PREDIV 0x01
#define PLL_HAS_POSTDIV 0x02
struct clk {
struct list_head node;
struct module *owner;
const char *name;
unsigned int *rate;
int id;
__s8 usecount;
__u8 flags;
__u8 lpsc;
unsigned long rate;
u8 usecount;
u8 flags;
u8 lpsc;
struct clk *parent;
struct pll_data *pll_data;
u32 div_reg;
};
/* Clock flags */
#define RATE_CKCTL 1
#define RATE_FIXED 2
#define RATE_PROPAGATES 4
#define VIRTUAL_CLOCK 8
#define ALWAYS_ENABLED 16
#define ENABLE_REG_32BIT 32
#define ALWAYS_ENABLED BIT(1)
#define CLK_PSC BIT(2)
#define PSC_DSP BIT(3) /* PSC uses DSP domain, not ARM */
#define CLK_PLL BIT(4) /* PLL-derived clock */
#define PRE_PLL BIT(5) /* source is before PLL mult/div */
struct davinci_clk {
struct clk_lookup lk;
};
#define CLK(dev, con, ck) \
{ \
.lk = { \
.dev_id = dev, \
.con_id = con, \
.clk = ck, \
}, \
}
int davinci_clk_init(struct davinci_clk *clocks);
#endif

View File

@ -21,6 +21,10 @@
#include <mach/hardware.h>
#include <mach/i2c.h>
#include <mach/irqs.h>
#include <mach/cputype.h>
#include <mach/mux.h>
#define DAVINCI_I2C_BASE 0x01C21000
static struct resource i2c_resources[] = {
{
@ -43,6 +47,9 @@ static struct platform_device davinci_i2c_device = {
void __init davinci_init_i2c(struct davinci_i2c_platform_data *pdata)
{
if (cpu_is_davinci_dm644x())
davinci_cfg_reg(DM644X_I2C);
davinci_i2c_device.dev.platform_data = pdata;
(void) platform_device_register(&davinci_i2c_device);
}

View File

@ -0,0 +1,461 @@
/*
* TI DaVinci DM644x chip specific setup
*
* Author: Kevin Hilman, Deep Root Systems, LLC
*
* 2007 (c) Deep Root Systems, LLC. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <mach/dm644x.h>
#include <mach/clock.h>
#include <mach/cputype.h>
#include <mach/edma.h>
#include <mach/irqs.h>
#include <mach/psc.h>
#include <mach/mux.h>
#include "clock.h"
#include "mux.h"
/*
* Device specific clocks
*/
#define DM644X_REF_FREQ 27000000
static struct pll_data pll1_data = {
.num = 1,
.phys_base = DAVINCI_PLL1_BASE,
};
static struct pll_data pll2_data = {
.num = 2,
.phys_base = DAVINCI_PLL2_BASE,
};
static struct clk ref_clk = {
.name = "ref_clk",
.rate = DM644X_REF_FREQ,
};
static struct clk pll1_clk = {
.name = "pll1",
.parent = &ref_clk,
.pll_data = &pll1_data,
.flags = CLK_PLL,
};
static struct clk pll1_sysclk1 = {
.name = "pll1_sysclk1",
.parent = &pll1_clk,
.flags = CLK_PLL,
.div_reg = PLLDIV1,
};
static struct clk pll1_sysclk2 = {
.name = "pll1_sysclk2",
.parent = &pll1_clk,
.flags = CLK_PLL,
.div_reg = PLLDIV2,
};
static struct clk pll1_sysclk3 = {
.name = "pll1_sysclk3",
.parent = &pll1_clk,
.flags = CLK_PLL,
.div_reg = PLLDIV3,
};
static struct clk pll1_sysclk5 = {
.name = "pll1_sysclk5",
.parent = &pll1_clk,
.flags = CLK_PLL,
.div_reg = PLLDIV5,
};
static struct clk pll1_aux_clk = {
.name = "pll1_aux_clk",
.parent = &pll1_clk,
.flags = CLK_PLL | PRE_PLL,
};
static struct clk pll1_sysclkbp = {
.name = "pll1_sysclkbp",
.parent = &pll1_clk,
.flags = CLK_PLL | PRE_PLL,
.div_reg = BPDIV
};
static struct clk pll2_clk = {
.name = "pll2",
.parent = &ref_clk,
.pll_data = &pll2_data,
.flags = CLK_PLL,
};
static struct clk pll2_sysclk1 = {
.name = "pll2_sysclk1",
.parent = &pll2_clk,
.flags = CLK_PLL,
.div_reg = PLLDIV1,
};
static struct clk pll2_sysclk2 = {
.name = "pll2_sysclk2",
.parent = &pll2_clk,
.flags = CLK_PLL,
.div_reg = PLLDIV2,
};
static struct clk pll2_sysclkbp = {
.name = "pll2_sysclkbp",
.parent = &pll2_clk,
.flags = CLK_PLL | PRE_PLL,
.div_reg = BPDIV
};
static struct clk dsp_clk = {
.name = "dsp",
.parent = &pll1_sysclk1,
.lpsc = DAVINCI_LPSC_GEM,
.flags = PSC_DSP,
.usecount = 1, /* REVISIT how to disable? */
};
static struct clk arm_clk = {
.name = "arm",
.parent = &pll1_sysclk2,
.lpsc = DAVINCI_LPSC_ARM,
.flags = ALWAYS_ENABLED,
};
static struct clk vicp_clk = {
.name = "vicp",
.parent = &pll1_sysclk2,
.lpsc = DAVINCI_LPSC_IMCOP,
.flags = PSC_DSP,
.usecount = 1, /* REVISIT how to disable? */
};
static struct clk vpss_master_clk = {
.name = "vpss_master",
.parent = &pll1_sysclk3,
.lpsc = DAVINCI_LPSC_VPSSMSTR,
.flags = CLK_PSC,
};
static struct clk vpss_slave_clk = {
.name = "vpss_slave",
.parent = &pll1_sysclk3,
.lpsc = DAVINCI_LPSC_VPSSSLV,
};
static struct clk uart0_clk = {
.name = "uart0",
.parent = &pll1_aux_clk,
.lpsc = DAVINCI_LPSC_UART0,
};
static struct clk uart1_clk = {
.name = "uart1",
.parent = &pll1_aux_clk,
.lpsc = DAVINCI_LPSC_UART1,
};
static struct clk uart2_clk = {
.name = "uart2",
.parent = &pll1_aux_clk,
.lpsc = DAVINCI_LPSC_UART2,
};
static struct clk emac_clk = {
.name = "emac",
.parent = &pll1_sysclk5,
.lpsc = DAVINCI_LPSC_EMAC_WRAPPER,
};
static struct clk i2c_clk = {
.name = "i2c",
.parent = &pll1_aux_clk,
.lpsc = DAVINCI_LPSC_I2C,
};
static struct clk ide_clk = {
.name = "ide",
.parent = &pll1_sysclk5,
.lpsc = DAVINCI_LPSC_ATA,
};
static struct clk asp_clk = {
.name = "asp0",
.parent = &pll1_sysclk5,
.lpsc = DAVINCI_LPSC_McBSP,
};
static struct clk mmcsd_clk = {
.name = "mmcsd",
.parent = &pll1_sysclk5,
.lpsc = DAVINCI_LPSC_MMC_SD,
};
static struct clk spi_clk = {
.name = "spi",
.parent = &pll1_sysclk5,
.lpsc = DAVINCI_LPSC_SPI,
};
static struct clk gpio_clk = {
.name = "gpio",
.parent = &pll1_sysclk5,
.lpsc = DAVINCI_LPSC_GPIO,
};
static struct clk usb_clk = {
.name = "usb",
.parent = &pll1_sysclk5,
.lpsc = DAVINCI_LPSC_USB,
};
static struct clk vlynq_clk = {
.name = "vlynq",
.parent = &pll1_sysclk5,
.lpsc = DAVINCI_LPSC_VLYNQ,
};
static struct clk aemif_clk = {
.name = "aemif",
.parent = &pll1_sysclk5,
.lpsc = DAVINCI_LPSC_AEMIF,
};
static struct clk pwm0_clk = {
.name = "pwm0",
.parent = &pll1_aux_clk,
.lpsc = DAVINCI_LPSC_PWM0,
};
static struct clk pwm1_clk = {
.name = "pwm1",
.parent = &pll1_aux_clk,
.lpsc = DAVINCI_LPSC_PWM1,
};
static struct clk pwm2_clk = {
.name = "pwm2",
.parent = &pll1_aux_clk,
.lpsc = DAVINCI_LPSC_PWM2,
};
static struct clk timer0_clk = {
.name = "timer0",
.parent = &pll1_aux_clk,
.lpsc = DAVINCI_LPSC_TIMER0,
};
static struct clk timer1_clk = {
.name = "timer1",
.parent = &pll1_aux_clk,
.lpsc = DAVINCI_LPSC_TIMER1,
};
static struct clk timer2_clk = {
.name = "timer2",
.parent = &pll1_aux_clk,
.lpsc = DAVINCI_LPSC_TIMER2,
.usecount = 1, /* REVISIT: why cant' this be disabled? */
};
struct davinci_clk dm644x_clks[] = {
CLK(NULL, "ref", &ref_clk),
CLK(NULL, "pll1", &pll1_clk),
CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
CLK(NULL, "pll1_sysclk5", &pll1_sysclk5),
CLK(NULL, "pll1_aux", &pll1_aux_clk),
CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
CLK(NULL, "pll2", &pll2_clk),
CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
CLK(NULL, "pll2_sysclk2", &pll2_sysclk2),
CLK(NULL, "pll2_sysclkbp", &pll2_sysclkbp),
CLK(NULL, "dsp", &dsp_clk),
CLK(NULL, "arm", &arm_clk),
CLK(NULL, "vicp", &vicp_clk),
CLK(NULL, "vpss_master", &vpss_master_clk),
CLK(NULL, "vpss_slave", &vpss_slave_clk),
CLK(NULL, "arm", &arm_clk),
CLK(NULL, "uart0", &uart0_clk),
CLK(NULL, "uart1", &uart1_clk),
CLK(NULL, "uart2", &uart2_clk),
CLK("davinci_emac.1", NULL, &emac_clk),
CLK("i2c_davinci.1", NULL, &i2c_clk),
CLK("palm_bk3710", NULL, &ide_clk),
CLK("soc-audio.0", NULL, &asp_clk),
CLK("davinci_mmc.0", NULL, &mmcsd_clk),
CLK(NULL, "spi", &spi_clk),
CLK(NULL, "gpio", &gpio_clk),
CLK(NULL, "usb", &usb_clk),
CLK(NULL, "vlynq", &vlynq_clk),
CLK(NULL, "aemif", &aemif_clk),
CLK(NULL, "pwm0", &pwm0_clk),
CLK(NULL, "pwm1", &pwm1_clk),
CLK(NULL, "pwm2", &pwm2_clk),
CLK(NULL, "timer0", &timer0_clk),
CLK(NULL, "timer1", &timer1_clk),
CLK("watchdog", NULL, &timer2_clk),
CLK(NULL, NULL, NULL),
};
#if defined(CONFIG_TI_DAVINCI_EMAC) || defined(CONFIG_TI_DAVINCI_EMAC_MODULE)
static struct resource dm644x_emac_resources[] = {
{
.start = DM644X_EMAC_BASE,
.end = DM644X_EMAC_BASE + 0x47ff,
.flags = IORESOURCE_MEM,
},
{
.start = IRQ_EMACINT,
.end = IRQ_EMACINT,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device dm644x_emac_device = {
.name = "davinci_emac",
.id = 1,
.num_resources = ARRAY_SIZE(dm644x_emac_resources),
.resource = dm644x_emac_resources,
};
#endif
/*
* Device specific mux setup
*
* soc description mux mode mode mux dbg
* reg offset mask mode
*/
static const struct mux_config dm644x_pins[] = {
MUX_CFG(DM644X, HDIREN, 0, 16, 1, 1, true)
MUX_CFG(DM644X, ATAEN, 0, 17, 1, 1, true)
MUX_CFG(DM644X, ATAEN_DISABLE, 0, 17, 1, 0, true)
MUX_CFG(DM644X, HPIEN_DISABLE, 0, 29, 1, 0, true)
MUX_CFG(DM644X, AEAW, 0, 0, 31, 31, true)
MUX_CFG(DM644X, MSTK, 1, 9, 1, 0, false)
MUX_CFG(DM644X, I2C, 1, 7, 1, 1, false)
MUX_CFG(DM644X, MCBSP, 1, 10, 1, 1, false)
MUX_CFG(DM644X, UART1, 1, 1, 1, 1, true)
MUX_CFG(DM644X, UART2, 1, 2, 1, 1, true)
MUX_CFG(DM644X, PWM0, 1, 4, 1, 1, false)
MUX_CFG(DM644X, PWM1, 1, 5, 1, 1, false)
MUX_CFG(DM644X, PWM2, 1, 6, 1, 1, false)
MUX_CFG(DM644X, VLYNQEN, 0, 15, 1, 1, false)
MUX_CFG(DM644X, VLSCREN, 0, 14, 1, 1, false)
MUX_CFG(DM644X, VLYNQWD, 0, 12, 3, 3, false)
MUX_CFG(DM644X, EMACEN, 0, 31, 1, 1, true)
MUX_CFG(DM644X, GPIO3V, 0, 31, 1, 0, true)
MUX_CFG(DM644X, GPIO0, 0, 24, 1, 0, true)
MUX_CFG(DM644X, GPIO3, 0, 25, 1, 0, false)
MUX_CFG(DM644X, GPIO43_44, 1, 7, 1, 0, false)
MUX_CFG(DM644X, GPIO46_47, 0, 22, 1, 0, true)
MUX_CFG(DM644X, RGB666, 0, 22, 1, 1, true)
MUX_CFG(DM644X, LOEEN, 0, 24, 1, 1, true)
MUX_CFG(DM644X, LFLDEN, 0, 25, 1, 1, false)
};
/*----------------------------------------------------------------------*/
static const s8 dma_chan_dm644x_no_event[] = {
0, 1, 12, 13, 14,
15, 25, 30, 31, 45,
46, 47, 55, 56, 57,
58, 59, 60, 61, 62,
63,
-1
};
static struct edma_soc_info dm644x_edma_info = {
.n_channel = 64,
.n_region = 4,
.n_slot = 128,
.n_tc = 2,
.noevent = dma_chan_dm644x_no_event,
};
static struct resource edma_resources[] = {
{
.name = "edma_cc",
.start = 0x01c00000,
.end = 0x01c00000 + SZ_64K - 1,
.flags = IORESOURCE_MEM,
},
{
.name = "edma_tc0",
.start = 0x01c10000,
.end = 0x01c10000 + SZ_1K - 1,
.flags = IORESOURCE_MEM,
},
{
.name = "edma_tc1",
.start = 0x01c10400,
.end = 0x01c10400 + SZ_1K - 1,
.flags = IORESOURCE_MEM,
},
{
.start = IRQ_CCINT0,
.flags = IORESOURCE_IRQ,
},
{
.start = IRQ_CCERRINT,
.flags = IORESOURCE_IRQ,
},
/* not using TC*_ERR */
};
static struct platform_device dm644x_edma_device = {
.name = "edma",
.id = -1,
.dev.platform_data = &dm644x_edma_info,
.num_resources = ARRAY_SIZE(edma_resources),
.resource = edma_resources,
};
/*----------------------------------------------------------------------*/
void __init dm644x_init(void)
{
davinci_clk_init(dm644x_clks);
davinci_mux_register(dm644x_pins, ARRAY_SIZE(dm644x_pins));
}
static int __init dm644x_init_devices(void)
{
if (!cpu_is_davinci_dm644x())
return 0;
platform_device_register(&dm644x_edma_device);
return 0;
}
postcore_initcall(dm644x_init_devices);

File diff suppressed because it is too large Load Diff

View File

@ -20,6 +20,7 @@
#include <linux/irq.h>
#include <linux/bitops.h>
#include <mach/cputype.h>
#include <mach/irqs.h>
#include <mach/hardware.h>
#include <mach/gpio.h>
@ -36,9 +37,10 @@ struct davinci_gpio {
static struct davinci_gpio chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)];
static unsigned __initdata ngpio;
/* create a non-inlined version */
static struct gpio_controller *__iomem __init gpio2controller(unsigned gpio)
static struct gpio_controller __iomem * __init gpio2controller(unsigned gpio)
{
return __gpio_to_controller(gpio);
}
@ -114,9 +116,30 @@ static int __init davinci_gpio_setup(void)
{
int i, base;
for (i = 0, base = 0;
i < ARRAY_SIZE(chips);
i++, base += 32) {
/* The gpio banks conceptually expose a segmented bitmap,
* and "ngpio" is one more than the largest zero-based
* bit index that's valid.
*/
if (cpu_is_davinci_dm355()) { /* or dm335() */
ngpio = 104;
} else if (cpu_is_davinci_dm644x()) { /* or dm337() */
ngpio = 71;
} else if (cpu_is_davinci_dm646x()) {
/* NOTE: each bank has several "reserved" bits,
* unusable as GPIOs. Only 33 of the GPIO numbers
* are usable, and we're not rejecting the others.
*/
ngpio = 43;
} else {
/* if cpu_is_davinci_dm643x() ngpio = 111 */
pr_err("GPIO setup: how many GPIOs?\n");
return -EINVAL;
}
if (WARN_ON(DAVINCI_N_GPIO < ngpio))
ngpio = DAVINCI_N_GPIO;
for (i = 0, base = 0; base < ngpio; i++, base += 32) {
chips[i].chip.label = "DaVinci";
chips[i].chip.direction_input = davinci_direction_in;
@ -125,7 +148,7 @@ static int __init davinci_gpio_setup(void)
chips[i].chip.set = davinci_gpio_set;
chips[i].chip.base = base;
chips[i].chip.ngpio = DAVINCI_N_GPIO - base;
chips[i].chip.ngpio = ngpio - base;
if (chips[i].chip.ngpio > 32)
chips[i].chip.ngpio = 32;
@ -143,11 +166,11 @@ pure_initcall(davinci_gpio_setup);
* We expect irqs will normally be set up as input pins, but they can also be
* used as output pins ... which is convenient for testing.
*
* NOTE: GPIO0..GPIO7 also have direct INTC hookups, which work in addition
* to their GPIOBNK0 irq (but with a bit less overhead). But we don't have
* a good way to hook those up ...
* NOTE: The first few GPIOs also have direct INTC hookups in addition
* to their GPIOBNK0 irq, with a bit less overhead but less flexibility
* on triggering (e.g. no edge options). We don't try to use those.
*
* All those INTC hookups (GPIO0..GPIO7 plus five IRQ banks) can also
* All those INTC hookups (direct, plus several IRQ banks) can also
* serve as EDMA event triggers.
*/
@ -235,29 +258,42 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
}
/*
* NOTE: for suspend/resume, probably best to make a sysdev (and class)
* with its suspend/resume calls hooking into the results of the set_wake()
* NOTE: for suspend/resume, probably best to make a platform_device with
* suspend_late/resume_resume calls hooking into results of the set_wake()
* calls ... so if no gpios are wakeup events the clock can be disabled,
* with outputs left at previously set levels, and so that VDD3P3V.IOPWDN0
* can be set appropriately for GPIOV33 pins.
* (dm6446) can be set appropriately for GPIOV33 pins.
*/
static int __init davinci_gpio_irq_setup(void)
{
unsigned gpio, irq, bank;
unsigned bank_irq;
struct clk *clk;
u32 binten = 0;
if (cpu_is_davinci_dm355()) { /* or dm335() */
bank_irq = IRQ_DM355_GPIOBNK0;
} else if (cpu_is_davinci_dm644x()) {
bank_irq = IRQ_GPIOBNK0;
} else if (cpu_is_davinci_dm646x()) {
bank_irq = IRQ_DM646X_GPIOBNK0;
} else {
printk(KERN_ERR "Don't know first GPIO bank IRQ.\n");
return -EINVAL;
}
clk = clk_get(NULL, "gpio");
if (IS_ERR(clk)) {
printk(KERN_ERR "Error %ld getting gpio clock?\n",
PTR_ERR(clk));
return 0;
return PTR_ERR(clk);
}
clk_enable(clk);
for (gpio = 0, irq = gpio_to_irq(0), bank = IRQ_GPIOBNK0;
gpio < DAVINCI_N_GPIO; bank++) {
for (gpio = 0, irq = gpio_to_irq(0), bank = 0;
gpio < ngpio;
bank++, bank_irq++) {
struct gpio_controller *__iomem g = gpio2controller(gpio);
unsigned i;
@ -265,28 +301,28 @@ static int __init davinci_gpio_irq_setup(void)
__raw_writel(~0, &g->clr_rising);
/* set up all irqs in this bank */
set_irq_chained_handler(bank, gpio_irq_handler);
set_irq_chip_data(bank, g);
set_irq_data(bank, (void *)irq);
set_irq_chained_handler(bank_irq, gpio_irq_handler);
set_irq_chip_data(bank_irq, g);
set_irq_data(bank_irq, (void *)irq);
for (i = 0; i < 16 && gpio < DAVINCI_N_GPIO;
i++, irq++, gpio++) {
for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) {
set_irq_chip(irq, &gpio_irqchip);
set_irq_chip_data(irq, g);
set_irq_handler(irq, handle_simple_irq);
set_irq_flags(irq, IRQF_VALID);
}
binten |= BIT(bank);
}
/* BINTEN -- per-bank interrupt enable. genirq would also let these
* bits be set/cleared dynamically.
*/
__raw_writel(0x1f, (void *__iomem)
__raw_writel(binten, (void *__iomem)
IO_ADDRESS(DAVINCI_GPIO_BASE + 0x08));
printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0));
return 0;
}
arch_initcall(davinci_gpio_irq_setup);

View File

@ -15,7 +15,9 @@
#include <linux/init.h>
#include <linux/io.h>
#define JTAG_ID_BASE 0x01c40028
#define JTAG_ID_BASE IO_ADDRESS(0x01c40028)
static unsigned int davinci_revision;
struct davinci_id {
u8 variant; /* JTAG ID bits 31:28 */
@ -33,6 +35,20 @@ static struct davinci_id davinci_ids[] __initdata = {
.manufacturer = 0x017,
.type = 0x64460000,
},
{
/* DM646X */
.part_no = 0xb770,
.variant = 0x0,
.manufacturer = 0x017,
.type = 0x64670000,
},
{
/* DM355 */
.part_no = 0xb73b,
.variant = 0x0,
.manufacturer = 0x00f,
.type = 0x03550000,
},
};
/*
@ -42,7 +58,7 @@ static u16 __init davinci_get_part_no(void)
{
u32 dev_id, part_no;
dev_id = davinci_readl(JTAG_ID_BASE);
dev_id = __raw_readl(JTAG_ID_BASE);
part_no = ((dev_id >> 12) & 0xffff);
@ -56,13 +72,19 @@ static u8 __init davinci_get_variant(void)
{
u32 variant;
variant = davinci_readl(JTAG_ID_BASE);
variant = __raw_readl(JTAG_ID_BASE);
variant = (variant >> 28) & 0xf;
return variant;
}
unsigned int davinci_rev(void)
{
return davinci_revision >> 16;
}
EXPORT_SYMBOL(davinci_rev);
void __init davinci_check_revision(void)
{
int i;
@ -75,7 +97,7 @@ void __init davinci_check_revision(void)
/* First check only the major version in a safe way */
for (i = 0; i < ARRAY_SIZE(davinci_ids); i++) {
if (part_no == (davinci_ids[i].part_no)) {
system_rev = davinci_ids[i].type;
davinci_revision = davinci_ids[i].type;
break;
}
}
@ -84,10 +106,11 @@ void __init davinci_check_revision(void)
for (i = 0; i < ARRAY_SIZE(davinci_ids); i++) {
if (part_no == davinci_ids[i].part_no &&
variant == davinci_ids[i].variant) {
system_rev = davinci_ids[i].type;
davinci_revision = davinci_ids[i].type;
break;
}
}
printk("DaVinci DM%04x variant 0x%x\n", system_rev >> 16, variant);
printk(KERN_INFO "DaVinci DM%04x variant 0x%x\n",
davinci_rev(), variant);
}

View File

@ -0,0 +1,20 @@
/*
* DaVinci DM6446 EVM board specific headers
*
* Author: Kevin Hilman, Deep Root Systems, LLC
*
* 2007 (c) Deep Root Systems, LLC. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or ifndef.
*/
#ifndef _MACH_DAVINCI_DM6446EVM_H
#define _MACH_DAVINCI_DM6446EVM_H
#include <linux/types.h>
int dm6446evm_eeprom_read(char *buf, off_t off, size_t count);
int dm6446evm_eeprom_write(char *buf, off_t off, size_t count);
#endif

View File

@ -0,0 +1,13 @@
#ifndef __MACH_CLKDEV_H
#define __MACH_CLKDEV_H
static inline int __clk_get(struct clk *clk)
{
return 1;
}
static inline void __clk_put(struct clk *clk)
{
}
#endif

View File

@ -17,6 +17,5 @@ struct clk;
extern int clk_register(struct clk *clk);
extern void clk_unregister(struct clk *clk);
extern int davinci_clk_init(void);
#endif

View File

@ -16,6 +16,12 @@ struct sys_timer;
extern struct sys_timer davinci_timer;
extern void davinci_irq_init(void);
extern void davinci_map_common_io(void);
/* parameters describe VBUS sourcing for host mode */
extern void setup_usb(unsigned mA, unsigned potpgt_msec);
/* parameters describe VBUS sourcing for host mode */
extern void setup_usb(unsigned mA, unsigned potpgt_msec);

View File

@ -0,0 +1,49 @@
/*
* DaVinci CPU type detection
*
* Author: Kevin Hilman, Deep Root Systems, LLC
*
* Defines the cpu_is_*() macros for runtime detection of DaVinci
* device type. In addtion, if support for a given device is not
* compiled in to the kernel, the macros return 0 so that
* resulting code can be optimized out.
*
* 2009 (c) Deep Root Systems, LLC. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#ifndef _ASM_ARCH_CPU_H
#define _ASM_ARCH_CPU_H
extern unsigned int davinci_rev(void);
#define IS_DAVINCI_CPU(type, id) \
static inline int is_davinci_dm ##type(void) \
{ \
return (davinci_rev() == (id)) ? 1 : 0; \
}
IS_DAVINCI_CPU(644x, 0x6446)
IS_DAVINCI_CPU(646x, 0x6467)
IS_DAVINCI_CPU(355, 0x355)
#ifdef CONFIG_ARCH_DAVINCI_DM644x
#define cpu_is_davinci_dm644x() is_davinci_dm644x()
#else
#define cpu_is_davinci_dm644x() 0
#endif
#ifdef CONFIG_ARCH_DAVINCI_DM646x
#define cpu_is_davinci_dm646x() is_davinci_dm646x()
#else
#define cpu_is_davinci_dm646x() 0
#endif
#ifdef CONFIG_ARCH_DAVINCI_DM355
#define cpu_is_davinci_dm355() is_davinci_dm355()
#else
#define cpu_is_davinci_dm355() 0
#endif
#endif

View File

@ -1,7 +1,8 @@
/*
* arch/arm/mach-imx/include/mach/mx1ads.h
* This file contains the processor specific definitions
* of the TI DM644x.
*
* Copyright (C) 2004 Robert Schwebel, Pengutronix
* Copyright (C) 2008 Texas Instruments.
*
* 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
@ -18,19 +19,19 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef __ASM_ARCH_DM644X_H
#define __ASM_ARCH_DM644X_H
#ifndef __ASM_ARCH_MX1ADS_H
#define __ASM_ARCH_MX1ADS_H
#include <linux/platform_device.h>
#include <mach/hardware.h>
/* ------------------------------------------------------------------------ */
/* Memory Map for the M9328MX1ADS (MX1ADS) Board */
/* ------------------------------------------------------------------------ */
#define DM644X_EMAC_BASE (0x01C80000)
#define DM644X_EMAC_CNTRL_OFFSET (0x0000)
#define DM644X_EMAC_CNTRL_MOD_OFFSET (0x1000)
#define DM644X_EMAC_CNTRL_RAM_OFFSET (0x2000)
#define DM644X_EMAC_MDIO_OFFSET (0x4000)
#define DM644X_EMAC_CNTRL_RAM_SIZE (0x2000)
#define MX1ADS_FLASH_PHYS 0x10000000
#define MX1ADS_FLASH_SIZE (16*1024*1024)
void __init dm644x_init(void);
#define IMX_FB_PHYS (0x0C000000 - 0x40000)
#define CLK32 32000
#endif /* __ASM_ARCH_MX1ADS_H */
#endif /* __ASM_ARCH_DM644X_H */

View File

@ -0,0 +1,228 @@
/*
* TI DAVINCI dma definitions
*
* Copyright (C) 2006-2009 Texas Instruments.
*
* 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.
*
*/
/*
* This EDMA3 programming framework exposes two basic kinds of resource:
*
* Channel Triggers transfers, usually from a hardware event but
* also manually or by "chaining" from DMA completions.
* Each channel is coupled to a Parameter RAM (PaRAM) slot.
*
* Slot Each PaRAM slot holds a DMA transfer descriptor (PaRAM
* "set"), source and destination addresses, a link to a
* next PaRAM slot (if any), options for the transfer, and
* instructions for updating those addresses. There are
* more than twice as many slots as event channels.
*
* Each PaRAM set describes a sequence of transfers, either for one large
* buffer or for several discontiguous smaller buffers. An EDMA transfer
* is driven only from a channel, which performs the transfers specified
* in its PaRAM slot until there are no more transfers. When that last
* transfer completes, the "link" field may be used to reload the channel's
* PaRAM slot with a new transfer descriptor.
*
* The EDMA Channel Controller (CC) maps requests from channels into physical
* Transfer Controller (TC) requests when the channel triggers (by hardware
* or software events, or by chaining). The two physical DMA channels provided
* by the TCs are thus shared by many logical channels.
*
* DaVinci hardware also has a "QDMA" mechanism which is not currently
* supported through this interface. (DSP firmware uses it though.)
*/
#ifndef EDMA_H_
#define EDMA_H_
/* PaRAM slots are laid out like this */
struct edmacc_param {
unsigned int opt;
unsigned int src;
unsigned int a_b_cnt;
unsigned int dst;
unsigned int src_dst_bidx;
unsigned int link_bcntrld;
unsigned int src_dst_cidx;
unsigned int ccnt;
};
#define CCINT0_INTERRUPT 16
#define CCERRINT_INTERRUPT 17
#define TCERRINT0_INTERRUPT 18
#define TCERRINT1_INTERRUPT 19
/* fields in edmacc_param.opt */
#define SAM BIT(0)
#define DAM BIT(1)
#define SYNCDIM BIT(2)
#define STATIC BIT(3)
#define EDMA_FWID (0x07 << 8)
#define TCCMODE BIT(11)
#define EDMA_TCC(t) ((t) << 12)
#define TCINTEN BIT(20)
#define ITCINTEN BIT(21)
#define TCCHEN BIT(22)
#define ITCCHEN BIT(23)
#define TRWORD (0x7<<2)
#define PAENTRY (0x1ff<<5)
/* Drivers should avoid using these symbolic names for dm644x
* channels, and use platform_device IORESOURCE_DMA resources
* instead. (Other DaVinci chips have different peripherals
* and thus have different DMA channel mappings.)
*/
#define DAVINCI_DMA_MCBSP_TX 2
#define DAVINCI_DMA_MCBSP_RX 3
#define DAVINCI_DMA_VPSS_HIST 4
#define DAVINCI_DMA_VPSS_H3A 5
#define DAVINCI_DMA_VPSS_PRVU 6
#define DAVINCI_DMA_VPSS_RSZ 7
#define DAVINCI_DMA_IMCOP_IMXINT 8
#define DAVINCI_DMA_IMCOP_VLCDINT 9
#define DAVINCI_DMA_IMCO_PASQINT 10
#define DAVINCI_DMA_IMCOP_DSQINT 11
#define DAVINCI_DMA_SPI_SPIX 16
#define DAVINCI_DMA_SPI_SPIR 17
#define DAVINCI_DMA_UART0_URXEVT0 18
#define DAVINCI_DMA_UART0_UTXEVT0 19
#define DAVINCI_DMA_UART1_URXEVT1 20
#define DAVINCI_DMA_UART1_UTXEVT1 21
#define DAVINCI_DMA_UART2_URXEVT2 22
#define DAVINCI_DMA_UART2_UTXEVT2 23
#define DAVINCI_DMA_MEMSTK_MSEVT 24
#define DAVINCI_DMA_MMCRXEVT 26
#define DAVINCI_DMA_MMCTXEVT 27
#define DAVINCI_DMA_I2C_ICREVT 28
#define DAVINCI_DMA_I2C_ICXEVT 29
#define DAVINCI_DMA_GPIO_GPINT0 32
#define DAVINCI_DMA_GPIO_GPINT1 33
#define DAVINCI_DMA_GPIO_GPINT2 34
#define DAVINCI_DMA_GPIO_GPINT3 35
#define DAVINCI_DMA_GPIO_GPINT4 36
#define DAVINCI_DMA_GPIO_GPINT5 37
#define DAVINCI_DMA_GPIO_GPINT6 38
#define DAVINCI_DMA_GPIO_GPINT7 39
#define DAVINCI_DMA_GPIO_GPBNKINT0 40
#define DAVINCI_DMA_GPIO_GPBNKINT1 41
#define DAVINCI_DMA_GPIO_GPBNKINT2 42
#define DAVINCI_DMA_GPIO_GPBNKINT3 43
#define DAVINCI_DMA_GPIO_GPBNKINT4 44
#define DAVINCI_DMA_TIMER0_TINT0 48
#define DAVINCI_DMA_TIMER1_TINT1 49
#define DAVINCI_DMA_TIMER2_TINT2 50
#define DAVINCI_DMA_TIMER3_TINT3 51
#define DAVINCI_DMA_PWM0 52
#define DAVINCI_DMA_PWM1 53
#define DAVINCI_DMA_PWM2 54
/*ch_status paramater of callback function possible values*/
#define DMA_COMPLETE 1
#define DMA_CC_ERROR 2
#define DMA_TC1_ERROR 3
#define DMA_TC2_ERROR 4
enum address_mode {
INCR = 0,
FIFO = 1
};
enum fifo_width {
W8BIT = 0,
W16BIT = 1,
W32BIT = 2,
W64BIT = 3,
W128BIT = 4,
W256BIT = 5
};
enum dma_event_q {
EVENTQ_0 = 0,
EVENTQ_1 = 1,
EVENTQ_DEFAULT = -1
};
enum sync_dimension {
ASYNC = 0,
ABSYNC = 1
};
#define EDMA_CHANNEL_ANY -1 /* for edma_alloc_channel() */
#define EDMA_SLOT_ANY -1 /* for edma_alloc_slot() */
/* alloc/free DMA channels and their dedicated parameter RAM slots */
int edma_alloc_channel(int channel,
void (*callback)(unsigned channel, u16 ch_status, void *data),
void *data, enum dma_event_q);
void edma_free_channel(unsigned channel);
/* alloc/free parameter RAM slots */
int edma_alloc_slot(int slot);
void edma_free_slot(unsigned slot);
/* calls that operate on part of a parameter RAM slot */
void edma_set_src(unsigned slot, dma_addr_t src_port,
enum address_mode mode, enum fifo_width);
void edma_set_dest(unsigned slot, dma_addr_t dest_port,
enum address_mode mode, enum fifo_width);
void edma_get_position(unsigned slot, dma_addr_t *src, dma_addr_t *dst);
void edma_set_src_index(unsigned slot, s16 src_bidx, s16 src_cidx);
void edma_set_dest_index(unsigned slot, s16 dest_bidx, s16 dest_cidx);
void edma_set_transfer_params(unsigned slot, u16 acnt, u16 bcnt, u16 ccnt,
u16 bcnt_rld, enum sync_dimension sync_mode);
void edma_link(unsigned from, unsigned to);
void edma_unlink(unsigned from);
/* calls that operate on an entire parameter RAM slot */
void edma_write_slot(unsigned slot, const struct edmacc_param *params);
void edma_read_slot(unsigned slot, struct edmacc_param *params);
/* channel control operations */
int edma_start(unsigned channel);
void edma_stop(unsigned channel);
void edma_clean_channel(unsigned channel);
void edma_clear_event(unsigned channel);
void edma_pause(unsigned channel);
void edma_resume(unsigned channel);
/* UNRELATED TO DMA */
int davinci_alloc_iram(unsigned size);
void davinci_free_iram(unsigned addr, unsigned size);
/* platform_data for EDMA driver */
struct edma_soc_info {
/* how many dma resources of each type */
unsigned n_channel;
unsigned n_region;
unsigned n_slot;
unsigned n_tc;
/* list of channels with no even trigger; terminated by "-1" */
const s8 *noevent;
};
#endif

View File

@ -15,9 +15,11 @@
#include <linux/io.h>
#include <asm-generic/gpio.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
#define DAVINCI_GPIO_BASE 0x01C67000
/*
* basic gpio routines
*
@ -26,23 +28,18 @@
* go through boot loaders.
*
* the gpio clock will be turned on when gpios are used, and you may also
* need to pay attention to PINMUX0 and PINMUX1 to be sure those pins are
* need to pay attention to PINMUX registers to be sure those pins are
* used as gpios, not with other peripherals.
*
* On-chip GPIOs are numbered 0..(DAVINCI_N_GPIO-1). For documentation,
* and maybe for later updates, code should write GPIO(N) or:
* - GPIOV18(N) for 1.8V pins, N in 0..53; same as GPIO(0)..GPIO(53)
* - GPIOV33(N) for 3.3V pins, N in 0..17; same as GPIO(54)..GPIO(70)
*
* For GPIO IRQs use gpio_to_irq(GPIO(N)) or gpio_to_irq(GPIOV33(N)) etc
* for now, that's != GPIO(N)
* and maybe for later updates, code may write GPIO(N). These may be
* all 1.8V signals, all 3.3V ones, or a mix of the two. A given chip
* may not support all the GPIOs in that range.
*
* GPIOs can also be on external chips, numbered after the ones built-in
* to the DaVinci chip. For now, they won't be usable as IRQ sources.
*/
#define GPIO(X) (X) /* 0 <= X <= 70 */
#define GPIOV18(X) (X) /* 1.8V i/o; 0 <= X <= 53 */
#define GPIOV33(X) ((X)+54) /* 3.3V i/o; 0 <= X <= 17 */
#define GPIO(X) (X) /* 0 <= X <= (DAVINCI_N_GPIO - 1) */
struct gpio_controller {
u32 dir;
@ -71,12 +68,14 @@ __gpio_to_controller(unsigned gpio)
{
void *__iomem ptr;
if (gpio < 32)
if (gpio < 32 * 1)
ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x10);
else if (gpio < 64)
else if (gpio < 32 * 2)
ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x38);
else if (gpio < DAVINCI_N_GPIO)
else if (gpio < 32 * 3)
ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x60);
else if (gpio < 32 * 4)
ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x88);
else
ptr = NULL;
return ptr;

View File

@ -1,9 +1,9 @@
/*
* Common hardware definitions
* Hardware definitions common to all DaVinci family processors
*
* Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
* Author: Kevin Hilman, Deep Root Systems, LLC
*
* 2007 (c) MontaVista Software, Inc. This file is licensed under
* 2007 (c) Deep Root Systems, LLC. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
@ -12,41 +12,16 @@
#define __ASM_ARCH_HARDWARE_H
/*
* Base register addresses
* Before you add anything to ths file:
*
* This header is for defines common to ALL DaVinci family chips.
* Anything that is chip specific should go in <chipname>.h,
* and the chip/board init code should then explicitly include
* <chipname>.h
*/
#define DAVINCI_DMA_3PCC_BASE (0x01C00000)
#define DAVINCI_DMA_3PTC0_BASE (0x01C10000)
#define DAVINCI_DMA_3PTC1_BASE (0x01C10400)
#define DAVINCI_I2C_BASE (0x01C21000)
#define DAVINCI_PWM0_BASE (0x01C22000)
#define DAVINCI_PWM1_BASE (0x01C22400)
#define DAVINCI_PWM2_BASE (0x01C22800)
#define DAVINCI_SYSTEM_MODULE_BASE (0x01C40000)
#define DAVINCI_PLL_CNTRL0_BASE (0x01C40800)
#define DAVINCI_PLL_CNTRL1_BASE (0x01C40C00)
#define DAVINCI_PWR_SLEEP_CNTRL_BASE (0x01C41000)
#define DAVINCI_SYSTEM_DFT_BASE (0x01C42000)
#define DAVINCI_IEEE1394_BASE (0x01C60000)
#define DAVINCI_USB_OTG_BASE (0x01C64000)
#define DAVINCI_CFC_ATA_BASE (0x01C66000)
#define DAVINCI_SPI_BASE (0x01C66800)
#define DAVINCI_GPIO_BASE (0x01C67000)
#define DAVINCI_UHPI_BASE (0x01C67800)
#define DAVINCI_VPSS_REGS_BASE (0x01C70000)
#define DAVINCI_EMAC_CNTRL_REGS_BASE (0x01C80000)
#define DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE (0x01C81000)
#define DAVINCI_EMAC_WRAPPER_RAM_BASE (0x01C82000)
#define DAVINCI_MDIO_CNTRL_REGS_BASE (0x01C84000)
#define DAVINCI_IMCOP_BASE (0x01CC0000)
#define DAVINCI_ASYNC_EMIF_CNTRL_BASE (0x01E00000)
#define DAVINCI_VLYNQ_BASE (0x01E01000)
#define DAVINCI_MCBSP_BASE (0x01E02000)
#define DAVINCI_MMC_SD_BASE (0x01E10000)
#define DAVINCI_MS_BASE (0x01E20000)
#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE (0x02000000)
#define DAVINCI_ASYNC_EMIF_DATA_CE1_BASE (0x04000000)
#define DAVINCI_ASYNC_EMIF_DATA_CE2_BASE (0x06000000)
#define DAVINCI_ASYNC_EMIF_DATA_CE3_BASE (0x08000000)
#define DAVINCI_VLYNQ_REMOTE_BASE (0x0C000000)
#define DAVINCI_SYSTEM_MODULE_BASE 0x01C40000
/* System control register offsets */
#define DM64XX_VDD3P3V_PWDN 0x48
#endif /* __ASM_ARCH_HARDWARE_H */

View File

@ -40,22 +40,12 @@
#else
#define IOMEM(x) ((void __force __iomem *)(x))
/*
* Functions to access the DaVinci IO region
*
* NOTE: - Use davinci_read/write[bwl] for physical register addresses
* - Use __raw_read/write[bwl]() for virtual register addresses
* - Use IO_ADDRESS(phys_addr) to convert registers to virtual addresses
* - DO NOT use hardcoded virtual addresses to allow changing the
* IO address space again if needed
*/
#define davinci_readb(a) __raw_readb(IO_ADDRESS(a))
#define davinci_readw(a) __raw_readw(IO_ADDRESS(a))
#define davinci_readl(a) __raw_readl(IO_ADDRESS(a))
#define __arch_ioremap(p, s, t) davinci_ioremap(p, s, t)
#define __arch_iounmap(v) davinci_iounmap(v)
#define davinci_writeb(v, a) __raw_writeb(v, IO_ADDRESS(a))
#define davinci_writew(v, a) __raw_writew(v, IO_ADDRESS(a))
#define davinci_writel(v, a) __raw_writel(v, IO_ADDRESS(a))
void __iomem *davinci_ioremap(unsigned long phys, size_t size,
unsigned int type);
void davinci_iounmap(volatile void __iomem *addr);
#endif /* __ASSEMBLER__ */
#endif /* __ASM_ARCH_IO_H */

View File

@ -96,10 +96,111 @@
#define IRQ_EMUINT 63
#define DAVINCI_N_AINTC_IRQ 64
#define DAVINCI_N_GPIO 71
#define DAVINCI_N_GPIO 104
#define NR_IRQS (DAVINCI_N_AINTC_IRQ + DAVINCI_N_GPIO)
#define ARCH_TIMER_IRQ IRQ_TINT1_TINT34
/* DaVinci DM6467-specific Interrupts */
#define IRQ_DM646X_VP_VERTINT0 0
#define IRQ_DM646X_VP_VERTINT1 1
#define IRQ_DM646X_VP_VERTINT2 2
#define IRQ_DM646X_VP_VERTINT3 3
#define IRQ_DM646X_VP_ERRINT 4
#define IRQ_DM646X_RESERVED_1 5
#define IRQ_DM646X_RESERVED_2 6
#define IRQ_DM646X_WDINT 7
#define IRQ_DM646X_CRGENINT0 8
#define IRQ_DM646X_CRGENINT1 9
#define IRQ_DM646X_TSIFINT0 10
#define IRQ_DM646X_TSIFINT1 11
#define IRQ_DM646X_VDCEINT 12
#define IRQ_DM646X_USBINT 13
#define IRQ_DM646X_USBDMAINT 14
#define IRQ_DM646X_PCIINT 15
#define IRQ_DM646X_TCERRINT2 20
#define IRQ_DM646X_TCERRINT3 21
#define IRQ_DM646X_IDE 22
#define IRQ_DM646X_HPIINT 23
#define IRQ_DM646X_EMACRXTHINT 24
#define IRQ_DM646X_EMACRXINT 25
#define IRQ_DM646X_EMACTXINT 26
#define IRQ_DM646X_EMACMISCINT 27
#define IRQ_DM646X_MCASP0TXINT 28
#define IRQ_DM646X_MCASP0RXINT 29
#define IRQ_DM646X_RESERVED_3 31
#define IRQ_DM646X_MCASP1TXINT 32
#define IRQ_DM646X_VLQINT 38
#define IRQ_DM646X_UARTINT2 42
#define IRQ_DM646X_SPINT0 43
#define IRQ_DM646X_SPINT1 44
#define IRQ_DM646X_DSP2ARMINT 45
#define IRQ_DM646X_RESERVED_4 46
#define IRQ_DM646X_PSCINT 47
#define IRQ_DM646X_GPIO0 48
#define IRQ_DM646X_GPIO1 49
#define IRQ_DM646X_GPIO2 50
#define IRQ_DM646X_GPIO3 51
#define IRQ_DM646X_GPIO4 52
#define IRQ_DM646X_GPIO5 53
#define IRQ_DM646X_GPIO6 54
#define IRQ_DM646X_GPIO7 55
#define IRQ_DM646X_GPIOBNK0 56
#define IRQ_DM646X_GPIOBNK1 57
#define IRQ_DM646X_GPIOBNK2 58
#define IRQ_DM646X_DDRINT 59
#define IRQ_DM646X_AEMIFINT 60
/* DaVinci DM355-specific Interrupts */
#define IRQ_DM355_CCDC_VDINT0 0
#define IRQ_DM355_CCDC_VDINT1 1
#define IRQ_DM355_CCDC_VDINT2 2
#define IRQ_DM355_IPIPE_HST 3
#define IRQ_DM355_H3AINT 4
#define IRQ_DM355_IPIPE_SDR 5
#define IRQ_DM355_IPIPEIFINT 6
#define IRQ_DM355_OSDINT 7
#define IRQ_DM355_VENCINT 8
#define IRQ_DM355_IMCOPINT 11
#define IRQ_DM355_RTOINT 13
#define IRQ_DM355_TINT4 13
#define IRQ_DM355_TINT2_TINT12 13
#define IRQ_DM355_UARTINT2 14
#define IRQ_DM355_TINT5 14
#define IRQ_DM355_TINT2_TINT34 14
#define IRQ_DM355_TINT6 15
#define IRQ_DM355_TINT3_TINT12 15
#define IRQ_DM355_SPINT1_0 17
#define IRQ_DM355_SPINT1_1 18
#define IRQ_DM355_SPINT2_0 19
#define IRQ_DM355_SPINT2_1 21
#define IRQ_DM355_TINT7 22
#define IRQ_DM355_TINT3_TINT34 22
#define IRQ_DM355_SDIOINT0 23
#define IRQ_DM355_MMCINT0 26
#define IRQ_DM355_MSINT 26
#define IRQ_DM355_MMCINT1 27
#define IRQ_DM355_PWMINT3 28
#define IRQ_DM355_SDIOINT1 31
#define IRQ_DM355_SPINT0_0 42
#define IRQ_DM355_SPINT0_1 43
#define IRQ_DM355_GPIO0 44
#define IRQ_DM355_GPIO1 45
#define IRQ_DM355_GPIO2 46
#define IRQ_DM355_GPIO3 47
#define IRQ_DM355_GPIO4 48
#define IRQ_DM355_GPIO5 49
#define IRQ_DM355_GPIO6 50
#define IRQ_DM355_GPIO7 51
#define IRQ_DM355_GPIO8 52
#define IRQ_DM355_GPIO9 53
#define IRQ_DM355_GPIOBNK0 54
#define IRQ_DM355_GPIOBNK1 55
#define IRQ_DM355_GPIOBNK2 56
#define IRQ_DM355_GPIOBNK3 57
#define IRQ_DM355_GPIOBNK4 58
#define IRQ_DM355_GPIOBNK5 59
#define IRQ_DM355_GPIOBNK6 60
#endif /* __ASM_ARCH_IRQS_H */

View File

@ -1,55 +1,183 @@
/*
* DaVinci pin multiplexing defines
* Table of the DAVINCI register configurations for the PINMUX combinations
*
* Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com>
*
* Based on linux/include/asm-arm/arch-omap/mux.h:
* Copyright (C) 2003 - 2005 Nokia Corporation
*
* Written by Tony Lindgren
*
* 2007 (c) MontaVista Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*
* Copyright (C) 2008 Texas Instruments.
*/
#ifndef __ASM_ARCH_MUX_H
#define __ASM_ARCH_MUX_H
#define DAVINCI_MUX_AEAW0 0
#define DAVINCI_MUX_AEAW1 1
#define DAVINCI_MUX_AEAW2 2
#define DAVINCI_MUX_AEAW3 3
#define DAVINCI_MUX_AEAW4 4
#define DAVINCI_MUX_AECS4 10
#define DAVINCI_MUX_AECS5 11
#define DAVINCI_MUX_VLYNQWD0 12
#define DAVINCI_MUX_VLYNQWD1 13
#define DAVINCI_MUX_VLSCREN 14
#define DAVINCI_MUX_VLYNQEN 15
#define DAVINCI_MUX_HDIREN 16
#define DAVINCI_MUX_ATAEN 17
#define DAVINCI_MUX_RGB666 22
#define DAVINCI_MUX_RGB888 23
#define DAVINCI_MUX_LOEEN 24
#define DAVINCI_MUX_LFLDEN 25
#define DAVINCI_MUX_CWEN 26
#define DAVINCI_MUX_CFLDEN 27
#define DAVINCI_MUX_HPIEN 29
#define DAVINCI_MUX_1394EN 30
#define DAVINCI_MUX_EMACEN 31
#ifndef __INC_MACH_MUX_H
#define __INC_MACH_MUX_H
#define DAVINCI_MUX_LEVEL2 32
#define DAVINCI_MUX_UART0 (DAVINCI_MUX_LEVEL2 + 0)
#define DAVINCI_MUX_UART1 (DAVINCI_MUX_LEVEL2 + 1)
#define DAVINCI_MUX_UART2 (DAVINCI_MUX_LEVEL2 + 2)
#define DAVINCI_MUX_U2FLO (DAVINCI_MUX_LEVEL2 + 3)
#define DAVINCI_MUX_PWM0 (DAVINCI_MUX_LEVEL2 + 4)
#define DAVINCI_MUX_PWM1 (DAVINCI_MUX_LEVEL2 + 5)
#define DAVINCI_MUX_PWM2 (DAVINCI_MUX_LEVEL2 + 6)
#define DAVINCI_MUX_I2C (DAVINCI_MUX_LEVEL2 + 7)
#define DAVINCI_MUX_SPI (DAVINCI_MUX_LEVEL2 + 8)
#define DAVINCI_MUX_MSTK (DAVINCI_MUX_LEVEL2 + 9)
#define DAVINCI_MUX_ASP (DAVINCI_MUX_LEVEL2 + 10)
#define DAVINCI_MUX_CLK0 (DAVINCI_MUX_LEVEL2 + 16)
#define DAVINCI_MUX_CLK1 (DAVINCI_MUX_LEVEL2 + 17)
#define DAVINCI_MUX_TIMIN (DAVINCI_MUX_LEVEL2 + 18)
/* System module registers */
#define PINMUX0 0x00
#define PINMUX1 0x04
/* dm355 only */
#define PINMUX2 0x08
#define PINMUX3 0x0c
#define PINMUX4 0x10
#define INTMUX 0x18
#define EVTMUX 0x1c
extern void davinci_mux_peripheral(unsigned int mux, unsigned int enable);
struct mux_config {
const char *name;
const char *mux_reg_name;
const unsigned char mux_reg;
const unsigned char mask_offset;
const unsigned char mask;
const unsigned char mode;
bool debug;
};
#endif /* __ASM_ARCH_MUX_H */
enum davinci_dm644x_index {
/* ATA and HDDIR functions */
DM644X_HDIREN,
DM644X_ATAEN,
DM644X_ATAEN_DISABLE,
/* HPI functions */
DM644X_HPIEN_DISABLE,
/* AEAW functions */
DM644X_AEAW,
/* Memory Stick */
DM644X_MSTK,
/* I2C */
DM644X_I2C,
/* ASP function */
DM644X_MCBSP,
/* UART1 */
DM644X_UART1,
/* UART2 */
DM644X_UART2,
/* PWM0 */
DM644X_PWM0,
/* PWM1 */
DM644X_PWM1,
/* PWM2 */
DM644X_PWM2,
/* VLYNQ function */
DM644X_VLYNQEN,
DM644X_VLSCREN,
DM644X_VLYNQWD,
/* EMAC and MDIO function */
DM644X_EMACEN,
/* GPIO3V[0:16] pins */
DM644X_GPIO3V,
/* GPIO pins */
DM644X_GPIO0,
DM644X_GPIO3,
DM644X_GPIO43_44,
DM644X_GPIO46_47,
/* VPBE */
DM644X_RGB666,
/* LCD */
DM644X_LOEEN,
DM644X_LFLDEN,
};
enum davinci_dm646x_index {
/* ATA function */
DM646X_ATAEN,
/* AUDIO Clock */
DM646X_AUDCK1,
DM646X_AUDCK0,
/* CRGEN Control */
DM646X_CRGMUX,
/* VPIF Control */
DM646X_STSOMUX_DISABLE,
DM646X_STSIMUX_DISABLE,
DM646X_PTSOMUX_DISABLE,
DM646X_PTSIMUX_DISABLE,
/* TSIF Control */
DM646X_STSOMUX,
DM646X_STSIMUX,
DM646X_PTSOMUX_PARALLEL,
DM646X_PTSIMUX_PARALLEL,
DM646X_PTSOMUX_SERIAL,
DM646X_PTSIMUX_SERIAL,
};
enum davinci_dm355_index {
/* MMC/SD 0 */
DM355_MMCSD0,
/* MMC/SD 1 */
DM355_SD1_CLK,
DM355_SD1_CMD,
DM355_SD1_DATA3,
DM355_SD1_DATA2,
DM355_SD1_DATA1,
DM355_SD1_DATA0,
/* I2C */
DM355_I2C_SDA,
DM355_I2C_SCL,
/* ASP0 function */
DM355_MCBSP0_BDX,
DM355_MCBSP0_X,
DM355_MCBSP0_BFSX,
DM355_MCBSP0_BDR,
DM355_MCBSP0_R,
DM355_MCBSP0_BFSR,
/* SPI0 */
DM355_SPI0_SDI,
DM355_SPI0_SDENA0,
DM355_SPI0_SDENA1,
/* IRQ muxing */
DM355_INT_EDMA_CC,
DM355_INT_EDMA_TC0_ERR,
DM355_INT_EDMA_TC1_ERR,
/* EDMA event muxing */
DM355_EVT8_ASP1_TX,
DM355_EVT9_ASP1_RX,
DM355_EVT26_MMC0_RX,
};
#ifdef CONFIG_DAVINCI_MUX
/* setup pin muxing */
extern void davinci_mux_init(void);
extern int davinci_mux_register(const struct mux_config *pins,
unsigned long size);
extern int davinci_cfg_reg(unsigned long reg_cfg);
#else
/* boot loader does it all (no warnings from CONFIG_DAVINCI_MUX_WARNINGS) */
static inline void davinci_mux_init(void) {}
static inline int davinci_mux_register(const struct mux_config *pins,
unsigned long size) { return 0; }
static inline int davinci_cfg_reg(unsigned long reg_cfg) { return 0; }
#endif
#endif /* __INC_MACH_MUX_H */

View File

@ -38,8 +38,6 @@
#define DAVINCI_LPSC_TPTC1 4
#define DAVINCI_LPSC_EMAC 5
#define DAVINCI_LPSC_EMAC_WRAPPER 6
#define DAVINCI_LPSC_MDIO 7
#define DAVINCI_LPSC_IEEE1394 8
#define DAVINCI_LPSC_USB 9
#define DAVINCI_LPSC_ATA 10
#define DAVINCI_LPSC_VLYNQ 11
@ -47,7 +45,6 @@
#define DAVINCI_LPSC_DDR_EMIF 13
#define DAVINCI_LPSC_AEMIF 14
#define DAVINCI_LPSC_MMC_SD 15
#define DAVINCI_LPSC_MEMSTICK 16
#define DAVINCI_LPSC_McBSP 17
#define DAVINCI_LPSC_I2C 18
#define DAVINCI_LPSC_UART0 19
@ -73,4 +70,54 @@
#define DAVINCI_LPSC_GEM 39
#define DAVINCI_LPSC_IMCOP 40
#define DM355_LPSC_TIMER3 5
#define DM355_LPSC_SPI1 6
#define DM355_LPSC_MMC_SD1 7
#define DM355_LPSC_McBSP1 8
#define DM355_LPSC_PWM3 10
#define DM355_LPSC_SPI2 11
#define DM355_LPSC_RTO 12
#define DM355_LPSC_VPSS_DAC 41
/*
* LPSC Assignments
*/
#define DM646X_LPSC_ARM 0
#define DM646X_LPSC_C64X_CPU 1
#define DM646X_LPSC_HDVICP0 2
#define DM646X_LPSC_HDVICP1 3
#define DM646X_LPSC_TPCC 4
#define DM646X_LPSC_TPTC0 5
#define DM646X_LPSC_TPTC1 6
#define DM646X_LPSC_TPTC2 7
#define DM646X_LPSC_TPTC3 8
#define DM646X_LPSC_PCI 13
#define DM646X_LPSC_EMAC 14
#define DM646X_LPSC_VDCE 15
#define DM646X_LPSC_VPSSMSTR 16
#define DM646X_LPSC_VPSSSLV 17
#define DM646X_LPSC_TSIF0 18
#define DM646X_LPSC_TSIF1 19
#define DM646X_LPSC_DDR_EMIF 20
#define DM646X_LPSC_AEMIF 21
#define DM646X_LPSC_McASP0 22
#define DM646X_LPSC_McASP1 23
#define DM646X_LPSC_CRGEN0 24
#define DM646X_LPSC_CRGEN1 25
#define DM646X_LPSC_UART0 26
#define DM646X_LPSC_UART1 27
#define DM646X_LPSC_UART2 28
#define DM646X_LPSC_PWM0 29
#define DM646X_LPSC_PWM1 30
#define DM646X_LPSC_I2C 31
#define DM646X_LPSC_SPI 32
#define DM646X_LPSC_GPIO 33
#define DM646X_LPSC_TIMER0 34
#define DM646X_LPSC_TIMER1 35
#define DM646X_LPSC_ARM_INTC 45
extern int davinci_psc_is_clk_active(unsigned int id);
extern void davinci_psc_config(unsigned int domain, unsigned int id,
char enable);
#endif /* __ASM_ARCH_PSC_H */

View File

@ -13,8 +13,23 @@
#include <mach/io.h>
#define DAVINCI_UART0_BASE (IO_PHYS + 0x20000)
#define DAVINCI_UART1_BASE (IO_PHYS + 0x20400)
#define DAVINCI_UART2_BASE (IO_PHYS + 0x20800)
#define DAVINCI_MAX_NR_UARTS 3
#define DAVINCI_UART0_BASE (IO_PHYS + 0x20000)
#define DAVINCI_UART1_BASE (IO_PHYS + 0x20400)
#define DAVINCI_UART2_BASE (IO_PHYS + 0x20800)
#define DM355_UART2_BASE (IO_PHYS + 0x206000)
/* DaVinci UART register offsets */
#define UART_DAVINCI_PWREMU 0x0c
#define UART_DM646X_SCR 0x10
#define UART_DM646X_SCR_TX_WATERMARK 0x08
struct davinci_uart_config {
/* Bit field of UARTs present; bit 0 --> UART1 */
unsigned int enabled_uarts;
};
extern void davinci_serial_init(struct davinci_uart_config *);
#endif /* __ASM_ARCH_SERIAL_H */

View File

@ -51,7 +51,26 @@ void __init davinci_map_common_io(void)
davinci_check_revision();
}
void __init davinci_init_common_hw(void)
#define BETWEEN(p, st, sz) ((p) >= (st) && (p) < ((st) + (sz)))
#define XLATE(p, pst, vst) ((void __iomem *)((p) - (pst) + (vst)))
/*
* Intercept ioremap() requests for addresses in our fixed mapping regions.
*/
void __iomem *davinci_ioremap(unsigned long p, size_t size, unsigned int type)
{
davinci_clk_init();
if (BETWEEN(p, IO_PHYS, IO_SIZE))
return XLATE(p, IO_PHYS, IO_VIRT);
return __arm_ioremap(p, size, type);
}
EXPORT_SYMBOL(davinci_ioremap);
void davinci_iounmap(volatile void __iomem *addr)
{
unsigned long virt = (unsigned long)addr;
if (virt >= VMALLOC_START && virt < VMALLOC_END)
__iounmap(addr);
}
EXPORT_SYMBOL(davinci_iounmap);

View File

@ -25,6 +25,7 @@
#include <linux/io.h>
#include <mach/hardware.h>
#include <mach/cputype.h>
#include <asm/mach/irq.h>
#define IRQ_BIT(irq) ((irq) & 0x1f)
@ -40,14 +41,18 @@
#define IRQ_INTPRI0_REG_OFFSET 0x0030
#define IRQ_INTPRI7_REG_OFFSET 0x004C
const u8 *davinci_def_priorities;
#define INTC_BASE IO_ADDRESS(DAVINCI_ARM_INTC_BASE)
static inline unsigned int davinci_irq_readl(int offset)
{
return davinci_readl(DAVINCI_ARM_INTC_BASE + offset);
return __raw_readl(INTC_BASE + offset);
}
static inline void davinci_irq_writel(unsigned long value, int offset)
{
davinci_writel(value, DAVINCI_ARM_INTC_BASE + offset);
__raw_writel(value, INTC_BASE + offset);
}
/* Disable interrupt */
@ -108,9 +113,8 @@ static struct irq_chip davinci_irq_chip_0 = {
.unmask = davinci_unmask_irq,
};
/* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */
static const u8 default_priorities[DAVINCI_N_AINTC_IRQ] __initdata = {
static const u8 dm644x_default_priorities[DAVINCI_N_AINTC_IRQ] __initdata = {
[IRQ_VDINT0] = 2,
[IRQ_VDINT1] = 6,
[IRQ_VDINT2] = 6,
@ -177,11 +181,149 @@ static const u8 default_priorities[DAVINCI_N_AINTC_IRQ] __initdata = {
[IRQ_EMUINT] = 7,
};
static const u8 dm646x_default_priorities[DAVINCI_N_AINTC_IRQ] = {
[IRQ_DM646X_VP_VERTINT0] = 7,
[IRQ_DM646X_VP_VERTINT1] = 7,
[IRQ_DM646X_VP_VERTINT2] = 7,
[IRQ_DM646X_VP_VERTINT3] = 7,
[IRQ_DM646X_VP_ERRINT] = 7,
[IRQ_DM646X_RESERVED_1] = 7,
[IRQ_DM646X_RESERVED_2] = 7,
[IRQ_DM646X_WDINT] = 7,
[IRQ_DM646X_CRGENINT0] = 7,
[IRQ_DM646X_CRGENINT1] = 7,
[IRQ_DM646X_TSIFINT0] = 7,
[IRQ_DM646X_TSIFINT1] = 7,
[IRQ_DM646X_VDCEINT] = 7,
[IRQ_DM646X_USBINT] = 7,
[IRQ_DM646X_USBDMAINT] = 7,
[IRQ_DM646X_PCIINT] = 7,
[IRQ_CCINT0] = 7, /* dma */
[IRQ_CCERRINT] = 7, /* dma */
[IRQ_TCERRINT0] = 7, /* dma */
[IRQ_TCERRINT] = 7, /* dma */
[IRQ_DM646X_TCERRINT2] = 7,
[IRQ_DM646X_TCERRINT3] = 7,
[IRQ_DM646X_IDE] = 7,
[IRQ_DM646X_HPIINT] = 7,
[IRQ_DM646X_EMACRXTHINT] = 7,
[IRQ_DM646X_EMACRXINT] = 7,
[IRQ_DM646X_EMACTXINT] = 7,
[IRQ_DM646X_EMACMISCINT] = 7,
[IRQ_DM646X_MCASP0TXINT] = 7,
[IRQ_DM646X_MCASP0RXINT] = 7,
[IRQ_AEMIFINT] = 7,
[IRQ_DM646X_RESERVED_3] = 7,
[IRQ_DM646X_MCASP1TXINT] = 7, /* clockevent */
[IRQ_TINT0_TINT34] = 7, /* clocksource */
[IRQ_TINT1_TINT12] = 7, /* DSP timer */
[IRQ_TINT1_TINT34] = 7, /* system tick */
[IRQ_PWMINT0] = 7,
[IRQ_PWMINT1] = 7,
[IRQ_DM646X_VLQINT] = 7,
[IRQ_I2C] = 7,
[IRQ_UARTINT0] = 7,
[IRQ_UARTINT1] = 7,
[IRQ_DM646X_UARTINT2] = 7,
[IRQ_DM646X_SPINT0] = 7,
[IRQ_DM646X_SPINT1] = 7,
[IRQ_DM646X_DSP2ARMINT] = 7,
[IRQ_DM646X_RESERVED_4] = 7,
[IRQ_DM646X_PSCINT] = 7,
[IRQ_DM646X_GPIO0] = 7,
[IRQ_DM646X_GPIO1] = 7,
[IRQ_DM646X_GPIO2] = 7,
[IRQ_DM646X_GPIO3] = 7,
[IRQ_DM646X_GPIO4] = 7,
[IRQ_DM646X_GPIO5] = 7,
[IRQ_DM646X_GPIO6] = 7,
[IRQ_DM646X_GPIO7] = 7,
[IRQ_DM646X_GPIOBNK0] = 7,
[IRQ_DM646X_GPIOBNK1] = 7,
[IRQ_DM646X_GPIOBNK2] = 7,
[IRQ_DM646X_DDRINT] = 7,
[IRQ_DM646X_AEMIFINT] = 7,
[IRQ_COMMTX] = 7,
[IRQ_COMMRX] = 7,
[IRQ_EMUINT] = 7,
};
static const u8 dm355_default_priorities[DAVINCI_N_AINTC_IRQ] = {
[IRQ_DM355_CCDC_VDINT0] = 2,
[IRQ_DM355_CCDC_VDINT1] = 6,
[IRQ_DM355_CCDC_VDINT2] = 6,
[IRQ_DM355_IPIPE_HST] = 6,
[IRQ_DM355_H3AINT] = 6,
[IRQ_DM355_IPIPE_SDR] = 6,
[IRQ_DM355_IPIPEIFINT] = 6,
[IRQ_DM355_OSDINT] = 7,
[IRQ_DM355_VENCINT] = 6,
[IRQ_ASQINT] = 6,
[IRQ_IMXINT] = 6,
[IRQ_USBINT] = 4,
[IRQ_DM355_RTOINT] = 4,
[IRQ_DM355_UARTINT2] = 7,
[IRQ_DM355_TINT6] = 7,
[IRQ_CCINT0] = 5, /* dma */
[IRQ_CCERRINT] = 5, /* dma */
[IRQ_TCERRINT0] = 5, /* dma */
[IRQ_TCERRINT] = 5, /* dma */
[IRQ_DM355_SPINT2_1] = 7,
[IRQ_DM355_TINT7] = 4,
[IRQ_DM355_SDIOINT0] = 7,
[IRQ_MBXINT] = 7,
[IRQ_MBRINT] = 7,
[IRQ_MMCINT] = 7,
[IRQ_DM355_MMCINT1] = 7,
[IRQ_DM355_PWMINT3] = 7,
[IRQ_DDRINT] = 7,
[IRQ_AEMIFINT] = 7,
[IRQ_DM355_SDIOINT1] = 4,
[IRQ_TINT0_TINT12] = 2, /* clockevent */
[IRQ_TINT0_TINT34] = 2, /* clocksource */
[IRQ_TINT1_TINT12] = 7, /* DSP timer */
[IRQ_TINT1_TINT34] = 7, /* system tick */
[IRQ_PWMINT0] = 7,
[IRQ_PWMINT1] = 7,
[IRQ_PWMINT2] = 7,
[IRQ_I2C] = 3,
[IRQ_UARTINT0] = 3,
[IRQ_UARTINT1] = 3,
[IRQ_DM355_SPINT0_0] = 3,
[IRQ_DM355_SPINT0_1] = 3,
[IRQ_DM355_GPIO0] = 3,
[IRQ_DM355_GPIO1] = 7,
[IRQ_DM355_GPIO2] = 4,
[IRQ_DM355_GPIO3] = 4,
[IRQ_DM355_GPIO4] = 7,
[IRQ_DM355_GPIO5] = 7,
[IRQ_DM355_GPIO6] = 7,
[IRQ_DM355_GPIO7] = 7,
[IRQ_DM355_GPIO8] = 7,
[IRQ_DM355_GPIO9] = 7,
[IRQ_DM355_GPIOBNK0] = 7,
[IRQ_DM355_GPIOBNK1] = 7,
[IRQ_DM355_GPIOBNK2] = 7,
[IRQ_DM355_GPIOBNK3] = 7,
[IRQ_DM355_GPIOBNK4] = 7,
[IRQ_DM355_GPIOBNK5] = 7,
[IRQ_DM355_GPIOBNK6] = 7,
[IRQ_COMMTX] = 7,
[IRQ_COMMRX] = 7,
[IRQ_EMUINT] = 7,
};
/* ARM Interrupt Controller Initialization */
void __init davinci_irq_init(void)
{
unsigned i;
const u8 *priority = default_priorities;
if (cpu_is_davinci_dm644x())
davinci_def_priorities = dm644x_default_priorities;
else if (cpu_is_davinci_dm646x())
davinci_def_priorities = dm646x_default_priorities;
else if (cpu_is_davinci_dm355())
davinci_def_priorities = dm355_default_priorities;
/* Clear all interrupt requests */
davinci_irq_writel(~0x0, FIQ_REG0_OFFSET);
@ -209,8 +351,8 @@ void __init davinci_irq_init(void)
unsigned j;
u32 pri;
for (j = 0, pri = 0; j < 32; j += 4, priority++)
pri |= (*priority & 0x07) << j;
for (j = 0, pri = 0; j < 32; j += 4, davinci_def_priorities++)
pri |= (*davinci_def_priorities & 0x07) << j;
davinci_irq_writel(pri, i);
}

View File

@ -1,41 +1,103 @@
/*
* DaVinci pin multiplexing configurations
* Utility to set the DAVINCI MUX register from a table in mux.h
*
* Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com>
*
* Based on linux/arch/arm/plat-omap/mux.c:
* Copyright (C) 2003 - 2005 Nokia Corporation
*
* Written by Tony Lindgren
*
* 2007 (c) MontaVista Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*
* Copyright (C) 2008 Texas Instruments.
*/
#include <linux/io.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <mach/hardware.h>
#include <mach/mux.h>
/* System control register offsets */
#define PINMUX0 0x00
#define PINMUX1 0x04
static const struct mux_config *mux_table;
static unsigned long pin_table_sz;
static DEFINE_SPINLOCK(mux_lock);
void davinci_mux_peripheral(unsigned int mux, unsigned int enable)
int __init davinci_mux_register(const struct mux_config *pins,
unsigned long size)
{
u32 pinmux, muxreg = PINMUX0;
mux_table = pins;
pin_table_sz = size;
if (mux >= DAVINCI_MUX_LEVEL2) {
muxreg = PINMUX1;
mux -= DAVINCI_MUX_LEVEL2;
return 0;
}
/*
* Sets the DAVINCI MUX register based on the table
*/
int __init_or_module davinci_cfg_reg(const unsigned long index)
{
static DEFINE_SPINLOCK(mux_spin_lock);
void __iomem *base = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE);
unsigned long flags;
const struct mux_config *cfg;
unsigned int reg_orig = 0, reg = 0;
unsigned int mask, warn = 0;
if (!mux_table)
BUG();
if (index >= pin_table_sz) {
printk(KERN_ERR "Invalid pin mux index: %lu (%lu)\n",
index, pin_table_sz);
dump_stack();
return -ENODEV;
}
spin_lock(&mux_lock);
pinmux = davinci_readl(DAVINCI_SYSTEM_MODULE_BASE + muxreg);
if (enable)
pinmux |= (1 << mux);
else
pinmux &= ~(1 << mux);
davinci_writel(pinmux, DAVINCI_SYSTEM_MODULE_BASE + muxreg);
spin_unlock(&mux_lock);
cfg = &mux_table[index];
if (cfg->name == NULL) {
printk(KERN_ERR "No entry for the specified index\n");
return -ENODEV;
}
/* Update the mux register in question */
if (cfg->mask) {
unsigned tmp1, tmp2;
spin_lock_irqsave(&mux_spin_lock, flags);
reg_orig = __raw_readl(base + cfg->mux_reg);
mask = (cfg->mask << cfg->mask_offset);
tmp1 = reg_orig & mask;
reg = reg_orig & ~mask;
tmp2 = (cfg->mode << cfg->mask_offset);
reg |= tmp2;
if (tmp1 != tmp2)
warn = 1;
__raw_writel(reg, base + cfg->mux_reg);
spin_unlock_irqrestore(&mux_spin_lock, flags);
}
if (warn) {
#ifdef CONFIG_DAVINCI_MUX_WARNINGS
printk(KERN_WARNING "MUX: initialized %s\n", cfg->name);
#endif
}
#ifdef CONFIG_DAVINCI_MUX_DEBUG
if (cfg->debug || warn) {
printk(KERN_WARNING "MUX: Setting register %s\n", cfg->name);
printk(KERN_WARNING " %s (0x%08x) = 0x%08x -> 0x%08x\n",
cfg->mux_reg_name, cfg->mux_reg, reg_orig, reg);
}
#endif
return 0;
}
EXPORT_SYMBOL(davinci_cfg_reg);

View File

@ -0,0 +1,51 @@
/*
* Pin-multiplex helper macros for TI DaVinci family devices
*
* Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com>
*
* 2007 (c) MontaVista Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*
* Copyright (C) 2008 Texas Instruments.
*/
#ifndef _MACH_DAVINCI_MUX_H_
#define _MACH_DAVINCI_MUX_H_
#include <mach/mux.h>
#define MUX_CFG(soc, desc, muxreg, mode_offset, mode_mask, mux_mode, dbg)\
[soc##_##desc] = { \
.name = #desc, \
.debug = dbg, \
.mux_reg_name = "PINMUX"#muxreg, \
.mux_reg = PINMUX##muxreg, \
.mask_offset = mode_offset, \
.mask = mode_mask, \
.mode = mux_mode, \
},
#define INT_CFG(soc, desc, mode_offset, mode_mask, mux_mode, dbg) \
[soc##_##desc] = { \
.name = #desc, \
.debug = dbg, \
.mux_reg_name = "INTMUX", \
.mux_reg = INTMUX, \
.mask_offset = mode_offset, \
.mask = mode_mask, \
.mode = mux_mode, \
},
#define EVT_CFG(soc, desc, mode_offset, mode_mask, mux_mode, dbg) \
[soc##_##desc] = { \
.name = #desc, \
.debug = dbg, \
.mux_reg_name = "EVTMUX", \
.mux_reg = EVTMUX, \
.mask_offset = mode_offset, \
.mask = mode_mask, \
.mode = mux_mode, \
},
#endif /* _MACH_DAVINCI_MUX_H */

View File

@ -23,10 +23,13 @@
#include <linux/init.h>
#include <linux/io.h>
#include <mach/cputype.h>
#include <mach/hardware.h>
#include <mach/psc.h>
#include <mach/mux.h>
#define DAVINCI_PWR_SLEEP_CNTRL_BASE 0x01C41000
/* PSC register offsets */
#define EPCPR 0x070
#define PTCMD 0x120
@ -36,102 +39,61 @@
#define MDSTAT 0x800
#define MDCTL 0xA00
/* System control register offsets */
#define VDD3P3V_PWDN 0x48
#define MDSTAT_STATE_MASK 0x1f
static void davinci_psc_mux(unsigned int id)
/* Return nonzero iff the domain's clock is active */
int __init davinci_psc_is_clk_active(unsigned int id)
{
switch (id) {
case DAVINCI_LPSC_ATA:
davinci_mux_peripheral(DAVINCI_MUX_HDIREN, 1);
davinci_mux_peripheral(DAVINCI_MUX_ATAEN, 1);
break;
case DAVINCI_LPSC_MMC_SD:
/* VDD power manupulations are done in U-Boot for CPMAC
* so applies to MMC as well
*/
/*Set up the pull regiter for MMC */
davinci_writel(0, DAVINCI_SYSTEM_MODULE_BASE + VDD3P3V_PWDN);
davinci_mux_peripheral(DAVINCI_MUX_MSTK, 0);
break;
case DAVINCI_LPSC_I2C:
davinci_mux_peripheral(DAVINCI_MUX_I2C, 1);
break;
case DAVINCI_LPSC_McBSP:
davinci_mux_peripheral(DAVINCI_MUX_ASP, 1);
break;
default:
break;
}
void __iomem *psc_base = IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE);
u32 mdstat = __raw_readl(psc_base + MDSTAT + 4 * id);
/* if clocked, state can be "Enable" or "SyncReset" */
return mdstat & BIT(12);
}
/* Enable or disable a PSC domain */
void davinci_psc_config(unsigned int domain, unsigned int id, char enable)
{
u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl, mdstat_mask;
u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl;
void __iomem *psc_base = IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE);
u32 next_state = enable ? 0x3 : 0x2; /* 0x3 enables, 0x2 disables */
mdctl = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + MDCTL + 4 * id);
if (enable)
mdctl |= 0x00000003; /* Enable Module */
else
mdctl &= 0xFFFFFFF2; /* Disable Module */
davinci_writel(mdctl, DAVINCI_PWR_SLEEP_CNTRL_BASE + MDCTL + 4 * id);
mdctl = __raw_readl(psc_base + MDCTL + 4 * id);
mdctl &= ~MDSTAT_STATE_MASK;
mdctl |= next_state;
__raw_writel(mdctl, psc_base + MDCTL + 4 * id);
pdstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + PDSTAT);
pdstat = __raw_readl(psc_base + PDSTAT);
if ((pdstat & 0x00000001) == 0) {
pdctl1 = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
pdctl1 = __raw_readl(psc_base + PDCTL1);
pdctl1 |= 0x1;
davinci_writel(pdctl1, DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
__raw_writel(pdctl1, psc_base + PDCTL1);
ptcmd = 1 << domain;
davinci_writel(ptcmd, DAVINCI_PWR_SLEEP_CNTRL_BASE + PTCMD);
__raw_writel(ptcmd, psc_base + PTCMD);
do {
epcpr = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
EPCPR);
epcpr = __raw_readl(psc_base + EPCPR);
} while ((((epcpr >> domain) & 1) == 0));
pdctl1 = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
pdctl1 = __raw_readl(psc_base + PDCTL1);
pdctl1 |= 0x100;
davinci_writel(pdctl1, DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
__raw_writel(pdctl1, psc_base + PDCTL1);
do {
ptstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
ptstat = __raw_readl(psc_base +
PTSTAT);
} while (!(((ptstat >> domain) & 1) == 0));
} else {
ptcmd = 1 << domain;
davinci_writel(ptcmd, DAVINCI_PWR_SLEEP_CNTRL_BASE + PTCMD);
__raw_writel(ptcmd, psc_base + PTCMD);
do {
ptstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
PTSTAT);
ptstat = __raw_readl(psc_base + PTSTAT);
} while (!(((ptstat >> domain) & 1) == 0));
}
if (enable)
mdstat_mask = 0x3;
else
mdstat_mask = 0x2;
do {
mdstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
MDSTAT + 4 * id);
} while (!((mdstat & 0x0000001F) == mdstat_mask));
if (enable)
davinci_psc_mux(id);
}
void __init davinci_psc_init(void)
{
davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_VPSSMSTR, 1);
davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_VPSSSLV, 1);
davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TPCC, 1);
davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TPTC0, 1);
davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TPTC1, 1);
davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_GPIO, 1);
/* Turn on WatchDog timer LPSC. Needed for RESET to work */
davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TIMER2, 1);
mdstat = __raw_readl(psc_base + MDSTAT + 4 * id);
} while (!((mdstat & MDSTAT_STATE_MASK) == next_state));
}

View File

@ -32,32 +32,47 @@
#include <mach/hardware.h>
#include <mach/serial.h>
#include <mach/irqs.h>
#include <mach/cputype.h>
#include "clock.h"
#define UART_DAVINCI_PWREMU 0x0c
static inline unsigned int davinci_serial_in(struct plat_serial8250_port *up,
int offset)
static inline unsigned int serial_read_reg(struct plat_serial8250_port *up,
int offset)
{
offset <<= up->regshift;
return (unsigned int)__raw_readb(up->membase + offset);
return (unsigned int)__raw_readl(IO_ADDRESS(up->mapbase) + offset);
}
static inline void davinci_serial_outp(struct plat_serial8250_port *p,
int offset, int value)
static inline void serial_write_reg(struct plat_serial8250_port *p, int offset,
int value)
{
offset <<= p->regshift;
__raw_writeb(value, p->membase + offset);
__raw_writel(value, IO_ADDRESS(p->mapbase) + offset);
}
static struct plat_serial8250_port serial_platform_data[] = {
{
.membase = (char *)IO_ADDRESS(DAVINCI_UART0_BASE),
.mapbase = (unsigned long)DAVINCI_UART0_BASE,
.mapbase = DAVINCI_UART0_BASE,
.irq = IRQ_UARTINT0,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
UPF_IOREMAP,
.iotype = UPIO_MEM,
.regshift = 2,
},
{
.mapbase = DAVINCI_UART1_BASE,
.irq = IRQ_UARTINT1,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
UPF_IOREMAP,
.iotype = UPIO_MEM,
.regshift = 2,
},
{
.mapbase = DAVINCI_UART2_BASE,
.irq = IRQ_UARTINT2,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
UPF_IOREMAP,
.iotype = UPIO_MEM,
.regshift = 2,
.uartclk = 27000000,
},
{
.flags = 0
@ -74,22 +89,68 @@ static struct platform_device serial_device = {
static void __init davinci_serial_reset(struct plat_serial8250_port *p)
{
/* reset both transmitter and receiver: bits 14,13 = UTRST, URRST */
unsigned int pwremu = 0;
davinci_serial_outp(p, UART_IER, 0); /* disable all interrupts */
serial_write_reg(p, UART_IER, 0); /* disable all interrupts */
davinci_serial_outp(p, UART_DAVINCI_PWREMU, pwremu);
/* reset both transmitter and receiver: bits 14,13 = UTRST, URRST */
serial_write_reg(p, UART_DAVINCI_PWREMU, pwremu);
mdelay(10);
pwremu |= (0x3 << 13);
pwremu |= 0x1;
davinci_serial_outp(p, UART_DAVINCI_PWREMU, pwremu);
serial_write_reg(p, UART_DAVINCI_PWREMU, pwremu);
if (cpu_is_davinci_dm646x())
serial_write_reg(p, UART_DM646X_SCR,
UART_DM646X_SCR_TX_WATERMARK);
}
void __init davinci_serial_init(struct davinci_uart_config *info)
{
int i;
char name[16];
struct clk *uart_clk;
struct device *dev = &serial_device.dev;
/*
* 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.
*/
for (i = 0; i < DAVINCI_MAX_NR_UARTS; i++) {
struct plat_serial8250_port *p = serial_platform_data + i;
if (!(info->enabled_uarts & (1 << i))) {
p->flags = 0;
continue;
}
if (cpu_is_davinci_dm646x())
p->iotype = UPIO_MEM32;
if (cpu_is_davinci_dm355()) {
if (i == 2) {
p->mapbase = (unsigned long)DM355_UART2_BASE;
p->irq = IRQ_DM355_UARTINT2;
}
}
sprintf(name, "uart%d", i);
uart_clk = clk_get(dev, name);
if (IS_ERR(uart_clk))
printk(KERN_ERR "%s:%d: failed to get UART%d clock\n",
__func__, __LINE__, i);
else {
clk_enable(uart_clk);
p->uartclk = clk_get_rate(uart_clk);
davinci_serial_reset(p);
}
}
}
static int __init davinci_init(void)
{
davinci_serial_reset(&serial_platform_data[0]);
return platform_device_register(&serial_device);
}

View File

@ -16,6 +16,9 @@
#include <linux/clockchips.h>
#include <linux/spinlock.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/device.h>
#include <mach/hardware.h>
#include <asm/system.h>
@ -24,8 +27,11 @@
#include <asm/mach/time.h>
#include <asm/errno.h>
#include <mach/io.h>
#include <mach/cputype.h>
#include "clock.h"
static struct clock_event_device clockevent_davinci;
static unsigned int davinci_clock_tick_rate;
#define DAVINCI_TIMER0_BASE (IO_PHYS + 0x21400)
#define DAVINCI_TIMER1_BASE (IO_PHYS + 0x21800)
@ -99,9 +105,9 @@ struct timer_s {
unsigned int id;
unsigned long period;
unsigned long opts;
unsigned long reg_base;
unsigned long tim_reg;
unsigned long prd_reg;
void __iomem *base;
unsigned long tim_off;
unsigned long prd_off;
unsigned long enamode_shift;
struct irqaction irqaction;
};
@ -114,15 +120,15 @@ static struct timer_s timers[];
static int timer32_config(struct timer_s *t)
{
u32 tcr = davinci_readl(t->reg_base + TCR);
u32 tcr = __raw_readl(t->base + TCR);
/* disable timer */
tcr &= ~(TCR_ENAMODE_MASK << t->enamode_shift);
davinci_writel(tcr, t->reg_base + TCR);
__raw_writel(tcr, t->base + TCR);
/* reset counter to zero, set new period */
davinci_writel(0, t->tim_reg);
davinci_writel(t->period, t->prd_reg);
__raw_writel(0, t->base + t->tim_off);
__raw_writel(t->period, t->base + t->prd_off);
/* Set enable mode */
if (t->opts & TIMER_OPTS_ONESHOT) {
@ -131,13 +137,13 @@ static int timer32_config(struct timer_s *t)
tcr |= TCR_ENAMODE_PERIODIC << t->enamode_shift;
}
davinci_writel(tcr, t->reg_base + TCR);
__raw_writel(tcr, t->base + TCR);
return 0;
}
static inline u32 timer32_read(struct timer_s *t)
{
return davinci_readl(t->tim_reg);
return __raw_readl(t->base + t->tim_off);
}
static irqreturn_t timer_interrupt(int irq, void *dev_id)
@ -176,51 +182,54 @@ static struct timer_s timers[] = {
static void __init timer_init(void)
{
u32 bases[] = {DAVINCI_TIMER0_BASE, DAVINCI_TIMER1_BASE};
u32 phys_bases[] = {DAVINCI_TIMER0_BASE, DAVINCI_TIMER1_BASE};
int i;
/* Global init of each 64-bit timer as a whole */
for(i=0; i<2; i++) {
u32 tgcr, base = bases[i];
u32 tgcr;
void __iomem *base = IO_ADDRESS(phys_bases[i]);
/* Disabled, Internal clock source */
davinci_writel(0, base + TCR);
__raw_writel(0, base + TCR);
/* reset both timers, no pre-scaler for timer34 */
tgcr = 0;
davinci_writel(tgcr, base + TGCR);
__raw_writel(tgcr, base + TGCR);
/* Set both timers to unchained 32-bit */
tgcr = TGCR_TIMMODE_32BIT_UNCHAINED << TGCR_TIMMODE_SHIFT;
davinci_writel(tgcr, base + TGCR);
__raw_writel(tgcr, base + TGCR);
/* Unreset timers */
tgcr |= (TGCR_UNRESET << TGCR_TIM12RS_SHIFT) |
(TGCR_UNRESET << TGCR_TIM34RS_SHIFT);
davinci_writel(tgcr, base + TGCR);
__raw_writel(tgcr, base + TGCR);
/* Init both counters to zero */
davinci_writel(0, base + TIM12);
davinci_writel(0, base + TIM34);
__raw_writel(0, base + TIM12);
__raw_writel(0, base + TIM34);
}
/* Init of each timer as a 32-bit timer */
for (i=0; i< ARRAY_SIZE(timers); i++) {
struct timer_s *t = &timers[i];
u32 phys_base;
if (t->name) {
t->id = i;
t->reg_base = (IS_TIMER1(t->id) ?
phys_base = (IS_TIMER1(t->id) ?
DAVINCI_TIMER1_BASE : DAVINCI_TIMER0_BASE);
t->base = IO_ADDRESS(phys_base);
if (IS_TIMER_BOT(t->id)) {
t->enamode_shift = 6;
t->tim_reg = t->reg_base + TIM12;
t->prd_reg = t->reg_base + PRD12;
t->tim_off = TIM12;
t->prd_off = PRD12;
} else {
t->enamode_shift = 22;
t->tim_reg = t->reg_base + TIM34;
t->prd_reg = t->reg_base + PRD34;
t->tim_off = TIM34;
t->prd_off = PRD34;
}
/* Register interrupt */
@ -274,7 +283,7 @@ static void davinci_set_mode(enum clock_event_mode mode,
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
t->period = CLOCK_TICK_RATE / (HZ);
t->period = davinci_clock_tick_rate / (HZ);
t->opts = TIMER_OPTS_PERIODIC;
timer32_config(t);
break;
@ -301,21 +310,29 @@ static struct clock_event_device clockevent_davinci = {
static void __init davinci_timer_init(void)
{
struct clk *timer_clk;
static char err[] __initdata = KERN_ERR
"%s: can't register clocksource!\n";
/* init timer hw */
timer_init();
timer_clk = clk_get(NULL, "timer0");
BUG_ON(IS_ERR(timer_clk));
clk_enable(timer_clk);
davinci_clock_tick_rate = clk_get_rate(timer_clk);
/* setup clocksource */
clocksource_davinci.mult =
clocksource_khz2mult(CLOCK_TICK_RATE/1000,
clocksource_khz2mult(davinci_clock_tick_rate/1000,
clocksource_davinci.shift);
if (clocksource_register(&clocksource_davinci))
printk(err, clocksource_davinci.name);
/* setup clockevent */
clockevent_davinci.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC,
clockevent_davinci.mult = div_sc(davinci_clock_tick_rate, NSEC_PER_SEC,
clockevent_davinci.shift);
clockevent_davinci.max_delta_ns =
clockevent_delta2ns(0xfffffffe, &clockevent_davinci);
@ -333,42 +350,52 @@ struct sys_timer davinci_timer = {
/* reset board using watchdog timer */
void davinci_watchdog_reset(void) {
u32 tgcr, wdtcr, base = DAVINCI_WDOG_BASE;
u32 tgcr, wdtcr;
void __iomem *base = IO_ADDRESS(DAVINCI_WDOG_BASE);
struct device dev;
struct clk *wd_clk;
char *name = "watchdog";
dev_set_name(&dev, name);
wd_clk = clk_get(&dev, NULL);
if (WARN_ON(IS_ERR(wd_clk)))
return;
clk_enable(wd_clk);
/* disable, internal clock source */
davinci_writel(0, base + TCR);
__raw_writel(0, base + TCR);
/* reset timer, set mode to 64-bit watchdog, and unreset */
tgcr = 0;
davinci_writel(tgcr, base + TCR);
__raw_writel(tgcr, base + TCR);
tgcr = TGCR_TIMMODE_64BIT_WDOG << TGCR_TIMMODE_SHIFT;
tgcr |= (TGCR_UNRESET << TGCR_TIM12RS_SHIFT) |
(TGCR_UNRESET << TGCR_TIM34RS_SHIFT);
davinci_writel(tgcr, base + TCR);
__raw_writel(tgcr, base + TCR);
/* clear counter and period regs */
davinci_writel(0, base + TIM12);
davinci_writel(0, base + TIM34);
davinci_writel(0, base + PRD12);
davinci_writel(0, base + PRD34);
__raw_writel(0, base + TIM12);
__raw_writel(0, base + TIM34);
__raw_writel(0, base + PRD12);
__raw_writel(0, base + PRD34);
/* enable */
wdtcr = davinci_readl(base + WDTCR);
wdtcr = __raw_readl(base + WDTCR);
wdtcr |= WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT;
davinci_writel(wdtcr, base + WDTCR);
__raw_writel(wdtcr, base + WDTCR);
/* put watchdog in pre-active state */
wdtcr = (WDTCR_WDKEY_SEQ0 << WDTCR_WDKEY_SHIFT) |
(WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT);
davinci_writel(wdtcr, base + WDTCR);
__raw_writel(wdtcr, base + WDTCR);
/* put watchdog in active state */
wdtcr = (WDTCR_WDKEY_SEQ1 << WDTCR_WDKEY_SHIFT) |
(WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT);
davinci_writel(wdtcr, base + WDTCR);
__raw_writel(wdtcr, base + WDTCR);
/* write an invalid value to the WDKEY field to trigger
* a watchdog reset */
wdtcr = 0x00004000;
davinci_writel(wdtcr, base + WDTCR);
__raw_writel(wdtcr, base + WDTCR);
}

View File

@ -14,6 +14,8 @@
#include <mach/hardware.h>
#include <mach/irqs.h>
#define DAVINCI_USB_OTG_BASE 0x01C64000
#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE)
static struct musb_hdrc_eps_bits musb_eps[] = {
{ "ep1_tx", 8, },

View File

@ -1,11 +0,0 @@
menu "IMX Implementations"
depends on ARCH_IMX
config ARCH_MX1ADS
bool "mx1ads"
depends on ARCH_IMX
select ISA
help
Say Y here if you are using the Motorola MX1ADS board
endmenu

View File

@ -1,18 +0,0 @@
#
# Makefile for the linux kernel.
#
# Object file lists.
obj-y += irq.o time.o dma.o generic.o clock.o
obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o
# Specific board support
obj-$(CONFIG_ARCH_MX1ADS) += mx1ads.o
# Support for blinky lights
led-y := leds.o
obj-$(CONFIG_LEDS) += $(led-y)
led-$(CONFIG_ARCH_MX1ADS) += leds-mx1ads.o

View File

@ -1,2 +0,0 @@
zreladdr-$(CONFIG_ARCH_MX1ADS) := 0x08008000

View File

@ -1,210 +0,0 @@
/*
* Copyright (C) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
*
* 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/kernel.h>
#include <linux/device.h>
#include <linux/list.h>
#include <linux/math64.h>
#include <linux/err.h>
#include <linux/io.h>
#include <mach/hardware.h>
/*
* Very simple approach: We can't disable clocks, so we do
* not need refcounting
*/
struct clk {
struct list_head node;
const char *name;
unsigned long (*get_rate)(void);
};
/*
* get the system pll clock in Hz
*
* mfi + mfn / (mfd +1)
* f = 2 * f_ref * --------------------
* pd + 1
*/
static unsigned long imx_decode_pll(unsigned int pll, u32 f_ref)
{
unsigned long long ll;
unsigned long quot;
u32 mfi = (pll >> 10) & 0xf;
u32 mfn = pll & 0x3ff;
u32 mfd = (pll >> 16) & 0x3ff;
u32 pd = (pll >> 26) & 0xf;
mfi = mfi <= 5 ? 5 : mfi;
ll = 2 * (unsigned long long)f_ref *
((mfi << 16) + (mfn << 16) / (mfd + 1));
quot = (pd + 1) * (1 << 16);
ll += quot / 2;
do_div(ll, quot);
return (unsigned long)ll;
}
static unsigned long imx_get_system_clk(void)
{
u32 f_ref = (CSCR & CSCR_SYSTEM_SEL) ? 16000000 : (CLK32 * 512);
return imx_decode_pll(SPCTL0, f_ref);
}
static unsigned long imx_get_mcu_clk(void)
{
return imx_decode_pll(MPCTL0, CLK32 * 512);
}
/*
* get peripheral clock 1 ( UART[12], Timer[12], PWM )
*/
static unsigned long imx_get_perclk1(void)
{
return imx_get_system_clk() / (((PCDR) & 0xf)+1);
}
/*
* get peripheral clock 2 ( LCD, SD, SPI[12] )
*/
static unsigned long imx_get_perclk2(void)
{
return imx_get_system_clk() / (((PCDR>>4) & 0xf)+1);
}
/*
* get peripheral clock 3 ( SSI )
*/
static unsigned long imx_get_perclk3(void)
{
return imx_get_system_clk() / (((PCDR>>16) & 0x7f)+1);
}
/*
* get hclk ( SDRAM, CSI, Memory Stick, I2C, DMA )
*/
static unsigned long imx_get_hclk(void)
{
return imx_get_system_clk() / (((CSCR>>10) & 0xf)+1);
}
static struct clk clk_system_clk = {
.name = "system_clk",
.get_rate = imx_get_system_clk,
};
static struct clk clk_hclk = {
.name = "hclk",
.get_rate = imx_get_hclk,
};
static struct clk clk_mcu_clk = {
.name = "mcu_clk",
.get_rate = imx_get_mcu_clk,
};
static struct clk clk_perclk1 = {
.name = "perclk1",
.get_rate = imx_get_perclk1,
};
static struct clk clk_uart_clk = {
.name = "uart_clk",
.get_rate = imx_get_perclk1,
};
static struct clk clk_perclk2 = {
.name = "perclk2",
.get_rate = imx_get_perclk2,
};
static struct clk clk_perclk3 = {
.name = "perclk3",
.get_rate = imx_get_perclk3,
};
static struct clk *clks[] = {
&clk_perclk1,
&clk_perclk2,
&clk_perclk3,
&clk_system_clk,
&clk_hclk,
&clk_mcu_clk,
&clk_uart_clk,
};
static LIST_HEAD(clocks);
static DEFINE_MUTEX(clocks_mutex);
struct clk *clk_get(struct device *dev, const char *id)
{
struct clk *p, *clk = ERR_PTR(-ENOENT);
mutex_lock(&clocks_mutex);
list_for_each_entry(p, &clocks, node) {
if (!strcmp(p->name, id)) {
clk = p;
goto found;
}
}
found:
mutex_unlock(&clocks_mutex);
return clk;
}
EXPORT_SYMBOL(clk_get);
void clk_put(struct clk *clk)
{
}
EXPORT_SYMBOL(clk_put);
int clk_enable(struct clk *clk)
{
return 0;
}
EXPORT_SYMBOL(clk_enable);
void clk_disable(struct clk *clk)
{
}
EXPORT_SYMBOL(clk_disable);
unsigned long clk_get_rate(struct clk *clk)
{
return clk->get_rate();
}
EXPORT_SYMBOL(clk_get_rate);
int imx_clocks_init(void)
{
int i;
mutex_lock(&clocks_mutex);
for (i = 0; i < ARRAY_SIZE(clks); i++)
list_add(&clks[i]->node, &clocks);
mutex_unlock(&clocks_mutex);
return 0;
}

View File

@ -1,315 +0,0 @@
/*
* cpu.c: clock scaling for the iMX
*
* Copyright (C) 2000 2001, The Delft University of Technology
* Copyright (c) 2004 Sascha Hauer <sascha@saschahauer.de>
* Copyright (C) 2006 Inky Lung <ilung@cwlinux.com>
* Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com>
*
* Based on SA1100 version written by:
* - Johan Pouwelse (J.A.Pouwelse@its.tudelft.nl): initial version
* - Erik Mouw (J.A.K.Mouw@its.tudelft.nl):
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/*#define DEBUG*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/cpufreq.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <asm/system.h>
#include <mach/hardware.h>
#include "generic.h"
#ifndef __val2mfld
#define __val2mfld(mask,val) (((mask)&~((mask)<<1))*(val)&(mask))
#endif
#ifndef __mfld2val
#define __mfld2val(mask,val) (((val)&(mask))/((mask)&~((mask)<<1)))
#endif
#define CR_920T_CLOCK_MODE 0xC0000000
#define CR_920T_FASTBUS_MODE 0x00000000
#define CR_920T_ASYNC_MODE 0xC0000000
static u32 mpctl0_at_boot;
static u32 bclk_div_at_boot;
static struct clk *system_clk, *mcu_clk;
static void imx_set_async_mode(void)
{
adjust_cr(CR_920T_CLOCK_MODE, CR_920T_ASYNC_MODE);
}
static void imx_set_fastbus_mode(void)
{
adjust_cr(CR_920T_CLOCK_MODE, CR_920T_FASTBUS_MODE);
}
static void imx_set_mpctl0(u32 mpctl0)
{
unsigned long flags;
if (mpctl0 == 0) {
local_irq_save(flags);
CSCR &= ~CSCR_MPEN;
local_irq_restore(flags);
return;
}
local_irq_save(flags);
MPCTL0 = mpctl0;
CSCR |= CSCR_MPEN;
local_irq_restore(flags);
}
/**
* imx_compute_mpctl - compute new PLL parameters
* @new_mpctl: pointer to location assigned by new PLL control register value
* @cur_mpctl: current PLL control register parameters
* @f_ref: reference source frequency Hz
* @freq: required frequency in Hz
* @relation: is one of %CPUFREQ_RELATION_L (supremum)
* and %CPUFREQ_RELATION_H (infimum)
*/
long imx_compute_mpctl(u32 *new_mpctl, u32 cur_mpctl, u32 f_ref, unsigned long freq, int relation)
{
u32 mfi;
u32 mfn;
u32 mfd;
u32 pd;
unsigned long long ll;
long l;
long quot;
/* Fdppl=2*Fref*(MFI+MFN/(MFD+1))/(PD+1) */
/* PD=<0,15>, MFD=<1,1023>, MFI=<5,15> MFN=<0,1022> */
if (cur_mpctl) {
mfd = ((cur_mpctl >> 16) & 0x3ff) + 1;
pd = ((cur_mpctl >> 26) & 0xf) + 1;
} else {
pd=2; mfd=313;
}
/* pd=2; mfd=313; mfi=8; mfn=183; */
/* (MFI+MFN/(MFD)) = Fdppl / (2*Fref) * (PD); */
quot = (f_ref + (1 << 9)) >> 10;
l = (freq * pd + quot) / (2 * quot);
mfi = l >> 10;
mfn = ((l & ((1 << 10) - 1)) * mfd + (1 << 9)) >> 10;
mfd -= 1;
pd -= 1;
*new_mpctl = ((mfi & 0xf) << 10) | (mfn & 0x3ff) | ((mfd & 0x3ff) << 16)
| ((pd & 0xf) << 26);
ll = 2 * (unsigned long long)f_ref * ( (mfi<<16) + (mfn<<16) / (mfd+1) );
quot = (pd+1) * (1<<16);
ll += quot / 2;
do_div(ll, quot);
freq = ll;
pr_debug(KERN_DEBUG "imx: new PLL parameters pd=%d mfd=%d mfi=%d mfn=%d, freq=%ld\n",
pd, mfd, mfi, mfn, freq);
return freq;
}
static int imx_verify_speed(struct cpufreq_policy *policy)
{
if (policy->cpu != 0)
return -EINVAL;
cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, policy->cpuinfo.max_freq);
return 0;
}
static unsigned int imx_get_speed(unsigned int cpu)
{
unsigned int freq;
unsigned int cr;
unsigned int cscr;
unsigned int bclk_div;
if (cpu)
return 0;
cscr = CSCR;
bclk_div = __mfld2val(CSCR_BCLK_DIV, cscr) + 1;
cr = get_cr();
if((cr & CR_920T_CLOCK_MODE) == CR_920T_FASTBUS_MODE) {
freq = clk_get_rate(system_clk);
freq = (freq + bclk_div/2) / bclk_div;
} else {
freq = clk_get_rate(mcu_clk);
if (cscr & CSCR_MPU_PRESC)
freq /= 2;
}
freq = (freq + 500) / 1000;
return freq;
}
static int imx_set_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{
struct cpufreq_freqs freqs;
u32 mpctl0 = 0;
u32 cscr;
unsigned long flags;
long freq;
long sysclk;
unsigned int bclk_div = bclk_div_at_boot;
/*
* Some governors do not respects CPU and policy lower limits
* which leads to bad things (division by zero etc), ensure
* that such things do not happen.
*/
if(target_freq < policy->cpuinfo.min_freq)
target_freq = policy->cpuinfo.min_freq;
if(target_freq < policy->min)
target_freq = policy->min;
freq = target_freq * 1000;
pr_debug(KERN_DEBUG "imx: requested frequency %ld Hz, mpctl0 at boot 0x%08x\n",
freq, mpctl0_at_boot);
sysclk = clk_get_rate(system_clk);
if (freq > sysclk / bclk_div_at_boot + 1000000) {
freq = imx_compute_mpctl(&mpctl0, mpctl0_at_boot, CLK32 * 512, freq, relation);
if (freq < 0) {
printk(KERN_WARNING "imx: target frequency %ld Hz cannot be set\n", freq);
return -EINVAL;
}
} else {
if(freq + 1000 < sysclk) {
if (relation == CPUFREQ_RELATION_L)
bclk_div = (sysclk - 1000) / freq;
else
bclk_div = (sysclk + freq + 1000) / freq;
if(bclk_div > 16)
bclk_div = 16;
if(bclk_div < bclk_div_at_boot)
bclk_div = bclk_div_at_boot;
}
freq = (sysclk + bclk_div / 2) / bclk_div;
}
freqs.old = imx_get_speed(0);
freqs.new = (freq + 500) / 1000;
freqs.cpu = 0;
freqs.flags = 0;
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
local_irq_save(flags);
imx_set_fastbus_mode();
imx_set_mpctl0(mpctl0);
cscr = CSCR;
cscr &= ~CSCR_BCLK_DIV;
cscr |= __val2mfld(CSCR_BCLK_DIV, bclk_div - 1);
CSCR = cscr;
if(mpctl0) {
CSCR |= CSCR_MPLL_RESTART;
/* Wait until MPLL is stabilized */
while( CSCR & CSCR_MPLL_RESTART );
imx_set_async_mode();
}
local_irq_restore(flags);
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
pr_debug(KERN_INFO "imx: set frequency %ld Hz, running from %s\n",
freq, mpctl0? "MPLL": "SPLL");
return 0;
}
static int __init imx_cpufreq_driver_init(struct cpufreq_policy *policy)
{
printk(KERN_INFO "i.MX cpu freq change driver v1.0\n");
if (policy->cpu != 0)
return -EINVAL;
policy->cur = policy->min = policy->max = imx_get_speed(0);
policy->cpuinfo.min_freq = 8000;
policy->cpuinfo.max_freq = 200000;
/* Manual states, that PLL stabilizes in two CLK32 periods */
policy->cpuinfo.transition_latency = 4 * 1000000000LL / CLK32;
return 0;
}
static struct cpufreq_driver imx_driver = {
.flags = CPUFREQ_STICKY,
.verify = imx_verify_speed,
.target = imx_set_target,
.get = imx_get_speed,
.init = imx_cpufreq_driver_init,
.name = "imx",
};
static int __init imx_cpufreq_init(void)
{
bclk_div_at_boot = __mfld2val(CSCR_BCLK_DIV, CSCR) + 1;
mpctl0_at_boot = 0;
system_clk = clk_get(NULL, "system_clk");
if (IS_ERR(system_clk))
return PTR_ERR(system_clk);
mcu_clk = clk_get(NULL, "mcu_clk");
if (IS_ERR(mcu_clk)) {
clk_put(system_clk);
return PTR_ERR(mcu_clk);
}
if((CSCR & CSCR_MPEN) &&
((get_cr() & CR_920T_CLOCK_MODE) != CR_920T_FASTBUS_MODE))
mpctl0_at_boot = MPCTL0;
return cpufreq_register_driver(&imx_driver);
}
arch_initcall(imx_cpufreq_init);

View File

@ -1,597 +0,0 @@
/*
* linux/arch/arm/mach-imx/dma.c
*
* imx DMA registration and IRQ dispatching
*
* 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.
*
* 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
*
* 2006-05-31 Pavel Pisa <pisa@cmp.felk.cvut.cz>
* Corrected error handling code.
*
*/
#undef DEBUG
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
#include <asm/scatterlist.h>
#include <asm/system.h>
#include <asm/irq.h>
#include <mach/hardware.h>
#include <mach/dma.h>
#include <mach/imx-dma.h>
struct imx_dma_channel imx_dma_channels[IMX_DMA_CHANNELS];
/*
* 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)
{
struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
unsigned int nextcount;
unsigned int nextaddr;
if (!imxdma->name) {
printk(KERN_CRIT "%s: called for not allocated channel %d\n",
__func__, dma_ch);
return 0;
}
imxdma->resbytes -= lastcount;
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(imxdma->resbytes < nextcount)
nextcount = imxdma->resbytes;
if ((imxdma->dma_mode & DMA_MODE_MASK) == DMA_MODE_READ)
DAR(dma_ch) = nextaddr;
else
SAR(dma_ch) = nextaddr;
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;
}
/*
* 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 transferred.
* 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,
unsigned int 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 sets up 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 careful here 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, unsigned int 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 *),
void (*err_handler) (int, void *, int),
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",
__func__, 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",
__func__, 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;
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",
__func__, 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",
__func__, dma_ch);
return;
}
local_irq_save(flags);
/* Disable interrupts */
DIMR |= (1 << dma_ch);
CCR(dma_ch) &= ~CCR_CEN;
imxdma->name = NULL;
local_irq_restore(flags);
}
/**
* imx_dma_request_by_prio - find and request some of free channels best suiting requested priority
* @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.
* On successful allocation channel is returned.
*/
imx_dmach_t imx_dma_request_by_prio(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)) {
return i;
}
}
for (i = best - 1; i >= 0; i--) {
if (!imx_dma_request(i, name)) {
return i;
}
}
printk(KERN_ERR "%s: no free DMA channel found\n", __func__);
return -ENODEV;
}
static irqreturn_t dma_err_handler(int irq, void *dev_id)
{
int i, disr = DISR;
struct imx_dma_channel *channel;
unsigned int err_mask = DBTOSR | DRTOSR | DSESR | DBOSR;
int errcode;
DISR = disr & err_mask;
for (i = 0; i < IMX_DMA_CHANNELS; i++) {
if(!(err_mask & (1 << i)))
continue;
channel = &imx_dma_channels[i];
errcode = 0;
if (DBTOSR & (1 << i)) {
DBTOSR = (1 << i);
errcode |= IMX_DMA_ERR_BURST;
}
if (DRTOSR & (1 << i)) {
DRTOSR = (1 << i);
errcode |= IMX_DMA_ERR_REQUEST;
}
if (DSESR & (1 << i)) {
DSESR = (1 << i);
errcode |= IMX_DMA_ERR_TRANSFER;
}
if (DBOSR & (1 << i)) {
DBOSR = (1 << i);
errcode |= IMX_DMA_ERR_BUFFER;
}
/*
* The cleaning of @sg field would be questionable
* there, because its value can help to compute
* remaining/transferred bytes count in the handler
*/
/*imx_dma_channels[i].sg = NULL;*/
if (channel->name && channel->err_handler) {
channel->err_handler(i, channel->data, errcode);
continue;
}
imx_dma_channels[i].sg = NULL;
printk(KERN_WARNING
"DMA timeout on channel %d (%s) -%s%s%s%s\n",
i, channel->name,
errcode&IMX_DMA_ERR_BURST? " burst":"",
errcode&IMX_DMA_ERR_REQUEST? " request":"",
errcode&IMX_DMA_ERR_TRANSFER? " transfer":"",
errcode&IMX_DMA_ERR_BUFFER? " buffer":"");
}
return IRQ_HANDLED;
}
static irqreturn_t dma_irq_handler(int irq, void *dev_id)
{
int i, disr = DISR;
pr_debug("imxdma: dma_irq_handler called, disr=0x%08x\n",
disr);
DISR = disr;
for (i = 0; i < IMX_DMA_CHANNELS; i++) {
if (disr & (1 << i)) {
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);
}
} else {
/*
* IRQ for an unregistered DMA channel:
* let's clear the interrupts and disable it.
*/
printk(KERN_WARNING
"spurious IRQ for DMA channel %d\n", i);
}
}
}
return IRQ_HANDLED;
}
static int __init imx_dma_init(void)
{
int ret;
int i;
/* reset DMA module */
DCR = DCR_DRST;
ret = request_irq(DMA_INT, dma_irq_handler, 0, "DMA", NULL);
if (ret) {
printk(KERN_CRIT "Wow! Can't register IRQ for DMA\n");
return ret;
}
ret = request_irq(DMA_ERR, dma_err_handler, 0, "DMA", NULL);
if (ret) {
printk(KERN_CRIT "Wow! Can't register ERRIRQ for DMA\n");
free_irq(DMA_INT, NULL);
}
/* enable DMA module */
DCR = DCR_DEN;
/* clear all interrupts */
DISR = (1 << IMX_DMA_CHANNELS) - 1;
/* enable interrupts */
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_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);

View File

@ -1,271 +0,0 @@
/*
* arch/arm/mach-imx/generic.c
*
* author: Sascha Hauer
* Created: april 20th, 2004
* Copyright: Synertronixx GmbH
*
* Common code for i.MX machines
*
* 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/platform_device.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/string.h>
#include <asm/errno.h>
#include <mach/hardware.h>
#include <mach/imx-regs.h>
#include <asm/mach/map.h>
#include <mach/mmc.h>
#include <mach/gpio.h>
unsigned long imx_gpio_alloc_map[(GPIO_PORT_MAX + 1) * 32 / BITS_PER_LONG];
void imx_gpio_mode(int gpio_mode)
{
unsigned int pin = gpio_mode & GPIO_PIN_MASK;
unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> GPIO_OCR_SHIFT;
unsigned int tmp;
/* Pullup enable */
if(gpio_mode & GPIO_PUEN)
PUEN(port) |= (1<<pin);
else
PUEN(port) &= ~(1<<pin);
/* Data direction */
if(gpio_mode & GPIO_OUT)
DDIR(port) |= 1<<pin;
else
DDIR(port) &= ~(1<<pin);
/* Primary / alternate function */
if(gpio_mode & GPIO_AF)
GPR(port) |= (1<<pin);
else
GPR(port) &= ~(1<<pin);
/* use as gpio? */
if(gpio_mode & GPIO_GIUS)
GIUS(port) |= (1<<pin);
else
GIUS(port) &= ~(1<<pin);
/* Output / input configuration */
/* FIXME: I'm not very sure about OCR and ICONF, someone
* should have a look over it
*/
if(pin<16) {
tmp = OCR1(port);
tmp &= ~( 3<<(pin*2));
tmp |= (ocr << (pin*2));
OCR1(port) = tmp;
ICONFA1(port) &= ~( 3<<(pin*2));
ICONFA1(port) |= ((gpio_mode >> GPIO_AOUT_SHIFT) & 3) << (pin * 2);
ICONFB1(port) &= ~( 3<<(pin*2));
ICONFB1(port) |= ((gpio_mode >> GPIO_BOUT_SHIFT) & 3) << (pin * 2);
} else {
tmp = OCR2(port);
tmp &= ~( 3<<((pin-16)*2));
tmp |= (ocr << ((pin-16)*2));
OCR2(port) = tmp;
ICONFA2(port) &= ~( 3<<((pin-16)*2));
ICONFA2(port) |= ((gpio_mode >> GPIO_AOUT_SHIFT) & 3) << ((pin-16) * 2);
ICONFB2(port) &= ~( 3<<((pin-16)*2));
ICONFB2(port) |= ((gpio_mode >> GPIO_BOUT_SHIFT) & 3) << ((pin-16) * 2);
}
}
EXPORT_SYMBOL(imx_gpio_mode);
int imx_gpio_request(unsigned gpio, const char *label)
{
if(gpio >= (GPIO_PORT_MAX + 1) * 32) {
printk(KERN_ERR "imx_gpio: Attempt to request nonexistent GPIO %d for \"%s\"\n",
gpio, label ? label : "?");
return -EINVAL;
}
if(test_and_set_bit(gpio, imx_gpio_alloc_map)) {
printk(KERN_ERR "imx_gpio: GPIO %d already used. Allocation for \"%s\" failed\n",
gpio, label ? label : "?");
return -EBUSY;
}
return 0;
}
EXPORT_SYMBOL(imx_gpio_request);
void imx_gpio_free(unsigned gpio)
{
if(gpio >= (GPIO_PORT_MAX + 1) * 32)
return;
clear_bit(gpio, imx_gpio_alloc_map);
}
EXPORT_SYMBOL(imx_gpio_free);
int imx_gpio_direction_input(unsigned gpio)
{
imx_gpio_mode(gpio | GPIO_IN | GPIO_GIUS | GPIO_DR);
return 0;
}
EXPORT_SYMBOL(imx_gpio_direction_input);
int imx_gpio_direction_output(unsigned gpio, int value)
{
imx_gpio_set_value(gpio, value);
imx_gpio_mode(gpio | GPIO_OUT | GPIO_GIUS | GPIO_DR);
return 0;
}
EXPORT_SYMBOL(imx_gpio_direction_output);
int imx_gpio_setup_multiple_pins(const int *pin_list, unsigned count,
int alloc_mode, const char *label)
{
const int *p = pin_list;
int i;
unsigned gpio;
unsigned mode;
for (i = 0; i < count; i++) {
gpio = *p & (GPIO_PIN_MASK | GPIO_PORT_MASK);
mode = *p & ~(GPIO_PIN_MASK | GPIO_PORT_MASK);
if (gpio >= (GPIO_PORT_MAX + 1) * 32)
goto setup_error;
if (alloc_mode & IMX_GPIO_ALLOC_MODE_RELEASE)
imx_gpio_free(gpio);
else if (!(alloc_mode & IMX_GPIO_ALLOC_MODE_NO_ALLOC))
if (imx_gpio_request(gpio, label))
if (!(alloc_mode & IMX_GPIO_ALLOC_MODE_TRY_ALLOC))
goto setup_error;
if (!(alloc_mode & (IMX_GPIO_ALLOC_MODE_ALLOC_ONLY |
IMX_GPIO_ALLOC_MODE_RELEASE)))
imx_gpio_mode(gpio | mode);
p++;
}
return 0;
setup_error:
if(alloc_mode & (IMX_GPIO_ALLOC_MODE_NO_ALLOC |
IMX_GPIO_ALLOC_MODE_TRY_ALLOC))
return -EINVAL;
while (p != pin_list) {
p--;
gpio = *p & (GPIO_PIN_MASK | GPIO_PORT_MASK);
imx_gpio_free(gpio);
}
return -EINVAL;
}
EXPORT_SYMBOL(imx_gpio_setup_multiple_pins);
void __imx_gpio_set_value(unsigned gpio, int value)
{
imx_gpio_set_value_inline(gpio, value);
}
EXPORT_SYMBOL(__imx_gpio_set_value);
int imx_gpio_to_irq(unsigned gpio)
{
return IRQ_GPIOA(0) + gpio;
}
EXPORT_SYMBOL(imx_gpio_to_irq);
int imx_irq_to_gpio(unsigned irq)
{
if (irq < IRQ_GPIOA(0))
return -EINVAL;
return irq - IRQ_GPIOA(0);
}
EXPORT_SYMBOL(imx_irq_to_gpio);
static struct resource imx_mmc_resources[] = {
[0] = {
.start = 0x00214000,
.end = 0x002140FF,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = (SDHC_INT),
.end = (SDHC_INT),
.flags = IORESOURCE_IRQ,
},
};
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;
}
static struct platform_device *devices[] __initdata = {
&imx_mmc_device,
};
static struct map_desc imx_io_desc[] __initdata = {
{
.virtual = IMX_IO_BASE,
.pfn = __phys_to_pfn(IMX_IO_PHYS),
.length = IMX_IO_SIZE,
.type = MT_DEVICE
}
};
void __init
imx_map_io(void)
{
iotable_init(imx_io_desc, ARRAY_SIZE(imx_io_desc));
}
static int __init imx_init(void)
{
return platform_add_devices(devices, ARRAY_SIZE(devices));
}
subsys_initcall(imx_init);

View File

@ -1,16 +0,0 @@
/*
* linux/arch/arm/mach-imx/generic.h
*
* Author: Sascha Hauer <sascha@saschahauer.de>
* Copyright: Synertronixx GmbH
*
* 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.
*/
extern void __init imx_map_io(void);
extern void __init imx_init_irq(void);
struct sys_timer;
extern struct sys_timer imx_timer;

View File

@ -1,34 +0,0 @@
/* arch/arm/mach-imx/include/mach/debug-macro.S
*
* Debugging macro include header
*
* Copyright (C) 1994-1999 Russell King
* Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
*
* 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.
*
*/
.macro addruart,rx
mrc p15, 0, \rx, c1, c0
tst \rx, #1 @ MMU enabled?
moveq \rx, #0x00000000 @ physical
movne \rx, #0xe0000000 @ virtual
orreq \rx, \rx, #0x00200000 @ physical
orr \rx, \rx, #0x00006000 @ UART1 offset
.endm
.macro senduart,rd,rx
str \rd, [\rx, #0x40] @ TXDATA
.endm
.macro waituart,rd,rx
.endm
.macro busyuart,rd,rx
1002: ldr \rd, [\rx, #0x98] @ SR2
tst \rd, #1 << 3 @ TXDC
beq 1002b @ wait until transmit done
.endm

View File

@ -1,56 +0,0 @@
/*
* linux/include/asm-arm/imxads/dma.h
*
* Copyright (C) 1997,1998 Russell King
*
* 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
*/
#ifndef __ASM_ARCH_DMA_H
#define __ASM_ARCH_DMA_H
typedef enum {
DMA_PRIO_HIGH = 0,
DMA_PRIO_MEDIUM = 1,
DMA_PRIO_LOW = 2
} imx_dma_prio;
#define DMA_REQ_UART3_T 2
#define DMA_REQ_UART3_R 3
#define DMA_REQ_SSI2_T 4
#define DMA_REQ_SSI2_R 5
#define DMA_REQ_CSI_STAT 6
#define DMA_REQ_CSI_R 7
#define DMA_REQ_MSHC 8
#define DMA_REQ_DSPA_DCT_DOUT 9
#define DMA_REQ_DSPA_DCT_DIN 10
#define DMA_REQ_DSPA_MAC 11
#define DMA_REQ_EXT 12
#define DMA_REQ_SDHC 13
#define DMA_REQ_SPI1_R 14
#define DMA_REQ_SPI1_T 15
#define DMA_REQ_SSI_T 16
#define DMA_REQ_SSI_R 17
#define DMA_REQ_ASP_DAC 18
#define DMA_REQ_ASP_ADC 19
#define DMA_REQ_USP_EP(x) (20+(x))
#define DMA_REQ_SPI2_R 26
#define DMA_REQ_SPI2_T 27
#define DMA_REQ_UART2_T 28
#define DMA_REQ_UART2_R 29
#define DMA_REQ_UART1_T 30
#define DMA_REQ_UART1_R 31
#endif /* _ASM_ARCH_DMA_H */

View File

@ -1,32 +0,0 @@
/*
* arch/arm/mach-imx/include/mach/entry-macro.S
*
* Low-level IRQ helper macros for iMX-based platforms
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <mach/hardware.h>
.macro disable_fiq
.endm
.macro get_irqnr_preamble, base, tmp
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm
#define AITC_NIVECSR 0x40
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
ldr \base, =IO_ADDRESS(IMX_AITC_BASE)
@ Load offset & priority of the highest priority
@ interrupt pending.
ldr \irqstat, [\base, #AITC_NIVECSR]
@ Shift off the priority leaving the offset or
@ "interrupt number", use arithmetic shift to
@ transform illegal source (0xffff) as -1
mov \irqnr, \irqstat, asr #16
adds \tmp, \irqnr, #1
.endm

View File

@ -1,106 +0,0 @@
#ifndef _IMX_GPIO_H
#include <linux/kernel.h>
#include <mach/hardware.h>
#include <mach/imx-regs.h>
#define IMX_GPIO_ALLOC_MODE_NORMAL 0
#define IMX_GPIO_ALLOC_MODE_NO_ALLOC 1
#define IMX_GPIO_ALLOC_MODE_TRY_ALLOC 2
#define IMX_GPIO_ALLOC_MODE_ALLOC_ONLY 4
#define IMX_GPIO_ALLOC_MODE_RELEASE 8
extern int imx_gpio_request(unsigned gpio, const char *label);
extern void imx_gpio_free(unsigned gpio);
extern int imx_gpio_setup_multiple_pins(const int *pin_list, unsigned count,
int alloc_mode, const char *label);
extern int imx_gpio_direction_input(unsigned gpio);
extern int imx_gpio_direction_output(unsigned gpio, int value);
extern void __imx_gpio_set_value(unsigned gpio, int value);
static inline int imx_gpio_get_value(unsigned gpio)
{
return SSR(gpio >> GPIO_PORT_SHIFT) & (1 << (gpio & GPIO_PIN_MASK));
}
static inline void imx_gpio_set_value_inline(unsigned gpio, int value)
{
unsigned long flags;
raw_local_irq_save(flags);
if(value)
DR(gpio >> GPIO_PORT_SHIFT) |= (1 << (gpio & GPIO_PIN_MASK));
else
DR(gpio >> GPIO_PORT_SHIFT) &= ~(1 << (gpio & GPIO_PIN_MASK));
raw_local_irq_restore(flags);
}
static inline void imx_gpio_set_value(unsigned gpio, int value)
{
if(__builtin_constant_p(gpio))
imx_gpio_set_value_inline(gpio, value);
else
__imx_gpio_set_value(gpio, value);
}
extern int imx_gpio_to_irq(unsigned gpio);
extern int imx_irq_to_gpio(unsigned irq);
/*-------------------------------------------------------------------------*/
/* Wrappers for "new style" GPIO calls. These calls i.MX specific versions
* to allow future extension of GPIO logic.
*/
static inline int gpio_request(unsigned gpio, const char *label)
{
return imx_gpio_request(gpio, label);
}
static inline void gpio_free(unsigned gpio)
{
might_sleep();
imx_gpio_free(gpio);
}
static inline int gpio_direction_input(unsigned gpio)
{
return imx_gpio_direction_input(gpio);
}
static inline int gpio_direction_output(unsigned gpio, int value)
{
return imx_gpio_direction_output(gpio, value);
}
static inline int gpio_get_value(unsigned gpio)
{
return imx_gpio_get_value(gpio);
}
static inline void gpio_set_value(unsigned gpio, int value)
{
imx_gpio_set_value(gpio, value);
}
#include <asm-generic/gpio.h> /* cansleep wrappers */
static inline int gpio_to_irq(unsigned gpio)
{
return imx_gpio_to_irq(gpio);
}
static inline int irq_to_gpio(unsigned irq)
{
return imx_irq_to_gpio(irq);
}
#endif

View File

@ -1,91 +0,0 @@
/*
* arch/arm/mach-imx/include/mach/hardware.h
*
* Copyright (C) 1999 ARM Limited.
*
* 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
*/
#ifndef __ASM_ARCH_HARDWARE_H
#define __ASM_ARCH_HARDWARE_H
#include <asm/sizes.h>
#include "imx-regs.h"
#ifndef __ASSEMBLY__
# define __REG(x) (*((volatile u32 *)IO_ADDRESS(x)))
# define __REG2(x,y) (*(volatile u32 *)((u32)&__REG(x) + (y)))
#endif
/*
* Memory map
*/
#define IMX_IO_PHYS 0x00200000
#define IMX_IO_SIZE 0x00100000
#define IMX_IO_BASE 0xe0000000
#define IMX_CS0_PHYS 0x10000000
#define IMX_CS0_SIZE 0x02000000
#define IMX_CS0_VIRT 0xe8000000
#define IMX_CS1_PHYS 0x12000000
#define IMX_CS1_SIZE 0x01000000
#define IMX_CS1_VIRT 0xea000000
#define IMX_CS2_PHYS 0x13000000
#define IMX_CS2_SIZE 0x01000000
#define IMX_CS2_VIRT 0xeb000000
#define IMX_CS3_PHYS 0x14000000
#define IMX_CS3_SIZE 0x01000000
#define IMX_CS3_VIRT 0xec000000
#define IMX_CS4_PHYS 0x15000000
#define IMX_CS4_SIZE 0x01000000
#define IMX_CS4_VIRT 0xed000000
#define IMX_CS5_PHYS 0x16000000
#define IMX_CS5_SIZE 0x01000000
#define IMX_CS5_VIRT 0xee000000
#define IMX_FB_VIRT 0xF1000000
#define IMX_FB_SIZE (256*1024)
/* macro to get at IO space when running virtually */
#define IO_ADDRESS(x) ((x) | IMX_IO_BASE)
#ifndef __ASSEMBLY__
/*
* Handy routine to set GPIO functions
*/
extern void imx_gpio_mode( int gpio_mode );
#endif
#define MAXIRQNUM 62
#define MAXFIQNUM 62
#define MAXSWINUM 62
/*
* Use SDRAM for memory
*/
#define MEM_SIZE 0x01000000
#ifdef CONFIG_ARCH_MX1ADS
#include "mx1ads.h"
#endif
#endif

View File

@ -1,98 +0,0 @@
/*
* linux/include/asm-arm/imxads/dma.h
*
* Copyright (C) 1997,1998 Russell King
*
* 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 <mach/dma.h>
#ifndef __ASM_ARCH_IMX_DMA_H
#define __ASM_ARCH_IMX_DMA_H
#define IMX_DMA_CHANNELS 11
/*
* struct imx_dma_channel - i.MX specific DMA extension
* @name: name specified by DMA client
* @irq_handler: client callback for end of transfer
* @err_handler: client callback for error condition
* @data: clients context data for callbacks
* @dma_mode: direction of the transfer %DMA_MODE_READ or %DMA_MODE_WRITE
* @sg: pointer to the actual read/written chunk for scatter-gather emulation
* @sgbc: counter of processed bytes in the actual read/written chunk
* @resbytes: total residual number of bytes to transfer
* (it can be lower or same as sum of SG mapped chunk sizes)
* @sgcount: number of chunks to be read/written
*
* Structure is used for IMX DMA processing. It would be probably good
* @struct dma_struct in the future for external interfacing and use
* @struct imx_dma_channel only as extension to it.
*/
struct imx_dma_channel {
const char *name;
void (*irq_handler) (int, void *);
void (*err_handler) (int, void *, int errcode);
void *data;
unsigned int dma_mode;
struct scatterlist *sg;
unsigned int sgbc;
unsigned int sgcount;
unsigned int resbytes;
int dma_num;
};
extern struct imx_dma_channel imx_dma_channels[IMX_DMA_CHANNELS];
#define IMX_DMA_ERR_BURST 1
#define IMX_DMA_ERR_REQUEST 2
#define IMX_DMA_ERR_TRANSFER 4
#define IMX_DMA_ERR_BUFFER 8
/* The type to distinguish channel numbers parameter from ordinal int type */
typedef int imx_dmach_t;
#define DMA_MODE_READ 0
#define DMA_MODE_WRITE 1
#define DMA_MODE_MASK 1
int
imx_dma_setup_single(imx_dmach_t dma_ch, dma_addr_t dma_address,
unsigned int dma_length, unsigned int dev_addr, unsigned int dmamode);
int
imx_dma_setup_sg(imx_dmach_t dma_ch,
struct scatterlist *sg, unsigned int sgcount, unsigned int dma_length,
unsigned int dev_addr, unsigned int dmamode);
int
imx_dma_setup_handlers(imx_dmach_t dma_ch,
void (*irq_handler) (int, void *),
void (*err_handler) (int, void *, int), void *data);
void imx_dma_enable(imx_dmach_t dma_ch);
void imx_dma_disable(imx_dmach_t dma_ch);
int imx_dma_request(imx_dmach_t dma_ch, const char *name);
void imx_dma_free(imx_dmach_t dma_ch);
imx_dmach_t imx_dma_request_by_prio(const char *name, imx_dma_prio prio);
#endif /* _ASM_ARCH_IMX_DMA_H */

View File

@ -1,376 +0,0 @@
#ifndef _IMX_REGS_H
#define _IMX_REGS_H
/* ------------------------------------------------------------------------
* Motorola IMX system registers
* ------------------------------------------------------------------------
*
*/
/*
* Register BASEs, based on OFFSETs
*
*/
#define IMX_AIPI1_BASE (0x00000 + IMX_IO_BASE)
#define IMX_WDT_BASE (0x01000 + IMX_IO_BASE)
#define IMX_TIM1_BASE (0x02000 + IMX_IO_BASE)
#define IMX_TIM2_BASE (0x03000 + IMX_IO_BASE)
#define IMX_RTC_BASE (0x04000 + IMX_IO_BASE)
#define IMX_LCDC_BASE (0x05000 + IMX_IO_BASE)
#define IMX_UART1_BASE (0x06000 + IMX_IO_BASE)
#define IMX_UART2_BASE (0x07000 + IMX_IO_BASE)
#define IMX_PWM_BASE (0x08000 + IMX_IO_BASE)
#define IMX_DMAC_BASE (0x09000 + IMX_IO_BASE)
#define IMX_AIPI2_BASE (0x10000 + IMX_IO_BASE)
#define IMX_SIM_BASE (0x11000 + IMX_IO_BASE)
#define IMX_USBD_BASE (0x12000 + IMX_IO_BASE)
#define IMX_SPI1_BASE (0x13000 + IMX_IO_BASE)
#define IMX_MMC_BASE (0x14000 + IMX_IO_BASE)
#define IMX_ASP_BASE (0x15000 + IMX_IO_BASE)
#define IMX_BTA_BASE (0x16000 + IMX_IO_BASE)
#define IMX_I2C_BASE (0x17000 + IMX_IO_BASE)
#define IMX_SSI_BASE (0x18000 + IMX_IO_BASE)
#define IMX_SPI2_BASE (0x19000 + IMX_IO_BASE)
#define IMX_MSHC_BASE (0x1A000 + IMX_IO_BASE)
#define IMX_PLL_BASE (0x1B000 + IMX_IO_BASE)
#define IMX_GPIO_BASE (0x1C000 + IMX_IO_BASE)
#define IMX_EIM_BASE (0x20000 + IMX_IO_BASE)
#define IMX_SDRAMC_BASE (0x21000 + IMX_IO_BASE)
#define IMX_MMA_BASE (0x22000 + IMX_IO_BASE)
#define IMX_AITC_BASE (0x23000 + IMX_IO_BASE)
#define IMX_CSI_BASE (0x24000 + IMX_IO_BASE)
/* PLL registers */
#define CSCR __REG(IMX_PLL_BASE) /* Clock Source Control Register */
#define CSCR_SPLL_RESTART (1<<22)
#define CSCR_MPLL_RESTART (1<<21)
#define CSCR_SYSTEM_SEL (1<<16)
#define CSCR_BCLK_DIV (0xf<<10)
#define CSCR_MPU_PRESC (1<<15)
#define CSCR_SPEN (1<<1)
#define CSCR_MPEN (1<<0)
#define MPCTL0 __REG(IMX_PLL_BASE + 0x4) /* MCU PLL Control Register 0 */
#define MPCTL1 __REG(IMX_PLL_BASE + 0x8) /* MCU PLL and System Clock Register 1 */
#define SPCTL0 __REG(IMX_PLL_BASE + 0xc) /* System PLL Control Register 0 */
#define SPCTL1 __REG(IMX_PLL_BASE + 0x10) /* System PLL Control Register 1 */
#define PCDR __REG(IMX_PLL_BASE + 0x20) /* Peripheral Clock Divider Register */
/*
* GPIO Module and I/O Multiplexer
* x = 0..3 for reg_A, reg_B, reg_C, reg_D
*/
#define DDIR(x) __REG2(IMX_GPIO_BASE + 0x00, ((x) & 3) << 8)
#define OCR1(x) __REG2(IMX_GPIO_BASE + 0x04, ((x) & 3) << 8)
#define OCR2(x) __REG2(IMX_GPIO_BASE + 0x08, ((x) & 3) << 8)
#define ICONFA1(x) __REG2(IMX_GPIO_BASE + 0x0c, ((x) & 3) << 8)
#define ICONFA2(x) __REG2(IMX_GPIO_BASE + 0x10, ((x) & 3) << 8)
#define ICONFB1(x) __REG2(IMX_GPIO_BASE + 0x14, ((x) & 3) << 8)
#define ICONFB2(x) __REG2(IMX_GPIO_BASE + 0x18, ((x) & 3) << 8)
#define DR(x) __REG2(IMX_GPIO_BASE + 0x1c, ((x) & 3) << 8)
#define GIUS(x) __REG2(IMX_GPIO_BASE + 0x20, ((x) & 3) << 8)
#define SSR(x) __REG2(IMX_GPIO_BASE + 0x24, ((x) & 3) << 8)
#define ICR1(x) __REG2(IMX_GPIO_BASE + 0x28, ((x) & 3) << 8)
#define ICR2(x) __REG2(IMX_GPIO_BASE + 0x2c, ((x) & 3) << 8)
#define IMR(x) __REG2(IMX_GPIO_BASE + 0x30, ((x) & 3) << 8)
#define ISR(x) __REG2(IMX_GPIO_BASE + 0x34, ((x) & 3) << 8)
#define GPR(x) __REG2(IMX_GPIO_BASE + 0x38, ((x) & 3) << 8)
#define SWR(x) __REG2(IMX_GPIO_BASE + 0x3c, ((x) & 3) << 8)
#define PUEN(x) __REG2(IMX_GPIO_BASE + 0x40, ((x) & 3) << 8)
#define GPIO_PORT_MAX 3
#define GPIO_PIN_MASK 0x1f
#define GPIO_PORT_MASK (0x3 << 5)
#define GPIO_PORT_SHIFT 5
#define GPIO_PORTA (0<<5)
#define GPIO_PORTB (1<<5)
#define GPIO_PORTC (2<<5)
#define GPIO_PORTD (3<<5)
#define GPIO_OUT (1<<7)
#define GPIO_IN (0<<7)
#define GPIO_PUEN (1<<8)
#define GPIO_PF (0<<9)
#define GPIO_AF (1<<9)
#define GPIO_OCR_SHIFT 10
#define GPIO_OCR_MASK (3<<10)
#define GPIO_AIN (0<<10)
#define GPIO_BIN (1<<10)
#define GPIO_CIN (2<<10)
#define GPIO_DR (3<<10)
#define GPIO_AOUT_SHIFT 12
#define GPIO_AOUT_MASK (3<<12)
#define GPIO_AOUT (0<<12)
#define GPIO_AOUT_ISR (1<<12)
#define GPIO_AOUT_0 (2<<12)
#define GPIO_AOUT_1 (3<<12)
#define GPIO_BOUT_SHIFT 14
#define GPIO_BOUT_MASK (3<<14)
#define GPIO_BOUT (0<<14)
#define GPIO_BOUT_ISR (1<<14)
#define GPIO_BOUT_0 (2<<14)
#define GPIO_BOUT_1 (3<<14)
#define GPIO_GIUS (1<<16)
/* assignements for GPIO alternate/primary functions */
/* FIXME: This list is not completed. The correct directions are
* missing on some (many) pins
*/
#define PA0_AIN_SPI2_CLK ( GPIO_GIUS | GPIO_PORTA | GPIO_OUT | 0 )
#define PA0_AF_ETMTRACESYNC ( GPIO_PORTA | GPIO_AF | 0 )
#define PA1_AOUT_SPI2_RXD ( GPIO_GIUS | GPIO_PORTA | GPIO_IN | 1 )
#define PA1_PF_TIN ( GPIO_PORTA | GPIO_PF | 1 )
#define PA2_PF_PWM0 ( GPIO_PORTA | GPIO_OUT | GPIO_PF | 2 )
#define PA3_PF_CSI_MCLK ( GPIO_PORTA | GPIO_PF | 3 )
#define PA4_PF_CSI_D0 ( GPIO_PORTA | GPIO_PF | 4 )
#define PA5_PF_CSI_D1 ( GPIO_PORTA | GPIO_PF | 5 )
#define PA6_PF_CSI_D2 ( GPIO_PORTA | GPIO_PF | 6 )
#define PA7_PF_CSI_D3 ( GPIO_PORTA | GPIO_PF | 7 )
#define PA8_PF_CSI_D4 ( GPIO_PORTA | GPIO_PF | 8 )
#define PA9_PF_CSI_D5 ( GPIO_PORTA | GPIO_PF | 9 )
#define PA10_PF_CSI_D6 ( GPIO_PORTA | GPIO_PF | 10 )
#define PA11_PF_CSI_D7 ( GPIO_PORTA | GPIO_PF | 11 )
#define PA12_PF_CSI_VSYNC ( GPIO_PORTA | GPIO_PF | 12 )
#define PA13_PF_CSI_HSYNC ( GPIO_PORTA | GPIO_PF | 13 )
#define PA14_PF_CSI_PIXCLK ( GPIO_PORTA | GPIO_PF | 14 )
#define PA15_PF_I2C_SDA ( GPIO_PORTA | GPIO_OUT | GPIO_PF | 15 )
#define PA16_PF_I2C_SCL ( GPIO_PORTA | GPIO_OUT | GPIO_PF | 16 )
#define PA17_AF_ETMTRACEPKT4 ( GPIO_PORTA | GPIO_AF | 17 )
#define PA17_AIN_SPI2_SS ( GPIO_GIUS | GPIO_PORTA | GPIO_OUT | 17 )
#define PA18_AF_ETMTRACEPKT5 ( GPIO_PORTA | GPIO_AF | 18 )
#define PA19_AF_ETMTRACEPKT6 ( GPIO_PORTA | GPIO_AF | 19 )
#define PA20_AF_ETMTRACEPKT7 ( GPIO_PORTA | GPIO_AF | 20 )
#define PA21_PF_A0 ( GPIO_PORTA | GPIO_PF | 21 )
#define PA22_PF_CS4 ( GPIO_PORTA | GPIO_PF | 22 )
#define PA23_PF_CS5 ( GPIO_PORTA | GPIO_PF | 23 )
#define PA24_PF_A16 ( GPIO_PORTA | GPIO_PF | 24 )
#define PA24_AF_ETMTRACEPKT0 ( GPIO_PORTA | GPIO_AF | 24 )
#define PA25_PF_A17 ( GPIO_PORTA | GPIO_PF | 25 )
#define PA25_AF_ETMTRACEPKT1 ( GPIO_PORTA | GPIO_AF | 25 )
#define PA26_PF_A18 ( GPIO_PORTA | GPIO_PF | 26 )
#define PA26_AF_ETMTRACEPKT2 ( GPIO_PORTA | GPIO_AF | 26 )
#define PA27_PF_A19 ( GPIO_PORTA | GPIO_PF | 27 )
#define PA27_AF_ETMTRACEPKT3 ( GPIO_PORTA | GPIO_AF | 27 )
#define PA28_PF_A20 ( GPIO_PORTA | GPIO_PF | 28 )
#define PA28_AF_ETMPIPESTAT0 ( GPIO_PORTA | GPIO_AF | 28 )
#define PA29_PF_A21 ( GPIO_PORTA | GPIO_PF | 29 )
#define PA29_AF_ETMPIPESTAT1 ( GPIO_PORTA | GPIO_AF | 29 )
#define PA30_PF_A22 ( GPIO_PORTA | GPIO_PF | 30 )
#define PA30_AF_ETMPIPESTAT2 ( GPIO_PORTA | GPIO_AF | 30 )
#define PA31_PF_A23 ( GPIO_PORTA | GPIO_PF | 31 )
#define PA31_AF_ETMTRACECLK ( GPIO_PORTA | GPIO_AF | 31 )
#define PB8_PF_SD_DAT0 ( GPIO_PORTB | GPIO_PF | GPIO_PUEN | 8 )
#define PB8_AF_MS_PIO ( GPIO_PORTB | GPIO_AF | 8 )
#define PB9_PF_SD_DAT1 ( GPIO_PORTB | GPIO_PF | GPIO_PUEN | 9 )
#define PB9_AF_MS_PI1 ( GPIO_PORTB | GPIO_AF | 9 )
#define PB10_PF_SD_DAT2 ( GPIO_PORTB | GPIO_PF | GPIO_PUEN | 10 )
#define PB10_AF_MS_SCLKI ( GPIO_PORTB | GPIO_AF | 10 )
#define PB11_PF_SD_DAT3 ( GPIO_PORTB | GPIO_PF | 11 )
#define PB11_AF_MS_SDIO ( GPIO_PORTB | GPIO_AF | 11 )
#define PB12_PF_SD_CLK ( GPIO_PORTB | GPIO_PF | 12 )
#define PB12_AF_MS_SCLK0 ( GPIO_PORTB | GPIO_AF | 12 )
#define PB13_PF_SD_CMD ( GPIO_PORTB | GPIO_PF | GPIO_PUEN | 13 )
#define PB13_AF_MS_BS ( GPIO_PORTB | GPIO_AF | 13 )
#define PB14_AF_SSI_RXFS ( GPIO_PORTB | GPIO_AF | 14 )
#define PB15_AF_SSI_RXCLK ( GPIO_PORTB | GPIO_AF | 15 )
#define PB16_AF_SSI_RXDAT ( GPIO_PORTB | GPIO_IN | GPIO_AF | 16 )
#define PB17_AF_SSI_TXDAT ( GPIO_PORTB | GPIO_OUT | GPIO_AF | 17 )
#define PB18_AF_SSI_TXFS ( GPIO_PORTB | GPIO_AF | 18 )
#define PB19_AF_SSI_TXCLK ( GPIO_PORTB | GPIO_AF | 19 )
#define PB20_PF_USBD_AFE ( GPIO_PORTB | GPIO_PF | 20 )
#define PB21_PF_USBD_OE ( GPIO_PORTB | GPIO_PF | 21 )
#define PB22_PFUSBD_RCV ( GPIO_PORTB | GPIO_PF | 22 )
#define PB23_PF_USBD_SUSPND ( GPIO_PORTB | GPIO_PF | 23 )
#define PB24_PF_USBD_VP ( GPIO_PORTB | GPIO_PF | 24 )
#define PB25_PF_USBD_VM ( GPIO_PORTB | GPIO_PF | 25 )
#define PB26_PF_USBD_VPO ( GPIO_PORTB | GPIO_PF | 26 )
#define PB27_PF_USBD_VMO ( GPIO_PORTB | GPIO_PF | 27 )
#define PB28_PF_UART2_CTS ( GPIO_PORTB | GPIO_OUT | GPIO_PF | 28 )
#define PB29_PF_UART2_RTS ( GPIO_PORTB | GPIO_IN | GPIO_PF | 29 )
#define PB30_PF_UART2_TXD ( GPIO_PORTB | GPIO_OUT | GPIO_PF | 30 )
#define PB31_PF_UART2_RXD ( GPIO_PORTB | GPIO_IN | GPIO_PF | 31 )
#define PC3_PF_SSI_RXFS ( GPIO_PORTC | GPIO_PF | 3 )
#define PC4_PF_SSI_RXCLK ( GPIO_PORTC | GPIO_PF | 4 )
#define PC5_PF_SSI_RXDAT ( GPIO_PORTC | GPIO_IN | GPIO_PF | 5 )
#define PC6_PF_SSI_TXDAT ( GPIO_PORTC | GPIO_OUT | GPIO_PF | 6 )
#define PC7_PF_SSI_TXFS ( GPIO_PORTC | GPIO_PF | 7 )
#define PC8_PF_SSI_TXCLK ( GPIO_PORTC | GPIO_PF | 8 )
#define PC9_PF_UART1_CTS ( GPIO_PORTC | GPIO_OUT | GPIO_PF | 9 )
#define PC10_PF_UART1_RTS ( GPIO_PORTC | GPIO_IN | GPIO_PF | 10 )
#define PC11_PF_UART1_TXD ( GPIO_PORTC | GPIO_OUT | GPIO_PF | 11 )
#define PC12_PF_UART1_RXD ( GPIO_PORTC | GPIO_IN | GPIO_PF | 12 )
#define PC13_PF_SPI1_SPI_RDY ( GPIO_PORTC | GPIO_PF | 13 )
#define PC14_PF_SPI1_SCLK ( GPIO_PORTC | GPIO_PF | 14 )
#define PC15_PF_SPI1_SS ( GPIO_PORTC | GPIO_PF | 15 )
#define PC16_PF_SPI1_MISO ( GPIO_PORTC | GPIO_PF | 16 )
#define PC17_PF_SPI1_MOSI ( GPIO_PORTC | GPIO_PF | 17 )
#define PC24_BIN_UART3_RI ( GPIO_GIUS | GPIO_PORTC | GPIO_OUT | GPIO_BIN | 24 )
#define PC25_BIN_UART3_DSR ( GPIO_GIUS | GPIO_PORTC | GPIO_OUT | GPIO_BIN | 25 )
#define PC26_AOUT_UART3_DTR ( GPIO_GIUS | GPIO_PORTC | GPIO_IN | 26 )
#define PC27_BIN_UART3_DCD ( GPIO_GIUS | GPIO_PORTC | GPIO_OUT | GPIO_BIN | 27 )
#define PC28_BIN_UART3_CTS ( GPIO_GIUS | GPIO_PORTC | GPIO_OUT | GPIO_BIN | 28 )
#define PC29_AOUT_UART3_RTS ( GPIO_GIUS | GPIO_PORTC | GPIO_IN | 29 )
#define PC30_BIN_UART3_TX ( GPIO_GIUS | GPIO_PORTC | GPIO_BIN | 30 )
#define PC31_AOUT_UART3_RX ( GPIO_GIUS | GPIO_PORTC | GPIO_IN | 31)
#define PD6_PF_LSCLK ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 6 )
#define PD7_PF_REV ( GPIO_PORTD | GPIO_PF | 7 )
#define PD7_AF_UART2_DTR ( GPIO_GIUS | GPIO_PORTD | GPIO_IN | GPIO_AF | 7 )
#define PD7_AIN_SPI2_SCLK ( GPIO_GIUS | GPIO_PORTD | GPIO_AIN | 7 )
#define PD8_PF_CLS ( GPIO_PORTD | GPIO_PF | 8 )
#define PD8_AF_UART2_DCD ( GPIO_PORTD | GPIO_OUT | GPIO_AF | 8 )
#define PD8_AIN_SPI2_SS ( GPIO_GIUS | GPIO_PORTD | GPIO_AIN | 8 )
#define PD9_PF_PS ( GPIO_PORTD | GPIO_PF | 9 )
#define PD9_AF_UART2_RI ( GPIO_PORTD | GPIO_OUT | GPIO_AF | 9 )
#define PD9_AOUT_SPI2_RXD ( GPIO_GIUS | GPIO_PORTD | GPIO_IN | 9 )
#define PD10_PF_SPL_SPR ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 10 )
#define PD10_AF_UART2_DSR ( GPIO_PORTD | GPIO_OUT | GPIO_AF | 10 )
#define PD10_AIN_SPI2_TXD ( GPIO_GIUS | GPIO_PORTD | GPIO_OUT | 10 )
#define PD11_PF_CONTRAST ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 11 )
#define PD12_PF_ACD_OE ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 12 )
#define PD13_PF_LP_HSYNC ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 13 )
#define PD14_PF_FLM_VSYNC ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 14 )
#define PD15_PF_LD0 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 15 )
#define PD16_PF_LD1 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 16 )
#define PD17_PF_LD2 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 17 )
#define PD18_PF_LD3 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 18 )
#define PD19_PF_LD4 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 19 )
#define PD20_PF_LD5 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 20 )
#define PD21_PF_LD6 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 21 )
#define PD22_PF_LD7 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 22 )
#define PD23_PF_LD8 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 23 )
#define PD24_PF_LD9 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 24 )
#define PD25_PF_LD10 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 25 )
#define PD26_PF_LD11 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 26 )
#define PD27_PF_LD12 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 27 )
#define PD28_PF_LD13 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 28 )
#define PD29_PF_LD14 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 29 )
#define PD30_PF_LD15 ( GPIO_PORTD | GPIO_OUT | GPIO_PF | 30 )
#define PD31_PF_TMR2OUT ( GPIO_PORTD | GPIO_PF | 31 )
#define PD31_BIN_SPI2_TXD ( GPIO_GIUS | GPIO_PORTD | GPIO_BIN | 31 )
/*
* PWM controller
*/
#define PWMC __REG(IMX_PWM_BASE + 0x00) /* PWM Control Register */
#define PWMS __REG(IMX_PWM_BASE + 0x04) /* PWM Sample Register */
#define PWMP __REG(IMX_PWM_BASE + 0x08) /* PWM Period Register */
#define PWMCNT __REG(IMX_PWM_BASE + 0x0C) /* PWM Counter Register */
#define PWMC_HCTR (0x01<<18) /* Halfword FIFO Data Swapping */
#define PWMC_BCTR (0x01<<17) /* Byte FIFO Data Swapping */
#define PWMC_SWR (0x01<<16) /* Software Reset */
#define PWMC_CLKSRC (0x01<<15) /* Clock Source */
#define PWMC_PRESCALER(x) (((x-1) & 0x7F) << 8) /* PRESCALER */
#define PWMC_IRQ (0x01<< 7) /* Interrupt Request */
#define PWMC_IRQEN (0x01<< 6) /* Interrupt Request Enable */
#define PWMC_FIFOAV (0x01<< 5) /* FIFO Available */
#define PWMC_EN (0x01<< 4) /* Enables/Disables the PWM */
#define PWMC_REPEAT(x) (((x) & 0x03) << 2) /* Sample Repeats */
#define PWMC_CLKSEL(x) (((x) & 0x03) << 0) /* Clock Selection */
#define PWMS_SAMPLE(x) ((x) & 0xFFFF) /* Contains a two-sample word */
#define PWMP_PERIOD(x) ((x) & 0xFFFF) /* Represents the PWM's period */
#define PWMC_COUNTER(x) ((x) & 0xFFFF) /* Represents the current count value */
/*
* DMA Controller
*/
#define DCR __REG(IMX_DMAC_BASE +0x00) /* DMA Control Register */
#define DISR __REG(IMX_DMAC_BASE +0x04) /* DMA Interrupt status Register */
#define DIMR __REG(IMX_DMAC_BASE +0x08) /* DMA Interrupt mask Register */
#define DBTOSR __REG(IMX_DMAC_BASE +0x0c) /* DMA Burst timeout status Register */
#define DRTOSR __REG(IMX_DMAC_BASE +0x10) /* DMA Request timeout Register */
#define DSESR __REG(IMX_DMAC_BASE +0x14) /* DMA Transfer Error Status Register */
#define DBOSR __REG(IMX_DMAC_BASE +0x18) /* DMA Buffer overflow status Register */
#define DBTOCR __REG(IMX_DMAC_BASE +0x1c) /* DMA Burst timeout control Register */
#define WSRA __REG(IMX_DMAC_BASE +0x40) /* W-Size Register A */
#define XSRA __REG(IMX_DMAC_BASE +0x44) /* X-Size Register A */
#define YSRA __REG(IMX_DMAC_BASE +0x48) /* Y-Size Register A */
#define WSRB __REG(IMX_DMAC_BASE +0x4c) /* W-Size Register B */
#define XSRB __REG(IMX_DMAC_BASE +0x50) /* X-Size Register B */
#define YSRB __REG(IMX_DMAC_BASE +0x54) /* Y-Size Register B */
#define SAR(x) __REG2( IMX_DMAC_BASE + 0x80, (x) << 6) /* Source Address Registers */
#define DAR(x) __REG2( IMX_DMAC_BASE + 0x84, (x) << 6) /* Destination Address Registers */
#define CNTR(x) __REG2( IMX_DMAC_BASE + 0x88, (x) << 6) /* Count Registers */
#define CCR(x) __REG2( IMX_DMAC_BASE + 0x8c, (x) << 6) /* Control Registers */
#define RSSR(x) __REG2( IMX_DMAC_BASE + 0x90, (x) << 6) /* Request source select Registers */
#define BLR(x) __REG2( IMX_DMAC_BASE + 0x94, (x) << 6) /* Burst length Registers */
#define RTOR(x) __REG2( IMX_DMAC_BASE + 0x98, (x) << 6) /* Request timeout Registers */
#define BUCR(x) __REG2( IMX_DMAC_BASE + 0x98, (x) << 6) /* Bus Utilization Registers */
#define DCR_DRST (1<<1)
#define DCR_DEN (1<<0)
#define DBTOCR_EN (1<<15)
#define DBTOCR_CNT(x) ((x) & 0x7fff )
#define CNTR_CNT(x) ((x) & 0xffffff )
#define CCR_DMOD_LINEAR ( 0x0 << 12 )
#define CCR_DMOD_2D ( 0x1 << 12 )
#define CCR_DMOD_FIFO ( 0x2 << 12 )
#define CCR_DMOD_EOBFIFO ( 0x3 << 12 )
#define CCR_SMOD_LINEAR ( 0x0 << 10 )
#define CCR_SMOD_2D ( 0x1 << 10 )
#define CCR_SMOD_FIFO ( 0x2 << 10 )
#define CCR_SMOD_EOBFIFO ( 0x3 << 10 )
#define CCR_MDIR_DEC (1<<9)
#define CCR_MSEL_B (1<<8)
#define CCR_DSIZ_32 ( 0x0 << 6 )
#define CCR_DSIZ_8 ( 0x1 << 6 )
#define CCR_DSIZ_16 ( 0x2 << 6 )
#define CCR_SSIZ_32 ( 0x0 << 4 )
#define CCR_SSIZ_8 ( 0x1 << 4 )
#define CCR_SSIZ_16 ( 0x2 << 4 )
#define CCR_REN (1<<3)
#define CCR_RPT (1<<2)
#define CCR_FRC (1<<1)
#define CCR_CEN (1<<0)
#define RTOR_EN (1<<15)
#define RTOR_CLK (1<<14)
#define RTOR_PSC (1<<13)
/*
* Interrupt controller
*/
#define IMX_INTCNTL __REG(IMX_AITC_BASE+0x00)
#define INTCNTL_FIAD (1<<19)
#define INTCNTL_NIAD (1<<20)
#define IMX_NIMASK __REG(IMX_AITC_BASE+0x04)
#define IMX_INTENNUM __REG(IMX_AITC_BASE+0x08)
#define IMX_INTDISNUM __REG(IMX_AITC_BASE+0x0c)
#define IMX_INTENABLEH __REG(IMX_AITC_BASE+0x10)
#define IMX_INTENABLEL __REG(IMX_AITC_BASE+0x14)
/*
* General purpose timers
*/
#define IMX_TCTL(x) __REG( 0x00 + (x))
#define TCTL_SWR (1<<15)
#define TCTL_FRR (1<<8)
#define TCTL_CAP_RIS (1<<6)
#define TCTL_CAP_FAL (2<<6)
#define TCTL_CAP_RIS_FAL (3<<6)
#define TCTL_OM (1<<5)
#define TCTL_IRQEN (1<<4)
#define TCTL_CLK_PCLK1 (1<<1)
#define TCTL_CLK_PCLK1_16 (2<<1)
#define TCTL_CLK_TIN (3<<1)
#define TCTL_CLK_32 (4<<1)
#define TCTL_TEN (1<<0)
#define IMX_TPRER(x) __REG( 0x04 + (x))
#define IMX_TCMP(x) __REG( 0x08 + (x))
#define IMX_TCR(x) __REG( 0x0C + (x))
#define IMX_TCN(x) __REG( 0x10 + (x))
#define IMX_TSTAT(x) __REG( 0x14 + (x))
#define TSTAT_CAPT (1<<1)
#define TSTAT_COMP (1<<0)
#endif // _IMX_REGS_H

View File

@ -1,12 +0,0 @@
#ifndef ASMARM_ARCH_UART_H
#define ASMARM_ARCH_UART_H
#define IMXUART_HAVE_RTSCTS (1<<0)
struct imxuart_platform_data {
int (*init)(struct platform_device *pdev);
void (*exit)(struct platform_device *pdev);
unsigned int flags;
};
#endif

View File

@ -1,28 +0,0 @@
/*
* arch/arm/mach-imxads/include/mach/io.h
*
* Copyright (C) 1999 ARM Limited
*
* 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
*/
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
#define IO_SPACE_LIMIT 0xffffffff
#define __io(a) __typesafe_io(a)
#define __mem_pci(a) (a)
#endif

View File

@ -1,121 +0,0 @@
/*
* arch/arm/mach-imxads/include/mach/irqs.h
*
* Copyright (C) 1999 ARM Limited
* Copyright (C) 2000 Deep Blue Solutions 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.
*
* 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
*/
#ifndef __ARM_IRQS_H__
#define __ARM_IRQS_H__
/* Use the imx definitions */
#include <mach/hardware.h>
/*
* IMX Interrupt numbers
*
*/
#define INT_SOFTINT 0
#define CSI_INT 6
#define DSPA_MAC_INT 7
#define DSPA_INT 8
#define COMP_INT 9
#define MSHC_XINT 10
#define GPIO_INT_PORTA 11
#define GPIO_INT_PORTB 12
#define GPIO_INT_PORTC 13
#define LCDC_INT 14
#define SIM_INT 15
#define SIM_DATA_INT 16
#define RTC_INT 17
#define RTC_SAMINT 18
#define UART2_MINT_PFERR 19
#define UART2_MINT_RTS 20
#define UART2_MINT_DTR 21
#define UART2_MINT_UARTC 22
#define UART2_MINT_TX 23
#define UART2_MINT_RX 24
#define UART1_MINT_PFERR 25
#define UART1_MINT_RTS 26
#define UART1_MINT_DTR 27
#define UART1_MINT_UARTC 28
#define UART1_MINT_TX 29
#define UART1_MINT_RX 30
#define VOICE_DAC_INT 31
#define VOICE_ADC_INT 32
#define PEN_DATA_INT 33
#define PWM_INT 34
#define SDHC_INT 35
#define I2C_INT 39
#define CSPI_INT 41
#define SSI_TX_INT 42
#define SSI_TX_ERR_INT 43
#define SSI_RX_INT 44
#define SSI_RX_ERR_INT 45
#define TOUCH_INT 46
#define USBD_INT0 47
#define USBD_INT1 48
#define USBD_INT2 49
#define USBD_INT3 50
#define USBD_INT4 51
#define USBD_INT5 52
#define USBD_INT6 53
#define BTSYS_INT 55
#define BTTIM_INT 56
#define BTWUI_INT 57
#define TIM2_INT 58
#define TIM1_INT 59
#define DMA_ERR 60
#define DMA_INT 61
#define GPIO_INT_PORTD 62
#define IMX_IRQS (64)
/* note: the IMX has four gpio ports (A-D), but only
* the following pins are connected to the outside
* world:
*
* PORT A: bits 0-31
* PORT B: bits 8-31
* PORT C: bits 3-17
* PORT D: bits 6-31
*
* We map these interrupts straight on. As a result we have
* several holes in the interrupt mapping. We do this for two
* reasons:
* - mapping the interrupts without holes would get
* far more complicated
* - Motorola could well decide to bring some processor
* with more pins connected
*/
#define IRQ_GPIOA(x) (IMX_IRQS + x)
#define IRQ_GPIOB(x) (IRQ_GPIOA(32) + x)
#define IRQ_GPIOC(x) (IRQ_GPIOB(32) + x)
#define IRQ_GPIOD(x) (IRQ_GPIOC(32) + x)
/* decode irq number to use with IMR(x), ISR(x) and friends */
#define IRQ_TO_REG(irq) ((irq - IMX_IRQS) >> 5)
/* all normal IRQs can be FIQs */
#define FIQ_START 0
/* switch betwean IRQ and FIQ */
extern int imx_set_irq_fiq(unsigned int irq, unsigned int type);
#define NR_IRQS (IRQ_GPIOD(32) + 1)
#define IRQ_GPIO(x)
#endif

View File

@ -1,26 +0,0 @@
/*
* arch/arm/mach-imx/include/mach/memory.h
*
* Copyright (C) 1999 ARM Limited
* Copyright (C) 2002 Shane Nay (shane@minirl.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
*/
#ifndef __ASM_ARCH_MMU_H
#define __ASM_ARCH_MMU_H
#define PHYS_OFFSET UL(0x08000000)
#endif

View File

@ -1,15 +0,0 @@
#ifndef ASMARM_ARCH_MMC_H
#define ASMARM_ARCH_MMC_H
#include <linux/mmc/host.h>
struct device;
struct imxmmc_platform_data {
int (*card_present)(struct device *);
int (*get_ro)(struct device *);
};
extern void imx_set_mmc_info(struct imxmmc_platform_data *info);
#endif

View File

@ -1,72 +0,0 @@
/*
* arch/arm/mach-imx/include/mach/spi_imx.h
*
* Copyright (C) 2006 SWAPP
* Andrea Paterniani <a.paterniani@swapp-eng.it>
*
* Initial version inspired by:
* linux-2.6.17-rc3-mm1/arch/arm/mach-pxa/include/mach/pxa2xx_spi.h
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef SPI_IMX_H_
#define SPI_IMX_H_
/*-------------------------------------------------------------------------*/
/**
* struct spi_imx_master - device.platform_data for SPI controller devices.
* @num_chipselect: chipselects are used to distinguish individual
* SPI slaves, and are numbered from zero to num_chipselects - 1.
* each slave has a chipselect signal, but it's common that not
* every chipselect is connected to a slave.
* @enable_dma: if true enables DMA driven transfers.
*/
struct spi_imx_master {
u8 num_chipselect;
u8 enable_dma:1;
};
/*-------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------*/
/**
* struct spi_imx_chip - spi_board_info.controller_data for SPI
* slave devices, copied to spi_device.controller_data.
* @enable_loopback : used for test purpouse to internally connect RX and TX
* sections.
* @enable_dma : enables dma transfer (provided that controller driver has
* dma enabled too).
* @ins_ss_pulse : enable /SS pulse insertion between SPI burst.
* @bclk_wait : number of bclk waits between each bits_per_word SPI burst.
* @cs_control : function pointer to board-specific function to assert/deassert
* I/O port to control HW generation of devices chip-select.
*/
struct spi_imx_chip {
u8 enable_loopback:1;
u8 enable_dma:1;
u8 ins_ss_pulse:1;
u16 bclk_wait:15;
void (*cs_control)(u32 control);
};
/* Chip-select state */
#define SPI_CS_ASSERT (1 << 0)
#define SPI_CS_DEASSERT (1 << 1)
/*-------------------------------------------------------------------------*/
#endif /* SPI_IMX_H_*/

View File

@ -1,40 +0,0 @@
/*
* arch/arm/mach-imxads/include/mach/system.h
*
* Copyright (C) 1999 ARM Limited
* Copyright (C) 2000 Deep Blue Solutions 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.
*
* 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
*/
#ifndef __ASM_ARCH_SYSTEM_H
#define __ASM_ARCH_SYSTEM_H
static void
arch_idle(void)
{
/*
* This should do all the clock switching
* and wait for interrupt tricks
*/
cpu_do_idle();
}
static inline void
arch_reset(char mode, const char *cmd)
{
cpu_reset(0);
}
#endif

View File

@ -1,71 +0,0 @@
/*
* arch/arm/mach-imxads/include/mach/uncompress.h
*
*
*
* Copyright (C) 1999 ARM Limited
* Copyright (C) Shane Nay (shane@minirl.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
*/
#define UART(x) (*(volatile unsigned long *)(serial_port + (x)))
#define UART1_BASE 0x206000
#define UART2_BASE 0x207000
#define USR2 0x98
#define USR2_TXFE (1<<14)
#define TXR 0x40
#define UCR1 0x80
#define UCR1_UARTEN 1
/*
* The following code assumes the serial port has already been
* initialized by the bootloader. We search for the first enabled
* port in the most probable order. If you didn't setup a port in
* your bootloader then nothing will appear (which might be desired).
*
* This does not append a newline
*/
static void putc(int c)
{
unsigned long serial_port;
do {
serial_port = UART1_BASE;
if ( UART(UCR1) & UCR1_UARTEN )
break;
serial_port = UART2_BASE;
if ( UART(UCR1) & UCR1_UARTEN )
break;
return;
} while(0);
while (!(UART(USR2) & USR2_TXFE))
barrier();
UART(TXR) = c;
}
static inline void flush(void)
{
}
/*
* nothing to do
*/
#define arch_decomp_setup()
#define arch_decomp_wdog()

View File

@ -1,20 +0,0 @@
/*
* arch/arm/mach-imx/include/mach/vmalloc.h
*
* Copyright (C) 2000 Russell King.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define VMALLOC_END (PAGE_OFFSET + 0x10000000)

View File

@ -1,311 +0,0 @@
/*
* linux/arch/arm/mach-imx/irq.c
*
* Copyright (C) 1999 ARM Limited
* Copyright (C) 2002 Shane Nay (shane@minirl.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
*
* 03/03/2004 Sascha Hauer <sascha@saschahauer.de>
* Copied from the motorola bsp package and added gpio demux
* interrupt handler
*/
#include <linux/init.h>
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/io.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/mach/irq.h>
/*
*
* We simply use the ENABLE DISABLE registers inside of the IMX
* to turn on/off specific interrupts.
*
*/
#define INTCNTL_OFF 0x00
#define NIMASK_OFF 0x04
#define INTENNUM_OFF 0x08
#define INTDISNUM_OFF 0x0C
#define INTENABLEH_OFF 0x10
#define INTENABLEL_OFF 0x14
#define INTTYPEH_OFF 0x18
#define INTTYPEL_OFF 0x1C
#define NIPRIORITY_OFF(x) (0x20+4*(7-(x)))
#define NIVECSR_OFF 0x40
#define FIVECSR_OFF 0x44
#define INTSRCH_OFF 0x48
#define INTSRCL_OFF 0x4C
#define INTFRCH_OFF 0x50
#define INTFRCL_OFF 0x54
#define NIPNDH_OFF 0x58
#define NIPNDL_OFF 0x5C
#define FIPNDH_OFF 0x60
#define FIPNDL_OFF 0x64
#define VA_AITC_BASE IO_ADDRESS(IMX_AITC_BASE)
#define IMX_AITC_INTCNTL (VA_AITC_BASE + INTCNTL_OFF)
#define IMX_AITC_NIMASK (VA_AITC_BASE + NIMASK_OFF)
#define IMX_AITC_INTENNUM (VA_AITC_BASE + INTENNUM_OFF)
#define IMX_AITC_INTDISNUM (VA_AITC_BASE + INTDISNUM_OFF)
#define IMX_AITC_INTENABLEH (VA_AITC_BASE + INTENABLEH_OFF)
#define IMX_AITC_INTENABLEL (VA_AITC_BASE + INTENABLEL_OFF)
#define IMX_AITC_INTTYPEH (VA_AITC_BASE + INTTYPEH_OFF)
#define IMX_AITC_INTTYPEL (VA_AITC_BASE + INTTYPEL_OFF)
#define IMX_AITC_NIPRIORITY(x) (VA_AITC_BASE + NIPRIORITY_OFF(x))
#define IMX_AITC_NIVECSR (VA_AITC_BASE + NIVECSR_OFF)
#define IMX_AITC_FIVECSR (VA_AITC_BASE + FIVECSR_OFF)
#define IMX_AITC_INTSRCH (VA_AITC_BASE + INTSRCH_OFF)
#define IMX_AITC_INTSRCL (VA_AITC_BASE + INTSRCL_OFF)
#define IMX_AITC_INTFRCH (VA_AITC_BASE + INTFRCH_OFF)
#define IMX_AITC_INTFRCL (VA_AITC_BASE + INTFRCL_OFF)
#define IMX_AITC_NIPNDH (VA_AITC_BASE + NIPNDH_OFF)
#define IMX_AITC_NIPNDL (VA_AITC_BASE + NIPNDL_OFF)
#define IMX_AITC_FIPNDH (VA_AITC_BASE + FIPNDH_OFF)
#define IMX_AITC_FIPNDL (VA_AITC_BASE + FIPNDL_OFF)
#if 0
#define DEBUG_IRQ(fmt...) printk(fmt)
#else
#define DEBUG_IRQ(fmt...) do { } while (0)
#endif
static void
imx_mask_irq(unsigned int irq)
{
__raw_writel(irq, IMX_AITC_INTDISNUM);
}
static void
imx_unmask_irq(unsigned int irq)
{
__raw_writel(irq, IMX_AITC_INTENNUM);
}
#ifdef CONFIG_FIQ
int imx_set_irq_fiq(unsigned int irq, unsigned int type)
{
unsigned int irqt;
if (irq >= IMX_IRQS)
return -EINVAL;
if (irq < IMX_IRQS / 2) {
irqt = __raw_readl(IMX_AITC_INTTYPEL) & ~(1 << irq);
__raw_writel(irqt | (!!type << irq), IMX_AITC_INTTYPEL);
} else {
irq -= IMX_IRQS / 2;
irqt = __raw_readl(IMX_AITC_INTTYPEH) & ~(1 << irq);
__raw_writel(irqt | (!!type << irq), IMX_AITC_INTTYPEH);
}
return 0;
}
EXPORT_SYMBOL(imx_set_irq_fiq);
#endif /* CONFIG_FIQ */
static int
imx_gpio_irq_type(unsigned int _irq, unsigned int type)
{
unsigned int irq_type = 0, irq, reg, bit;
irq = _irq - IRQ_GPIOA(0);
reg = irq >> 5;
bit = 1 << (irq % 32);
if (type == IRQ_TYPE_PROBE) {
/* Don't mess with enabled GPIOs using preconfigured edges or
GPIOs set to alternate function during probe */
/* TODO: support probe */
// if ((GPIO_IRQ_rising_edge[idx] | GPIO_IRQ_falling_edge[idx]) &
// GPIO_bit(gpio))
// return 0;
// if (GAFR(gpio) & (0x3 << (((gpio) & 0xf)*2)))
// return 0;
// type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
}
GIUS(reg) |= bit;
DDIR(reg) &= ~(bit);
DEBUG_IRQ("setting type of irq %d to ", _irq);
if (type & IRQ_TYPE_EDGE_RISING) {
DEBUG_IRQ("rising edges\n");
irq_type = 0x0;
}
if (type & IRQ_TYPE_EDGE_FALLING) {
DEBUG_IRQ("falling edges\n");
irq_type = 0x1;
}
if (type & IRQ_TYPE_LEVEL_LOW) {
DEBUG_IRQ("low level\n");
irq_type = 0x3;
}
if (type & IRQ_TYPE_LEVEL_HIGH) {
DEBUG_IRQ("high level\n");
irq_type = 0x2;
}
if (irq % 32 < 16) {
ICR1(reg) = (ICR1(reg) & ~(0x3 << ((irq % 16) * 2))) |
(irq_type << ((irq % 16) * 2));
} else {
ICR2(reg) = (ICR2(reg) & ~(0x3 << ((irq % 16) * 2))) |
(irq_type << ((irq % 16) * 2));
}
return 0;
}
static void
imx_gpio_ack_irq(unsigned int irq)
{
DEBUG_IRQ("%s: irq %d\n", __func__, irq);
ISR(IRQ_TO_REG(irq)) = 1 << ((irq - IRQ_GPIOA(0)) % 32);
}
static void
imx_gpio_mask_irq(unsigned int irq)
{
DEBUG_IRQ("%s: irq %d\n", __func__, irq);
IMR(IRQ_TO_REG(irq)) &= ~( 1 << ((irq - IRQ_GPIOA(0)) % 32));
}
static void
imx_gpio_unmask_irq(unsigned int irq)
{
DEBUG_IRQ("%s: irq %d\n", __func__, irq);
IMR(IRQ_TO_REG(irq)) |= 1 << ((irq - IRQ_GPIOA(0)) % 32);
}
static void
imx_gpio_handler(unsigned int mask, unsigned int irq,
struct irq_desc *desc)
{
while (mask) {
if (mask & 1) {
DEBUG_IRQ("handling irq %d\n", irq);
generic_handle_irq(irq);
}
irq++;
mask >>= 1;
}
}
static void
imx_gpioa_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
{
unsigned int mask, irq;
mask = ISR(0);
irq = IRQ_GPIOA(0);
imx_gpio_handler(mask, irq, desc);
}
static void
imx_gpiob_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
{
unsigned int mask, irq;
mask = ISR(1);
irq = IRQ_GPIOB(0);
imx_gpio_handler(mask, irq, desc);
}
static void
imx_gpioc_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
{
unsigned int mask, irq;
mask = ISR(2);
irq = IRQ_GPIOC(0);
imx_gpio_handler(mask, irq, desc);
}
static void
imx_gpiod_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
{
unsigned int mask, irq;
mask = ISR(3);
irq = IRQ_GPIOD(0);
imx_gpio_handler(mask, irq, desc);
}
static struct irq_chip imx_internal_chip = {
.name = "MPU",
.ack = imx_mask_irq,
.mask = imx_mask_irq,
.unmask = imx_unmask_irq,
};
static struct irq_chip imx_gpio_chip = {
.name = "GPIO",
.ack = imx_gpio_ack_irq,
.mask = imx_gpio_mask_irq,
.unmask = imx_gpio_unmask_irq,
.set_type = imx_gpio_irq_type,
};
void __init
imx_init_irq(void)
{
unsigned int irq;
DEBUG_IRQ("Initializing imx interrupts\n");
/* Disable all interrupts initially. */
/* Do not rely on the bootloader. */
__raw_writel(0, IMX_AITC_INTENABLEH);
__raw_writel(0, IMX_AITC_INTENABLEL);
/* Mask all GPIO interrupts as well */
IMR(0) = 0;
IMR(1) = 0;
IMR(2) = 0;
IMR(3) = 0;
for (irq = 0; irq < IMX_IRQS; irq++) {
set_irq_chip(irq, &imx_internal_chip);
set_irq_handler(irq, handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
}
for (irq = IRQ_GPIOA(0); irq < IRQ_GPIOD(32); irq++) {
set_irq_chip(irq, &imx_gpio_chip);
set_irq_handler(irq, handle_edge_irq);
set_irq_flags(irq, IRQF_VALID);
}
set_irq_chained_handler(GPIO_INT_PORTA, imx_gpioa_demux_handler);
set_irq_chained_handler(GPIO_INT_PORTB, imx_gpiob_demux_handler);
set_irq_chained_handler(GPIO_INT_PORTC, imx_gpioc_demux_handler);
set_irq_chained_handler(GPIO_INT_PORTD, imx_gpiod_demux_handler);
/* Release masking of interrupts according to priority */
__raw_writel(-1, IMX_AITC_NIMASK);
#ifdef CONFIG_FIQ
/* Initialize FIQ */
init_FIQ();
#endif
}

View File

@ -1,53 +0,0 @@
/*
* linux/arch/arm/mach-imx/leds-mx1ads.c
*
* Copyright (c) 2004 Sascha Hauer <sascha@saschahauer.de>
*
* Original (leds-footbridge.c) by Russell King
*
* 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/io.h>
#include <mach/hardware.h>
#include <asm/system.h>
#include <asm/leds.h>
#include "leds.h"
/*
* The MX1ADS Board has only one usable LED,
* so select only the timer led or the
* cpu usage led
*/
void
mx1ads_leds_event(led_event_t ledevt)
{
unsigned long flags;
local_irq_save(flags);
switch (ledevt) {
#ifdef CONFIG_LEDS_CPU
case led_idle_start:
DR(0) &= ~(1<<2);
break;
case led_idle_end:
DR(0) |= 1<<2;
break;
#endif
#ifdef CONFIG_LEDS_TIMER
case led_timer:
DR(0) ^= 1<<2;
#endif
default:
break;
}
local_irq_restore(flags);
}

View File

@ -1,31 +0,0 @@
/*
* linux/arch/arm/mach-imx/leds.c
*
* Copyright (C) 2004 Sascha Hauer <sascha@saschahauer.de>
*
*
* 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 <asm/leds.h>
#include <asm/mach-types.h>
#include "leds.h"
static int __init
leds_init(void)
{
if (machine_is_mx1ads()) {
leds_event = mx1ads_leds_event;
}
return 0;
}
__initcall(leds_init);

View File

@ -1,9 +0,0 @@
/*
* arch/arm/mach-imx/leds.h
*
* Copyright (c) 2004 Sascha Hauer <sascha@saschahauer.de>
*
* blinky lights for IMX-based systems
*
*/
extern void mx1ads_leds_event(led_event_t evt);

View File

@ -1,180 +0,0 @@
/*
* arch/arm/mach-imx/mx1ads.c
*
* Initially based on:
* linux-2.6.7-imx/arch/arm/mach-imx/scb9328.c
* Copyright (c) 2004 Sascha Hauer <sascha@saschahauer.de>
*
* 2004 (c) MontaVista Software, Inc.
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/device.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <asm/system.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/mach/map.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/mmc.h>
#include <mach/imx-uart.h>
#include <linux/interrupt.h>
#include "generic.h"
static struct resource cs89x0_resources[] = {
[0] = {
.start = IMX_CS4_PHYS + 0x300,
.end = IMX_CS4_PHYS + 0x300 + 16,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_GPIOC(17),
.end = IRQ_GPIOC(17),
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device cs89x0_device = {
.name = "cirrus-cs89x0",
.num_resources = ARRAY_SIZE(cs89x0_resources),
.resource = cs89x0_resources,
};
static struct imxuart_platform_data uart_pdata = {
.flags = IMXUART_HAVE_RTSCTS,
};
static struct resource imx_uart1_resources[] = {
[0] = {
.start = 0x00206000,
.end = 0x002060FF,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = (UART1_MINT_RX),
.end = (UART1_MINT_RX),
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = (UART1_MINT_TX),
.end = (UART1_MINT_TX),
.flags = IORESOURCE_IRQ,
},
[3] = {
.start = UART1_MINT_RTS,
.end = UART1_MINT_RTS,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device imx_uart1_device = {
.name = "imx-uart",
.id = 0,
.num_resources = ARRAY_SIZE(imx_uart1_resources),
.resource = imx_uart1_resources,
.dev = {
.platform_data = &uart_pdata,
}
};
static struct resource imx_uart2_resources[] = {
[0] = {
.start = 0x00207000,
.end = 0x002070FF,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = (UART2_MINT_RX),
.end = (UART2_MINT_RX),
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = (UART2_MINT_TX),
.end = (UART2_MINT_TX),
.flags = IORESOURCE_IRQ,
},
[3] = {
.start = UART2_MINT_RTS,
.end = UART2_MINT_RTS,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device imx_uart2_device = {
.name = "imx-uart",
.id = 1,
.num_resources = ARRAY_SIZE(imx_uart2_resources),
.resource = imx_uart2_resources,
.dev = {
.platform_data = &uart_pdata,
}
};
static struct platform_device *devices[] __initdata = {
&cs89x0_device,
&imx_uart1_device,
&imx_uart2_device,
};
#if defined(CONFIG_MMC_IMX) || defined(CONFIG_MMC_IMX_MODULE)
static int mx1ads_mmc_card_present(struct device *dev)
{
/* 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
#if defined(CONFIG_MMC_IMX) || defined(CONFIG_MMC_IMX_MODULE)
/* SD/MMC card detect */
imx_gpio_mode(GPIO_PORTB | GPIO_GIUS | GPIO_IN | 20);
imx_set_mmc_info(&mx1ads_mmc_info);
#endif
imx_gpio_mode(PC9_PF_UART1_CTS);
imx_gpio_mode(PC10_PF_UART1_RTS);
imx_gpio_mode(PC11_PF_UART1_TXD);
imx_gpio_mode(PC12_PF_UART1_RXD);
imx_gpio_mode(PB28_PF_UART2_CTS);
imx_gpio_mode(PB29_PF_UART2_RTS);
imx_gpio_mode(PB30_PF_UART2_TXD);
imx_gpio_mode(PB31_PF_UART2_RXD);
platform_add_devices(devices, ARRAY_SIZE(devices));
}
static void __init
mx1ads_map_io(void)
{
imx_map_io();
}
MACHINE_START(MX1ADS, "Motorola MX1ADS")
/* Maintainer: Sascha Hauer, Pengutronix */
.phys_io = 0x00200000,
.io_pg_offst = ((0xe0000000) >> 18) & 0xfffc,
.boot_params = 0x08000100,
.map_io = mx1ads_map_io,
.init_irq = imx_init_irq,
.timer = &imx_timer,
.init_machine = mx1ads_init,
MACHINE_END

View File

@ -1,220 +0,0 @@
/*
* linux/arch/arm/mach-imx/time.c
*
* Copyright (C) 2000-2001 Deep Blue Solutions
* Copyright (C) 2002 Shane Nay (shane@minirl.com)
* Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.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/kernel.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/time.h>
#include <linux/clocksource.h>
#include <linux/clockchips.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <mach/hardware.h>
#include <asm/leds.h>
#include <asm/irq.h>
#include <asm/mach/time.h>
/* Use timer 1 as system timer */
#define TIMER_BASE IMX_TIM1_BASE
static struct clock_event_device clockevent_imx;
static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
/*
* IRQ handler for the timer
*/
static irqreturn_t
imx_timer_interrupt(int irq, void *dev_id)
{
struct clock_event_device *evt = &clockevent_imx;
uint32_t tstat;
irqreturn_t ret = IRQ_NONE;
/* clear the interrupt */
tstat = IMX_TSTAT(TIMER_BASE);
IMX_TSTAT(TIMER_BASE) = 0;
if (tstat & TSTAT_COMP) {
evt->event_handler(evt);
ret = IRQ_HANDLED;
}
return ret;
}
static struct irqaction imx_timer_irq = {
.name = "i.MX Timer Tick",
.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = imx_timer_interrupt,
};
/*
* Set up timer hardware into expected mode and state.
*/
static void __init imx_timer_hardware_init(void)
{
/*
* Initialise to a known state (all timers off, and timing reset)
*/
IMX_TCTL(TIMER_BASE) = 0;
IMX_TPRER(TIMER_BASE) = 0;
IMX_TCTL(TIMER_BASE) = TCTL_FRR | TCTL_CLK_PCLK1 | TCTL_TEN;
}
cycle_t imx_get_cycles(struct clocksource *cs)
{
return IMX_TCN(TIMER_BASE);
}
static struct clocksource clocksource_imx = {
.name = "imx_timer1",
.rating = 200,
.read = imx_get_cycles,
.mask = 0xFFFFFFFF,
.shift = 20,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
static int __init imx_clocksource_init(unsigned long rate)
{
clocksource_imx.mult =
clocksource_hz2mult(rate, clocksource_imx.shift);
clocksource_register(&clocksource_imx);
return 0;
}
static int imx_set_next_event(unsigned long evt,
struct clock_event_device *unused)
{
unsigned long tcmp;
tcmp = IMX_TCN(TIMER_BASE) + evt;
IMX_TCMP(TIMER_BASE) = tcmp;
return (int32_t)(tcmp - IMX_TCN(TIMER_BASE)) < 0 ? -ETIME : 0;
}
#ifdef DEBUG
static const char *clock_event_mode_label[]={
[CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
[CLOCK_EVT_MODE_ONESHOT] = "CLOCK_EVT_MODE_ONESHOT",
[CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
[CLOCK_EVT_MODE_UNUSED] = "CLOCK_EVT_MODE_UNUSED"
};
#endif /*DEBUG*/
static void imx_set_mode(enum clock_event_mode mode, struct clock_event_device *evt)
{
unsigned long flags;
/*
* The timer interrupt generation is disabled at least
* for enough time to call imx_set_next_event()
*/
local_irq_save(flags);
/* Disable interrupt in GPT module */
IMX_TCTL(TIMER_BASE) &= ~TCTL_IRQEN;
if (mode != clockevent_mode) {
/* Set event time into far-far future */
IMX_TCMP(TIMER_BASE) = IMX_TCN(TIMER_BASE) - 3;
/* Clear pending interrupt */
IMX_TSTAT(TIMER_BASE) &= ~TSTAT_COMP;
}
#ifdef DEBUG
printk(KERN_INFO "imx_set_mode: changing mode from %s to %s\n",
clock_event_mode_label[clockevent_mode], clock_event_mode_label[mode]);
#endif /*DEBUG*/
/* Remember timer mode */
clockevent_mode = mode;
local_irq_restore(flags);
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
printk(KERN_ERR "imx_set_mode: Periodic mode is not supported for i.MX\n");
break;
case CLOCK_EVT_MODE_ONESHOT:
/*
* Do not put overhead of interrupt enable/disable into
* imx_set_next_event(), the core has about 4 minutes
* to call imx_set_next_event() or shutdown clock after
* mode switching
*/
local_irq_save(flags);
IMX_TCTL(TIMER_BASE) |= TCTL_IRQEN;
local_irq_restore(flags);
break;
case CLOCK_EVT_MODE_SHUTDOWN:
case CLOCK_EVT_MODE_UNUSED:
case CLOCK_EVT_MODE_RESUME:
/* Left event sources disabled, no more interrupts appears */
break;
}
}
static struct clock_event_device clockevent_imx = {
.name = "imx_timer1",
.features = CLOCK_EVT_FEAT_ONESHOT,
.shift = 32,
.set_mode = imx_set_mode,
.set_next_event = imx_set_next_event,
.rating = 200,
};
static int __init imx_clockevent_init(unsigned long rate)
{
clockevent_imx.mult = div_sc(rate, NSEC_PER_SEC,
clockevent_imx.shift);
clockevent_imx.max_delta_ns =
clockevent_delta2ns(0xfffffffe, &clockevent_imx);
clockevent_imx.min_delta_ns =
clockevent_delta2ns(0xf, &clockevent_imx);
clockevent_imx.cpumask = cpumask_of(0);
clockevents_register_device(&clockevent_imx);
return 0;
}
extern int imx_clocks_init(void);
static void __init imx_timer_init(void)
{
struct clk *clk;
unsigned long rate;
imx_clocks_init();
clk = clk_get(NULL, "perclk1");
clk_enable(clk);
rate = clk_get_rate(clk);
imx_timer_hardware_init();
imx_clocksource_init(rate);
imx_clockevent_init(rate);
/*
* Make irqs happen for the system timer
*/
setup_irq(TIM1_INT, &imx_timer_irq);
}
struct sys_timer imx_timer = {
.init = imx_timer_init,
};

View File

@ -26,6 +26,7 @@
#include <asm/mach/map.h>
#include <mach/common.h>
#include <mach/hardware.h>
static struct map_desc imx_io_desc[] __initdata = {
@ -37,7 +38,9 @@ static struct map_desc imx_io_desc[] __initdata = {
}
};
void __init mxc_map_io(void)
void __init mx1_map_io(void)
{
mxc_set_cpu_type(MXC_CPU_MX1);
iotable_init(imx_io_desc, ARRAY_SIZE(imx_io_desc));
}

View File

@ -12,77 +12,56 @@
* warranty of any kind, whether express or implied.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/mtd/physmap.h>
#include <linux/i2c.h>
#include <linux/i2c/pcf857x.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/mtd/physmap.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
#include <mach/irqs.h>
#include <mach/hardware.h>
#include <mach/common.h>
#include <mach/imx-uart.h>
#include <mach/irqs.h>
#include <mach/hardware.h>
#include <mach/i2c.h>
#include <mach/imx-uart.h>
#include <mach/iomux.h>
#include <mach/irqs.h>
#include "devices.h"
/*
* UARTs platform data
*/
static int mxc_uart1_pins[] = {
static int mx1ads_pins[] = {
/* UART1 */
PC9_PF_UART1_CTS,
PC10_PF_UART1_RTS,
PC11_PF_UART1_TXD,
PC12_PF_UART1_RXD,
};
static int uart1_mxc_init(struct platform_device *pdev)
{
return mxc_gpio_setup_multiple_pins(mxc_uart1_pins,
ARRAY_SIZE(mxc_uart1_pins), "UART1");
}
static int uart1_mxc_exit(struct platform_device *pdev)
{
mxc_gpio_release_multiple_pins(mxc_uart1_pins,
ARRAY_SIZE(mxc_uart1_pins));
return 0;
}
static int mxc_uart2_pins[] = {
/* UART2 */
PB28_PF_UART2_CTS,
PB29_PF_UART2_RTS,
PB30_PF_UART2_TXD,
PB31_PF_UART2_RXD,
/* I2C */
PA15_PF_I2C_SDA,
PA16_PF_I2C_SCL,
/* SPI */
PC13_PF_SPI1_SPI_RDY,
PC14_PF_SPI1_SCLK,
PC15_PF_SPI1_SS,
PC16_PF_SPI1_MISO,
PC17_PF_SPI1_MOSI,
};
static int uart2_mxc_init(struct platform_device *pdev)
{
return mxc_gpio_setup_multiple_pins(mxc_uart2_pins,
ARRAY_SIZE(mxc_uart2_pins), "UART2");
}
static int uart2_mxc_exit(struct platform_device *pdev)
{
mxc_gpio_release_multiple_pins(mxc_uart2_pins,
ARRAY_SIZE(mxc_uart2_pins));
return 0;
}
/*
* UARTs platform data
*/
static struct imxuart_platform_data uart_pdata[] = {
{
.init = uart1_mxc_init,
.exit = uart1_mxc_exit,
.flags = IMXUART_HAVE_RTSCTS,
}, {
.init = uart2_mxc_init,
.exit = uart2_mxc_exit,
.flags = IMXUART_HAVE_RTSCTS,
},
};
@ -111,24 +90,6 @@ static struct platform_device flash_device = {
/*
* I2C
*/
static int i2c_pins[] = {
PA15_PF_I2C_SDA,
PA16_PF_I2C_SCL,
};
static int i2c_init(struct device *dev)
{
return mxc_gpio_setup_multiple_pins(i2c_pins,
ARRAY_SIZE(i2c_pins), "I2C");
}
static void i2c_exit(struct device *dev)
{
mxc_gpio_release_multiple_pins(i2c_pins,
ARRAY_SIZE(i2c_pins));
}
static struct pcf857x_platform_data pcf857x_data[] = {
{
.gpio_base = 4 * 32,
@ -139,8 +100,6 @@ static struct pcf857x_platform_data pcf857x_data[] = {
static struct imxi2c_platform_data mx1ads_i2c_data = {
.bitrate = 100000,
.init = i2c_init,
.exit = i2c_exit,
};
static struct i2c_board_info mx1ads_i2c_devices[] = {
@ -160,6 +119,9 @@ static struct i2c_board_info mx1ads_i2c_devices[] = {
*/
static void __init mx1ads_init(void)
{
mxc_gpio_setup_multiple_pins(mx1ads_pins,
ARRAY_SIZE(mx1ads_pins), "mx1ads");
/* UART */
mxc_register_device(&imx_uart1_device, &uart_pdata[0]);
mxc_register_device(&imx_uart2_device, &uart_pdata[1]);
@ -188,7 +150,7 @@ MACHINE_START(MX1ADS, "Freescale MX1ADS")
.phys_io = IMX_IO_PHYS,
.io_pg_offst = (IMX_IO_BASE >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x100,
.map_io = mxc_map_io,
.map_io = mx1_map_io,
.init_irq = mxc_init_irq,
.timer = &mx1ads_timer,
.init_machine = mx1ads_init,
@ -198,7 +160,7 @@ MACHINE_START(MXLADS, "Freescale MXLADS")
.phys_io = IMX_IO_PHYS,
.io_pg_offst = (IMX_IO_BASE >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x100,
.map_io = mxc_map_io,
.map_io = mx1_map_io,
.init_irq = mxc_init_irq,
.timer = &mx1ads_timer,
.init_machine = mx1ads_init,

View File

@ -153,7 +153,7 @@ MACHINE_START(SCB9328, "Synertronixx scb9328")
.phys_io = 0x00200000,
.io_pg_offst = ((0xe0200000) >> 18) & 0xfffc,
.boot_params = 0x08000100,
.map_io = mxc_map_io,
.map_io = mx1_map_io,
.init_irq = mxc_init_irq,
.timer = &scb9328_timer,
.init_machine = scb9328_init,

Some files were not shown because too many files have changed in this diff Show More