Merge branch 'for-rmk-devel' of git://git.pengutronix.de/git/imx/linux-2.6 into devel
Conflicts: arch/arm/Kconfig arch/arm/Makefile
This commit is contained in:
commit
a2ab67fae1
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
65
Documentation/input/bcm5974.txt
Normal file
65
Documentation/input/bcm5974.txt
Normal 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/
|
140
Documentation/input/multi-touch-protocol.txt
Normal file
140
Documentation/input/multi-touch-protocol.txt
Normal 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.
|
|
@ -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).
|
||||
|
|
213
Documentation/isdn/INTERFACE.CAPI
Normal file
213
Documentation/isdn/INTERFACE.CAPI
Normal 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)
|
||||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
BIN
Documentation/logo.gif
Normal file
BIN
Documentation/logo.gif
Normal file
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 |
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
21
MAINTAINERS
21
MAINTAINERS
|
@ -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
|
||||
|
|
10
Makefile
10
Makefile
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ SECTIONS
|
|||
|
||||
_text = .; /* Text and read-only data */
|
||||
.text : {
|
||||
*(.text.head)
|
||||
HEAD_TEXT
|
||||
TEXT_TEXT
|
||||
SCHED_TEXT
|
||||
LOCK_TEXT
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
1784
arch/arm/configs/davinci_all_defconfig
Normal file
1784
arch/arm/configs/davinci_all_defconfig
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
461
arch/arm/mach-davinci/dm644x.c
Normal file
461
arch/arm/mach-davinci/dm644x.c
Normal 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);
|
1135
arch/arm/mach-davinci/dma.c
Normal file
1135
arch/arm/mach-davinci/dma.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
20
arch/arm/mach-davinci/include/mach/board-dm6446evm.h
Normal file
20
arch/arm/mach-davinci/include/mach/board-dm6446evm.h
Normal 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
|
13
arch/arm/mach-davinci/include/mach/clkdev.h
Normal file
13
arch/arm/mach-davinci/include/mach/clkdev.h
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
49
arch/arm/mach-davinci/include/mach/cputype.h
Normal file
49
arch/arm/mach-davinci/include/mach/cputype.h
Normal 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
|
|
@ -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 */
|
228
arch/arm/mach-davinci/include/mach/edma.h
Normal file
228
arch/arm/mach-davinci/include/mach/edma.h
Normal 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
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
51
arch/arm/mach-davinci/mux.h
Normal file
51
arch/arm/mach-davinci/mux.h
Normal 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 */
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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, },
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -1,2 +0,0 @@
|
|||
zreladdr-$(CONFIG_ARCH_MX1ADS) := 0x08008000
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
@ -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);
|
|
@ -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);
|
|
@ -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;
|
|
@ -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
|
|
@ -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 */
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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 */
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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_*/
|
|
@ -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
|
|
@ -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()
|
|
@ -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)
|
|
@ -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
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
|
@ -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);
|
|
@ -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
|
|
@ -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,
|
||||
};
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
Loading…
Reference in a new issue