mirror of https://gitee.com/openkylin/linux.git
Merge branches 'arm', 'at91', 'bcmring', 'ep93xx', 'mach-types', 'misc' and 'w90x900' into devel
This commit is contained in:
commit
cf7a2b4fb6
|
@ -27,6 +27,7 @@
|
|||
*.gz
|
||||
*.lzma
|
||||
*.patch
|
||||
*.gcno
|
||||
|
||||
#
|
||||
# Top-level generic files
|
||||
|
|
|
@ -184,8 +184,6 @@ usage should require reading the full document.
|
|||
!Finclude/net/mac80211.h ieee80211_ctstoself_get
|
||||
!Finclude/net/mac80211.h ieee80211_ctstoself_duration
|
||||
!Finclude/net/mac80211.h ieee80211_generic_frame_duration
|
||||
!Finclude/net/mac80211.h ieee80211_get_hdrlen_from_skb
|
||||
!Finclude/net/mac80211.h ieee80211_hdrlen
|
||||
!Finclude/net/mac80211.h ieee80211_wake_queue
|
||||
!Finclude/net/mac80211.h ieee80211_stop_queue
|
||||
!Finclude/net/mac80211.h ieee80211_wake_queues
|
||||
|
|
|
@ -50,7 +50,7 @@ encouraged them to allow separation of the data and integrity metadata
|
|||
scatter-gather lists.
|
||||
|
||||
The controller will interleave the buffers on write and split them on
|
||||
read. This means that the Linux can DMA the data buffers to and from
|
||||
read. This means that Linux can DMA the data buffers to and from
|
||||
host memory without changes to the page cache.
|
||||
|
||||
Also, the 16-bit CRC checksum mandated by both the SCSI and SATA specs
|
||||
|
@ -66,7 +66,7 @@ software RAID5).
|
|||
|
||||
The IP checksum is weaker than the CRC in terms of detecting bit
|
||||
errors. However, the strength is really in the separation of the data
|
||||
buffers and the integrity metadata. These two distinct buffers much
|
||||
buffers and the integrity metadata. These two distinct buffers must
|
||||
match up for an I/O to complete.
|
||||
|
||||
The separation of the data and integrity metadata buffers as well as
|
||||
|
|
|
@ -777,6 +777,18 @@ in cpuset directories:
|
|||
# /bin/echo 1-4 > cpus -> set cpus list to cpus 1,2,3,4
|
||||
# /bin/echo 1,2,3,4 > cpus -> set cpus list to cpus 1,2,3,4
|
||||
|
||||
To add a CPU to a cpuset, write the new list of CPUs including the
|
||||
CPU to be added. To add 6 to the above cpuset:
|
||||
|
||||
# /bin/echo 1-4,6 > cpus -> set cpus list to cpus 1,2,3,4,6
|
||||
|
||||
Similarly to remove a CPU from a cpuset, write the new list of CPUs
|
||||
without the CPU to be removed.
|
||||
|
||||
To remove all the CPUs:
|
||||
|
||||
# /bin/echo "" > cpus -> clear cpus list
|
||||
|
||||
2.3 Setting flags
|
||||
-----------------
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ use IO::Handle;
|
|||
"tda10046lifeview", "av7110", "dec2000t", "dec2540t",
|
||||
"dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004",
|
||||
"or51211", "or51132_qam", "or51132_vsb", "bluebird",
|
||||
"opera1", "cx231xx", "cx18", "cx23885", "pvrusb2" );
|
||||
"opera1", "cx231xx", "cx18", "cx23885", "pvrusb2", "mpc718" );
|
||||
|
||||
# Check args
|
||||
syntax() if (scalar(@ARGV) != 1);
|
||||
|
@ -381,6 +381,57 @@ sub cx18 {
|
|||
$allfiles;
|
||||
}
|
||||
|
||||
sub mpc718 {
|
||||
my $archive = 'Yuan MPC718 TV Tuner Card 2.13.10.1016.zip';
|
||||
my $url = "ftp://ftp.work.acer-euro.com/desktop/aspire_idea510/vista/Drivers/$archive";
|
||||
my $fwfile = "dvb-cx18-mpc718-mt352.fw";
|
||||
my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
|
||||
|
||||
checkstandard();
|
||||
wgetfile($archive, $url);
|
||||
unzip($archive, $tmpdir);
|
||||
|
||||
my $sourcefile = "$tmpdir/Yuan MPC718 TV Tuner Card 2.13.10.1016/mpc718_32bit/yuanrap.sys";
|
||||
my $found = 0;
|
||||
|
||||
open IN, '<', $sourcefile or die "Couldn't open $sourcefile to extract $fwfile data\n";
|
||||
binmode IN;
|
||||
open OUT, '>', $fwfile;
|
||||
binmode OUT;
|
||||
{
|
||||
# Block scope because we change the line terminator variable $/
|
||||
my $prevlen = 0;
|
||||
my $currlen;
|
||||
|
||||
# Buried in the data segment are 3 runs of almost identical
|
||||
# register-value pairs that end in 0x5d 0x01 which is a "TUNER GO"
|
||||
# command for the MT352.
|
||||
# Pull out the middle run (because it's easy) of register-value
|
||||
# pairs to make the "firmware" file.
|
||||
|
||||
local $/ = "\x5d\x01"; # MT352 "TUNER GO"
|
||||
|
||||
while (<IN>) {
|
||||
$currlen = length($_);
|
||||
if ($prevlen == $currlen && $currlen <= 64) {
|
||||
chop; chop; # Get rid of "TUNER GO"
|
||||
s/^\0\0//; # get rid of leading 00 00 if it's there
|
||||
printf OUT "$_";
|
||||
$found = 1;
|
||||
last;
|
||||
}
|
||||
$prevlen = $currlen;
|
||||
}
|
||||
}
|
||||
close OUT;
|
||||
close IN;
|
||||
if (!$found) {
|
||||
unlink $fwfile;
|
||||
die "Couldn't find valid register-value sequence in $sourcefile for $fwfile\n";
|
||||
}
|
||||
$fwfile;
|
||||
}
|
||||
|
||||
sub cx23885 {
|
||||
my $url = "http://linuxtv.org/downloads/firmware/";
|
||||
|
||||
|
|
|
@ -458,3 +458,13 @@ Why: Remove the old legacy 32bit machine check code. This has been
|
|||
but the old version has been kept around for easier testing. Note this
|
||||
doesn't impact the old P5 and WinChip machine check handlers.
|
||||
Who: Andi Kleen <andi@firstfloor.org>
|
||||
|
||||
----------------------------
|
||||
|
||||
What: lock_policy_rwsem_* and unlock_policy_rwsem_* will not be
|
||||
exported interface anymore.
|
||||
When: 2.6.33
|
||||
Why: cpu_policy_rwsem has a new cleaner definition making it local to
|
||||
cpufreq core and contained inside cpufreq.c. Other dependent
|
||||
drivers should not use it in order to safely avoid lockdep issues.
|
||||
Who: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
|
||||
|
|
|
@ -188,13 +188,18 @@ Solution: Exclude affected source files from profiling by specifying
|
|||
GCOV_PROFILE := n or GCOV_PROFILE_basename.o := n in the
|
||||
corresponding Makefile.
|
||||
|
||||
Problem: Files copied from sysfs appear empty or incomplete.
|
||||
Cause: Due to the way seq_file works, some tools such as cp or tar
|
||||
may not correctly copy files from sysfs.
|
||||
Solution: Use 'cat' to read .gcda files and 'cp -d' to copy links.
|
||||
Alternatively use the mechanism shown in Appendix B.
|
||||
|
||||
|
||||
Appendix A: gather_on_build.sh
|
||||
==============================
|
||||
|
||||
Sample script to gather coverage meta files on the build machine
|
||||
(see 6a):
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
KSRC=$1
|
||||
|
@ -226,7 +231,7 @@ Appendix B: gather_on_test.sh
|
|||
Sample script to gather coverage data files on the test machine
|
||||
(see 6b):
|
||||
|
||||
#!/bin/bash
|
||||
#!/bin/bash -e
|
||||
|
||||
DEST=$1
|
||||
GCDA=/sys/kernel/debug/gcov
|
||||
|
@ -236,11 +241,13 @@ if [ -z "$DEST" ] ; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
find $GCDA -name '*.gcno' -o -name '*.gcda' | tar cfz $DEST -T -
|
||||
TEMPDIR=$(mktemp -d)
|
||||
echo Collecting data..
|
||||
find $GCDA -type d -exec mkdir -p $TEMPDIR/\{\} \;
|
||||
find $GCDA -name '*.gcda' -exec sh -c 'cat < $0 > '$TEMPDIR'/$0' {} \;
|
||||
find $GCDA -name '*.gcno' -exec sh -c 'cp -d $0 '$TEMPDIR'/$0' {} \;
|
||||
tar czf $DEST -C $TEMPDIR sys
|
||||
rm -rf $TEMPDIR
|
||||
|
||||
if [ $? -eq 0 ] ; then
|
||||
echo "$DEST successfully created, copy to build system and unpack with:"
|
||||
echo " tar xfz $DEST"
|
||||
else
|
||||
echo "Could not create file $DEST"
|
||||
fi
|
||||
echo "$DEST successfully created, copy to build system and unpack with:"
|
||||
echo " tar xfz $DEST"
|
||||
|
|
|
@ -1720,8 +1720,8 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||
oprofile.cpu_type= Force an oprofile cpu type
|
||||
This might be useful if you have an older oprofile
|
||||
userland or if you want common events.
|
||||
Format: { archperfmon }
|
||||
archperfmon: [X86] Force use of architectural
|
||||
Format: { arch_perfmon }
|
||||
arch_perfmon: [X86] Force use of architectural
|
||||
perfmon on Intel CPUs instead of the
|
||||
CPU specific event set.
|
||||
|
||||
|
@ -1915,6 +1915,12 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||
Format: { 0 | 1 }
|
||||
See arch/parisc/kernel/pdc_chassis.c
|
||||
|
||||
percpu_alloc= [X86] Select which percpu first chunk allocator to use.
|
||||
Allowed values are one of "lpage", "embed" and "4k".
|
||||
See comments in arch/x86/kernel/setup_percpu.c for
|
||||
details on each allocator. This parameter is primarily
|
||||
for debugging and performance comparison.
|
||||
|
||||
pf. [PARIDE]
|
||||
See Documentation/blockdev/paride.txt.
|
||||
|
||||
|
@ -2467,7 +2473,8 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||
|
||||
tp720= [HW,PS2]
|
||||
|
||||
trace_buf_size=nn[KMG] [ftrace] will set tracing buffer size.
|
||||
trace_buf_size=nn[KMG]
|
||||
[FTRACE] will set tracing buffer size.
|
||||
|
||||
trix= [HW,OSS] MediaTrix AudioTrix Pro
|
||||
Format:
|
||||
|
|
|
@ -16,13 +16,17 @@ Usage
|
|||
-----
|
||||
|
||||
CONFIG_DEBUG_KMEMLEAK in "Kernel hacking" has to be enabled. A kernel
|
||||
thread scans the memory every 10 minutes (by default) and prints any new
|
||||
unreferenced objects found. To trigger an intermediate scan and display
|
||||
all the possible memory leaks:
|
||||
thread scans the memory every 10 minutes (by default) and prints the
|
||||
number of new unreferenced objects found. To display the details of all
|
||||
the possible memory leaks:
|
||||
|
||||
# mount -t debugfs nodev /sys/kernel/debug/
|
||||
# cat /sys/kernel/debug/kmemleak
|
||||
|
||||
To trigger an intermediate memory scan:
|
||||
|
||||
# echo scan > /sys/kernel/debug/kmemleak
|
||||
|
||||
Note that the orphan objects are listed in the order they were allocated
|
||||
and one object at the beginning of the list may cause other subsequent
|
||||
objects to be reported as orphan.
|
||||
|
@ -31,16 +35,21 @@ Memory scanning parameters can be modified at run-time by writing to the
|
|||
/sys/kernel/debug/kmemleak file. The following parameters are supported:
|
||||
|
||||
off - disable kmemleak (irreversible)
|
||||
stack=on - enable the task stacks scanning
|
||||
stack=on - enable the task stacks scanning (default)
|
||||
stack=off - disable the tasks stacks scanning
|
||||
scan=on - start the automatic memory scanning thread
|
||||
scan=on - start the automatic memory scanning thread (default)
|
||||
scan=off - stop the automatic memory scanning thread
|
||||
scan=<secs> - set the automatic memory scanning period in seconds (0
|
||||
to disable it)
|
||||
scan=<secs> - set the automatic memory scanning period in seconds
|
||||
(default 600, 0 to stop the automatic scanning)
|
||||
scan - trigger a memory scan
|
||||
|
||||
Kmemleak can also be disabled at boot-time by passing "kmemleak=off" on
|
||||
the kernel command line.
|
||||
|
||||
Memory may be allocated or freed before kmemleak is initialised and
|
||||
these actions are stored in an early log buffer. The size of this buffer
|
||||
is configured via the CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE option.
|
||||
|
||||
Basic Algorithm
|
||||
---------------
|
||||
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
Kernel driver lp3944
|
||||
====================
|
||||
|
||||
* National Semiconductor LP3944 Fun-light Chip
|
||||
Prefix: 'lp3944'
|
||||
Addresses scanned: None (see the Notes section below)
|
||||
Datasheet: Publicly available at the National Semiconductor website
|
||||
http://www.national.com/pf/LP/LP3944.html
|
||||
|
||||
Authors:
|
||||
Antonio Ospite <ospite@studenti.unina.it>
|
||||
|
||||
|
||||
Description
|
||||
-----------
|
||||
The LP3944 is a helper chip that can drive up to 8 leds, with two programmable
|
||||
DIM modes; it could even be used as a gpio expander but this driver assumes it
|
||||
is used as a led controller.
|
||||
|
||||
The DIM modes are used to set _blink_ patterns for leds, the pattern is
|
||||
specified supplying two parameters:
|
||||
- period: from 0s to 1.6s
|
||||
- duty cycle: percentage of the period the led is on, from 0 to 100
|
||||
|
||||
Setting a led in DIM0 or DIM1 mode makes it blink according to the pattern.
|
||||
See the datasheet for details.
|
||||
|
||||
LP3944 can be found on Motorola A910 smartphone, where it drives the rgb
|
||||
leds, the camera flash light and the lcds power.
|
||||
|
||||
|
||||
Notes
|
||||
-----
|
||||
The chip is used mainly in embedded contexts, so this driver expects it is
|
||||
registered using the i2c_board_info mechanism.
|
||||
|
||||
To register the chip at address 0x60 on adapter 0, set the platform data
|
||||
according to include/linux/leds-lp3944.h, set the i2c board info:
|
||||
|
||||
static struct i2c_board_info __initdata a910_i2c_board_info[] = {
|
||||
{
|
||||
I2C_BOARD_INFO("lp3944", 0x60),
|
||||
.platform_data = &a910_lp3944_leds,
|
||||
},
|
||||
};
|
||||
|
||||
and register it in the platform init function
|
||||
|
||||
i2c_register_board_info(0, a910_i2c_board_info,
|
||||
ARRAY_SIZE(a910_i2c_board_info));
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,148 @@
|
|||
4xx/Axon EMAC ethernet nodes
|
||||
|
||||
The EMAC ethernet controller in IBM and AMCC 4xx chips, and also
|
||||
the Axon bridge. To operate this needs to interact with a ths
|
||||
special McMAL DMA controller, and sometimes an RGMII or ZMII
|
||||
interface. In addition to the nodes and properties described
|
||||
below, the node for the OPB bus on which the EMAC sits must have a
|
||||
correct clock-frequency property.
|
||||
|
||||
i) The EMAC node itself
|
||||
|
||||
Required properties:
|
||||
- device_type : "network"
|
||||
|
||||
- compatible : compatible list, contains 2 entries, first is
|
||||
"ibm,emac-CHIP" where CHIP is the host ASIC (440gx,
|
||||
405gp, Axon) and second is either "ibm,emac" or
|
||||
"ibm,emac4". For Axon, thus, we have: "ibm,emac-axon",
|
||||
"ibm,emac4"
|
||||
- interrupts : <interrupt mapping for EMAC IRQ and WOL IRQ>
|
||||
- interrupt-parent : optional, if needed for interrupt mapping
|
||||
- reg : <registers mapping>
|
||||
- local-mac-address : 6 bytes, MAC address
|
||||
- mal-device : phandle of the associated McMAL node
|
||||
- mal-tx-channel : 1 cell, index of the tx channel on McMAL associated
|
||||
with this EMAC
|
||||
- mal-rx-channel : 1 cell, index of the rx channel on McMAL associated
|
||||
with this EMAC
|
||||
- cell-index : 1 cell, hardware index of the EMAC cell on a given
|
||||
ASIC (typically 0x0 and 0x1 for EMAC0 and EMAC1 on
|
||||
each Axon chip)
|
||||
- max-frame-size : 1 cell, maximum frame size supported in bytes
|
||||
- rx-fifo-size : 1 cell, Rx fifo size in bytes for 10 and 100 Mb/sec
|
||||
operations.
|
||||
For Axon, 2048
|
||||
- tx-fifo-size : 1 cell, Tx fifo size in bytes for 10 and 100 Mb/sec
|
||||
operations.
|
||||
For Axon, 2048.
|
||||
- fifo-entry-size : 1 cell, size of a fifo entry (used to calculate
|
||||
thresholds).
|
||||
For Axon, 0x00000010
|
||||
- mal-burst-size : 1 cell, MAL burst size (used to calculate thresholds)
|
||||
in bytes.
|
||||
For Axon, 0x00000100 (I think ...)
|
||||
- phy-mode : string, mode of operations of the PHY interface.
|
||||
Supported values are: "mii", "rmii", "smii", "rgmii",
|
||||
"tbi", "gmii", rtbi", "sgmii".
|
||||
For Axon on CAB, it is "rgmii"
|
||||
- mdio-device : 1 cell, required iff using shared MDIO registers
|
||||
(440EP). phandle of the EMAC to use to drive the
|
||||
MDIO lines for the PHY used by this EMAC.
|
||||
- zmii-device : 1 cell, required iff connected to a ZMII. phandle of
|
||||
the ZMII device node
|
||||
- zmii-channel : 1 cell, required iff connected to a ZMII. Which ZMII
|
||||
channel or 0xffffffff if ZMII is only used for MDIO.
|
||||
- rgmii-device : 1 cell, required iff connected to an RGMII. phandle
|
||||
of the RGMII device node.
|
||||
For Axon: phandle of plb5/plb4/opb/rgmii
|
||||
- rgmii-channel : 1 cell, required iff connected to an RGMII. Which
|
||||
RGMII channel is used by this EMAC.
|
||||
Fox Axon: present, whatever value is appropriate for each
|
||||
EMAC, that is the content of the current (bogus) "phy-port"
|
||||
property.
|
||||
|
||||
Optional properties:
|
||||
- phy-address : 1 cell, optional, MDIO address of the PHY. If absent,
|
||||
a search is performed.
|
||||
- phy-map : 1 cell, optional, bitmap of addresses to probe the PHY
|
||||
for, used if phy-address is absent. bit 0x00000001 is
|
||||
MDIO address 0.
|
||||
For Axon it can be absent, though my current driver
|
||||
doesn't handle phy-address yet so for now, keep
|
||||
0x00ffffff in it.
|
||||
- rx-fifo-size-gige : 1 cell, Rx fifo size in bytes for 1000 Mb/sec
|
||||
operations (if absent the value is the same as
|
||||
rx-fifo-size). For Axon, either absent or 2048.
|
||||
- tx-fifo-size-gige : 1 cell, Tx fifo size in bytes for 1000 Mb/sec
|
||||
operations (if absent the value is the same as
|
||||
tx-fifo-size). For Axon, either absent or 2048.
|
||||
- tah-device : 1 cell, optional. If connected to a TAH engine for
|
||||
offload, phandle of the TAH device node.
|
||||
- tah-channel : 1 cell, optional. If appropriate, channel used on the
|
||||
TAH engine.
|
||||
|
||||
Example:
|
||||
|
||||
EMAC0: ethernet@40000800 {
|
||||
device_type = "network";
|
||||
compatible = "ibm,emac-440gp", "ibm,emac";
|
||||
interrupt-parent = <&UIC1>;
|
||||
interrupts = <1c 4 1d 4>;
|
||||
reg = <40000800 70>;
|
||||
local-mac-address = [00 04 AC E3 1B 1E];
|
||||
mal-device = <&MAL0>;
|
||||
mal-tx-channel = <0 1>;
|
||||
mal-rx-channel = <0>;
|
||||
cell-index = <0>;
|
||||
max-frame-size = <5dc>;
|
||||
rx-fifo-size = <1000>;
|
||||
tx-fifo-size = <800>;
|
||||
phy-mode = "rmii";
|
||||
phy-map = <00000001>;
|
||||
zmii-device = <&ZMII0>;
|
||||
zmii-channel = <0>;
|
||||
};
|
||||
|
||||
ii) McMAL node
|
||||
|
||||
Required properties:
|
||||
- device_type : "dma-controller"
|
||||
- compatible : compatible list, containing 2 entries, first is
|
||||
"ibm,mcmal-CHIP" where CHIP is the host ASIC (like
|
||||
emac) and the second is either "ibm,mcmal" or
|
||||
"ibm,mcmal2".
|
||||
For Axon, "ibm,mcmal-axon","ibm,mcmal2"
|
||||
- interrupts : <interrupt mapping for the MAL interrupts sources:
|
||||
5 sources: tx_eob, rx_eob, serr, txde, rxde>.
|
||||
For Axon: This is _different_ from the current
|
||||
firmware. We use the "delayed" interrupts for txeob
|
||||
and rxeob. Thus we end up with mapping those 5 MPIC
|
||||
interrupts, all level positive sensitive: 10, 11, 32,
|
||||
33, 34 (in decimal)
|
||||
- dcr-reg : < DCR registers range >
|
||||
- dcr-parent : if needed for dcr-reg
|
||||
- num-tx-chans : 1 cell, number of Tx channels
|
||||
- num-rx-chans : 1 cell, number of Rx channels
|
||||
|
||||
iii) ZMII node
|
||||
|
||||
Required properties:
|
||||
- compatible : compatible list, containing 2 entries, first is
|
||||
"ibm,zmii-CHIP" where CHIP is the host ASIC (like
|
||||
EMAC) and the second is "ibm,zmii".
|
||||
For Axon, there is no ZMII node.
|
||||
- reg : <registers mapping>
|
||||
|
||||
iv) RGMII node
|
||||
|
||||
Required properties:
|
||||
- compatible : compatible list, containing 2 entries, first is
|
||||
"ibm,rgmii-CHIP" where CHIP is the host ASIC (like
|
||||
EMAC) and the second is "ibm,rgmii".
|
||||
For Axon, "ibm,rgmii-axon","ibm,rgmii"
|
||||
- reg : <registers mapping>
|
||||
- revision : as provided by the RGMII new version register if
|
||||
available.
|
||||
For Axon: 0x0000012a
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
Specifying GPIO information for devices
|
||||
============================================
|
||||
|
||||
1) gpios property
|
||||
-----------------
|
||||
|
||||
Nodes that makes use of GPIOs should define them using `gpios' property,
|
||||
format of which is: <&gpio-controller1-phandle gpio1-specifier
|
||||
&gpio-controller2-phandle gpio2-specifier
|
||||
0 /* holes are permitted, means no GPIO 3 */
|
||||
&gpio-controller4-phandle gpio4-specifier
|
||||
...>;
|
||||
|
||||
Note that gpio-specifier length is controller dependent.
|
||||
|
||||
gpio-specifier may encode: bank, pin position inside the bank,
|
||||
whether pin is open-drain and whether pin is logically inverted.
|
||||
|
||||
Example of the node using GPIOs:
|
||||
|
||||
node {
|
||||
gpios = <&qe_pio_e 18 0>;
|
||||
};
|
||||
|
||||
In this example gpio-specifier is "18 0" and encodes GPIO pin number,
|
||||
and empty GPIO flags as accepted by the "qe_pio_e" gpio-controller.
|
||||
|
||||
2) gpio-controller nodes
|
||||
------------------------
|
||||
|
||||
Every GPIO controller node must have #gpio-cells property defined,
|
||||
this information will be used to translate gpio-specifiers.
|
||||
|
||||
Example of two SOC GPIO banks defined as gpio-controller nodes:
|
||||
|
||||
qe_pio_a: gpio-controller@1400 {
|
||||
#gpio-cells = <2>;
|
||||
compatible = "fsl,qe-pario-bank-a", "fsl,qe-pario-bank";
|
||||
reg = <0x1400 0x18>;
|
||||
gpio-controller;
|
||||
};
|
||||
|
||||
qe_pio_e: gpio-controller@1460 {
|
||||
#gpio-cells = <2>;
|
||||
compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank";
|
||||
reg = <0x1460 0x18>;
|
||||
gpio-controller;
|
||||
};
|
||||
|
||||
|
|
@ -16,10 +16,17 @@ LED sub-node properties:
|
|||
string defining the trigger assigned to the LED. Current triggers are:
|
||||
"backlight" - LED will act as a back-light, controlled by the framebuffer
|
||||
system
|
||||
"default-on" - LED will turn on
|
||||
"default-on" - LED will turn on, but see "default-state" below
|
||||
"heartbeat" - LED "double" flashes at a load average based rate
|
||||
"ide-disk" - LED indicates disk activity
|
||||
"timer" - LED flashes at a fixed, configurable rate
|
||||
- default-state: (optional) The initial state of the LED. Valid
|
||||
values are "on", "off", and "keep". If the LED is already on or off
|
||||
and the default-state property is set the to same value, then no
|
||||
glitch should be produced where the LED momentarily turns off (or
|
||||
on). The "keep" setting will keep the LED at whatever its current
|
||||
state is, without producing a glitch. The default is off if this
|
||||
property is not present.
|
||||
|
||||
Examples:
|
||||
|
||||
|
@ -30,14 +37,22 @@ leds {
|
|||
gpios = <&mcu_pio 0 1>; /* Active low */
|
||||
linux,default-trigger = "ide-disk";
|
||||
};
|
||||
|
||||
fault {
|
||||
gpios = <&mcu_pio 1 0>;
|
||||
/* Keep LED on if BIOS detected hardware fault */
|
||||
default-state = "keep";
|
||||
};
|
||||
};
|
||||
|
||||
run-control {
|
||||
compatible = "gpio-leds";
|
||||
red {
|
||||
gpios = <&mpc8572 6 0>;
|
||||
default-state = "off";
|
||||
};
|
||||
green {
|
||||
gpios = <&mpc8572 7 0>;
|
||||
default-state = "on";
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
MDIO on GPIOs
|
||||
|
||||
Currently defined compatibles:
|
||||
- virtual,gpio-mdio
|
||||
|
||||
MDC and MDIO lines connected to GPIO controllers are listed in the
|
||||
gpios property as described in section VIII.1 in the following order:
|
||||
|
||||
MDC, MDIO.
|
||||
|
||||
Example:
|
||||
|
||||
mdio {
|
||||
compatible = "virtual,mdio-gpio";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
gpios = <&qe_pio_a 11
|
||||
&qe_pio_c 6>;
|
||||
};
|
|
@ -0,0 +1,521 @@
|
|||
Marvell Discovery mv64[345]6x System Controller chips
|
||||
===========================================================
|
||||
|
||||
The Marvell mv64[345]60 series of system controller chips contain
|
||||
many of the peripherals needed to implement a complete computer
|
||||
system. In this section, we define device tree nodes to describe
|
||||
the system controller chip itself and each of the peripherals
|
||||
which it contains. Compatible string values for each node are
|
||||
prefixed with the string "marvell,", for Marvell Technology Group Ltd.
|
||||
|
||||
1) The /system-controller node
|
||||
|
||||
This node is used to represent the system-controller and must be
|
||||
present when the system uses a system controller chip. The top-level
|
||||
system-controller node contains information that is global to all
|
||||
devices within the system controller chip. The node name begins
|
||||
with "system-controller" followed by the unit address, which is
|
||||
the base address of the memory-mapped register set for the system
|
||||
controller chip.
|
||||
|
||||
Required properties:
|
||||
|
||||
- ranges : Describes the translation of system controller addresses
|
||||
for memory mapped registers.
|
||||
- clock-frequency: Contains the main clock frequency for the system
|
||||
controller chip.
|
||||
- reg : This property defines the address and size of the
|
||||
memory-mapped registers contained within the system controller
|
||||
chip. The address specified in the "reg" property should match
|
||||
the unit address of the system-controller node.
|
||||
- #address-cells : Address representation for system controller
|
||||
devices. This field represents the number of cells needed to
|
||||
represent the address of the memory-mapped registers of devices
|
||||
within the system controller chip.
|
||||
- #size-cells : Size representation for for the memory-mapped
|
||||
registers within the system controller chip.
|
||||
- #interrupt-cells : Defines the width of cells used to represent
|
||||
interrupts.
|
||||
|
||||
Optional properties:
|
||||
|
||||
- model : The specific model of the system controller chip. Such
|
||||
as, "mv64360", "mv64460", or "mv64560".
|
||||
- compatible : A string identifying the compatibility identifiers
|
||||
of the system controller chip.
|
||||
|
||||
The system-controller node contains child nodes for each system
|
||||
controller device that the platform uses. Nodes should not be created
|
||||
for devices which exist on the system controller chip but are not used
|
||||
|
||||
Example Marvell Discovery mv64360 system-controller node:
|
||||
|
||||
system-controller@f1000000 { /* Marvell Discovery mv64360 */
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
model = "mv64360"; /* Default */
|
||||
compatible = "marvell,mv64360";
|
||||
clock-frequency = <133333333>;
|
||||
reg = <0xf1000000 0x10000>;
|
||||
virtual-reg = <0xf1000000>;
|
||||
ranges = <0x88000000 0x88000000 0x1000000 /* PCI 0 I/O Space */
|
||||
0x80000000 0x80000000 0x8000000 /* PCI 0 MEM Space */
|
||||
0xa0000000 0xa0000000 0x4000000 /* User FLASH */
|
||||
0x00000000 0xf1000000 0x0010000 /* Bridge's regs */
|
||||
0xf2000000 0xf2000000 0x0040000>;/* Integrated SRAM */
|
||||
|
||||
[ child node definitions... ]
|
||||
}
|
||||
|
||||
2) Child nodes of /system-controller
|
||||
|
||||
a) Marvell Discovery MDIO bus
|
||||
|
||||
The MDIO is a bus to which the PHY devices are connected. For each
|
||||
device that exists on this bus, a child node should be created. See
|
||||
the definition of the PHY node below for an example of how to define
|
||||
a PHY.
|
||||
|
||||
Required properties:
|
||||
- #address-cells : Should be <1>
|
||||
- #size-cells : Should be <0>
|
||||
- device_type : Should be "mdio"
|
||||
- compatible : Should be "marvell,mv64360-mdio"
|
||||
|
||||
Example:
|
||||
|
||||
mdio {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
device_type = "mdio";
|
||||
compatible = "marvell,mv64360-mdio";
|
||||
|
||||
ethernet-phy@0 {
|
||||
......
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
b) Marvell Discovery ethernet controller
|
||||
|
||||
The Discover ethernet controller is described with two levels
|
||||
of nodes. The first level describes an ethernet silicon block
|
||||
and the second level describes up to 3 ethernet nodes within
|
||||
that block. The reason for the multiple levels is that the
|
||||
registers for the node are interleaved within a single set
|
||||
of registers. The "ethernet-block" level describes the
|
||||
shared register set, and the "ethernet" nodes describe ethernet
|
||||
port-specific properties.
|
||||
|
||||
Ethernet block node
|
||||
|
||||
Required properties:
|
||||
- #address-cells : <1>
|
||||
- #size-cells : <0>
|
||||
- compatible : "marvell,mv64360-eth-block"
|
||||
- reg : Offset and length of the register set for this block
|
||||
|
||||
Example Discovery Ethernet block node:
|
||||
ethernet-block@2000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "marvell,mv64360-eth-block";
|
||||
reg = <0x2000 0x2000>;
|
||||
ethernet@0 {
|
||||
.......
|
||||
};
|
||||
};
|
||||
|
||||
Ethernet port node
|
||||
|
||||
Required properties:
|
||||
- device_type : Should be "network".
|
||||
- compatible : Should be "marvell,mv64360-eth".
|
||||
- reg : Should be <0>, <1>, or <2>, according to which registers
|
||||
within the silicon block the device uses.
|
||||
- interrupts : <a> where a is the interrupt number for the port.
|
||||
- interrupt-parent : the phandle for the interrupt controller
|
||||
that services interrupts for this device.
|
||||
- phy : the phandle for the PHY connected to this ethernet
|
||||
controller.
|
||||
- local-mac-address : 6 bytes, MAC address
|
||||
|
||||
Example Discovery Ethernet port node:
|
||||
ethernet@0 {
|
||||
device_type = "network";
|
||||
compatible = "marvell,mv64360-eth";
|
||||
reg = <0>;
|
||||
interrupts = <32>;
|
||||
interrupt-parent = <&PIC>;
|
||||
phy = <&PHY0>;
|
||||
local-mac-address = [ 00 00 00 00 00 00 ];
|
||||
};
|
||||
|
||||
|
||||
|
||||
c) Marvell Discovery PHY nodes
|
||||
|
||||
Required properties:
|
||||
- device_type : Should be "ethernet-phy"
|
||||
- interrupts : <a> where a is the interrupt number for this phy.
|
||||
- interrupt-parent : the phandle for the interrupt controller that
|
||||
services interrupts for this device.
|
||||
- reg : The ID number for the phy, usually a small integer
|
||||
|
||||
Example Discovery PHY node:
|
||||
ethernet-phy@1 {
|
||||
device_type = "ethernet-phy";
|
||||
compatible = "broadcom,bcm5421";
|
||||
interrupts = <76>; /* GPP 12 */
|
||||
interrupt-parent = <&PIC>;
|
||||
reg = <1>;
|
||||
};
|
||||
|
||||
|
||||
d) Marvell Discovery SDMA nodes
|
||||
|
||||
Represent DMA hardware associated with the MPSC (multiprotocol
|
||||
serial controllers).
|
||||
|
||||
Required properties:
|
||||
- compatible : "marvell,mv64360-sdma"
|
||||
- reg : Offset and length of the register set for this device
|
||||
- interrupts : <a> where a is the interrupt number for the DMA
|
||||
device.
|
||||
- interrupt-parent : the phandle for the interrupt controller
|
||||
that services interrupts for this device.
|
||||
|
||||
Example Discovery SDMA node:
|
||||
sdma@4000 {
|
||||
compatible = "marvell,mv64360-sdma";
|
||||
reg = <0x4000 0xc18>;
|
||||
virtual-reg = <0xf1004000>;
|
||||
interrupts = <36>;
|
||||
interrupt-parent = <&PIC>;
|
||||
};
|
||||
|
||||
|
||||
e) Marvell Discovery BRG nodes
|
||||
|
||||
Represent baud rate generator hardware associated with the MPSC
|
||||
(multiprotocol serial controllers).
|
||||
|
||||
Required properties:
|
||||
- compatible : "marvell,mv64360-brg"
|
||||
- reg : Offset and length of the register set for this device
|
||||
- clock-src : A value from 0 to 15 which selects the clock
|
||||
source for the baud rate generator. This value corresponds
|
||||
to the CLKS value in the BRGx configuration register. See
|
||||
the mv64x60 User's Manual.
|
||||
- clock-frequence : The frequency (in Hz) of the baud rate
|
||||
generator's input clock.
|
||||
- current-speed : The current speed setting (presumably by
|
||||
firmware) of the baud rate generator.
|
||||
|
||||
Example Discovery BRG node:
|
||||
brg@b200 {
|
||||
compatible = "marvell,mv64360-brg";
|
||||
reg = <0xb200 0x8>;
|
||||
clock-src = <8>;
|
||||
clock-frequency = <133333333>;
|
||||
current-speed = <9600>;
|
||||
};
|
||||
|
||||
|
||||
f) Marvell Discovery CUNIT nodes
|
||||
|
||||
Represent the Serial Communications Unit device hardware.
|
||||
|
||||
Required properties:
|
||||
- reg : Offset and length of the register set for this device
|
||||
|
||||
Example Discovery CUNIT node:
|
||||
cunit@f200 {
|
||||
reg = <0xf200 0x200>;
|
||||
};
|
||||
|
||||
|
||||
g) Marvell Discovery MPSCROUTING nodes
|
||||
|
||||
Represent the Discovery's MPSC routing hardware
|
||||
|
||||
Required properties:
|
||||
- reg : Offset and length of the register set for this device
|
||||
|
||||
Example Discovery CUNIT node:
|
||||
mpscrouting@b500 {
|
||||
reg = <0xb400 0xc>;
|
||||
};
|
||||
|
||||
|
||||
h) Marvell Discovery MPSCINTR nodes
|
||||
|
||||
Represent the Discovery's MPSC DMA interrupt hardware registers
|
||||
(SDMA cause and mask registers).
|
||||
|
||||
Required properties:
|
||||
- reg : Offset and length of the register set for this device
|
||||
|
||||
Example Discovery MPSCINTR node:
|
||||
mpsintr@b800 {
|
||||
reg = <0xb800 0x100>;
|
||||
};
|
||||
|
||||
|
||||
i) Marvell Discovery MPSC nodes
|
||||
|
||||
Represent the Discovery's MPSC (Multiprotocol Serial Controller)
|
||||
serial port.
|
||||
|
||||
Required properties:
|
||||
- device_type : "serial"
|
||||
- compatible : "marvell,mv64360-mpsc"
|
||||
- reg : Offset and length of the register set for this device
|
||||
- sdma : the phandle for the SDMA node used by this port
|
||||
- brg : the phandle for the BRG node used by this port
|
||||
- cunit : the phandle for the CUNIT node used by this port
|
||||
- mpscrouting : the phandle for the MPSCROUTING node used by this port
|
||||
- mpscintr : the phandle for the MPSCINTR node used by this port
|
||||
- cell-index : the hardware index of this cell in the MPSC core
|
||||
- max_idle : value needed for MPSC CHR3 (Maximum Frame Length)
|
||||
register
|
||||
- interrupts : <a> where a is the interrupt number for the MPSC.
|
||||
- interrupt-parent : the phandle for the interrupt controller
|
||||
that services interrupts for this device.
|
||||
|
||||
Example Discovery MPSCINTR node:
|
||||
mpsc@8000 {
|
||||
device_type = "serial";
|
||||
compatible = "marvell,mv64360-mpsc";
|
||||
reg = <0x8000 0x38>;
|
||||
virtual-reg = <0xf1008000>;
|
||||
sdma = <&SDMA0>;
|
||||
brg = <&BRG0>;
|
||||
cunit = <&CUNIT>;
|
||||
mpscrouting = <&MPSCROUTING>;
|
||||
mpscintr = <&MPSCINTR>;
|
||||
cell-index = <0>;
|
||||
max_idle = <40>;
|
||||
interrupts = <40>;
|
||||
interrupt-parent = <&PIC>;
|
||||
};
|
||||
|
||||
|
||||
j) Marvell Discovery Watch Dog Timer nodes
|
||||
|
||||
Represent the Discovery's watchdog timer hardware
|
||||
|
||||
Required properties:
|
||||
- compatible : "marvell,mv64360-wdt"
|
||||
- reg : Offset and length of the register set for this device
|
||||
|
||||
Example Discovery Watch Dog Timer node:
|
||||
wdt@b410 {
|
||||
compatible = "marvell,mv64360-wdt";
|
||||
reg = <0xb410 0x8>;
|
||||
};
|
||||
|
||||
|
||||
k) Marvell Discovery I2C nodes
|
||||
|
||||
Represent the Discovery's I2C hardware
|
||||
|
||||
Required properties:
|
||||
- device_type : "i2c"
|
||||
- compatible : "marvell,mv64360-i2c"
|
||||
- reg : Offset and length of the register set for this device
|
||||
- interrupts : <a> where a is the interrupt number for the I2C.
|
||||
- interrupt-parent : the phandle for the interrupt controller
|
||||
that services interrupts for this device.
|
||||
|
||||
Example Discovery I2C node:
|
||||
compatible = "marvell,mv64360-i2c";
|
||||
reg = <0xc000 0x20>;
|
||||
virtual-reg = <0xf100c000>;
|
||||
interrupts = <37>;
|
||||
interrupt-parent = <&PIC>;
|
||||
};
|
||||
|
||||
|
||||
l) Marvell Discovery PIC (Programmable Interrupt Controller) nodes
|
||||
|
||||
Represent the Discovery's PIC hardware
|
||||
|
||||
Required properties:
|
||||
- #interrupt-cells : <1>
|
||||
- #address-cells : <0>
|
||||
- compatible : "marvell,mv64360-pic"
|
||||
- reg : Offset and length of the register set for this device
|
||||
- interrupt-controller
|
||||
|
||||
Example Discovery PIC node:
|
||||
pic {
|
||||
#interrupt-cells = <1>;
|
||||
#address-cells = <0>;
|
||||
compatible = "marvell,mv64360-pic";
|
||||
reg = <0x0 0x88>;
|
||||
interrupt-controller;
|
||||
};
|
||||
|
||||
|
||||
m) Marvell Discovery MPP (Multipurpose Pins) multiplexing nodes
|
||||
|
||||
Represent the Discovery's MPP hardware
|
||||
|
||||
Required properties:
|
||||
- compatible : "marvell,mv64360-mpp"
|
||||
- reg : Offset and length of the register set for this device
|
||||
|
||||
Example Discovery MPP node:
|
||||
mpp@f000 {
|
||||
compatible = "marvell,mv64360-mpp";
|
||||
reg = <0xf000 0x10>;
|
||||
};
|
||||
|
||||
|
||||
n) Marvell Discovery GPP (General Purpose Pins) nodes
|
||||
|
||||
Represent the Discovery's GPP hardware
|
||||
|
||||
Required properties:
|
||||
- compatible : "marvell,mv64360-gpp"
|
||||
- reg : Offset and length of the register set for this device
|
||||
|
||||
Example Discovery GPP node:
|
||||
gpp@f000 {
|
||||
compatible = "marvell,mv64360-gpp";
|
||||
reg = <0xf100 0x20>;
|
||||
};
|
||||
|
||||
|
||||
o) Marvell Discovery PCI host bridge node
|
||||
|
||||
Represents the Discovery's PCI host bridge device. The properties
|
||||
for this node conform to Rev 2.1 of the PCI Bus Binding to IEEE
|
||||
1275-1994. A typical value for the compatible property is
|
||||
"marvell,mv64360-pci".
|
||||
|
||||
Example Discovery PCI host bridge node
|
||||
pci@80000000 {
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
#interrupt-cells = <1>;
|
||||
device_type = "pci";
|
||||
compatible = "marvell,mv64360-pci";
|
||||
reg = <0xcf8 0x8>;
|
||||
ranges = <0x01000000 0x0 0x0
|
||||
0x88000000 0x0 0x01000000
|
||||
0x02000000 0x0 0x80000000
|
||||
0x80000000 0x0 0x08000000>;
|
||||
bus-range = <0 255>;
|
||||
clock-frequency = <66000000>;
|
||||
interrupt-parent = <&PIC>;
|
||||
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
|
||||
interrupt-map = <
|
||||
/* IDSEL 0x0a */
|
||||
0x5000 0 0 1 &PIC 80
|
||||
0x5000 0 0 2 &PIC 81
|
||||
0x5000 0 0 3 &PIC 91
|
||||
0x5000 0 0 4 &PIC 93
|
||||
|
||||
/* IDSEL 0x0b */
|
||||
0x5800 0 0 1 &PIC 91
|
||||
0x5800 0 0 2 &PIC 93
|
||||
0x5800 0 0 3 &PIC 80
|
||||
0x5800 0 0 4 &PIC 81
|
||||
|
||||
/* IDSEL 0x0c */
|
||||
0x6000 0 0 1 &PIC 91
|
||||
0x6000 0 0 2 &PIC 93
|
||||
0x6000 0 0 3 &PIC 80
|
||||
0x6000 0 0 4 &PIC 81
|
||||
|
||||
/* IDSEL 0x0d */
|
||||
0x6800 0 0 1 &PIC 93
|
||||
0x6800 0 0 2 &PIC 80
|
||||
0x6800 0 0 3 &PIC 81
|
||||
0x6800 0 0 4 &PIC 91
|
||||
>;
|
||||
};
|
||||
|
||||
|
||||
p) Marvell Discovery CPU Error nodes
|
||||
|
||||
Represent the Discovery's CPU error handler device.
|
||||
|
||||
Required properties:
|
||||
- compatible : "marvell,mv64360-cpu-error"
|
||||
- reg : Offset and length of the register set for this device
|
||||
- interrupts : the interrupt number for this device
|
||||
- interrupt-parent : the phandle for the interrupt controller
|
||||
that services interrupts for this device.
|
||||
|
||||
Example Discovery CPU Error node:
|
||||
cpu-error@0070 {
|
||||
compatible = "marvell,mv64360-cpu-error";
|
||||
reg = <0x70 0x10 0x128 0x28>;
|
||||
interrupts = <3>;
|
||||
interrupt-parent = <&PIC>;
|
||||
};
|
||||
|
||||
|
||||
q) Marvell Discovery SRAM Controller nodes
|
||||
|
||||
Represent the Discovery's SRAM controller device.
|
||||
|
||||
Required properties:
|
||||
- compatible : "marvell,mv64360-sram-ctrl"
|
||||
- reg : Offset and length of the register set for this device
|
||||
- interrupts : the interrupt number for this device
|
||||
- interrupt-parent : the phandle for the interrupt controller
|
||||
that services interrupts for this device.
|
||||
|
||||
Example Discovery SRAM Controller node:
|
||||
sram-ctrl@0380 {
|
||||
compatible = "marvell,mv64360-sram-ctrl";
|
||||
reg = <0x380 0x80>;
|
||||
interrupts = <13>;
|
||||
interrupt-parent = <&PIC>;
|
||||
};
|
||||
|
||||
|
||||
r) Marvell Discovery PCI Error Handler nodes
|
||||
|
||||
Represent the Discovery's PCI error handler device.
|
||||
|
||||
Required properties:
|
||||
- compatible : "marvell,mv64360-pci-error"
|
||||
- reg : Offset and length of the register set for this device
|
||||
- interrupts : the interrupt number for this device
|
||||
- interrupt-parent : the phandle for the interrupt controller
|
||||
that services interrupts for this device.
|
||||
|
||||
Example Discovery PCI Error Handler node:
|
||||
pci-error@1d40 {
|
||||
compatible = "marvell,mv64360-pci-error";
|
||||
reg = <0x1d40 0x40 0xc28 0x4>;
|
||||
interrupts = <12>;
|
||||
interrupt-parent = <&PIC>;
|
||||
};
|
||||
|
||||
|
||||
s) Marvell Discovery Memory Controller nodes
|
||||
|
||||
Represent the Discovery's memory controller device.
|
||||
|
||||
Required properties:
|
||||
- compatible : "marvell,mv64360-mem-ctrl"
|
||||
- reg : Offset and length of the register set for this device
|
||||
- interrupts : the interrupt number for this device
|
||||
- interrupt-parent : the phandle for the interrupt controller
|
||||
that services interrupts for this device.
|
||||
|
||||
Example Discovery Memory Controller node:
|
||||
mem-ctrl@1400 {
|
||||
compatible = "marvell,mv64360-mem-ctrl";
|
||||
reg = <0x1400 0x60>;
|
||||
interrupts = <17>;
|
||||
interrupt-parent = <&PIC>;
|
||||
};
|
||||
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
PHY nodes
|
||||
|
||||
Required properties:
|
||||
|
||||
- device_type : Should be "ethernet-phy"
|
||||
- interrupts : <a b> where a is the interrupt number and b is a
|
||||
field that represents an encoding of the sense and level
|
||||
information for the interrupt. This should be encoded based on
|
||||
the information in section 2) depending on the type of interrupt
|
||||
controller you have.
|
||||
- interrupt-parent : the phandle for the interrupt controller that
|
||||
services interrupts for this device.
|
||||
- reg : The ID number for the phy, usually a small integer
|
||||
- linux,phandle : phandle for this node; likely referenced by an
|
||||
ethernet controller node.
|
||||
|
||||
Example:
|
||||
|
||||
ethernet-phy@0 {
|
||||
linux,phandle = <2452000>
|
||||
interrupt-parent = <40000>;
|
||||
interrupts = <35 1>;
|
||||
reg = <0>;
|
||||
device_type = "ethernet-phy";
|
||||
};
|
|
@ -0,0 +1,57 @@
|
|||
SPI (Serial Peripheral Interface) busses
|
||||
|
||||
SPI busses can be described with a node for the SPI master device
|
||||
and a set of child nodes for each SPI slave on the bus. For this
|
||||
discussion, it is assumed that the system's SPI controller is in
|
||||
SPI master mode. This binding does not describe SPI controllers
|
||||
in slave mode.
|
||||
|
||||
The SPI master node requires the following properties:
|
||||
- #address-cells - number of cells required to define a chip select
|
||||
address on the SPI bus.
|
||||
- #size-cells - should be zero.
|
||||
- compatible - name of SPI bus controller following generic names
|
||||
recommended practice.
|
||||
No other properties are required in the SPI bus node. It is assumed
|
||||
that a driver for an SPI bus device will understand that it is an SPI bus.
|
||||
However, the binding does not attempt to define the specific method for
|
||||
assigning chip select numbers. Since SPI chip select configuration is
|
||||
flexible and non-standardized, it is left out of this binding with the
|
||||
assumption that board specific platform code will be used to manage
|
||||
chip selects. Individual drivers can define additional properties to
|
||||
support describing the chip select layout.
|
||||
|
||||
SPI slave nodes must be children of the SPI master node and can
|
||||
contain the following properties.
|
||||
- reg - (required) chip select address of device.
|
||||
- compatible - (required) name of SPI device following generic names
|
||||
recommended practice
|
||||
- spi-max-frequency - (required) Maximum SPI clocking speed of device in Hz
|
||||
- spi-cpol - (optional) Empty property indicating device requires
|
||||
inverse clock polarity (CPOL) mode
|
||||
- spi-cpha - (optional) Empty property indicating device requires
|
||||
shifted clock phase (CPHA) mode
|
||||
- spi-cs-high - (optional) Empty property indicating device requires
|
||||
chip select active high
|
||||
|
||||
SPI example for an MPC5200 SPI bus:
|
||||
spi@f00 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi";
|
||||
reg = <0xf00 0x20>;
|
||||
interrupts = <2 13 0 2 14 0>;
|
||||
interrupt-parent = <&mpc5200_pic>;
|
||||
|
||||
ethernet-switch@0 {
|
||||
compatible = "micrel,ks8995m";
|
||||
spi-max-frequency = <1000000>;
|
||||
reg = <0>;
|
||||
};
|
||||
|
||||
codec@1 {
|
||||
compatible = "ti,tlv320aic26";
|
||||
spi-max-frequency = <100000>;
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
|
@ -0,0 +1,25 @@
|
|||
USB EHCI controllers
|
||||
|
||||
Required properties:
|
||||
- compatible : should be "usb-ehci".
|
||||
- reg : should contain at least address and length of the standard EHCI
|
||||
register set for the device. Optional platform-dependent registers
|
||||
(debug-port or other) can be also specified here, but only after
|
||||
definition of standard EHCI registers.
|
||||
- interrupts : one EHCI interrupt should be described here.
|
||||
If device registers are implemented in big endian mode, the device
|
||||
node should have "big-endian-regs" property.
|
||||
If controller implementation operates with big endian descriptors,
|
||||
"big-endian-desc" property should be specified.
|
||||
If both big endian registers and descriptors are used by the controller
|
||||
implementation, "big-endian" property can be specified instead of having
|
||||
both "big-endian-regs" and "big-endian-desc".
|
||||
|
||||
Example (Sequoia 440EPx):
|
||||
ehci@e0000300 {
|
||||
compatible = "ibm,usb-ehci-440epx", "usb-ehci";
|
||||
interrupt-parent = <&UIC0>;
|
||||
interrupts = <1a 4>;
|
||||
reg = <0 e0000300 90 0 e0000390 70>;
|
||||
big-endian;
|
||||
};
|
|
@ -0,0 +1,295 @@
|
|||
d) Xilinx IP cores
|
||||
|
||||
The Xilinx EDK toolchain ships with a set of IP cores (devices) for use
|
||||
in Xilinx Spartan and Virtex FPGAs. The devices cover the whole range
|
||||
of standard device types (network, serial, etc.) and miscellaneous
|
||||
devices (gpio, LCD, spi, etc). Also, since these devices are
|
||||
implemented within the fpga fabric every instance of the device can be
|
||||
synthesised with different options that change the behaviour.
|
||||
|
||||
Each IP-core has a set of parameters which the FPGA designer can use to
|
||||
control how the core is synthesized. Historically, the EDK tool would
|
||||
extract the device parameters relevant to device drivers and copy them
|
||||
into an 'xparameters.h' in the form of #define symbols. This tells the
|
||||
device drivers how the IP cores are configured, but it requres the kernel
|
||||
to be recompiled every time the FPGA bitstream is resynthesized.
|
||||
|
||||
The new approach is to export the parameters into the device tree and
|
||||
generate a new device tree each time the FPGA bitstream changes. The
|
||||
parameters which used to be exported as #defines will now become
|
||||
properties of the device node. In general, device nodes for IP-cores
|
||||
will take the following form:
|
||||
|
||||
(name): (generic-name)@(base-address) {
|
||||
compatible = "xlnx,(ip-core-name)-(HW_VER)"
|
||||
[, (list of compatible devices), ...];
|
||||
reg = <(baseaddr) (size)>;
|
||||
interrupt-parent = <&interrupt-controller-phandle>;
|
||||
interrupts = < ... >;
|
||||
xlnx,(parameter1) = "(string-value)";
|
||||
xlnx,(parameter2) = <(int-value)>;
|
||||
};
|
||||
|
||||
(generic-name): an open firmware-style name that describes the
|
||||
generic class of device. Preferably, this is one word, such
|
||||
as 'serial' or 'ethernet'.
|
||||
(ip-core-name): the name of the ip block (given after the BEGIN
|
||||
directive in system.mhs). Should be in lowercase
|
||||
and all underscores '_' converted to dashes '-'.
|
||||
(name): is derived from the "PARAMETER INSTANCE" value.
|
||||
(parameter#): C_* parameters from system.mhs. The C_ prefix is
|
||||
dropped from the parameter name, the name is converted
|
||||
to lowercase and all underscore '_' characters are
|
||||
converted to dashes '-'.
|
||||
(baseaddr): the baseaddr parameter value (often named C_BASEADDR).
|
||||
(HW_VER): from the HW_VER parameter.
|
||||
(size): the address range size (often C_HIGHADDR - C_BASEADDR + 1).
|
||||
|
||||
Typically, the compatible list will include the exact IP core version
|
||||
followed by an older IP core version which implements the same
|
||||
interface or any other device with the same interface.
|
||||
|
||||
'reg', 'interrupt-parent' and 'interrupts' are all optional properties.
|
||||
|
||||
For example, the following block from system.mhs:
|
||||
|
||||
BEGIN opb_uartlite
|
||||
PARAMETER INSTANCE = opb_uartlite_0
|
||||
PARAMETER HW_VER = 1.00.b
|
||||
PARAMETER C_BAUDRATE = 115200
|
||||
PARAMETER C_DATA_BITS = 8
|
||||
PARAMETER C_ODD_PARITY = 0
|
||||
PARAMETER C_USE_PARITY = 0
|
||||
PARAMETER C_CLK_FREQ = 50000000
|
||||
PARAMETER C_BASEADDR = 0xEC100000
|
||||
PARAMETER C_HIGHADDR = 0xEC10FFFF
|
||||
BUS_INTERFACE SOPB = opb_7
|
||||
PORT OPB_Clk = CLK_50MHz
|
||||
PORT Interrupt = opb_uartlite_0_Interrupt
|
||||
PORT RX = opb_uartlite_0_RX
|
||||
PORT TX = opb_uartlite_0_TX
|
||||
PORT OPB_Rst = sys_bus_reset_0
|
||||
END
|
||||
|
||||
becomes the following device tree node:
|
||||
|
||||
opb_uartlite_0: serial@ec100000 {
|
||||
device_type = "serial";
|
||||
compatible = "xlnx,opb-uartlite-1.00.b";
|
||||
reg = <ec100000 10000>;
|
||||
interrupt-parent = <&opb_intc_0>;
|
||||
interrupts = <1 0>; // got this from the opb_intc parameters
|
||||
current-speed = <d#115200>; // standard serial device prop
|
||||
clock-frequency = <d#50000000>; // standard serial device prop
|
||||
xlnx,data-bits = <8>;
|
||||
xlnx,odd-parity = <0>;
|
||||
xlnx,use-parity = <0>;
|
||||
};
|
||||
|
||||
Some IP cores actually implement 2 or more logical devices. In
|
||||
this case, the device should still describe the whole IP core with
|
||||
a single node and add a child node for each logical device. The
|
||||
ranges property can be used to translate from parent IP-core to the
|
||||
registers of each device. In addition, the parent node should be
|
||||
compatible with the bus type 'xlnx,compound', and should contain
|
||||
#address-cells and #size-cells, as with any other bus. (Note: this
|
||||
makes the assumption that both logical devices have the same bus
|
||||
binding. If this is not true, then separate nodes should be used
|
||||
for each logical device). The 'cell-index' property can be used to
|
||||
enumerate logical devices within an IP core. For example, the
|
||||
following is the system.mhs entry for the dual ps2 controller found
|
||||
on the ml403 reference design.
|
||||
|
||||
BEGIN opb_ps2_dual_ref
|
||||
PARAMETER INSTANCE = opb_ps2_dual_ref_0
|
||||
PARAMETER HW_VER = 1.00.a
|
||||
PARAMETER C_BASEADDR = 0xA9000000
|
||||
PARAMETER C_HIGHADDR = 0xA9001FFF
|
||||
BUS_INTERFACE SOPB = opb_v20_0
|
||||
PORT Sys_Intr1 = ps2_1_intr
|
||||
PORT Sys_Intr2 = ps2_2_intr
|
||||
PORT Clkin1 = ps2_clk_rx_1
|
||||
PORT Clkin2 = ps2_clk_rx_2
|
||||
PORT Clkpd1 = ps2_clk_tx_1
|
||||
PORT Clkpd2 = ps2_clk_tx_2
|
||||
PORT Rx1 = ps2_d_rx_1
|
||||
PORT Rx2 = ps2_d_rx_2
|
||||
PORT Txpd1 = ps2_d_tx_1
|
||||
PORT Txpd2 = ps2_d_tx_2
|
||||
END
|
||||
|
||||
It would result in the following device tree nodes:
|
||||
|
||||
opb_ps2_dual_ref_0: opb-ps2-dual-ref@a9000000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "xlnx,compound";
|
||||
ranges = <0 a9000000 2000>;
|
||||
// If this device had extra parameters, then they would
|
||||
// go here.
|
||||
ps2@0 {
|
||||
compatible = "xlnx,opb-ps2-dual-ref-1.00.a";
|
||||
reg = <0 40>;
|
||||
interrupt-parent = <&opb_intc_0>;
|
||||
interrupts = <3 0>;
|
||||
cell-index = <0>;
|
||||
};
|
||||
ps2@1000 {
|
||||
compatible = "xlnx,opb-ps2-dual-ref-1.00.a";
|
||||
reg = <1000 40>;
|
||||
interrupt-parent = <&opb_intc_0>;
|
||||
interrupts = <3 0>;
|
||||
cell-index = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
Also, the system.mhs file defines bus attachments from the processor
|
||||
to the devices. The device tree structure should reflect the bus
|
||||
attachments. Again an example; this system.mhs fragment:
|
||||
|
||||
BEGIN ppc405_virtex4
|
||||
PARAMETER INSTANCE = ppc405_0
|
||||
PARAMETER HW_VER = 1.01.a
|
||||
BUS_INTERFACE DPLB = plb_v34_0
|
||||
BUS_INTERFACE IPLB = plb_v34_0
|
||||
END
|
||||
|
||||
BEGIN opb_intc
|
||||
PARAMETER INSTANCE = opb_intc_0
|
||||
PARAMETER HW_VER = 1.00.c
|
||||
PARAMETER C_BASEADDR = 0xD1000FC0
|
||||
PARAMETER C_HIGHADDR = 0xD1000FDF
|
||||
BUS_INTERFACE SOPB = opb_v20_0
|
||||
END
|
||||
|
||||
BEGIN opb_uart16550
|
||||
PARAMETER INSTANCE = opb_uart16550_0
|
||||
PARAMETER HW_VER = 1.00.d
|
||||
PARAMETER C_BASEADDR = 0xa0000000
|
||||
PARAMETER C_HIGHADDR = 0xa0001FFF
|
||||
BUS_INTERFACE SOPB = opb_v20_0
|
||||
END
|
||||
|
||||
BEGIN plb_v34
|
||||
PARAMETER INSTANCE = plb_v34_0
|
||||
PARAMETER HW_VER = 1.02.a
|
||||
END
|
||||
|
||||
BEGIN plb_bram_if_cntlr
|
||||
PARAMETER INSTANCE = plb_bram_if_cntlr_0
|
||||
PARAMETER HW_VER = 1.00.b
|
||||
PARAMETER C_BASEADDR = 0xFFFF0000
|
||||
PARAMETER C_HIGHADDR = 0xFFFFFFFF
|
||||
BUS_INTERFACE SPLB = plb_v34_0
|
||||
END
|
||||
|
||||
BEGIN plb2opb_bridge
|
||||
PARAMETER INSTANCE = plb2opb_bridge_0
|
||||
PARAMETER HW_VER = 1.01.a
|
||||
PARAMETER C_RNG0_BASEADDR = 0x20000000
|
||||
PARAMETER C_RNG0_HIGHADDR = 0x3FFFFFFF
|
||||
PARAMETER C_RNG1_BASEADDR = 0x60000000
|
||||
PARAMETER C_RNG1_HIGHADDR = 0x7FFFFFFF
|
||||
PARAMETER C_RNG2_BASEADDR = 0x80000000
|
||||
PARAMETER C_RNG2_HIGHADDR = 0xBFFFFFFF
|
||||
PARAMETER C_RNG3_BASEADDR = 0xC0000000
|
||||
PARAMETER C_RNG3_HIGHADDR = 0xDFFFFFFF
|
||||
BUS_INTERFACE SPLB = plb_v34_0
|
||||
BUS_INTERFACE MOPB = opb_v20_0
|
||||
END
|
||||
|
||||
Gives this device tree (some properties removed for clarity):
|
||||
|
||||
plb@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "xlnx,plb-v34-1.02.a";
|
||||
device_type = "ibm,plb";
|
||||
ranges; // 1:1 translation
|
||||
|
||||
plb_bram_if_cntrl_0: bram@ffff0000 {
|
||||
reg = <ffff0000 10000>;
|
||||
}
|
||||
|
||||
opb@20000000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges = <20000000 20000000 20000000
|
||||
60000000 60000000 20000000
|
||||
80000000 80000000 40000000
|
||||
c0000000 c0000000 20000000>;
|
||||
|
||||
opb_uart16550_0: serial@a0000000 {
|
||||
reg = <a00000000 2000>;
|
||||
};
|
||||
|
||||
opb_intc_0: interrupt-controller@d1000fc0 {
|
||||
reg = <d1000fc0 20>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
That covers the general approach to binding xilinx IP cores into the
|
||||
device tree. The following are bindings for specific devices:
|
||||
|
||||
i) Xilinx ML300 Framebuffer
|
||||
|
||||
Simple framebuffer device from the ML300 reference design (also on the
|
||||
ML403 reference design as well as others).
|
||||
|
||||
Optional properties:
|
||||
- resolution = <xres yres> : pixel resolution of framebuffer. Some
|
||||
implementations use a different resolution.
|
||||
Default is <d#640 d#480>
|
||||
- virt-resolution = <xvirt yvirt> : Size of framebuffer in memory.
|
||||
Default is <d#1024 d#480>.
|
||||
- rotate-display (empty) : rotate display 180 degrees.
|
||||
|
||||
ii) Xilinx SystemACE
|
||||
|
||||
The Xilinx SystemACE device is used to program FPGAs from an FPGA
|
||||
bitstream stored on a CF card. It can also be used as a generic CF
|
||||
interface device.
|
||||
|
||||
Optional properties:
|
||||
- 8-bit (empty) : Set this property for SystemACE in 8 bit mode
|
||||
|
||||
iii) Xilinx EMAC and Xilinx TEMAC
|
||||
|
||||
Xilinx Ethernet devices. In addition to general xilinx properties
|
||||
listed above, nodes for these devices should include a phy-handle
|
||||
property, and may include other common network device properties
|
||||
like local-mac-address.
|
||||
|
||||
iv) Xilinx Uartlite
|
||||
|
||||
Xilinx uartlite devices are simple fixed speed serial ports.
|
||||
|
||||
Required properties:
|
||||
- current-speed : Baud rate of uartlite
|
||||
|
||||
v) Xilinx hwicap
|
||||
|
||||
Xilinx hwicap devices provide access to the configuration logic
|
||||
of the FPGA through the Internal Configuration Access Port
|
||||
(ICAP). The ICAP enables partial reconfiguration of the FPGA,
|
||||
readback of the configuration information, and some control over
|
||||
'warm boots' of the FPGA fabric.
|
||||
|
||||
Required properties:
|
||||
- xlnx,family : The family of the FPGA, necessary since the
|
||||
capabilities of the underlying ICAP hardware
|
||||
differ between different families. May be
|
||||
'virtex2p', 'virtex4', or 'virtex5'.
|
||||
|
||||
vi) Xilinx Uart 16550
|
||||
|
||||
Xilinx UART 16550 devices are very similar to the NS16550 but with
|
||||
different register spacing and an offset from the base address.
|
||||
|
||||
Required properties:
|
||||
- clock-frequency : Frequency of the clock input
|
||||
- reg-offset : A value of 3 is required
|
||||
- reg-shift : A value of 2 is required
|
||||
|
||||
|
|
@ -240,6 +240,7 @@ AD1986A
|
|||
laptop-automute 2-channel with EAPD and HP-automute (Lenovo N100)
|
||||
ultra 2-channel with EAPD (Samsung Ultra tablet PC)
|
||||
samsung 2-channel with EAPD (Samsung R65)
|
||||
samsung-p50 2-channel with HP-automute (Samsung P50)
|
||||
|
||||
AD1988/AD1988B/AD1989A/AD1989B
|
||||
==============================
|
||||
|
|
|
@ -99,11 +99,13 @@ void parse_opts(int argc, char *argv[])
|
|||
{ "lsb", 0, 0, 'L' },
|
||||
{ "cs-high", 0, 0, 'C' },
|
||||
{ "3wire", 0, 0, '3' },
|
||||
{ "no-cs", 0, 0, 'N' },
|
||||
{ "ready", 0, 0, 'R' },
|
||||
{ NULL, 0, 0, 0 },
|
||||
};
|
||||
int c;
|
||||
|
||||
c = getopt_long(argc, argv, "D:s:d:b:lHOLC3", lopts, NULL);
|
||||
c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR", lopts, NULL);
|
||||
|
||||
if (c == -1)
|
||||
break;
|
||||
|
@ -139,6 +141,12 @@ void parse_opts(int argc, char *argv[])
|
|||
case '3':
|
||||
mode |= SPI_3WIRE;
|
||||
break;
|
||||
case 'N':
|
||||
mode |= SPI_NO_CS;
|
||||
break;
|
||||
case 'R':
|
||||
mode |= SPI_READY;
|
||||
break;
|
||||
default:
|
||||
print_usage(argv[0]);
|
||||
break;
|
||||
|
|
|
@ -66,3 +66,4 @@
|
|||
68 -> Terratec AV350 (em2860) [0ccd:0084]
|
||||
69 -> KWorld ATSC 315U HDTV TV Box (em2882) [eb1a:a313]
|
||||
70 -> Evga inDtube (em2882)
|
||||
71 -> Silvercrest Webcam 1.3mpix (em2820/em2840)
|
||||
|
|
|
@ -2,3 +2,5 @@
|
|||
- this file
|
||||
mtrr.txt
|
||||
- how to use x86 Memory Type Range Registers to increase performance
|
||||
exception-tables.txt
|
||||
- why and how Linux kernel uses exception tables on x86
|
||||
|
|
|
@ -1,123 +1,123 @@
|
|||
Kernel level exception handling in Linux 2.1.8
|
||||
Kernel level exception handling in Linux
|
||||
Commentary by Joerg Pommnitz <joerg@raleigh.ibm.com>
|
||||
|
||||
When a process runs in kernel mode, it often has to access user
|
||||
mode memory whose address has been passed by an untrusted program.
|
||||
When a process runs in kernel mode, it often has to access user
|
||||
mode memory whose address has been passed by an untrusted program.
|
||||
To protect itself the kernel has to verify this address.
|
||||
|
||||
In older versions of Linux this was done with the
|
||||
int verify_area(int type, const void * addr, unsigned long size)
|
||||
In older versions of Linux this was done with the
|
||||
int verify_area(int type, const void * addr, unsigned long size)
|
||||
function (which has since been replaced by access_ok()).
|
||||
|
||||
This function verified that the memory area starting at address
|
||||
This function verified that the memory area starting at address
|
||||
'addr' and of size 'size' was accessible for the operation specified
|
||||
in type (read or write). To do this, verify_read had to look up the
|
||||
virtual memory area (vma) that contained the address addr. In the
|
||||
normal case (correctly working program), this test was successful.
|
||||
in type (read or write). To do this, verify_read had to look up the
|
||||
virtual memory area (vma) that contained the address addr. In the
|
||||
normal case (correctly working program), this test was successful.
|
||||
It only failed for a few buggy programs. In some kernel profiling
|
||||
tests, this normally unneeded verification used up a considerable
|
||||
amount of time.
|
||||
|
||||
To overcome this situation, Linus decided to let the virtual memory
|
||||
To overcome this situation, Linus decided to let the virtual memory
|
||||
hardware present in every Linux-capable CPU handle this test.
|
||||
|
||||
How does this work?
|
||||
|
||||
Whenever the kernel tries to access an address that is currently not
|
||||
accessible, the CPU generates a page fault exception and calls the
|
||||
page fault handler
|
||||
Whenever the kernel tries to access an address that is currently not
|
||||
accessible, the CPU generates a page fault exception and calls the
|
||||
page fault handler
|
||||
|
||||
void do_page_fault(struct pt_regs *regs, unsigned long error_code)
|
||||
|
||||
in arch/i386/mm/fault.c. The parameters on the stack are set up by
|
||||
the low level assembly glue in arch/i386/kernel/entry.S. The parameter
|
||||
regs is a pointer to the saved registers on the stack, error_code
|
||||
in arch/x86/mm/fault.c. The parameters on the stack are set up by
|
||||
the low level assembly glue in arch/x86/kernel/entry_32.S. The parameter
|
||||
regs is a pointer to the saved registers on the stack, error_code
|
||||
contains a reason code for the exception.
|
||||
|
||||
do_page_fault first obtains the unaccessible address from the CPU
|
||||
control register CR2. If the address is within the virtual address
|
||||
space of the process, the fault probably occurred, because the page
|
||||
was not swapped in, write protected or something similar. However,
|
||||
we are interested in the other case: the address is not valid, there
|
||||
is no vma that contains this address. In this case, the kernel jumps
|
||||
to the bad_area label.
|
||||
do_page_fault first obtains the unaccessible address from the CPU
|
||||
control register CR2. If the address is within the virtual address
|
||||
space of the process, the fault probably occurred, because the page
|
||||
was not swapped in, write protected or something similar. However,
|
||||
we are interested in the other case: the address is not valid, there
|
||||
is no vma that contains this address. In this case, the kernel jumps
|
||||
to the bad_area label.
|
||||
|
||||
There it uses the address of the instruction that caused the exception
|
||||
(i.e. regs->eip) to find an address where the execution can continue
|
||||
(fixup). If this search is successful, the fault handler modifies the
|
||||
return address (again regs->eip) and returns. The execution will
|
||||
There it uses the address of the instruction that caused the exception
|
||||
(i.e. regs->eip) to find an address where the execution can continue
|
||||
(fixup). If this search is successful, the fault handler modifies the
|
||||
return address (again regs->eip) and returns. The execution will
|
||||
continue at the address in fixup.
|
||||
|
||||
Where does fixup point to?
|
||||
|
||||
Since we jump to the contents of fixup, fixup obviously points
|
||||
to executable code. This code is hidden inside the user access macros.
|
||||
I have picked the get_user macro defined in include/asm/uaccess.h as an
|
||||
example. The definition is somewhat hard to follow, so let's peek at
|
||||
Since we jump to the contents of fixup, fixup obviously points
|
||||
to executable code. This code is hidden inside the user access macros.
|
||||
I have picked the get_user macro defined in arch/x86/include/asm/uaccess.h
|
||||
as an example. The definition is somewhat hard to follow, so let's peek at
|
||||
the code generated by the preprocessor and the compiler. I selected
|
||||
the get_user call in drivers/char/console.c for a detailed examination.
|
||||
the get_user call in drivers/char/sysrq.c for a detailed examination.
|
||||
|
||||
The original code in console.c line 1405:
|
||||
The original code in sysrq.c line 587:
|
||||
get_user(c, buf);
|
||||
|
||||
The preprocessor output (edited to become somewhat readable):
|
||||
|
||||
(
|
||||
{
|
||||
long __gu_err = - 14 , __gu_val = 0;
|
||||
const __typeof__(*( ( buf ) )) *__gu_addr = ((buf));
|
||||
if (((((0 + current_set[0])->tss.segment) == 0x18 ) ||
|
||||
(((sizeof(*(buf))) <= 0xC0000000UL) &&
|
||||
((unsigned long)(__gu_addr ) <= 0xC0000000UL - (sizeof(*(buf)))))))
|
||||
{
|
||||
long __gu_err = - 14 , __gu_val = 0;
|
||||
const __typeof__(*( ( buf ) )) *__gu_addr = ((buf));
|
||||
if (((((0 + current_set[0])->tss.segment) == 0x18 ) ||
|
||||
(((sizeof(*(buf))) <= 0xC0000000UL) &&
|
||||
((unsigned long)(__gu_addr ) <= 0xC0000000UL - (sizeof(*(buf)))))))
|
||||
do {
|
||||
__gu_err = 0;
|
||||
switch ((sizeof(*(buf)))) {
|
||||
case 1:
|
||||
__asm__ __volatile__(
|
||||
"1: mov" "b" " %2,%" "b" "1\n"
|
||||
"2:\n"
|
||||
".section .fixup,\"ax\"\n"
|
||||
"3: movl %3,%0\n"
|
||||
" xor" "b" " %" "b" "1,%" "b" "1\n"
|
||||
" jmp 2b\n"
|
||||
".section __ex_table,\"a\"\n"
|
||||
" .align 4\n"
|
||||
" .long 1b,3b\n"
|
||||
".text" : "=r"(__gu_err), "=q" (__gu_val): "m"((*(struct __large_struct *)
|
||||
( __gu_addr )) ), "i"(- 14 ), "0"( __gu_err )) ;
|
||||
break;
|
||||
case 2:
|
||||
__gu_err = 0;
|
||||
switch ((sizeof(*(buf)))) {
|
||||
case 1:
|
||||
__asm__ __volatile__(
|
||||
"1: mov" "w" " %2,%" "w" "1\n"
|
||||
"2:\n"
|
||||
".section .fixup,\"ax\"\n"
|
||||
"3: movl %3,%0\n"
|
||||
" xor" "w" " %" "w" "1,%" "w" "1\n"
|
||||
" jmp 2b\n"
|
||||
".section __ex_table,\"a\"\n"
|
||||
" .align 4\n"
|
||||
" .long 1b,3b\n"
|
||||
"1: mov" "b" " %2,%" "b" "1\n"
|
||||
"2:\n"
|
||||
".section .fixup,\"ax\"\n"
|
||||
"3: movl %3,%0\n"
|
||||
" xor" "b" " %" "b" "1,%" "b" "1\n"
|
||||
" jmp 2b\n"
|
||||
".section __ex_table,\"a\"\n"
|
||||
" .align 4\n"
|
||||
" .long 1b,3b\n"
|
||||
".text" : "=r"(__gu_err), "=q" (__gu_val): "m"((*(struct __large_struct *)
|
||||
( __gu_addr )) ), "i"(- 14 ), "0"( __gu_err )) ;
|
||||
break;
|
||||
case 2:
|
||||
__asm__ __volatile__(
|
||||
"1: mov" "w" " %2,%" "w" "1\n"
|
||||
"2:\n"
|
||||
".section .fixup,\"ax\"\n"
|
||||
"3: movl %3,%0\n"
|
||||
" xor" "w" " %" "w" "1,%" "w" "1\n"
|
||||
" jmp 2b\n"
|
||||
".section __ex_table,\"a\"\n"
|
||||
" .align 4\n"
|
||||
" .long 1b,3b\n"
|
||||
".text" : "=r"(__gu_err), "=r" (__gu_val) : "m"((*(struct __large_struct *)
|
||||
( __gu_addr )) ), "i"(- 14 ), "0"( __gu_err ));
|
||||
break;
|
||||
case 4:
|
||||
__asm__ __volatile__(
|
||||
"1: mov" "l" " %2,%" "" "1\n"
|
||||
"2:\n"
|
||||
".section .fixup,\"ax\"\n"
|
||||
"3: movl %3,%0\n"
|
||||
" xor" "l" " %" "" "1,%" "" "1\n"
|
||||
" jmp 2b\n"
|
||||
".section __ex_table,\"a\"\n"
|
||||
" .align 4\n" " .long 1b,3b\n"
|
||||
( __gu_addr )) ), "i"(- 14 ), "0"( __gu_err ));
|
||||
break;
|
||||
case 4:
|
||||
__asm__ __volatile__(
|
||||
"1: mov" "l" " %2,%" "" "1\n"
|
||||
"2:\n"
|
||||
".section .fixup,\"ax\"\n"
|
||||
"3: movl %3,%0\n"
|
||||
" xor" "l" " %" "" "1,%" "" "1\n"
|
||||
" jmp 2b\n"
|
||||
".section __ex_table,\"a\"\n"
|
||||
" .align 4\n" " .long 1b,3b\n"
|
||||
".text" : "=r"(__gu_err), "=r" (__gu_val) : "m"((*(struct __large_struct *)
|
||||
( __gu_addr )) ), "i"(- 14 ), "0"(__gu_err));
|
||||
break;
|
||||
default:
|
||||
(__gu_val) = __get_user_bad();
|
||||
}
|
||||
} while (0) ;
|
||||
((c)) = (__typeof__(*((buf))))__gu_val;
|
||||
( __gu_addr )) ), "i"(- 14 ), "0"(__gu_err));
|
||||
break;
|
||||
default:
|
||||
(__gu_val) = __get_user_bad();
|
||||
}
|
||||
} while (0) ;
|
||||
((c)) = (__typeof__(*((buf))))__gu_val;
|
||||
__gu_err;
|
||||
}
|
||||
);
|
||||
|
@ -127,12 +127,12 @@ see what code gcc generates:
|
|||
|
||||
> xorl %edx,%edx
|
||||
> movl current_set,%eax
|
||||
> cmpl $24,788(%eax)
|
||||
> je .L1424
|
||||
> cmpl $24,788(%eax)
|
||||
> je .L1424
|
||||
> cmpl $-1073741825,64(%esp)
|
||||
> ja .L1423
|
||||
> ja .L1423
|
||||
> .L1424:
|
||||
> movl %edx,%eax
|
||||
> movl %edx,%eax
|
||||
> movl 64(%esp),%ebx
|
||||
> #APP
|
||||
> 1: movb (%ebx),%dl /* this is the actual user access */
|
||||
|
@ -149,17 +149,17 @@ see what code gcc generates:
|
|||
> .L1423:
|
||||
> movzbl %dl,%esi
|
||||
|
||||
The optimizer does a good job and gives us something we can actually
|
||||
understand. Can we? The actual user access is quite obvious. Thanks
|
||||
to the unified address space we can just access the address in user
|
||||
The optimizer does a good job and gives us something we can actually
|
||||
understand. Can we? The actual user access is quite obvious. Thanks
|
||||
to the unified address space we can just access the address in user
|
||||
memory. But what does the .section stuff do?????
|
||||
|
||||
To understand this we have to look at the final kernel:
|
||||
|
||||
> objdump --section-headers vmlinux
|
||||
>
|
||||
>
|
||||
> vmlinux: file format elf32-i386
|
||||
>
|
||||
>
|
||||
> Sections:
|
||||
> Idx Name Size VMA LMA File off Algn
|
||||
> 0 .text 00098f40 c0100000 c0100000 00001000 2**4
|
||||
|
@ -198,18 +198,18 @@ final kernel executable:
|
|||
|
||||
The whole user memory access is reduced to 10 x86 machine instructions.
|
||||
The instructions bracketed in the .section directives are no longer
|
||||
in the normal execution path. They are located in a different section
|
||||
in the normal execution path. They are located in a different section
|
||||
of the executable file:
|
||||
|
||||
> objdump --disassemble --section=.fixup vmlinux
|
||||
>
|
||||
>
|
||||
> c0199ff5 <.fixup+10b5> movl $0xfffffff2,%eax
|
||||
> c0199ffa <.fixup+10ba> xorb %dl,%dl
|
||||
> c0199ffc <.fixup+10bc> jmp c017e7a7 <do_con_write+e3>
|
||||
|
||||
And finally:
|
||||
> objdump --full-contents --section=__ex_table vmlinux
|
||||
>
|
||||
>
|
||||
> c01aa7c4 93c017c0 e09f19c0 97c017c0 99c017c0 ................
|
||||
> c01aa7d4 f6c217c0 e99f19c0 a5e717c0 f59f19c0 ................
|
||||
> c01aa7e4 080a18c0 01a019c0 0a0a18c0 04a019c0 ................
|
||||
|
@ -235,8 +235,8 @@ sections in the ELF object file. So the instructions
|
|||
ended up in the .fixup section of the object file and the addresses
|
||||
.long 1b,3b
|
||||
ended up in the __ex_table section of the object file. 1b and 3b
|
||||
are local labels. The local label 1b (1b stands for next label 1
|
||||
backward) is the address of the instruction that might fault, i.e.
|
||||
are local labels. The local label 1b (1b stands for next label 1
|
||||
backward) is the address of the instruction that might fault, i.e.
|
||||
in our case the address of the label 1 is c017e7a5:
|
||||
the original assembly code: > 1: movb (%ebx),%dl
|
||||
and linked in vmlinux : > c017e7a5 <do_con_write+e1> movb (%ebx),%dl
|
||||
|
@ -254,7 +254,7 @@ The assembly code
|
|||
becomes the value pair
|
||||
> c01aa7d4 c017c2f6 c0199fe9 c017e7a5 c0199ff5 ................
|
||||
^this is ^this is
|
||||
1b 3b
|
||||
1b 3b
|
||||
c017e7a5,c0199ff5 in the exception table of the kernel.
|
||||
|
||||
So, what actually happens if a fault from kernel mode with no suitable
|
||||
|
@ -266,9 +266,9 @@ vma occurs?
|
|||
3.) CPU calls do_page_fault
|
||||
4.) do page fault calls search_exception_table (regs->eip == c017e7a5);
|
||||
5.) search_exception_table looks up the address c017e7a5 in the
|
||||
exception table (i.e. the contents of the ELF section __ex_table)
|
||||
exception table (i.e. the contents of the ELF section __ex_table)
|
||||
and returns the address of the associated fault handle code c0199ff5.
|
||||
6.) do_page_fault modifies its own return address to point to the fault
|
||||
6.) do_page_fault modifies its own return address to point to the fault
|
||||
handle code and returns.
|
||||
7.) execution continues in the fault handling code.
|
||||
8.) 8a) EAX becomes -EFAULT (== -14)
|
106
MAINTAINERS
106
MAINTAINERS
|
@ -603,11 +603,32 @@ L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
|||
W: http://maxim.org.za/at91_26.html
|
||||
S: Maintained
|
||||
|
||||
ARM/CIRRUS LOGIC EP93XX ARM ARCHITECTURE
|
||||
P: Lennert Buytenhek
|
||||
M: kernel@wantstofly.org
|
||||
ARM/BCMRING ARM ARCHITECTURE
|
||||
P: Leo Chen <leochen@broadcom.com>
|
||||
P: Scott Branden <sbranden@broadcom.com>
|
||||
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
||||
S: Maintained
|
||||
F: arch/arm/mach-bcmring
|
||||
|
||||
ARM/BCMRING MTD NAND DRIVER
|
||||
P: Leo Chen <leochen@broadcom.com>
|
||||
P: Scott Branden <sbranden@broadcom.com>
|
||||
L: linux-mtd@lists.infradead.org
|
||||
S: Maintained
|
||||
F: drivers/mtd/nand/bcm_umi_nand.c
|
||||
F: drivers/mtd/nand/bcm_umi_bch.c
|
||||
F: drivers/mtd/nand/bcm_umi_hamming.c
|
||||
F: drivers/mtd/nand/nand_bcm_umi.h
|
||||
|
||||
ARM/CIRRUS LOGIC EP93XX ARM ARCHITECTURE
|
||||
P: Hartley Sweeten
|
||||
M: hsweeten@visionengravers.com
|
||||
P: Ryan Mallon
|
||||
M: ryan@bluewatersys.com
|
||||
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
||||
S: Maintained
|
||||
F: arch/arm/mach-ep93xx/
|
||||
F: arch/arm/mach-ep93xx/include/mach/
|
||||
|
||||
ARM/CIRRUS LOGIC EDB9315A MACHINE SUPPORT
|
||||
P: Lennert Buytenhek
|
||||
|
@ -867,12 +888,22 @@ M: alex@shark-linux.de
|
|||
W: http://www.shark-linux.de/shark.html
|
||||
S: Maintained
|
||||
|
||||
ARM/SAMSUNG ARM ARCHITECTURES
|
||||
P: Ben Dooks
|
||||
M: ben-linux@fluff.org
|
||||
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
||||
W: http://www.fluff.org/ben/linux/
|
||||
S: Maintained
|
||||
F: arch/arm/plat-s3c/
|
||||
F: arch/arm/plat-s3c24xx/
|
||||
|
||||
ARM/S3C2410 ARM ARCHITECTURE
|
||||
P: Ben Dooks
|
||||
M: ben-linux@fluff.org
|
||||
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
||||
W: http://www.fluff.org/ben/linux/
|
||||
S: Maintained
|
||||
F: arch/arm/mach-s3c2410/
|
||||
|
||||
ARM/S3C2440 ARM ARCHITECTURE
|
||||
P: Ben Dooks
|
||||
|
@ -880,6 +911,39 @@ M: ben-linux@fluff.org
|
|||
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
||||
W: http://www.fluff.org/ben/linux/
|
||||
S: Maintained
|
||||
F: arch/arm/mach-s3c2440/
|
||||
|
||||
ARM/S3C2442 ARM ARCHITECTURE
|
||||
P: Ben Dooks
|
||||
M: ben-linux@fluff.org
|
||||
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
||||
W: http://www.fluff.org/ben/linux/
|
||||
S: Maintained
|
||||
F: arch/arm/mach-s3c2442/
|
||||
|
||||
ARM/S3C2443 ARM ARCHITECTURE
|
||||
P: Ben Dooks
|
||||
M: ben-linux@fluff.org
|
||||
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
||||
W: http://www.fluff.org/ben/linux/
|
||||
S: Maintained
|
||||
F: arch/arm/mach-s3c2443/
|
||||
|
||||
ARM/S3C6400 ARM ARCHITECTURE
|
||||
P: Ben Dooks
|
||||
M: ben-linux@fluff.org
|
||||
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
||||
W: http://www.fluff.org/ben/linux/
|
||||
S: Maintained
|
||||
F: arch/arm/mach-s3c6400/
|
||||
|
||||
ARM/S3C6410 ARM ARCHITECTURE
|
||||
P: Ben Dooks
|
||||
M: ben-linux@fluff.org
|
||||
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
|
||||
W: http://www.fluff.org/ben/linux/
|
||||
S: Maintained
|
||||
F: arch/arm/mach-s3c6410/
|
||||
|
||||
ARM/TECHNOLOGIC SYSTEMS TS7250 MACHINE SUPPORT
|
||||
P: Lennert Buytenhek
|
||||
|
@ -2087,9 +2151,9 @@ F: drivers/edac/i5400_edac.c
|
|||
|
||||
EDAC-I82975X
|
||||
P: Ranganathan Desikan
|
||||
M: rdesikan@jetzbroadband.com
|
||||
M: ravi@jetztechnologies.com
|
||||
P: Arvind R.
|
||||
M: arvind@acarlab.com
|
||||
M: arvind@jetztechnologies.com
|
||||
L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers)
|
||||
W: bluesmoke.sourceforge.net
|
||||
S: Maintained
|
||||
|
@ -2808,7 +2872,9 @@ S: Maintained
|
|||
|
||||
IA64 (Itanium) PLATFORM
|
||||
P: Tony Luck
|
||||
P: Fenghua Yu
|
||||
M: tony.luck@intel.com
|
||||
M: fenghua.yu@intel.com
|
||||
L: linux-ia64@vger.kernel.org
|
||||
W: http://www.ia64-linux.org/
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6.git
|
||||
|
@ -2886,7 +2952,7 @@ P: Dmitry Eremin-Solenikov
|
|||
M: dbaryshkov@gmail.com
|
||||
P: Sergey Lapin
|
||||
M: slapin@ossfans.org
|
||||
L: linux-zigbee-devel@lists.sourceforge.net
|
||||
L: linux-zigbee-devel@lists.sourceforge.net (moderated for non-subscribers)
|
||||
W: http://apps.sourceforge.net/trac/linux-zigbee
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/lowpan/lowpan.git
|
||||
S: Maintained
|
||||
|
@ -4362,7 +4428,7 @@ W: http://www.nongnu.org/orinoco/
|
|||
S: Maintained
|
||||
F: drivers/net/wireless/orinoco/
|
||||
|
||||
OSD LIBRARY
|
||||
OSD LIBRARY and FILESYSTEM
|
||||
P: Boaz Harrosh
|
||||
M: bharrosh@panasas.com
|
||||
P: Benny Halevy
|
||||
|
@ -4371,6 +4437,9 @@ L: osd-dev@open-osd.org
|
|||
W: http://open-osd.org
|
||||
T: git git://git.open-osd.org/open-osd.git
|
||||
S: Maintained
|
||||
F: drivers/scsi/osd/
|
||||
F: drivers/include/scsi/osd_*
|
||||
F: fs/exofs/
|
||||
|
||||
P54 WIRELESS DRIVER
|
||||
P: Michael Wu
|
||||
|
@ -5533,8 +5602,8 @@ F: drivers/staging/
|
|||
|
||||
STARFIRE/DURALAN NETWORK DRIVER
|
||||
P: Ion Badulescu
|
||||
M: ionut@cs.columbia.edu
|
||||
S: Maintained
|
||||
M: ionut@badula.org
|
||||
S: Odd Fixes
|
||||
F: drivers/net/starfire*
|
||||
|
||||
STARMODE RADIO IP (STRIP) PROTOCOL DRIVER
|
||||
|
@ -5668,6 +5737,13 @@ F: drivers/misc/tifm*
|
|||
F: drivers/mmc/host/tifm_sd.c
|
||||
F: include/linux/tifm.h
|
||||
|
||||
TI TWL4030 SERIES SOC CODEC DRIVER
|
||||
P: Peter Ujfalusi
|
||||
M: peter.ujfalusi@nokia.com
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: sound/soc/codecs/twl4030*
|
||||
|
||||
TIPC NETWORK LAYER
|
||||
P: Per Liden
|
||||
M: per.liden@ericsson.com
|
||||
|
@ -5751,17 +5827,17 @@ P: Jiri Kosina
|
|||
M: trivial@kernel.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial.git
|
||||
S: Maintained
|
||||
F: drivers/char/tty_*
|
||||
F: drivers/serial/serial_core.c
|
||||
F: include/linux/serial_core.h
|
||||
F: include/linux/serial.h
|
||||
F: include/linux/tty.h
|
||||
|
||||
TTY LAYER
|
||||
P: Alan Cox
|
||||
M: alan@lxorguk.ukuu.org.uk
|
||||
S: Maintained
|
||||
T: stgit http://zeniv.linux.org.uk/~alan/ttydev/
|
||||
F: drivers/char/tty_*
|
||||
F: drivers/serial/serial_core.c
|
||||
F: include/linux/serial_core.h
|
||||
F: include/linux/serial.h
|
||||
F: include/linux/tty.h
|
||||
|
||||
TULIP NETWORK DRIVERS
|
||||
P: Grant Grundler
|
||||
|
@ -5799,7 +5875,7 @@ UBI FILE SYSTEM (UBIFS)
|
|||
P: Artem Bityutskiy
|
||||
M: dedekind@infradead.org
|
||||
P: Adrian Hunter
|
||||
M: ext-adrian.hunter@nokia.com
|
||||
M: adrian.hunter@nokia.com
|
||||
L: linux-mtd@lists.infradead.org
|
||||
T: git git://git.infradead.org/ubifs-2.6.git
|
||||
W: http://www.linux-mtd.infradead.org/doc/ubifs.html
|
||||
|
|
9
Makefile
9
Makefile
|
@ -1,7 +1,7 @@
|
|||
VERSION = 2
|
||||
PATCHLEVEL = 6
|
||||
SUBLEVEL = 31
|
||||
EXTRAVERSION = -rc1
|
||||
EXTRAVERSION = -rc2
|
||||
NAME = Man-Eating Seals of Antiquity
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
@ -140,15 +140,13 @@ _all: modules
|
|||
endif
|
||||
|
||||
srctree := $(if $(KBUILD_SRC),$(KBUILD_SRC),$(CURDIR))
|
||||
TOPDIR := $(srctree)
|
||||
# FIXME - TOPDIR is obsolete, use srctree/objtree
|
||||
objtree := $(CURDIR)
|
||||
src := $(srctree)
|
||||
obj := $(objtree)
|
||||
|
||||
VPATH := $(srctree)$(if $(KBUILD_EXTMOD),:$(KBUILD_EXTMOD))
|
||||
|
||||
export srctree objtree VPATH TOPDIR
|
||||
export srctree objtree VPATH
|
||||
|
||||
|
||||
# SUBARCH tells the usermode build what the underlying arch is. That is set
|
||||
|
@ -344,7 +342,8 @@ KBUILD_CPPFLAGS := -D__KERNEL__
|
|||
|
||||
KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
|
||||
-fno-strict-aliasing -fno-common \
|
||||
-Werror-implicit-function-declaration
|
||||
-Werror-implicit-function-declaration \
|
||||
-Wno-format-security
|
||||
KBUILD_AFLAGS := -D__ASSEMBLY__
|
||||
|
||||
# Read KERNELRELEASE from include/config/kernel.release (if it exists)
|
||||
|
|
|
@ -30,7 +30,7 @@ extern unsigned long __per_cpu_offset[NR_CPUS];
|
|||
|
||||
#ifndef MODULE
|
||||
#define SHIFT_PERCPU_PTR(var, offset) RELOC_HIDE(&per_cpu_var(var), (offset))
|
||||
#define PER_CPU_ATTRIBUTES
|
||||
#define PER_CPU_DEF_ATTRIBUTES
|
||||
#else
|
||||
/*
|
||||
* To calculate addresses of locally defined variables, GCC uses 32-bit
|
||||
|
@ -49,7 +49,7 @@ extern unsigned long __per_cpu_offset[NR_CPUS];
|
|||
: "=&r"(__ptr), "=&r"(tmp_gp)); \
|
||||
(typeof(&per_cpu_var(var)))(__ptr + (offset)); })
|
||||
|
||||
#define PER_CPU_ATTRIBUTES __used
|
||||
#define PER_CPU_DEF_ATTRIBUTES __used
|
||||
|
||||
#endif /* MODULE */
|
||||
|
||||
|
@ -71,7 +71,7 @@ extern unsigned long __per_cpu_offset[NR_CPUS];
|
|||
#define __get_cpu_var(var) per_cpu_var(var)
|
||||
#define __raw_get_cpu_var(var) per_cpu_var(var)
|
||||
|
||||
#define PER_CPU_ATTRIBUTES
|
||||
#define PER_CPU_DEF_ATTRIBUTES
|
||||
|
||||
#endif /* SMP */
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ struct thread_info {
|
|||
.task = &tsk, \
|
||||
.exec_domain = &default_exec_domain, \
|
||||
.addr_limit = KERNEL_DS, \
|
||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||
.restart_block = { \
|
||||
.fn = do_no_restart_syscall, \
|
||||
}, \
|
||||
|
|
|
@ -495,10 +495,18 @@ config ARCH_W90X900
|
|||
select CPU_ARM926T
|
||||
select ARCH_REQUIRE_GPIOLIB
|
||||
select GENERIC_GPIO
|
||||
select HAVE_CLK
|
||||
select COMMON_CLKDEV
|
||||
select GENERIC_TIME
|
||||
select GENERIC_CLOCKEVENTS
|
||||
help
|
||||
Support for Nuvoton (Winbond logic dept.) ARM9 processor,You
|
||||
can login www.mcuos.com or www.nuvoton.com to know more.
|
||||
Support for Nuvoton (Winbond logic dept.) ARM9 processor,
|
||||
At present, the w90x900 has been renamed nuc900, regarding
|
||||
the ARM series product line, you can login the following
|
||||
link address to know more.
|
||||
|
||||
<http://www.nuvoton.com/hq/enu/ProductAndSales/ProductLines/
|
||||
ConsumerElectronicsIC/ARMMicrocontroller/ARMMicrocontroller>
|
||||
|
||||
config ARCH_PNX4008
|
||||
bool "Philips Nexperia PNX4008 Mobile"
|
||||
|
@ -639,6 +647,18 @@ config ARCH_OMAP
|
|||
help
|
||||
Support for TI's OMAP platform (OMAP1 and OMAP2).
|
||||
|
||||
config ARCH_BCMRING
|
||||
bool "Broadcom BCMRING"
|
||||
depends on MMU
|
||||
select CPU_V6
|
||||
select ARM_AMBA
|
||||
select COMMON_CLKDEV
|
||||
select GENERIC_TIME
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select ARCH_WANT_OPTIONAL_GPIOLIB
|
||||
help
|
||||
Support for Broadcom's BCMRing platform.
|
||||
|
||||
endchoice
|
||||
|
||||
source "arch/arm/mach-clps711x/Kconfig"
|
||||
|
@ -732,6 +752,8 @@ source "arch/arm/mach-u300/Kconfig"
|
|||
|
||||
source "arch/arm/mach-w90x900/Kconfig"
|
||||
|
||||
source "arch/arm/mach-bcmring/Kconfig"
|
||||
|
||||
# Definitions to make life easier
|
||||
config ARCH_ACORN
|
||||
bool
|
||||
|
@ -1056,6 +1078,11 @@ config HIGHMEM
|
|||
|
||||
If unsure, say n.
|
||||
|
||||
config HIGHPTE
|
||||
bool "Allocate 2nd-level pagetables from highmem"
|
||||
depends on HIGHMEM
|
||||
depends on !OUTER_CACHE
|
||||
|
||||
source "mm/Kconfig"
|
||||
|
||||
config LEDS
|
||||
|
|
|
@ -99,14 +99,6 @@ config DEBUG_CLPS711X_UART2
|
|||
output to the second serial port on these devices. Saying N will
|
||||
cause the debug messages to appear on the first serial port.
|
||||
|
||||
config DEBUG_S3C_PORT
|
||||
depends on DEBUG_LL && PLAT_S3C
|
||||
bool "Kernel low-level debugging messages via S3C UART"
|
||||
help
|
||||
Say Y here if you want debug print routines to go to one of the
|
||||
S3C internal UARTs. The chosen UART must have been configured
|
||||
before it is used.
|
||||
|
||||
config DEBUG_S3C_UART
|
||||
depends on PLAT_S3C
|
||||
int "S3C UART to use for low-level debug"
|
||||
|
|
|
@ -112,6 +112,7 @@ endif
|
|||
# by CONFIG_* macro name.
|
||||
machine-$(CONFIG_ARCH_AAEC2000) := aaec2000
|
||||
machine-$(CONFIG_ARCH_AT91) := at91
|
||||
machine-$(CONFIG_ARCH_BCMRING) := bcmring
|
||||
machine-$(CONFIG_ARCH_CLPS711X) := clps711x
|
||||
machine-$(CONFIG_ARCH_DAVINCI) := davinci
|
||||
machine-$(CONFIG_ARCH_EBSA110) := ebsa110
|
||||
|
|
|
@ -0,0 +1,725 @@
|
|||
#
|
||||
# Automatically generated make config: don't edit
|
||||
# Linux kernel version: 2.6.31-rc3
|
||||
# Fri Jul 17 12:07:28 2009
|
||||
#
|
||||
CONFIG_ARM=y
|
||||
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
|
||||
CONFIG_GENERIC_TIME=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS=y
|
||||
CONFIG_MMU=y
|
||||
CONFIG_GENERIC_HARDIRQS=y
|
||||
CONFIG_STACKTRACE_SUPPORT=y
|
||||
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
|
||||
CONFIG_LOCKDEP_SUPPORT=y
|
||||
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
|
||||
CONFIG_HARDIRQS_SW_RESEND=y
|
||||
CONFIG_GENERIC_IRQ_PROBE=y
|
||||
CONFIG_RWSEM_GENERIC_SPINLOCK=y
|
||||
CONFIG_GENERIC_HWEIGHT=y
|
||||
CONFIG_GENERIC_CALIBRATE_DELAY=y
|
||||
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
|
||||
CONFIG_VECTORS_BASE=0xffff0000
|
||||
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
|
||||
CONFIG_CONSTRUCTORS=y
|
||||
|
||||
#
|
||||
# General setup
|
||||
#
|
||||
CONFIG_EXPERIMENTAL=y
|
||||
CONFIG_BROKEN_ON_SMP=y
|
||||
CONFIG_LOCK_KERNEL=y
|
||||
CONFIG_INIT_ENV_ARG_LIMIT=32
|
||||
CONFIG_LOCALVERSION=""
|
||||
# CONFIG_LOCALVERSION_AUTO is not set
|
||||
# CONFIG_SWAP is not set
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_SYSVIPC_SYSCTL=y
|
||||
# CONFIG_POSIX_MQUEUE is not set
|
||||
# CONFIG_BSD_PROCESS_ACCT is not set
|
||||
# CONFIG_TASKSTATS is not set
|
||||
# CONFIG_AUDIT is not set
|
||||
|
||||
#
|
||||
# RCU Subsystem
|
||||
#
|
||||
CONFIG_CLASSIC_RCU=y
|
||||
# CONFIG_TREE_RCU is not set
|
||||
# CONFIG_PREEMPT_RCU is not set
|
||||
# CONFIG_TREE_RCU_TRACE is not set
|
||||
# CONFIG_PREEMPT_RCU_TRACE is not set
|
||||
# CONFIG_IKCONFIG is not set
|
||||
CONFIG_LOG_BUF_SHIFT=17
|
||||
# CONFIG_GROUP_SCHED is not set
|
||||
# CONFIG_CGROUPS is not set
|
||||
# CONFIG_SYSFS_DEPRECATED_V2 is not set
|
||||
# CONFIG_RELAY is not set
|
||||
# CONFIG_NAMESPACES is not set
|
||||
# CONFIG_BLK_DEV_INITRD is not set
|
||||
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
|
||||
CONFIG_SYSCTL=y
|
||||
CONFIG_EMBEDDED=y
|
||||
CONFIG_UID16=y
|
||||
CONFIG_SYSCTL_SYSCALL=y
|
||||
CONFIG_KALLSYMS=y
|
||||
CONFIG_KALLSYMS_EXTRA_PASS=y
|
||||
# CONFIG_HOTPLUG is not set
|
||||
CONFIG_PRINTK=y
|
||||
CONFIG_BUG=y
|
||||
# CONFIG_ELF_CORE is not set
|
||||
CONFIG_BASE_FULL=y
|
||||
CONFIG_FUTEX=y
|
||||
# CONFIG_EPOLL is not set
|
||||
# CONFIG_SIGNALFD is not set
|
||||
# CONFIG_TIMERFD is not set
|
||||
# CONFIG_EVENTFD is not set
|
||||
CONFIG_SHMEM=y
|
||||
# CONFIG_AIO is not set
|
||||
|
||||
#
|
||||
# Performance Counters
|
||||
#
|
||||
# CONFIG_VM_EVENT_COUNTERS is not set
|
||||
# CONFIG_SLUB_DEBUG is not set
|
||||
# CONFIG_STRIP_ASM_SYMS is not set
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
# CONFIG_SLAB is not set
|
||||
CONFIG_SLUB=y
|
||||
# CONFIG_SLOB is not set
|
||||
# CONFIG_PROFILING is not set
|
||||
# CONFIG_MARKERS is not set
|
||||
CONFIG_HAVE_OPROFILE=y
|
||||
# CONFIG_KPROBES is not set
|
||||
CONFIG_HAVE_KPROBES=y
|
||||
CONFIG_HAVE_KRETPROBES=y
|
||||
|
||||
#
|
||||
# GCOV-based kernel profiling
|
||||
#
|
||||
# CONFIG_SLOW_WORK is not set
|
||||
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
|
||||
CONFIG_RT_MUTEXES=y
|
||||
CONFIG_BASE_SMALL=0
|
||||
CONFIG_MODULES=y
|
||||
# CONFIG_MODULE_FORCE_LOAD is not set
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
# CONFIG_MODULE_FORCE_UNLOAD is not set
|
||||
# CONFIG_MODVERSIONS is not set
|
||||
# CONFIG_MODULE_SRCVERSION_ALL is not set
|
||||
CONFIG_BLOCK=y
|
||||
CONFIG_LBDAF=y
|
||||
# CONFIG_BLK_DEV_BSG is not set
|
||||
# CONFIG_BLK_DEV_INTEGRITY is not set
|
||||
|
||||
#
|
||||
# IO Schedulers
|
||||
#
|
||||
CONFIG_IOSCHED_NOOP=y
|
||||
# CONFIG_IOSCHED_AS is not set
|
||||
# CONFIG_IOSCHED_DEADLINE is not set
|
||||
# CONFIG_IOSCHED_CFQ is not set
|
||||
# CONFIG_DEFAULT_AS is not set
|
||||
# CONFIG_DEFAULT_DEADLINE is not set
|
||||
# CONFIG_DEFAULT_CFQ is not set
|
||||
CONFIG_DEFAULT_NOOP=y
|
||||
CONFIG_DEFAULT_IOSCHED="noop"
|
||||
# CONFIG_FREEZER is not set
|
||||
|
||||
#
|
||||
# System Type
|
||||
#
|
||||
# CONFIG_ARCH_AAEC2000 is not set
|
||||
# CONFIG_ARCH_INTEGRATOR is not set
|
||||
# CONFIG_ARCH_REALVIEW is not set
|
||||
# CONFIG_ARCH_VERSATILE is not set
|
||||
# CONFIG_ARCH_AT91 is not set
|
||||
# CONFIG_ARCH_CLPS711X is not set
|
||||
# CONFIG_ARCH_GEMINI is not set
|
||||
# CONFIG_ARCH_EBSA110 is not set
|
||||
# CONFIG_ARCH_EP93XX is not set
|
||||
# CONFIG_ARCH_FOOTBRIDGE is not set
|
||||
# CONFIG_ARCH_MXC is not set
|
||||
# CONFIG_ARCH_STMP3XXX is not set
|
||||
# CONFIG_ARCH_NETX is not set
|
||||
# CONFIG_ARCH_H720X is not set
|
||||
# CONFIG_ARCH_IOP13XX is not set
|
||||
# CONFIG_ARCH_IOP32X is not set
|
||||
# CONFIG_ARCH_IOP33X is not set
|
||||
# CONFIG_ARCH_IXP23XX is not set
|
||||
# CONFIG_ARCH_IXP2000 is not set
|
||||
# CONFIG_ARCH_IXP4XX is not set
|
||||
# CONFIG_ARCH_L7200 is not set
|
||||
# CONFIG_ARCH_KIRKWOOD is not set
|
||||
# CONFIG_ARCH_LOKI is not set
|
||||
# CONFIG_ARCH_MV78XX0 is not set
|
||||
# CONFIG_ARCH_ORION5X is not set
|
||||
# CONFIG_ARCH_MMP is not set
|
||||
# CONFIG_ARCH_KS8695 is not set
|
||||
# CONFIG_ARCH_NS9XXX is not set
|
||||
# CONFIG_ARCH_W90X900 is not set
|
||||
# CONFIG_ARCH_PNX4008 is not set
|
||||
# CONFIG_ARCH_PXA is not set
|
||||
# CONFIG_ARCH_MSM is not set
|
||||
# CONFIG_ARCH_RPC is not set
|
||||
# CONFIG_ARCH_SA1100 is not set
|
||||
# CONFIG_ARCH_S3C2410 is not set
|
||||
# CONFIG_ARCH_S3C64XX is not set
|
||||
# CONFIG_ARCH_SHARK is not set
|
||||
# CONFIG_ARCH_LH7A40X is not set
|
||||
# CONFIG_ARCH_U300 is not set
|
||||
# CONFIG_ARCH_DAVINCI is not set
|
||||
# CONFIG_ARCH_OMAP is not set
|
||||
CONFIG_ARCH_BCMRING=y
|
||||
# CONFIG_ARCH_FPGA11107 is not set
|
||||
CONFIG_ARCH_BCM11107=y
|
||||
|
||||
#
|
||||
# BCMRING Options
|
||||
#
|
||||
CONFIG_BCM_ZRELADDR=0x8000
|
||||
|
||||
#
|
||||
# Processor Type
|
||||
#
|
||||
CONFIG_CPU_32=y
|
||||
CONFIG_CPU_V6=y
|
||||
CONFIG_CPU_32v6K=y
|
||||
CONFIG_CPU_32v6=y
|
||||
CONFIG_CPU_ABRT_EV6=y
|
||||
CONFIG_CPU_PABRT_NOIFAR=y
|
||||
CONFIG_CPU_CACHE_V6=y
|
||||
CONFIG_CPU_CACHE_VIPT=y
|
||||
CONFIG_CPU_COPY_V6=y
|
||||
CONFIG_CPU_TLB_V6=y
|
||||
CONFIG_CPU_HAS_ASID=y
|
||||
CONFIG_CPU_CP15=y
|
||||
CONFIG_CPU_CP15_MMU=y
|
||||
|
||||
#
|
||||
# Processor Features
|
||||
#
|
||||
CONFIG_ARM_THUMB=y
|
||||
# CONFIG_CPU_ICACHE_DISABLE is not set
|
||||
# CONFIG_CPU_DCACHE_DISABLE is not set
|
||||
# CONFIG_CPU_BPREDICT_DISABLE is not set
|
||||
# CONFIG_ARM_ERRATA_411920 is not set
|
||||
CONFIG_COMMON_CLKDEV=y
|
||||
|
||||
#
|
||||
# Bus support
|
||||
#
|
||||
CONFIG_ARM_AMBA=y
|
||||
# CONFIG_PCI_SYSCALL is not set
|
||||
# CONFIG_ARCH_SUPPORTS_MSI is not set
|
||||
|
||||
#
|
||||
# Kernel Features
|
||||
#
|
||||
CONFIG_TICK_ONESHOT=y
|
||||
CONFIG_NO_HZ=y
|
||||
# CONFIG_HIGH_RES_TIMERS is not set
|
||||
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
|
||||
CONFIG_VMSPLIT_3G=y
|
||||
# CONFIG_VMSPLIT_2G is not set
|
||||
# CONFIG_VMSPLIT_1G is not set
|
||||
CONFIG_PAGE_OFFSET=0xC0000000
|
||||
CONFIG_PREEMPT=y
|
||||
CONFIG_HZ=100
|
||||
CONFIG_AEABI=y
|
||||
# CONFIG_OABI_COMPAT is not set
|
||||
# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
|
||||
# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
|
||||
# CONFIG_HIGHMEM is not set
|
||||
CONFIG_SELECT_MEMORY_MODEL=y
|
||||
CONFIG_FLATMEM_MANUAL=y
|
||||
# CONFIG_DISCONTIGMEM_MANUAL is not set
|
||||
# CONFIG_SPARSEMEM_MANUAL is not set
|
||||
CONFIG_FLATMEM=y
|
||||
CONFIG_FLAT_NODE_MEM_MAP=y
|
||||
CONFIG_PAGEFLAGS_EXTENDED=y
|
||||
CONFIG_SPLIT_PTLOCK_CPUS=4
|
||||
# CONFIG_PHYS_ADDR_T_64BIT is not set
|
||||
CONFIG_ZONE_DMA_FLAG=0
|
||||
CONFIG_VIRT_TO_BUS=y
|
||||
CONFIG_HAVE_MLOCK=y
|
||||
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
|
||||
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
|
||||
CONFIG_ALIGNMENT_TRAP=y
|
||||
CONFIG_UACCESS_WITH_MEMCPY=y
|
||||
|
||||
#
|
||||
# Boot options
|
||||
#
|
||||
CONFIG_ZBOOT_ROM_TEXT=0x0e000000
|
||||
CONFIG_ZBOOT_ROM_BSS=0x0ea00000
|
||||
CONFIG_ZBOOT_ROM=y
|
||||
CONFIG_CMDLINE=""
|
||||
# CONFIG_KEXEC is not set
|
||||
|
||||
#
|
||||
# CPU Power Management
|
||||
#
|
||||
# CONFIG_CPU_IDLE is not set
|
||||
|
||||
#
|
||||
# Floating point emulation
|
||||
#
|
||||
|
||||
#
|
||||
# At least one emulation must be selected
|
||||
#
|
||||
# CONFIG_VFP is not set
|
||||
|
||||
#
|
||||
# Userspace binary formats
|
||||
#
|
||||
CONFIG_BINFMT_ELF=y
|
||||
CONFIG_HAVE_AOUT=y
|
||||
# CONFIG_BINFMT_AOUT is not set
|
||||
# CONFIG_BINFMT_MISC is not set
|
||||
|
||||
#
|
||||
# Power management options
|
||||
#
|
||||
# CONFIG_PM is not set
|
||||
CONFIG_ARCH_SUSPEND_POSSIBLE=y
|
||||
CONFIG_NET=y
|
||||
|
||||
#
|
||||
# Networking options
|
||||
#
|
||||
# CONFIG_PACKET is not set
|
||||
# CONFIG_UNIX is not set
|
||||
# CONFIG_NET_KEY is not set
|
||||
# CONFIG_INET is not set
|
||||
# CONFIG_NETWORK_SECMARK is not set
|
||||
# CONFIG_NETFILTER is not set
|
||||
# CONFIG_ATM is not set
|
||||
# CONFIG_BRIDGE is not set
|
||||
# CONFIG_NET_DSA is not set
|
||||
# CONFIG_VLAN_8021Q is not set
|
||||
# CONFIG_DECNET is not set
|
||||
# CONFIG_LLC2 is not set
|
||||
# CONFIG_IPX is not set
|
||||
# CONFIG_ATALK is not set
|
||||
# CONFIG_X25 is not set
|
||||
# CONFIG_LAPB is not set
|
||||
# CONFIG_WAN_ROUTER is not set
|
||||
# CONFIG_PHONET is not set
|
||||
# CONFIG_IEEE802154 is not set
|
||||
# CONFIG_NET_SCHED is not set
|
||||
# CONFIG_DCB is not set
|
||||
|
||||
#
|
||||
# Network testing
|
||||
#
|
||||
# CONFIG_NET_PKTGEN is not set
|
||||
# CONFIG_HAMRADIO is not set
|
||||
# CONFIG_CAN is not set
|
||||
# CONFIG_IRDA is not set
|
||||
# CONFIG_BT is not set
|
||||
# CONFIG_WIRELESS is not set
|
||||
# CONFIG_WIMAX is not set
|
||||
# CONFIG_RFKILL is not set
|
||||
# CONFIG_NET_9P is not set
|
||||
|
||||
#
|
||||
# Device Drivers
|
||||
#
|
||||
|
||||
#
|
||||
# Generic Driver Options
|
||||
#
|
||||
CONFIG_STANDALONE=y
|
||||
CONFIG_PREVENT_FIRMWARE_BUILD=y
|
||||
# CONFIG_SYS_HYPERVISOR is not set
|
||||
# CONFIG_CONNECTOR is not set
|
||||
CONFIG_MTD=y
|
||||
# CONFIG_MTD_DEBUG is not set
|
||||
CONFIG_MTD_CONCAT=y
|
||||
CONFIG_MTD_PARTITIONS=y
|
||||
# CONFIG_MTD_TESTS is not set
|
||||
# CONFIG_MTD_REDBOOT_PARTS is not set
|
||||
CONFIG_MTD_CMDLINE_PARTS=y
|
||||
# CONFIG_MTD_AFS_PARTS is not set
|
||||
# CONFIG_MTD_AR7_PARTS is not set
|
||||
|
||||
#
|
||||
# User Modules And Translation Layers
|
||||
#
|
||||
CONFIG_MTD_CHAR=y
|
||||
CONFIG_MTD_BLKDEVS=y
|
||||
CONFIG_MTD_BLOCK=y
|
||||
# CONFIG_FTL is not set
|
||||
# CONFIG_NFTL is not set
|
||||
# CONFIG_INFTL is not set
|
||||
# CONFIG_RFD_FTL is not set
|
||||
# CONFIG_SSFDC is not set
|
||||
# CONFIG_MTD_OOPS is not set
|
||||
|
||||
#
|
||||
# RAM/ROM/Flash chip drivers
|
||||
#
|
||||
CONFIG_MTD_CFI=y
|
||||
# CONFIG_MTD_JEDECPROBE is not set
|
||||
CONFIG_MTD_GEN_PROBE=y
|
||||
CONFIG_MTD_CFI_ADV_OPTIONS=y
|
||||
CONFIG_MTD_CFI_NOSWAP=y
|
||||
# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
|
||||
# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
|
||||
CONFIG_MTD_CFI_GEOMETRY=y
|
||||
CONFIG_MTD_MAP_BANK_WIDTH_1=y
|
||||
CONFIG_MTD_MAP_BANK_WIDTH_2=y
|
||||
CONFIG_MTD_MAP_BANK_WIDTH_4=y
|
||||
# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
|
||||
# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
|
||||
# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
|
||||
CONFIG_MTD_CFI_I1=y
|
||||
# CONFIG_MTD_CFI_I2 is not set
|
||||
# CONFIG_MTD_CFI_I4 is not set
|
||||
# CONFIG_MTD_CFI_I8 is not set
|
||||
# CONFIG_MTD_OTP is not set
|
||||
# CONFIG_MTD_CFI_INTELEXT is not set
|
||||
# CONFIG_MTD_CFI_AMDSTD is not set
|
||||
# CONFIG_MTD_CFI_STAA is not set
|
||||
CONFIG_MTD_CFI_UTIL=y
|
||||
# CONFIG_MTD_RAM is not set
|
||||
# CONFIG_MTD_ROM is not set
|
||||
# CONFIG_MTD_ABSENT is not set
|
||||
|
||||
#
|
||||
# Mapping drivers for chip access
|
||||
#
|
||||
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
|
||||
# CONFIG_MTD_PHYSMAP is not set
|
||||
# CONFIG_MTD_ARM_INTEGRATOR is not set
|
||||
# CONFIG_MTD_PLATRAM is not set
|
||||
|
||||
#
|
||||
# Self-contained MTD device drivers
|
||||
#
|
||||
# CONFIG_MTD_SLRAM is not set
|
||||
# CONFIG_MTD_PHRAM is not set
|
||||
# CONFIG_MTD_MTDRAM is not set
|
||||
# CONFIG_MTD_BLOCK2MTD is not set
|
||||
|
||||
#
|
||||
# Disk-On-Chip Device Drivers
|
||||
#
|
||||
# CONFIG_MTD_DOC2000 is not set
|
||||
# CONFIG_MTD_DOC2001 is not set
|
||||
# CONFIG_MTD_DOC2001PLUS is not set
|
||||
CONFIG_MTD_NAND=y
|
||||
CONFIG_MTD_NAND_VERIFY_WRITE=y
|
||||
# CONFIG_MTD_NAND_ECC_SMC is not set
|
||||
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
|
||||
CONFIG_MTD_NAND_IDS=y
|
||||
CONFIG_MTD_NAND_BCM_UMI=y
|
||||
CONFIG_MTD_NAND_BCM_UMI_HWCS=y
|
||||
# CONFIG_MTD_NAND_DISKONCHIP is not set
|
||||
# CONFIG_MTD_NAND_NANDSIM is not set
|
||||
# CONFIG_MTD_NAND_PLATFORM is not set
|
||||
# CONFIG_MTD_ONENAND is not set
|
||||
|
||||
#
|
||||
# LPDDR flash memory drivers
|
||||
#
|
||||
# CONFIG_MTD_LPDDR is not set
|
||||
|
||||
#
|
||||
# UBI - Unsorted block images
|
||||
#
|
||||
# CONFIG_MTD_UBI is not set
|
||||
# CONFIG_PARPORT is not set
|
||||
CONFIG_BLK_DEV=y
|
||||
# CONFIG_BLK_DEV_COW_COMMON is not set
|
||||
# CONFIG_BLK_DEV_LOOP is not set
|
||||
# CONFIG_BLK_DEV_NBD is not set
|
||||
# CONFIG_BLK_DEV_RAM is not set
|
||||
# CONFIG_CDROM_PKTCDVD is not set
|
||||
# CONFIG_ATA_OVER_ETH is not set
|
||||
# CONFIG_MISC_DEVICES is not set
|
||||
CONFIG_HAVE_IDE=y
|
||||
# CONFIG_IDE is not set
|
||||
|
||||
#
|
||||
# SCSI device support
|
||||
#
|
||||
# CONFIG_RAID_ATTRS is not set
|
||||
# CONFIG_SCSI is not set
|
||||
# CONFIG_SCSI_DMA is not set
|
||||
# CONFIG_SCSI_NETLINK is not set
|
||||
# CONFIG_ATA is not set
|
||||
# CONFIG_MD is not set
|
||||
# CONFIG_NETDEVICES is not set
|
||||
# CONFIG_ISDN is not set
|
||||
|
||||
#
|
||||
# Input device support
|
||||
#
|
||||
CONFIG_INPUT=y
|
||||
# CONFIG_INPUT_FF_MEMLESS is not set
|
||||
# CONFIG_INPUT_POLLDEV is not set
|
||||
|
||||
#
|
||||
# Userland interfaces
|
||||
#
|
||||
# CONFIG_INPUT_MOUSEDEV is not set
|
||||
# CONFIG_INPUT_JOYDEV is not set
|
||||
# CONFIG_INPUT_EVDEV is not set
|
||||
# CONFIG_INPUT_EVBUG is not set
|
||||
|
||||
#
|
||||
# Input Device Drivers
|
||||
#
|
||||
# CONFIG_INPUT_KEYBOARD is not set
|
||||
# CONFIG_INPUT_MOUSE is not set
|
||||
# CONFIG_INPUT_JOYSTICK is not set
|
||||
# CONFIG_INPUT_TABLET is not set
|
||||
# CONFIG_INPUT_TOUCHSCREEN is not set
|
||||
# CONFIG_INPUT_MISC is not set
|
||||
|
||||
#
|
||||
# Hardware I/O ports
|
||||
#
|
||||
# CONFIG_SERIO is not set
|
||||
# CONFIG_GAMEPORT is not set
|
||||
|
||||
#
|
||||
# Character devices
|
||||
#
|
||||
CONFIG_VT=y
|
||||
# CONFIG_CONSOLE_TRANSLATIONS is not set
|
||||
CONFIG_VT_CONSOLE=y
|
||||
CONFIG_HW_CONSOLE=y
|
||||
# CONFIG_VT_HW_CONSOLE_BINDING is not set
|
||||
# CONFIG_DEVKMEM is not set
|
||||
# CONFIG_SERIAL_NONSTANDARD is not set
|
||||
|
||||
#
|
||||
# Serial drivers
|
||||
#
|
||||
# CONFIG_SERIAL_8250 is not set
|
||||
|
||||
#
|
||||
# Non-8250 serial port support
|
||||
#
|
||||
# CONFIG_SERIAL_AMBA_PL010 is not set
|
||||
CONFIG_SERIAL_AMBA_PL011=y
|
||||
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
|
||||
CONFIG_SERIAL_CORE=y
|
||||
CONFIG_SERIAL_CORE_CONSOLE=y
|
||||
CONFIG_UNIX98_PTYS=y
|
||||
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
|
||||
CONFIG_LEGACY_PTYS=y
|
||||
CONFIG_LEGACY_PTY_COUNT=64
|
||||
# CONFIG_IPMI_HANDLER is not set
|
||||
# CONFIG_HW_RANDOM is not set
|
||||
# CONFIG_R3964 is not set
|
||||
# CONFIG_RAW_DRIVER is not set
|
||||
# CONFIG_TCG_TPM is not set
|
||||
# CONFIG_I2C is not set
|
||||
# CONFIG_SPI is not set
|
||||
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
|
||||
# CONFIG_GPIOLIB is not set
|
||||
# CONFIG_W1 is not set
|
||||
# CONFIG_POWER_SUPPLY is not set
|
||||
# CONFIG_HWMON is not set
|
||||
# CONFIG_THERMAL is not set
|
||||
# CONFIG_THERMAL_HWMON is not set
|
||||
# CONFIG_WATCHDOG is not set
|
||||
CONFIG_SSB_POSSIBLE=y
|
||||
|
||||
#
|
||||
# Sonics Silicon Backplane
|
||||
#
|
||||
# CONFIG_SSB is not set
|
||||
|
||||
#
|
||||
# Multifunction device drivers
|
||||
#
|
||||
# CONFIG_MFD_CORE is not set
|
||||
# CONFIG_MFD_SM501 is not set
|
||||
# CONFIG_HTC_PASIC3 is not set
|
||||
# CONFIG_MFD_TMIO is not set
|
||||
# CONFIG_MEDIA_SUPPORT is not set
|
||||
|
||||
#
|
||||
# Graphics support
|
||||
#
|
||||
# CONFIG_VGASTATE is not set
|
||||
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
|
||||
# CONFIG_FB is not set
|
||||
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
|
||||
|
||||
#
|
||||
# Display device support
|
||||
#
|
||||
# CONFIG_DISPLAY_SUPPORT is not set
|
||||
|
||||
#
|
||||
# Console display driver support
|
||||
#
|
||||
# CONFIG_VGA_CONSOLE is not set
|
||||
CONFIG_DUMMY_CONSOLE=y
|
||||
# CONFIG_SOUND is not set
|
||||
# CONFIG_HID_SUPPORT is not set
|
||||
# CONFIG_USB_SUPPORT is not set
|
||||
# CONFIG_MMC is not set
|
||||
# CONFIG_MEMSTICK is not set
|
||||
# CONFIG_ACCESSIBILITY is not set
|
||||
# CONFIG_NEW_LEDS is not set
|
||||
CONFIG_RTC_LIB=y
|
||||
# CONFIG_RTC_CLASS is not set
|
||||
# CONFIG_DMADEVICES is not set
|
||||
# CONFIG_AUXDISPLAY is not set
|
||||
# CONFIG_REGULATOR is not set
|
||||
# CONFIG_UIO is not set
|
||||
# CONFIG_STAGING is not set
|
||||
|
||||
#
|
||||
# File systems
|
||||
#
|
||||
# CONFIG_EXT2_FS is not set
|
||||
# CONFIG_EXT3_FS is not set
|
||||
# CONFIG_EXT4_FS is not set
|
||||
# CONFIG_REISERFS_FS is not set
|
||||
# CONFIG_JFS_FS is not set
|
||||
CONFIG_FS_POSIX_ACL=y
|
||||
# CONFIG_XFS_FS is not set
|
||||
# CONFIG_GFS2_FS is not set
|
||||
# CONFIG_OCFS2_FS is not set
|
||||
# CONFIG_BTRFS_FS is not set
|
||||
# CONFIG_FILE_LOCKING is not set
|
||||
# CONFIG_FSNOTIFY is not set
|
||||
# CONFIG_INOTIFY is not set
|
||||
# CONFIG_QUOTA is not set
|
||||
# CONFIG_AUTOFS_FS is not set
|
||||
# CONFIG_AUTOFS4_FS is not set
|
||||
# CONFIG_FUSE_FS is not set
|
||||
|
||||
#
|
||||
# Caches
|
||||
#
|
||||
# CONFIG_FSCACHE is not set
|
||||
|
||||
#
|
||||
# CD-ROM/DVD Filesystems
|
||||
#
|
||||
# CONFIG_ISO9660_FS is not set
|
||||
# CONFIG_UDF_FS is not set
|
||||
|
||||
#
|
||||
# DOS/FAT/NT Filesystems
|
||||
#
|
||||
# CONFIG_MSDOS_FS is not set
|
||||
# CONFIG_VFAT_FS is not set
|
||||
# CONFIG_NTFS_FS is not set
|
||||
|
||||
#
|
||||
# Pseudo filesystems
|
||||
#
|
||||
CONFIG_PROC_FS=y
|
||||
CONFIG_PROC_SYSCTL=y
|
||||
# CONFIG_PROC_PAGE_MONITOR is not set
|
||||
CONFIG_SYSFS=y
|
||||
CONFIG_TMPFS=y
|
||||
# CONFIG_TMPFS_POSIX_ACL is not set
|
||||
# CONFIG_HUGETLB_PAGE is not set
|
||||
# CONFIG_CONFIGFS_FS is not set
|
||||
CONFIG_MISC_FILESYSTEMS=y
|
||||
# CONFIG_ADFS_FS is not set
|
||||
# CONFIG_AFFS_FS is not set
|
||||
# CONFIG_HFS_FS is not set
|
||||
# CONFIG_HFSPLUS_FS is not set
|
||||
# CONFIG_BEFS_FS is not set
|
||||
# CONFIG_BFS_FS is not set
|
||||
# CONFIG_EFS_FS is not set
|
||||
CONFIG_JFFS2_FS=y
|
||||
CONFIG_JFFS2_FS_DEBUG=0
|
||||
CONFIG_JFFS2_FS_WRITEBUFFER=y
|
||||
# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
|
||||
CONFIG_JFFS2_SUMMARY=y
|
||||
CONFIG_JFFS2_FS_XATTR=y
|
||||
CONFIG_JFFS2_FS_POSIX_ACL=y
|
||||
# CONFIG_JFFS2_FS_SECURITY is not set
|
||||
# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
|
||||
CONFIG_JFFS2_ZLIB=y
|
||||
# CONFIG_JFFS2_LZO is not set
|
||||
CONFIG_JFFS2_RTIME=y
|
||||
# CONFIG_JFFS2_RUBIN is not set
|
||||
# CONFIG_CRAMFS is not set
|
||||
# CONFIG_SQUASHFS is not set
|
||||
# CONFIG_VXFS_FS is not set
|
||||
# CONFIG_MINIX_FS is not set
|
||||
# CONFIG_OMFS_FS is not set
|
||||
# CONFIG_HPFS_FS is not set
|
||||
# CONFIG_QNX4FS_FS is not set
|
||||
# CONFIG_ROMFS_FS is not set
|
||||
# CONFIG_SYSV_FS is not set
|
||||
# CONFIG_UFS_FS is not set
|
||||
# CONFIG_NILFS2_FS is not set
|
||||
# CONFIG_NETWORK_FILESYSTEMS is not set
|
||||
|
||||
#
|
||||
# Partition Types
|
||||
#
|
||||
# CONFIG_PARTITION_ADVANCED is not set
|
||||
CONFIG_MSDOS_PARTITION=y
|
||||
# CONFIG_NLS is not set
|
||||
|
||||
#
|
||||
# Kernel hacking
|
||||
#
|
||||
# CONFIG_PRINTK_TIME is not set
|
||||
# CONFIG_ENABLE_WARN_DEPRECATED is not set
|
||||
CONFIG_ENABLE_MUST_CHECK=y
|
||||
CONFIG_FRAME_WARN=1024
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
# CONFIG_UNUSED_SYMBOLS is not set
|
||||
# CONFIG_DEBUG_FS is not set
|
||||
CONFIG_HEADERS_CHECK=y
|
||||
# CONFIG_DEBUG_KERNEL is not set
|
||||
# CONFIG_DEBUG_BUGVERBOSE is not set
|
||||
# CONFIG_DEBUG_MEMORY_INIT is not set
|
||||
CONFIG_FRAME_POINTER=y
|
||||
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
|
||||
# CONFIG_LATENCYTOP is not set
|
||||
# CONFIG_SYSCTL_SYSCALL_CHECK is not set
|
||||
CONFIG_HAVE_FUNCTION_TRACER=y
|
||||
CONFIG_TRACING_SUPPORT=y
|
||||
# CONFIG_FTRACE is not set
|
||||
# CONFIG_BUILD_DOCSRC is not set
|
||||
# CONFIG_SAMPLES is not set
|
||||
CONFIG_HAVE_ARCH_KGDB=y
|
||||
# CONFIG_ARM_UNWIND is not set
|
||||
# CONFIG_DEBUG_USER is not set
|
||||
|
||||
#
|
||||
# Security options
|
||||
#
|
||||
# CONFIG_KEYS is not set
|
||||
# CONFIG_SECURITY is not set
|
||||
# CONFIG_SECURITYFS is not set
|
||||
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
|
||||
# CONFIG_CRYPTO is not set
|
||||
# CONFIG_BINARY_PRINTF is not set
|
||||
|
||||
#
|
||||
# Library routines
|
||||
#
|
||||
CONFIG_BITREVERSE=y
|
||||
CONFIG_GENERIC_FIND_LAST_BIT=y
|
||||
# CONFIG_CRC_CCITT is not set
|
||||
# CONFIG_CRC16 is not set
|
||||
# CONFIG_CRC_T10DIF is not set
|
||||
# CONFIG_CRC_ITU_T is not set
|
||||
CONFIG_CRC32=y
|
||||
# CONFIG_CRC7 is not set
|
||||
# CONFIG_LIBCRC32C is not set
|
||||
CONFIG_ZLIB_INFLATE=y
|
||||
CONFIG_ZLIB_DEFLATE=y
|
||||
CONFIG_HAS_IOMEM=y
|
||||
CONFIG_HAS_IOPORT=y
|
||||
CONFIG_HAS_DMA=y
|
||||
CONFIG_NLATTR=y
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -260,6 +260,7 @@ CONFIG_MACH_NEXCODER_2440=y
|
|||
CONFIG_SMDK2440_CPU2440=y
|
||||
CONFIG_MACH_AT2440EVB=y
|
||||
CONFIG_CPU_S3C2442=y
|
||||
CONFIG_MACH_MINI2440=y
|
||||
|
||||
#
|
||||
# S3C2442 Machines
|
||||
|
@ -2298,7 +2299,6 @@ CONFIG_DEBUG_ERRORS=y
|
|||
# CONFIG_DEBUG_STACK_USAGE is not set
|
||||
CONFIG_DEBUG_LL=y
|
||||
# CONFIG_DEBUG_ICEDCC is not set
|
||||
CONFIG_DEBUG_S3C_PORT=y
|
||||
CONFIG_DEBUG_S3C_UART=0
|
||||
|
||||
#
|
||||
|
|
|
@ -816,7 +816,6 @@ CONFIG_DEBUG_ERRORS=y
|
|||
# CONFIG_DEBUG_STACK_USAGE is not set
|
||||
CONFIG_DEBUG_LL=y
|
||||
# CONFIG_DEBUG_ICEDCC is not set
|
||||
CONFIG_DEBUG_S3C_PORT=y
|
||||
CONFIG_DEBUG_S3C_UART=0
|
||||
|
||||
#
|
||||
|
|
|
@ -857,7 +857,6 @@ CONFIG_DEBUG_ERRORS=y
|
|||
# CONFIG_DEBUG_STACK_USAGE is not set
|
||||
CONFIG_DEBUG_LL=y
|
||||
# CONFIG_DEBUG_ICEDCC is not set
|
||||
# CONFIG_DEBUG_S3C_PORT is not set
|
||||
CONFIG_DEBUG_S3C_UART=0
|
||||
|
||||
#
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#
|
||||
# Automatically generated make config: don't edit
|
||||
# Linux kernel version: 2.6.30-rc6
|
||||
# Mon Jun 1 09:18:22 2009
|
||||
# Linux kernel version: 2.6.31-rc1
|
||||
# Thu Jul 2 00:16:59 2009
|
||||
#
|
||||
CONFIG_ARM=y
|
||||
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
|
||||
|
@ -9,7 +9,7 @@ CONFIG_GENERIC_GPIO=y
|
|||
CONFIG_GENERIC_TIME=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS=y
|
||||
CONFIG_MMU=y
|
||||
# CONFIG_NO_IOPORT is not set
|
||||
CONFIG_HAVE_TCM=y
|
||||
CONFIG_GENERIC_HARDIRQS=y
|
||||
CONFIG_STACKTRACE_SUPPORT=y
|
||||
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
|
||||
|
@ -18,13 +18,12 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
|
|||
CONFIG_HARDIRQS_SW_RESEND=y
|
||||
CONFIG_GENERIC_IRQ_PROBE=y
|
||||
CONFIG_RWSEM_GENERIC_SPINLOCK=y
|
||||
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
|
||||
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
|
||||
CONFIG_GENERIC_HWEIGHT=y
|
||||
CONFIG_GENERIC_CALIBRATE_DELAY=y
|
||||
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
|
||||
CONFIG_VECTORS_BASE=0xffff0000
|
||||
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
|
||||
CONFIG_CONSTRUCTORS=y
|
||||
|
||||
#
|
||||
# General setup
|
||||
|
@ -68,7 +67,6 @@ CONFIG_SYSCTL_SYSCALL=y
|
|||
CONFIG_KALLSYMS=y
|
||||
# CONFIG_KALLSYMS_ALL is not set
|
||||
# CONFIG_KALLSYMS_EXTRA_PASS is not set
|
||||
# CONFIG_STRIP_ASM_SYMS is not set
|
||||
CONFIG_HOTPLUG=y
|
||||
CONFIG_PRINTK=y
|
||||
CONFIG_BUG=y
|
||||
|
@ -81,8 +79,13 @@ CONFIG_TIMERFD=y
|
|||
CONFIG_EVENTFD=y
|
||||
CONFIG_SHMEM=y
|
||||
# CONFIG_AIO is not set
|
||||
|
||||
#
|
||||
# Performance Counters
|
||||
#
|
||||
# CONFIG_VM_EVENT_COUNTERS is not set
|
||||
CONFIG_SLUB_DEBUG=y
|
||||
# CONFIG_STRIP_ASM_SYMS is not set
|
||||
CONFIG_COMPAT_BRK=y
|
||||
# CONFIG_SLAB is not set
|
||||
CONFIG_SLUB=y
|
||||
|
@ -94,6 +97,10 @@ CONFIG_HAVE_OPROFILE=y
|
|||
CONFIG_HAVE_KPROBES=y
|
||||
CONFIG_HAVE_KRETPROBES=y
|
||||
CONFIG_HAVE_CLK=y
|
||||
|
||||
#
|
||||
# GCOV-based kernel profiling
|
||||
#
|
||||
# CONFIG_SLOW_WORK is not set
|
||||
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
|
||||
CONFIG_SLABINFO=y
|
||||
|
@ -106,7 +113,7 @@ CONFIG_MODULE_UNLOAD=y
|
|||
# CONFIG_MODVERSIONS is not set
|
||||
# CONFIG_MODULE_SRCVERSION_ALL is not set
|
||||
CONFIG_BLOCK=y
|
||||
# CONFIG_LBD is not set
|
||||
CONFIG_LBDAF=y
|
||||
# CONFIG_BLK_DEV_BSG is not set
|
||||
# CONFIG_BLK_DEV_INTEGRITY is not set
|
||||
|
||||
|
@ -138,9 +145,9 @@ CONFIG_DEFAULT_IOSCHED="deadline"
|
|||
# CONFIG_ARCH_EP93XX is not set
|
||||
# CONFIG_ARCH_FOOTBRIDGE is not set
|
||||
# CONFIG_ARCH_MXC is not set
|
||||
# CONFIG_ARCH_STMP3XXX is not set
|
||||
# CONFIG_ARCH_NETX is not set
|
||||
# CONFIG_ARCH_H720X is not set
|
||||
# CONFIG_ARCH_IMX is not set
|
||||
# CONFIG_ARCH_IOP13XX is not set
|
||||
# CONFIG_ARCH_IOP32X is not set
|
||||
# CONFIG_ARCH_IOP33X is not set
|
||||
|
@ -216,8 +223,8 @@ CONFIG_ARM_THUMB=y
|
|||
# CONFIG_CPU_DCACHE_DISABLE is not set
|
||||
# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
|
||||
# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
|
||||
# CONFIG_OUTER_CACHE is not set
|
||||
CONFIG_ARM_VIC=y
|
||||
CONFIG_ARM_VIC_NR=2
|
||||
CONFIG_COMMON_CLKDEV=y
|
||||
|
||||
#
|
||||
|
@ -243,7 +250,6 @@ CONFIG_PREEMPT=y
|
|||
CONFIG_HZ=100
|
||||
CONFIG_AEABI=y
|
||||
CONFIG_OABI_COMPAT=y
|
||||
CONFIG_ARCH_FLATMEM_HAS_HOLES=y
|
||||
# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
|
||||
# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
|
||||
# CONFIG_HIGHMEM is not set
|
||||
|
@ -258,17 +264,18 @@ CONFIG_SPLIT_PTLOCK_CPUS=4096
|
|||
# CONFIG_PHYS_ADDR_T_64BIT is not set
|
||||
CONFIG_ZONE_DMA_FLAG=0
|
||||
CONFIG_VIRT_TO_BUS=y
|
||||
CONFIG_UNEVICTABLE_LRU=y
|
||||
CONFIG_HAVE_MLOCK=y
|
||||
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
|
||||
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
|
||||
CONFIG_ALIGNMENT_TRAP=y
|
||||
# CONFIG_UACCESS_WITH_MEMCPY is not set
|
||||
|
||||
#
|
||||
# Boot options
|
||||
#
|
||||
CONFIG_ZBOOT_ROM_TEXT=0x0
|
||||
CONFIG_ZBOOT_ROM_BSS=0x0
|
||||
CONFIG_CMDLINE="root=/dev/mtdblock2 rw rootfstype=yaffs2 console=ttyAMA0,115200n8 ab3100.force=0,0x48 mtdparts=u300nand:128k@0x0(bootrecords)ro,8064k@128k(free)ro,253952k@8192k(platform) lpj=515072"
|
||||
CONFIG_CMDLINE="root=/dev/ram0 rw rootfstype=rootfs console=ttyAMA0,115200n8 lpj=515072"
|
||||
# CONFIG_XIP_KERNEL is not set
|
||||
# CONFIG_KEXEC is not set
|
||||
|
||||
|
@ -359,6 +366,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
|
|||
# CONFIG_ECONET is not set
|
||||
# CONFIG_WAN_ROUTER is not set
|
||||
# CONFIG_PHONET is not set
|
||||
# CONFIG_IEEE802154 is not set
|
||||
# CONFIG_NET_SCHED is not set
|
||||
# CONFIG_DCB is not set
|
||||
|
||||
|
@ -497,6 +505,7 @@ CONFIG_MISC_DEVICES=y
|
|||
# CONFIG_EEPROM_AT24 is not set
|
||||
# CONFIG_EEPROM_AT25 is not set
|
||||
# CONFIG_EEPROM_LEGACY is not set
|
||||
# CONFIG_EEPROM_MAX6875 is not set
|
||||
# CONFIG_EEPROM_93CX6 is not set
|
||||
CONFIG_HAVE_IDE=y
|
||||
# CONFIG_IDE is not set
|
||||
|
@ -538,6 +547,7 @@ CONFIG_INPUT_KEYBOARD=y
|
|||
# CONFIG_KEYBOARD_XTKBD is not set
|
||||
# CONFIG_KEYBOARD_NEWTON is not set
|
||||
# CONFIG_KEYBOARD_STOWAWAY is not set
|
||||
# CONFIG_KEYBOARD_LM8323 is not set
|
||||
# CONFIG_KEYBOARD_GPIO is not set
|
||||
# CONFIG_INPUT_MOUSE is not set
|
||||
# CONFIG_INPUT_JOYSTICK is not set
|
||||
|
@ -597,9 +607,11 @@ CONFIG_I2C_HELPER_AUTO=y
|
|||
#
|
||||
# I2C system bus drivers (mostly embedded / system-on-chip)
|
||||
#
|
||||
# CONFIG_I2C_DESIGNWARE is not set
|
||||
# CONFIG_I2C_GPIO is not set
|
||||
# CONFIG_I2C_OCORES is not set
|
||||
# CONFIG_I2C_SIMTEC is not set
|
||||
CONFIG_I2C_STU300=y
|
||||
|
||||
#
|
||||
# External I2C/SMBus adapter drivers
|
||||
|
@ -620,7 +632,6 @@ CONFIG_I2C_HELPER_AUTO=y
|
|||
# CONFIG_SENSORS_PCF8574 is not set
|
||||
# CONFIG_PCF8575 is not set
|
||||
# CONFIG_SENSORS_PCA9539 is not set
|
||||
# CONFIG_SENSORS_MAX6875 is not set
|
||||
# CONFIG_SENSORS_TSL2550 is not set
|
||||
# CONFIG_I2C_DEBUG_CORE is not set
|
||||
# CONFIG_I2C_DEBUG_ALGO is not set
|
||||
|
@ -635,6 +646,7 @@ CONFIG_SPI_MASTER=y
|
|||
#
|
||||
# CONFIG_SPI_BITBANG is not set
|
||||
# CONFIG_SPI_GPIO is not set
|
||||
CONFIG_SPI_PL022=y
|
||||
|
||||
#
|
||||
# SPI Protocol Masters
|
||||
|
@ -647,6 +659,7 @@ CONFIG_POWER_SUPPLY=y
|
|||
# CONFIG_PDA_POWER is not set
|
||||
# CONFIG_BATTERY_DS2760 is not set
|
||||
# CONFIG_BATTERY_BQ27x00 is not set
|
||||
# CONFIG_BATTERY_MAX17040 is not set
|
||||
# CONFIG_HWMON is not set
|
||||
# CONFIG_THERMAL is not set
|
||||
# CONFIG_THERMAL_HWMON is not set
|
||||
|
@ -657,6 +670,7 @@ CONFIG_WATCHDOG=y
|
|||
# Watchdog Device Drivers
|
||||
#
|
||||
# CONFIG_SOFT_WATCHDOG is not set
|
||||
CONFIG_COH901327_WATCHDOG=y
|
||||
CONFIG_SSB_POSSIBLE=y
|
||||
|
||||
#
|
||||
|
@ -678,22 +692,9 @@ CONFIG_SSB_POSSIBLE=y
|
|||
# CONFIG_MFD_WM8400 is not set
|
||||
# CONFIG_MFD_WM8350_I2C is not set
|
||||
# CONFIG_MFD_PCF50633 is not set
|
||||
|
||||
#
|
||||
# Multimedia devices
|
||||
#
|
||||
|
||||
#
|
||||
# Multimedia core support
|
||||
#
|
||||
# CONFIG_VIDEO_DEV is not set
|
||||
# CONFIG_DVB_CORE is not set
|
||||
# CONFIG_VIDEO_MEDIA is not set
|
||||
|
||||
#
|
||||
# Multimedia drivers
|
||||
#
|
||||
# CONFIG_DAB is not set
|
||||
CONFIG_AB3100_CORE=y
|
||||
# CONFIG_EZX_PCAP is not set
|
||||
# CONFIG_MEDIA_SUPPORT is not set
|
||||
|
||||
#
|
||||
# Graphics support
|
||||
|
@ -760,6 +761,11 @@ CONFIG_SND_JACK=y
|
|||
# CONFIG_SND_VERBOSE_PROCFS is not set
|
||||
# CONFIG_SND_VERBOSE_PRINTK is not set
|
||||
# CONFIG_SND_DEBUG is not set
|
||||
# CONFIG_SND_RAWMIDI_SEQ is not set
|
||||
# CONFIG_SND_OPL3_LIB_SEQ is not set
|
||||
# CONFIG_SND_OPL4_LIB_SEQ is not set
|
||||
# CONFIG_SND_SBAWE_SEQ is not set
|
||||
# CONFIG_SND_EMU10K1_SEQ is not set
|
||||
# CONFIG_SND_DRIVERS is not set
|
||||
# CONFIG_SND_ARM is not set
|
||||
# CONFIG_SND_SPI is not set
|
||||
|
@ -770,7 +776,7 @@ CONFIG_SND_SOC_I2C_AND_SPI=y
|
|||
# CONFIG_HID_SUPPORT is not set
|
||||
# CONFIG_USB_SUPPORT is not set
|
||||
CONFIG_MMC=y
|
||||
# CONFIG_MMC_DEBUG is not set
|
||||
CONFIG_MMC_DEBUG=y
|
||||
# CONFIG_MMC_UNSAFE_RESUME is not set
|
||||
|
||||
#
|
||||
|
@ -797,7 +803,7 @@ CONFIG_LEDS_CLASS=y
|
|||
#
|
||||
# CONFIG_LEDS_PCA9532 is not set
|
||||
# CONFIG_LEDS_GPIO is not set
|
||||
# CONFIG_LEDS_LP5521 is not set
|
||||
# CONFIG_LEDS_LP3944 is not set
|
||||
# CONFIG_LEDS_PCA955X is not set
|
||||
# CONFIG_LEDS_DAC124S085 is not set
|
||||
# CONFIG_LEDS_BD2802 is not set
|
||||
|
@ -845,6 +851,7 @@ CONFIG_RTC_INTF_DEV=y
|
|||
# CONFIG_RTC_DRV_S35390A is not set
|
||||
# CONFIG_RTC_DRV_FM3130 is not set
|
||||
# CONFIG_RTC_DRV_RX8581 is not set
|
||||
# CONFIG_RTC_DRV_RX8025 is not set
|
||||
|
||||
#
|
||||
# SPI RTC drivers
|
||||
|
@ -887,7 +894,10 @@ CONFIG_REGULATOR=y
|
|||
# CONFIG_REGULATOR_DEBUG is not set
|
||||
# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
|
||||
# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
|
||||
# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
|
||||
# CONFIG_REGULATOR_BQ24022 is not set
|
||||
# CONFIG_REGULATOR_MAX1586 is not set
|
||||
# CONFIG_REGULATOR_LP3971 is not set
|
||||
# CONFIG_UIO is not set
|
||||
# CONFIG_STAGING is not set
|
||||
|
||||
|
@ -900,16 +910,20 @@ CONFIG_REGULATOR=y
|
|||
# CONFIG_REISERFS_FS is not set
|
||||
# CONFIG_JFS_FS is not set
|
||||
# CONFIG_FS_POSIX_ACL is not set
|
||||
CONFIG_FILE_LOCKING=y
|
||||
# CONFIG_XFS_FS is not set
|
||||
# CONFIG_GFS2_FS is not set
|
||||
# CONFIG_OCFS2_FS is not set
|
||||
# CONFIG_BTRFS_FS is not set
|
||||
CONFIG_FILE_LOCKING=y
|
||||
CONFIG_FSNOTIFY=y
|
||||
# CONFIG_DNOTIFY is not set
|
||||
# CONFIG_INOTIFY is not set
|
||||
CONFIG_INOTIFY_USER=y
|
||||
# CONFIG_QUOTA is not set
|
||||
# CONFIG_AUTOFS_FS is not set
|
||||
# CONFIG_AUTOFS4_FS is not set
|
||||
CONFIG_FUSE_FS=y
|
||||
# CONFIG_CUSE is not set
|
||||
|
||||
#
|
||||
# Caches
|
||||
|
@ -1033,6 +1047,7 @@ CONFIG_TIMER_STATS=y
|
|||
# CONFIG_DEBUG_OBJECTS is not set
|
||||
# CONFIG_SLUB_DEBUG_ON is not set
|
||||
# CONFIG_SLUB_STATS is not set
|
||||
# CONFIG_DEBUG_KMEMLEAK is not set
|
||||
# CONFIG_DEBUG_PREEMPT is not set
|
||||
# CONFIG_DEBUG_RT_MUTEXES is not set
|
||||
# CONFIG_RT_MUTEX_TESTER is not set
|
||||
|
@ -1063,18 +1078,16 @@ CONFIG_DEBUG_INFO=y
|
|||
# CONFIG_PAGE_POISONING is not set
|
||||
CONFIG_HAVE_FUNCTION_TRACER=y
|
||||
CONFIG_TRACING_SUPPORT=y
|
||||
|
||||
#
|
||||
# Tracers
|
||||
#
|
||||
CONFIG_FTRACE=y
|
||||
# CONFIG_FUNCTION_TRACER is not set
|
||||
# CONFIG_IRQSOFF_TRACER is not set
|
||||
# CONFIG_PREEMPT_TRACER is not set
|
||||
# CONFIG_SCHED_TRACER is not set
|
||||
# CONFIG_CONTEXT_SWITCH_TRACER is not set
|
||||
# CONFIG_EVENT_TRACER is not set
|
||||
# CONFIG_ENABLE_DEFAULT_TRACERS is not set
|
||||
# CONFIG_BOOT_TRACER is not set
|
||||
# CONFIG_TRACE_BRANCH_PROFILING is not set
|
||||
CONFIG_BRANCH_PROFILE_NONE=y
|
||||
# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
|
||||
# CONFIG_PROFILE_ALL_BRANCHES is not set
|
||||
# CONFIG_STACK_TRACER is not set
|
||||
# CONFIG_KMEMTRACE is not set
|
||||
# CONFIG_WORKQUEUE_TRACER is not set
|
||||
|
@ -1109,6 +1122,7 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
|
|||
# CONFIG_CRC32 is not set
|
||||
# CONFIG_CRC7 is not set
|
||||
# CONFIG_LIBCRC32C is not set
|
||||
CONFIG_GENERIC_ALLOCATOR=y
|
||||
CONFIG_HAS_IOMEM=y
|
||||
CONFIG_HAS_IOPORT=y
|
||||
CONFIG_HAS_DMA=y
|
||||
|
|
|
@ -11,4 +11,38 @@ extern void mcount(void);
|
|||
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND)
|
||||
/*
|
||||
* return_address uses walk_stackframe to do it's work. If both
|
||||
* CONFIG_FRAME_POINTER=y and CONFIG_ARM_UNWIND=y walk_stackframe uses unwind
|
||||
* information. For this to work in the function tracer many functions would
|
||||
* have to be marked with __notrace. So for now just depend on
|
||||
* !CONFIG_ARM_UNWIND.
|
||||
*/
|
||||
|
||||
void *return_address(unsigned int);
|
||||
|
||||
#else
|
||||
|
||||
extern inline void *return_address(unsigned int level)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define HAVE_ARCH_CALLER_ADDR
|
||||
|
||||
#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
|
||||
#define CALLER_ADDR1 ((unsigned long)return_address(1))
|
||||
#define CALLER_ADDR2 ((unsigned long)return_address(2))
|
||||
#define CALLER_ADDR3 ((unsigned long)return_address(3))
|
||||
#define CALLER_ADDR4 ((unsigned long)return_address(4))
|
||||
#define CALLER_ADDR5 ((unsigned long)return_address(5))
|
||||
#define CALLER_ADDR6 ((unsigned long)return_address(6))
|
||||
|
||||
#endif /* ifndef __ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASM_ARM_FTRACE */
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
/* PAGE_SHIFT determines the page size */
|
||||
#define PAGE_SHIFT 12
|
||||
#define PAGE_SIZE (1UL << PAGE_SHIFT)
|
||||
#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
|
||||
#define PAGE_MASK (~(PAGE_SIZE-1))
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
|
|
@ -36,6 +36,8 @@ extern void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd);
|
|||
#define pgd_alloc(mm) get_pgd_slow(mm)
|
||||
#define pgd_free(mm, pgd) free_pgd_slow(mm, pgd)
|
||||
|
||||
#define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO)
|
||||
|
||||
/*
|
||||
* Allocate one PTE table.
|
||||
*
|
||||
|
@ -57,7 +59,7 @@ pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
|
|||
{
|
||||
pte_t *pte;
|
||||
|
||||
pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
|
||||
pte = (pte_t *)__get_free_page(PGALLOC_GFP);
|
||||
if (pte) {
|
||||
clean_dcache_area(pte, sizeof(pte_t) * PTRS_PER_PTE);
|
||||
pte += PTRS_PER_PTE;
|
||||
|
@ -71,10 +73,16 @@ pte_alloc_one(struct mm_struct *mm, unsigned long addr)
|
|||
{
|
||||
struct page *pte;
|
||||
|
||||
pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
|
||||
#ifdef CONFIG_HIGHPTE
|
||||
pte = alloc_pages(PGALLOC_GFP | __GFP_HIGHMEM, 0);
|
||||
#else
|
||||
pte = alloc_pages(PGALLOC_GFP, 0);
|
||||
#endif
|
||||
if (pte) {
|
||||
void *page = page_address(pte);
|
||||
clean_dcache_area(page, sizeof(pte_t) * PTRS_PER_PTE);
|
||||
if (!PageHighMem(pte)) {
|
||||
void *page = page_address(pte);
|
||||
clean_dcache_area(page, sizeof(pte_t) * PTRS_PER_PTE);
|
||||
}
|
||||
pgtable_page_ctor(pte);
|
||||
}
|
||||
|
||||
|
|
|
@ -162,10 +162,8 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
|
|||
* entries are stored 1024 bytes below.
|
||||
*/
|
||||
#define L_PTE_PRESENT (1 << 0)
|
||||
#define L_PTE_FILE (1 << 1) /* only when !PRESENT */
|
||||
#define L_PTE_YOUNG (1 << 1)
|
||||
#define L_PTE_BUFFERABLE (1 << 2) /* obsolete, matches PTE */
|
||||
#define L_PTE_CACHEABLE (1 << 3) /* obsolete, matches PTE */
|
||||
#define L_PTE_FILE (1 << 2) /* only when !PRESENT */
|
||||
#define L_PTE_DIRTY (1 << 6)
|
||||
#define L_PTE_WRITE (1 << 7)
|
||||
#define L_PTE_USER (1 << 8)
|
||||
|
@ -264,10 +262,19 @@ extern struct page *empty_zero_page;
|
|||
#define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0)
|
||||
#define pte_page(pte) (pfn_to_page(pte_pfn(pte)))
|
||||
#define pte_offset_kernel(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr))
|
||||
#define pte_offset_map(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr))
|
||||
#define pte_offset_map_nested(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr))
|
||||
#define pte_unmap(pte) do { } while (0)
|
||||
#define pte_unmap_nested(pte) do { } while (0)
|
||||
|
||||
#define pte_offset_map(dir,addr) (__pte_map(dir, KM_PTE0) + __pte_index(addr))
|
||||
#define pte_offset_map_nested(dir,addr) (__pte_map(dir, KM_PTE1) + __pte_index(addr))
|
||||
#define pte_unmap(pte) __pte_unmap(pte, KM_PTE0)
|
||||
#define pte_unmap_nested(pte) __pte_unmap(pte, KM_PTE1)
|
||||
|
||||
#ifndef CONFIG_HIGHPTE
|
||||
#define __pte_map(dir,km) pmd_page_vaddr(*(dir))
|
||||
#define __pte_unmap(pte,km) do { } while (0)
|
||||
#else
|
||||
#define __pte_map(dir,km) ((pte_t *)kmap_atomic(pmd_page(*(dir)), km) + PTRS_PER_PTE)
|
||||
#define __pte_unmap(pte,km) kunmap_atomic((pte - PTRS_PER_PTE), km)
|
||||
#endif
|
||||
|
||||
#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
|
||||
|
||||
|
@ -285,15 +292,6 @@ extern struct page *empty_zero_page;
|
|||
#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG)
|
||||
#define pte_special(pte) (0)
|
||||
|
||||
/*
|
||||
* The following only works if pte_present() is not true.
|
||||
*/
|
||||
#define pte_file(pte) (pte_val(pte) & L_PTE_FILE)
|
||||
#define pte_to_pgoff(x) (pte_val(x) >> 2)
|
||||
#define pgoff_to_pte(x) __pte(((x) << 2) | L_PTE_FILE)
|
||||
|
||||
#define PTE_FILE_MAX_BITS 30
|
||||
|
||||
#define PTE_BIT_FUNC(fn,op) \
|
||||
static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
|
||||
|
||||
|
@ -384,16 +382,50 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
|
|||
|
||||
extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
|
||||
|
||||
/* Encode and decode a swap entry.
|
||||
/*
|
||||
* Encode and decode a swap entry. Swap entries are stored in the Linux
|
||||
* page tables as follows:
|
||||
*
|
||||
* We support up to 32GB of swap on 4k machines
|
||||
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
|
||||
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
|
||||
* <--------------- offset --------------------> <- type --> 0 0 0
|
||||
*
|
||||
* This gives us up to 63 swap files and 32GB per swap file. Note that
|
||||
* the offset field is always non-zero.
|
||||
*/
|
||||
#define __swp_type(x) (((x).val >> 2) & 0x7f)
|
||||
#define __swp_offset(x) ((x).val >> 9)
|
||||
#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 9) })
|
||||
#define __SWP_TYPE_SHIFT 3
|
||||
#define __SWP_TYPE_BITS 6
|
||||
#define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1)
|
||||
#define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT)
|
||||
|
||||
#define __swp_type(x) (((x).val >> __SWP_TYPE_SHIFT) & __SWP_TYPE_MASK)
|
||||
#define __swp_offset(x) ((x).val >> __SWP_OFFSET_SHIFT)
|
||||
#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << __SWP_TYPE_SHIFT) | ((offset) << __SWP_OFFSET_SHIFT) })
|
||||
|
||||
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
|
||||
#define __swp_entry_to_pte(swp) ((pte_t) { (swp).val })
|
||||
|
||||
/*
|
||||
* It is an error for the kernel to have more swap files than we can
|
||||
* encode in the PTEs. This ensures that we know when MAX_SWAPFILES
|
||||
* is increased beyond what we presently support.
|
||||
*/
|
||||
#define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > __SWP_TYPE_BITS)
|
||||
|
||||
/*
|
||||
* Encode and decode a file entry. File entries are stored in the Linux
|
||||
* page tables as follows:
|
||||
*
|
||||
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
|
||||
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
|
||||
* <----------------------- offset ------------------------> 1 0 0
|
||||
*/
|
||||
#define pte_file(pte) (pte_val(pte) & L_PTE_FILE)
|
||||
#define pte_to_pgoff(x) (pte_val(x) >> 3)
|
||||
#define pgoff_to_pte(x) __pte(((x) << 3) | L_PTE_FILE)
|
||||
|
||||
#define PTE_FILE_MAX_BITS 29
|
||||
|
||||
/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
|
||||
/* FIXME: this is not correct */
|
||||
#define kern_addr_valid(addr) (1)
|
||||
|
|
|
@ -73,7 +73,7 @@ struct thread_info {
|
|||
.task = &tsk, \
|
||||
.exec_domain = &default_exec_domain, \
|
||||
.flags = 0, \
|
||||
.preempt_count = 1, \
|
||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||
.addr_limit = KERNEL_DS, \
|
||||
.cpu_domain = domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
|
||||
domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
|
||||
|
@ -140,6 +140,7 @@ extern void vfp_sync_state(struct thread_info *thread);
|
|||
#define TIF_USING_IWMMXT 17
|
||||
#define TIF_MEMDIE 18
|
||||
#define TIF_FREEZE 19
|
||||
#define TIF_RESTORE_SIGMASK 20
|
||||
|
||||
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
|
||||
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
|
||||
|
@ -147,6 +148,7 @@ extern void vfp_sync_state(struct thread_info *thread);
|
|||
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
|
||||
#define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT)
|
||||
#define _TIF_FREEZE (1 << TIF_FREEZE)
|
||||
#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
|
||||
|
||||
/*
|
||||
* Change these and you break ASM code in entry-common.S
|
||||
|
|
|
@ -360,8 +360,8 @@
|
|||
#define __NR_readlinkat (__NR_SYSCALL_BASE+332)
|
||||
#define __NR_fchmodat (__NR_SYSCALL_BASE+333)
|
||||
#define __NR_faccessat (__NR_SYSCALL_BASE+334)
|
||||
/* 335 for pselect6 */
|
||||
/* 336 for ppoll */
|
||||
#define __NR_pselect6 (__NR_SYSCALL_BASE+335)
|
||||
#define __NR_ppoll (__NR_SYSCALL_BASE+336)
|
||||
#define __NR_unshare (__NR_SYSCALL_BASE+337)
|
||||
#define __NR_set_robust_list (__NR_SYSCALL_BASE+338)
|
||||
#define __NR_get_robust_list (__NR_SYSCALL_BASE+339)
|
||||
|
@ -372,7 +372,7 @@
|
|||
#define __NR_vmsplice (__NR_SYSCALL_BASE+343)
|
||||
#define __NR_move_pages (__NR_SYSCALL_BASE+344)
|
||||
#define __NR_getcpu (__NR_SYSCALL_BASE+345)
|
||||
/* 346 for epoll_pwait */
|
||||
#define __NR_epoll_pwait (__NR_SYSCALL_BASE+346)
|
||||
#define __NR_kexec_load (__NR_SYSCALL_BASE+347)
|
||||
#define __NR_utimensat (__NR_SYSCALL_BASE+348)
|
||||
#define __NR_signalfd (__NR_SYSCALL_BASE+349)
|
||||
|
@ -432,6 +432,7 @@
|
|||
#define __ARCH_WANT_SYS_SIGPENDING
|
||||
#define __ARCH_WANT_SYS_SIGPROCMASK
|
||||
#define __ARCH_WANT_SYS_RT_SIGACTION
|
||||
#define __ARCH_WANT_SYS_RT_SIGSUSPEND
|
||||
|
||||
#if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT)
|
||||
#define __ARCH_WANT_SYS_TIME
|
||||
|
|
|
@ -8,10 +8,12 @@ ifdef CONFIG_DYNAMIC_FTRACE
|
|||
CFLAGS_REMOVE_ftrace.o = -pg
|
||||
endif
|
||||
|
||||
CFLAGS_REMOVE_return_address.o = -pg
|
||||
|
||||
# Object file lists.
|
||||
|
||||
obj-y := compat.o elf.o entry-armv.o entry-common.o irq.o \
|
||||
process.o ptrace.o setup.o signal.o \
|
||||
process.o ptrace.o return_address.o setup.o signal.o \
|
||||
sys_arm.o stacktrace.o time.o traps.o
|
||||
|
||||
obj-$(CONFIG_ISA_DMA_API) += dma.o
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
CALL(sys_ni_syscall) /* was sys_ssetmask */
|
||||
/* 70 */ CALL(sys_setreuid16)
|
||||
CALL(sys_setregid16)
|
||||
CALL(sys_sigsuspend_wrapper)
|
||||
CALL(sys_sigsuspend)
|
||||
CALL(sys_sigpending)
|
||||
CALL(sys_sethostname)
|
||||
/* 75 */ CALL(sys_setrlimit)
|
||||
|
@ -188,7 +188,7 @@
|
|||
CALL(sys_rt_sigpending)
|
||||
CALL(sys_rt_sigtimedwait)
|
||||
CALL(sys_rt_sigqueueinfo)
|
||||
CALL(sys_rt_sigsuspend_wrapper)
|
||||
CALL(sys_rt_sigsuspend)
|
||||
/* 180 */ CALL(ABI(sys_pread64, sys_oabi_pread64))
|
||||
CALL(ABI(sys_pwrite64, sys_oabi_pwrite64))
|
||||
CALL(sys_chown16)
|
||||
|
@ -344,8 +344,8 @@
|
|||
CALL(sys_readlinkat)
|
||||
CALL(sys_fchmodat)
|
||||
CALL(sys_faccessat)
|
||||
/* 335 */ CALL(sys_ni_syscall) /* eventually pselect6 */
|
||||
CALL(sys_ni_syscall) /* eventually ppoll */
|
||||
/* 335 */ CALL(sys_pselect6)
|
||||
CALL(sys_ppoll)
|
||||
CALL(sys_unshare)
|
||||
CALL(sys_set_robust_list)
|
||||
CALL(sys_get_robust_list)
|
||||
|
@ -355,7 +355,7 @@
|
|||
CALL(sys_vmsplice)
|
||||
CALL(sys_move_pages)
|
||||
/* 345 */ CALL(sys_getcpu)
|
||||
CALL(sys_ni_syscall) /* eventually epoll_pwait */
|
||||
CALL(sys_epoll_pwait)
|
||||
CALL(sys_kexec_load)
|
||||
CALL(sys_utimensat)
|
||||
CALL(sys_signalfd)
|
||||
|
|
|
@ -31,7 +31,7 @@ void crunch_task_release(struct thread_info *thread)
|
|||
|
||||
static int crunch_enabled(u32 devcfg)
|
||||
{
|
||||
return !!(devcfg & EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE);
|
||||
return !!(devcfg & EP93XX_SYSCON_DEVCFG_CPENA);
|
||||
}
|
||||
|
||||
static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t)
|
||||
|
@ -56,11 +56,16 @@ static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t)
|
|||
break;
|
||||
|
||||
case THREAD_NOTIFY_SWITCH:
|
||||
devcfg = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG);
|
||||
devcfg = __raw_readl(EP93XX_SYSCON_DEVCFG);
|
||||
if (crunch_enabled(devcfg) || crunch_owner == crunch_state) {
|
||||
devcfg ^= EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE;
|
||||
/*
|
||||
* We don't use ep93xx_syscon_swlocked_write() here
|
||||
* because we are on the context switch path and
|
||||
* preemption is already disabled.
|
||||
*/
|
||||
devcfg ^= EP93XX_SYSCON_DEVCFG_CPENA;
|
||||
__raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
|
||||
__raw_writel(devcfg, EP93XX_SYSCON_DEVICE_CONFIG);
|
||||
__raw_writel(devcfg, EP93XX_SYSCON_DEVCFG);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -373,16 +373,6 @@ sys_clone_wrapper:
|
|||
b sys_clone
|
||||
ENDPROC(sys_clone_wrapper)
|
||||
|
||||
sys_sigsuspend_wrapper:
|
||||
add r3, sp, #S_OFF
|
||||
b sys_sigsuspend
|
||||
ENDPROC(sys_sigsuspend_wrapper)
|
||||
|
||||
sys_rt_sigsuspend_wrapper:
|
||||
add r2, sp, #S_OFF
|
||||
b sys_rt_sigsuspend
|
||||
ENDPROC(sys_rt_sigsuspend_wrapper)
|
||||
|
||||
sys_sigreturn_wrapper:
|
||||
add r0, sp, #S_OFF
|
||||
b sys_sigreturn
|
||||
|
|
|
@ -98,17 +98,6 @@ int show_interrupts(struct seq_file *p, void *v)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Handle bad interrupts */
|
||||
static struct irq_desc bad_irq_desc = {
|
||||
.handle_irq = handle_bad_irq,
|
||||
.lock = __SPIN_LOCK_UNLOCKED(bad_irq_desc.lock),
|
||||
};
|
||||
|
||||
#ifdef CONFIG_CPUMASK_OFFSTACK
|
||||
/* We are not allocating bad_irq_desc.affinity or .pending_mask */
|
||||
#error "ARM architecture does not support CONFIG_CPUMASK_OFFSTACK."
|
||||
#endif
|
||||
|
||||
/*
|
||||
* do_IRQ handles all hardware IRQ's. Decoded IRQs should not
|
||||
* come via this function. Instead, they should provide their
|
||||
|
@ -124,10 +113,13 @@ asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
|
|||
* Some hardware gives randomly wrong interrupts. Rather
|
||||
* than crashing, do something sensible.
|
||||
*/
|
||||
if (irq >= NR_IRQS)
|
||||
handle_bad_irq(irq, &bad_irq_desc);
|
||||
else
|
||||
if (unlikely(irq >= NR_IRQS)) {
|
||||
if (printk_ratelimit())
|
||||
printk(KERN_WARNING "Bad IRQ%u\n", irq);
|
||||
ack_bad_irq(irq);
|
||||
} else {
|
||||
generic_handle_irq(irq);
|
||||
}
|
||||
|
||||
/* AT91 specific workaround */
|
||||
irq_finish(irq);
|
||||
|
@ -165,10 +157,6 @@ void __init init_IRQ(void)
|
|||
for (irq = 0; irq < NR_IRQS; irq++)
|
||||
irq_desc[irq].status |= IRQ_NOREQUEST | IRQ_NOPROBE;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
cpumask_setall(bad_irq_desc.affinity);
|
||||
bad_irq_desc.node = smp_processor_id();
|
||||
#endif
|
||||
init_arch_irq();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* arch/arm/kernel/return_address.c
|
||||
*
|
||||
* Copyright (C) 2009 Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
|
||||
* for Pengutronix
|
||||
*
|
||||
* 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/module.h>
|
||||
|
||||
#if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND)
|
||||
#include <linux/sched.h>
|
||||
|
||||
#include <asm/stacktrace.h>
|
||||
|
||||
struct return_address_data {
|
||||
unsigned int level;
|
||||
void *addr;
|
||||
};
|
||||
|
||||
static int save_return_addr(struct stackframe *frame, void *d)
|
||||
{
|
||||
struct return_address_data *data = d;
|
||||
|
||||
if (!data->level) {
|
||||
data->addr = (void *)frame->lr;
|
||||
|
||||
return 1;
|
||||
} else {
|
||||
--data->level;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void *return_address(unsigned int level)
|
||||
{
|
||||
struct return_address_data data;
|
||||
struct stackframe frame;
|
||||
register unsigned long current_sp asm ("sp");
|
||||
|
||||
data.level = level + 1;
|
||||
|
||||
frame.fp = (unsigned long)__builtin_frame_address(0);
|
||||
frame.sp = current_sp;
|
||||
frame.lr = (unsigned long)__builtin_return_address(0);
|
||||
frame.pc = (unsigned long)return_address;
|
||||
|
||||
walk_stackframe(&frame, save_return_addr, &data);
|
||||
|
||||
if (!data.level)
|
||||
return data.addr;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else /* if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) */
|
||||
|
||||
#if defined(CONFIG_ARM_UNWIND)
|
||||
#warning "TODO: return_address should use unwind tables"
|
||||
#endif
|
||||
|
||||
void *return_address(unsigned int level)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) / else */
|
||||
|
||||
EXPORT_SYMBOL_GPL(return_address);
|
|
@ -47,57 +47,22 @@ const unsigned long sigreturn_codes[7] = {
|
|||
MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN,
|
||||
};
|
||||
|
||||
static int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall);
|
||||
|
||||
/*
|
||||
* atomically swap in the new signal mask, and wait for a signal.
|
||||
*/
|
||||
asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask, struct pt_regs *regs)
|
||||
asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask)
|
||||
{
|
||||
sigset_t saveset;
|
||||
|
||||
mask &= _BLOCKABLE;
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
saveset = current->blocked;
|
||||
current->saved_sigmask = current->blocked;
|
||||
siginitset(¤t->blocked, mask);
|
||||
recalc_sigpending();
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
regs->ARM_r0 = -EINTR;
|
||||
|
||||
while (1) {
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
if (do_signal(&saveset, regs, 0))
|
||||
return regs->ARM_r0;
|
||||
}
|
||||
}
|
||||
|
||||
asmlinkage int
|
||||
sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *regs)
|
||||
{
|
||||
sigset_t saveset, newset;
|
||||
|
||||
/* XXX: Don't preclude handling different sized sigset_t's. */
|
||||
if (sigsetsize != sizeof(sigset_t))
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(&newset, unewset, sizeof(newset)))
|
||||
return -EFAULT;
|
||||
sigdelsetmask(&newset, ~_BLOCKABLE);
|
||||
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
saveset = current->blocked;
|
||||
current->blocked = newset;
|
||||
recalc_sigpending();
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
regs->ARM_r0 = -EINTR;
|
||||
|
||||
while (1) {
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
if (do_signal(&saveset, regs, 0))
|
||||
return regs->ARM_r0;
|
||||
}
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
set_restore_sigmask();
|
||||
return -ERESTARTNOHAND;
|
||||
}
|
||||
|
||||
asmlinkage int
|
||||
|
@ -545,7 +510,7 @@ static inline void setup_syscall_restart(struct pt_regs *regs)
|
|||
/*
|
||||
* OK, we're invoking a handler
|
||||
*/
|
||||
static void
|
||||
static int
|
||||
handle_signal(unsigned long sig, struct k_sigaction *ka,
|
||||
siginfo_t *info, sigset_t *oldset,
|
||||
struct pt_regs * regs, int syscall)
|
||||
|
@ -596,7 +561,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
|
|||
|
||||
if (ret != 0) {
|
||||
force_sigsegv(sig, tsk);
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -610,6 +575,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
|
|||
recalc_sigpending();
|
||||
spin_unlock_irq(&tsk->sighand->siglock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -621,7 +587,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
|
|||
* the kernel can handle, and then we build all the user-level signal handling
|
||||
* stack-frames in one go after that.
|
||||
*/
|
||||
static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
|
||||
static void do_signal(struct pt_regs *regs, int syscall)
|
||||
{
|
||||
struct k_sigaction ka;
|
||||
siginfo_t info;
|
||||
|
@ -634,7 +600,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
|
|||
* if so.
|
||||
*/
|
||||
if (!user_mode(regs))
|
||||
return 0;
|
||||
return;
|
||||
|
||||
if (try_to_freeze())
|
||||
goto no_signal;
|
||||
|
@ -643,9 +609,24 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
|
|||
|
||||
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
|
||||
if (signr > 0) {
|
||||
handle_signal(signr, &ka, &info, oldset, regs, syscall);
|
||||
sigset_t *oldset;
|
||||
|
||||
if (test_thread_flag(TIF_RESTORE_SIGMASK))
|
||||
oldset = ¤t->saved_sigmask;
|
||||
else
|
||||
oldset = ¤t->blocked;
|
||||
if (handle_signal(signr, &ka, &info, oldset, regs, syscall) == 0) {
|
||||
/*
|
||||
* A signal was successfully delivered; the saved
|
||||
* sigmask will have been stored in the signal frame,
|
||||
* and will be restored by sigreturn, so we can simply
|
||||
* clear the TIF_RESTORE_SIGMASK flag.
|
||||
*/
|
||||
if (test_thread_flag(TIF_RESTORE_SIGMASK))
|
||||
clear_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
}
|
||||
single_step_set(current);
|
||||
return 1;
|
||||
return;
|
||||
}
|
||||
|
||||
no_signal:
|
||||
|
@ -697,14 +678,21 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
|
|||
regs->ARM_r0 == -ERESTARTNOINTR) {
|
||||
setup_syscall_restart(regs);
|
||||
}
|
||||
|
||||
/* If there's no signal to deliver, we just put the saved sigmask
|
||||
* back.
|
||||
*/
|
||||
if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
|
||||
clear_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL);
|
||||
}
|
||||
}
|
||||
single_step_set(current);
|
||||
return 0;
|
||||
}
|
||||
|
||||
asmlinkage void
|
||||
do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall)
|
||||
{
|
||||
if (thread_flags & _TIF_SIGPENDING)
|
||||
do_signal(¤t->blocked, regs, syscall);
|
||||
do_signal(regs, syscall);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
* Note that with framepointer enabled, even the leaf functions have the same
|
||||
* prologue and epilogue, therefore we can ignore the LR value in this case.
|
||||
*/
|
||||
int unwind_frame(struct stackframe *frame)
|
||||
int notrace unwind_frame(struct stackframe *frame)
|
||||
{
|
||||
unsigned long high, low;
|
||||
unsigned long fp = frame->fp;
|
||||
|
@ -43,7 +43,7 @@ int unwind_frame(struct stackframe *frame)
|
|||
}
|
||||
#endif
|
||||
|
||||
void walk_stackframe(struct stackframe *frame,
|
||||
void notrace walk_stackframe(struct stackframe *frame,
|
||||
int (*fn)(struct stackframe *, void *), void *data)
|
||||
{
|
||||
while (1) {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <asm-generic/vmlinux.lds.h>
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm/memory.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(stext)
|
||||
|
@ -63,7 +64,7 @@ SECTIONS
|
|||
usr/built-in.o(.init.ramfs)
|
||||
__initramfs_end = .;
|
||||
#endif
|
||||
. = ALIGN(4096);
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
__per_cpu_load = .;
|
||||
__per_cpu_start = .;
|
||||
*(.data.percpu.page_aligned)
|
||||
|
@ -73,7 +74,7 @@ SECTIONS
|
|||
#ifndef CONFIG_XIP_KERNEL
|
||||
__init_begin = _stext;
|
||||
INIT_DATA
|
||||
. = ALIGN(4096);
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
__init_end = .;
|
||||
#endif
|
||||
}
|
||||
|
@ -118,7 +119,7 @@ SECTIONS
|
|||
*(.got) /* Global offset table */
|
||||
}
|
||||
|
||||
RODATA
|
||||
RO_DATA(PAGE_SIZE)
|
||||
|
||||
_etext = .; /* End of text and rodata section */
|
||||
|
||||
|
@ -158,17 +159,17 @@ SECTIONS
|
|||
*(.data.init_task)
|
||||
|
||||
#ifdef CONFIG_XIP_KERNEL
|
||||
. = ALIGN(4096);
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
__init_begin = .;
|
||||
INIT_DATA
|
||||
. = ALIGN(4096);
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
__init_end = .;
|
||||
#endif
|
||||
|
||||
. = ALIGN(4096);
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
__nosave_begin = .;
|
||||
*(.data.nosave)
|
||||
. = ALIGN(4096);
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
__nosave_end = .;
|
||||
|
||||
/*
|
||||
|
|
|
@ -23,6 +23,12 @@ config ARCH_AT91SAM9261
|
|||
select GENERIC_TIME
|
||||
select GENERIC_CLOCKEVENTS
|
||||
|
||||
config ARCH_AT91SAM9G10
|
||||
bool "AT91SAM9G10"
|
||||
select CPU_ARM926T
|
||||
select GENERIC_TIME
|
||||
select GENERIC_CLOCKEVENTS
|
||||
|
||||
config ARCH_AT91SAM9263
|
||||
bool "AT91SAM9263"
|
||||
select CPU_ARM926T
|
||||
|
@ -41,6 +47,12 @@ config ARCH_AT91SAM9G20
|
|||
select GENERIC_TIME
|
||||
select GENERIC_CLOCKEVENTS
|
||||
|
||||
config ARCH_AT91SAM9G45
|
||||
bool "AT91SAM9G45"
|
||||
select CPU_ARM926T
|
||||
select GENERIC_TIME
|
||||
select GENERIC_CLOCKEVENTS
|
||||
|
||||
config ARCH_AT91CAP9
|
||||
bool "AT91CAP9"
|
||||
select CPU_ARM926T
|
||||
|
@ -144,6 +156,13 @@ config MACH_YL9200
|
|||
help
|
||||
Select this if you are using the ucDragon YL-9200 board.
|
||||
|
||||
config MACH_CPUAT91
|
||||
bool "Eukrea CPUAT91"
|
||||
depends on ARCH_AT91RM9200
|
||||
help
|
||||
Select this if you are using the Eukrea Electromatique's
|
||||
CPUAT91 board <http://www.eukrea.com/>.
|
||||
|
||||
endif
|
||||
|
||||
# ----------------------------------------------------------
|
||||
|
@ -205,6 +224,13 @@ config MACH_QIL_A9260
|
|||
Select this if you are using a Calao Systems QIL-A9260 Board.
|
||||
<http://www.calao-systems.com>
|
||||
|
||||
config MACH_CPU9260
|
||||
bool "Eukrea CPU9260 board"
|
||||
depends on ARCH_AT91SAM9260
|
||||
help
|
||||
Select this if you are using a Eukrea Electromatique's
|
||||
CPU9260 Board <http://www.eukrea.com/>
|
||||
|
||||
endif
|
||||
|
||||
# ----------------------------------------------------------
|
||||
|
@ -224,6 +250,21 @@ endif
|
|||
|
||||
# ----------------------------------------------------------
|
||||
|
||||
if ARCH_AT91SAM9G10
|
||||
|
||||
comment "AT91SAM9G10 Board Type"
|
||||
|
||||
config MACH_AT91SAM9G10EK
|
||||
bool "Atmel AT91SAM9G10-EK Evaluation Kit"
|
||||
depends on ARCH_AT91SAM9G10
|
||||
help
|
||||
Select this if you are using Atmel's AT91SAM9G10-EK Evaluation Kit.
|
||||
<http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4588>
|
||||
|
||||
endif
|
||||
|
||||
# ----------------------------------------------------------
|
||||
|
||||
if ARCH_AT91SAM9263
|
||||
|
||||
comment "AT91SAM9263 Board Type"
|
||||
|
@ -276,6 +317,29 @@ config MACH_AT91SAM9G20EK
|
|||
help
|
||||
Select this if you are using Atmel's AT91SAM9G20-EK Evaluation Kit.
|
||||
|
||||
config MACH_CPU9G20
|
||||
bool "Eukrea CPU9G20 board"
|
||||
depends on ARCH_AT91SAM9G20
|
||||
help
|
||||
Select this if you are using a Eukrea Electromatique's
|
||||
CPU9G20 Board <http://www.eukrea.com/>
|
||||
|
||||
endif
|
||||
|
||||
# ----------------------------------------------------------
|
||||
|
||||
if ARCH_AT91SAM9G45
|
||||
|
||||
comment "AT91SAM9G45 Board Type"
|
||||
|
||||
config MACH_AT91SAM9G45EKES
|
||||
bool "Atmel AT91SAM9G45-EKES Evaluation Kit"
|
||||
depends on ARCH_AT91SAM9G45
|
||||
help
|
||||
Select this if you are using Atmel's AT91SAM9G45-EKES Evaluation Kit.
|
||||
"ES" at the end of the name means that this board is an
|
||||
Engineering Sample.
|
||||
|
||||
endif
|
||||
|
||||
# ----------------------------------------------------------
|
||||
|
@ -315,13 +379,13 @@ comment "AT91 Board Options"
|
|||
|
||||
config MTD_AT91_DATAFLASH_CARD
|
||||
bool "Enable DataFlash Card support"
|
||||
depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_ECBAT91 || MACH_SAM9_L9260 || MACH_AT91CAP9ADK || MACH_NEOCORE926)
|
||||
depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_ECBAT91 || MACH_SAM9_L9260 || MACH_AT91CAP9ADK || MACH_NEOCORE926)
|
||||
help
|
||||
Enable support for the DataFlash card.
|
||||
|
||||
config MTD_NAND_ATMEL_BUSWIDTH_16
|
||||
bool "Enable 16-bit data bus interface to NAND flash"
|
||||
depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_AT91CAP9ADK)
|
||||
depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_AT91SAM9G45EKES || MACH_AT91CAP9ADK)
|
||||
help
|
||||
On AT91SAM926x boards both types of NAND flash can be present
|
||||
(8 and 16 bit data bus width).
|
||||
|
@ -383,7 +447,7 @@ config AT91_EARLY_USART2
|
|||
|
||||
config AT91_EARLY_USART3
|
||||
bool "USART3"
|
||||
depends on (ARCH_AT91RM9200 || ARCH_AT91SAM9RL || ARCH_AT91SAM9260 || ARCH_AT91SAM9G20)
|
||||
depends on (ARCH_AT91RM9200 || ARCH_AT91SAM9RL || ARCH_AT91SAM9260 || ARCH_AT91SAM9G20 || ARCH_AT91SAM9G45)
|
||||
|
||||
config AT91_EARLY_USART4
|
||||
bool "USART4"
|
||||
|
|
|
@ -13,9 +13,11 @@ obj-$(CONFIG_AT91_PMC_UNIT) += clock.o
|
|||
obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.o
|
||||
obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o
|
||||
obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o
|
||||
obj-$(CONFIG_ARCH_AT91SAM9G10) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o
|
||||
obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o
|
||||
obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o
|
||||
obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o
|
||||
obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
|
||||
obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o
|
||||
obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o
|
||||
|
||||
|
@ -32,6 +34,7 @@ obj-$(CONFIG_MACH_KAFA) += board-kafa.o
|
|||
obj-$(CONFIG_MACH_PICOTUX2XX) += board-picotux200.o
|
||||
obj-$(CONFIG_MACH_ECBAT91) += board-ecbat91.o
|
||||
obj-$(CONFIG_MACH_YL9200) += board-yl-9200.o
|
||||
obj-$(CONFIG_MACH_CPUAT91) += board-cpuat91.o
|
||||
|
||||
# AT91SAM9260 board-specific support
|
||||
obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o
|
||||
|
@ -40,9 +43,11 @@ obj-$(CONFIG_MACH_SAM9_L9260) += board-sam9-l9260.o
|
|||
obj-$(CONFIG_MACH_USB_A9260) += board-usb-a9260.o
|
||||
obj-$(CONFIG_MACH_QIL_A9260) += board-qil-a9260.o
|
||||
obj-$(CONFIG_MACH_AFEB9260) += board-afeb-9260v1.o
|
||||
obj-$(CONFIG_MACH_CPU9260) += board-cpu9krea.o
|
||||
|
||||
# AT91SAM9261 board-specific support
|
||||
obj-$(CONFIG_MACH_AT91SAM9261EK) += board-sam9261ek.o
|
||||
obj-$(CONFIG_MACH_AT91SAM9G10EK) += board-sam9261ek.o
|
||||
|
||||
# AT91SAM9263 board-specific support
|
||||
obj-$(CONFIG_MACH_AT91SAM9263EK) += board-sam9263ek.o
|
||||
|
@ -54,6 +59,10 @@ obj-$(CONFIG_MACH_AT91SAM9RLEK) += board-sam9rlek.o
|
|||
|
||||
# AT91SAM9G20 board-specific support
|
||||
obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o
|
||||
obj-$(CONFIG_MACH_CPU9G20) += board-cpu9krea.o
|
||||
|
||||
# AT91SAM9G45 board-specific support
|
||||
obj-$(CONFIG_MACH_AT91SAM9G45EKES) += board-sam9m10g45ek.o
|
||||
|
||||
# AT91CAP9 board-specific support
|
||||
obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o
|
||||
|
|
|
@ -7,6 +7,10 @@ ifeq ($(CONFIG_ARCH_AT91CAP9),y)
|
|||
zreladdr-y := 0x70008000
|
||||
params_phys-y := 0x70000100
|
||||
initrd_phys-y := 0x70410000
|
||||
else ifeq ($(CONFIG_ARCH_AT91SAM9G45),y)
|
||||
zreladdr-y := 0x70008000
|
||||
params_phys-y := 0x70000100
|
||||
initrd_phys-y := 0x70410000
|
||||
else
|
||||
zreladdr-y := 0x20008000
|
||||
params_phys-y := 0x20000100
|
||||
|
|
|
@ -1113,6 +1113,122 @@ void __init at91_set_serial_console(unsigned portnr) {}
|
|||
void __init at91_add_device_serial(void) {}
|
||||
#endif
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* CF/IDE
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#if defined(CONFIG_BLK_DEV_IDE_AT91) || defined(CONFIG_BLK_DEV_IDE_AT91_MODULE) || \
|
||||
defined(CONFIG_PATA_AT91) || defined(CONFIG_PATA_AT91_MODULE) || \
|
||||
defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE)
|
||||
|
||||
static struct at91_cf_data cf0_data;
|
||||
|
||||
static struct resource cf0_resources[] = {
|
||||
[0] = {
|
||||
.start = AT91_CHIPSELECT_4,
|
||||
.end = AT91_CHIPSELECT_4 + SZ_256M - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device cf0_device = {
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &cf0_data,
|
||||
},
|
||||
.resource = cf0_resources,
|
||||
.num_resources = ARRAY_SIZE(cf0_resources),
|
||||
};
|
||||
|
||||
static struct at91_cf_data cf1_data;
|
||||
|
||||
static struct resource cf1_resources[] = {
|
||||
[0] = {
|
||||
.start = AT91_CHIPSELECT_5,
|
||||
.end = AT91_CHIPSELECT_5 + SZ_256M - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device cf1_device = {
|
||||
.id = 1,
|
||||
.dev = {
|
||||
.platform_data = &cf1_data,
|
||||
},
|
||||
.resource = cf1_resources,
|
||||
.num_resources = ARRAY_SIZE(cf1_resources),
|
||||
};
|
||||
|
||||
void __init at91_add_device_cf(struct at91_cf_data *data)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
unsigned long csa;
|
||||
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
csa = at91_sys_read(AT91_MATRIX_EBICSA);
|
||||
|
||||
switch (data->chipselect) {
|
||||
case 4:
|
||||
at91_set_multi_drive(AT91_PIN_PC8, 0);
|
||||
at91_set_A_periph(AT91_PIN_PC8, 0);
|
||||
csa |= AT91_MATRIX_CS4A_SMC_CF1;
|
||||
cf0_data = *data;
|
||||
pdev = &cf0_device;
|
||||
break;
|
||||
case 5:
|
||||
at91_set_multi_drive(AT91_PIN_PC9, 0);
|
||||
at91_set_A_periph(AT91_PIN_PC9, 0);
|
||||
csa |= AT91_MATRIX_CS5A_SMC_CF2;
|
||||
cf1_data = *data;
|
||||
pdev = &cf1_device;
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR "AT91 CF: bad chip-select requested (%u)\n",
|
||||
data->chipselect);
|
||||
return;
|
||||
}
|
||||
|
||||
at91_sys_write(AT91_MATRIX_EBICSA, csa);
|
||||
|
||||
if (data->rst_pin) {
|
||||
at91_set_multi_drive(data->rst_pin, 0);
|
||||
at91_set_gpio_output(data->rst_pin, 1);
|
||||
}
|
||||
|
||||
if (data->irq_pin) {
|
||||
at91_set_gpio_input(data->irq_pin, 0);
|
||||
at91_set_deglitch(data->irq_pin, 1);
|
||||
}
|
||||
|
||||
if (data->det_pin) {
|
||||
at91_set_gpio_input(data->det_pin, 0);
|
||||
at91_set_deglitch(data->det_pin, 1);
|
||||
}
|
||||
|
||||
at91_set_B_periph(AT91_PIN_PC6, 0); /* CFCE1 */
|
||||
at91_set_B_periph(AT91_PIN_PC7, 0); /* CFCE2 */
|
||||
at91_set_A_periph(AT91_PIN_PC10, 0); /* CFRNW */
|
||||
at91_set_A_periph(AT91_PIN_PC15, 1); /* NWAIT */
|
||||
|
||||
if (data->flags & AT91_CF_TRUE_IDE)
|
||||
#if defined(CONFIG_PATA_AT91) || defined(CONFIG_PATA_AT91_MODULE)
|
||||
pdev->name = "pata_at91";
|
||||
#elif defined(CONFIG_BLK_DEV_IDE_AT91) || defined(CONFIG_BLK_DEV_IDE_AT91_MODULE)
|
||||
pdev->name = "at91_ide";
|
||||
#else
|
||||
#warning "board requires AT91_CF_TRUE_IDE: enable either at91_ide or pata_at91"
|
||||
#endif
|
||||
else
|
||||
pdev->name = "at91_cf";
|
||||
|
||||
platform_device_register(pdev);
|
||||
}
|
||||
|
||||
#else
|
||||
void __init at91_add_device_cf(struct at91_cf_data * data) {}
|
||||
#endif
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/*
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <asm/irq.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <mach/cpu.h>
|
||||
#include <mach/at91sam9261.h>
|
||||
#include <mach/at91_pmc.h>
|
||||
#include <mach/at91_rstc.h>
|
||||
|
@ -30,7 +31,11 @@ static struct map_desc at91sam9261_io_desc[] __initdata = {
|
|||
.pfn = __phys_to_pfn(AT91_BASE_SYS),
|
||||
.length = SZ_16K,
|
||||
.type = MT_DEVICE,
|
||||
}, {
|
||||
},
|
||||
};
|
||||
|
||||
static struct map_desc at91sam9261_sram_desc[] __initdata = {
|
||||
{
|
||||
.virtual = AT91_IO_VIRT_BASE - AT91SAM9261_SRAM_SIZE,
|
||||
.pfn = __phys_to_pfn(AT91SAM9261_SRAM_BASE),
|
||||
.length = AT91SAM9261_SRAM_SIZE,
|
||||
|
@ -38,6 +43,15 @@ static struct map_desc at91sam9261_io_desc[] __initdata = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct map_desc at91sam9g10_sram_desc[] __initdata = {
|
||||
{
|
||||
.virtual = AT91_IO_VIRT_BASE - AT91SAM9G10_SRAM_SIZE,
|
||||
.pfn = __phys_to_pfn(AT91SAM9G10_SRAM_BASE),
|
||||
.length = AT91SAM9G10_SRAM_SIZE,
|
||||
.type = MT_DEVICE,
|
||||
},
|
||||
};
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Clocks
|
||||
* -------------------------------------------------------------------- */
|
||||
|
@ -263,6 +277,12 @@ void __init at91sam9261_initialize(unsigned long main_clock)
|
|||
/* Map peripherals */
|
||||
iotable_init(at91sam9261_io_desc, ARRAY_SIZE(at91sam9261_io_desc));
|
||||
|
||||
if (cpu_is_at91sam9g10())
|
||||
iotable_init(at91sam9g10_sram_desc, ARRAY_SIZE(at91sam9g10_sram_desc));
|
||||
else
|
||||
iotable_init(at91sam9261_sram_desc, ARRAY_SIZE(at91sam9261_sram_desc));
|
||||
|
||||
|
||||
at91_arch_reset = at91sam9261_reset;
|
||||
pm_power_off = at91sam9261_poweroff;
|
||||
at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1)
|
||||
|
|
|
@ -707,9 +707,9 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
|
|||
* AC97
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#if defined(CONFIG_SND_AT91_AC97) || defined(CONFIG_SND_AT91_AC97_MODULE)
|
||||
#if defined(CONFIG_SND_ATMEL_AC97C) || defined(CONFIG_SND_ATMEL_AC97C_MODULE)
|
||||
static u64 ac97_dmamask = DMA_BIT_MASK(32);
|
||||
static struct atmel_ac97_data ac97_data;
|
||||
static struct ac97c_platform_data ac97_data;
|
||||
|
||||
static struct resource ac97_resources[] = {
|
||||
[0] = {
|
||||
|
@ -725,8 +725,8 @@ static struct resource ac97_resources[] = {
|
|||
};
|
||||
|
||||
static struct platform_device at91sam9263_ac97_device = {
|
||||
.name = "ac97c",
|
||||
.id = 1,
|
||||
.name = "atmel_ac97c",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.dma_mask = &ac97_dmamask,
|
||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||
|
@ -736,7 +736,7 @@ static struct platform_device at91sam9263_ac97_device = {
|
|||
.num_resources = ARRAY_SIZE(ac97_resources),
|
||||
};
|
||||
|
||||
void __init at91_add_device_ac97(struct atmel_ac97_data *data)
|
||||
void __init at91_add_device_ac97(struct ac97c_platform_data *data)
|
||||
{
|
||||
if (!data)
|
||||
return;
|
||||
|
@ -750,11 +750,11 @@ void __init at91_add_device_ac97(struct atmel_ac97_data *data)
|
|||
if (data->reset_pin)
|
||||
at91_set_gpio_output(data->reset_pin, 0);
|
||||
|
||||
ac97_data = *ek_data;
|
||||
ac97_data = *data;
|
||||
platform_device_register(&at91sam9263_ac97_device);
|
||||
}
|
||||
#else
|
||||
void __init at91_add_device_ac97(struct atmel_ac97_data *data) {}
|
||||
void __init at91_add_device_ac97(struct ac97c_platform_data *data) {}
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,360 @@
|
|||
/*
|
||||
* Chip-specific setup code for the AT91SAM9G45 family
|
||||
*
|
||||
* Copyright (C) 2009 Atmel Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/pm.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <mach/at91sam9g45.h>
|
||||
#include <mach/at91_pmc.h>
|
||||
#include <mach/at91_rstc.h>
|
||||
#include <mach/at91_shdwc.h>
|
||||
|
||||
#include "generic.h"
|
||||
#include "clock.h"
|
||||
|
||||
static struct map_desc at91sam9g45_io_desc[] __initdata = {
|
||||
{
|
||||
.virtual = AT91_VA_BASE_SYS,
|
||||
.pfn = __phys_to_pfn(AT91_BASE_SYS),
|
||||
.length = SZ_16K,
|
||||
.type = MT_DEVICE,
|
||||
}, {
|
||||
.virtual = AT91_IO_VIRT_BASE - AT91SAM9G45_SRAM_SIZE,
|
||||
.pfn = __phys_to_pfn(AT91SAM9G45_SRAM_BASE),
|
||||
.length = AT91SAM9G45_SRAM_SIZE,
|
||||
.type = MT_DEVICE,
|
||||
}
|
||||
};
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Clocks
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* The peripheral clocks.
|
||||
*/
|
||||
static struct clk pioA_clk = {
|
||||
.name = "pioA_clk",
|
||||
.pmc_mask = 1 << AT91SAM9G45_ID_PIOA,
|
||||
.type = CLK_TYPE_PERIPHERAL,
|
||||
};
|
||||
static struct clk pioB_clk = {
|
||||
.name = "pioB_clk",
|
||||
.pmc_mask = 1 << AT91SAM9G45_ID_PIOB,
|
||||
.type = CLK_TYPE_PERIPHERAL,
|
||||
};
|
||||
static struct clk pioC_clk = {
|
||||
.name = "pioC_clk",
|
||||
.pmc_mask = 1 << AT91SAM9G45_ID_PIOC,
|
||||
.type = CLK_TYPE_PERIPHERAL,
|
||||
};
|
||||
static struct clk pioDE_clk = {
|
||||
.name = "pioDE_clk",
|
||||
.pmc_mask = 1 << AT91SAM9G45_ID_PIODE,
|
||||
.type = CLK_TYPE_PERIPHERAL,
|
||||
};
|
||||
static struct clk usart0_clk = {
|
||||
.name = "usart0_clk",
|
||||
.pmc_mask = 1 << AT91SAM9G45_ID_US0,
|
||||
.type = CLK_TYPE_PERIPHERAL,
|
||||
};
|
||||
static struct clk usart1_clk = {
|
||||
.name = "usart1_clk",
|
||||
.pmc_mask = 1 << AT91SAM9G45_ID_US1,
|
||||
.type = CLK_TYPE_PERIPHERAL,
|
||||
};
|
||||
static struct clk usart2_clk = {
|
||||
.name = "usart2_clk",
|
||||
.pmc_mask = 1 << AT91SAM9G45_ID_US2,
|
||||
.type = CLK_TYPE_PERIPHERAL,
|
||||
};
|
||||
static struct clk usart3_clk = {
|
||||
.name = "usart3_clk",
|
||||
.pmc_mask = 1 << AT91SAM9G45_ID_US3,
|
||||
.type = CLK_TYPE_PERIPHERAL,
|
||||
};
|
||||
static struct clk mmc0_clk = {
|
||||
.name = "mci0_clk",
|
||||
.pmc_mask = 1 << AT91SAM9G45_ID_MCI0,
|
||||
.type = CLK_TYPE_PERIPHERAL,
|
||||
};
|
||||
static struct clk twi0_clk = {
|
||||
.name = "twi0_clk",
|
||||
.pmc_mask = 1 << AT91SAM9G45_ID_TWI0,
|
||||
.type = CLK_TYPE_PERIPHERAL,
|
||||
};
|
||||
static struct clk twi1_clk = {
|
||||
.name = "twi1_clk",
|
||||
.pmc_mask = 1 << AT91SAM9G45_ID_TWI1,
|
||||
.type = CLK_TYPE_PERIPHERAL,
|
||||
};
|
||||
static struct clk spi0_clk = {
|
||||
.name = "spi0_clk",
|
||||
.pmc_mask = 1 << AT91SAM9G45_ID_SPI0,
|
||||
.type = CLK_TYPE_PERIPHERAL,
|
||||
};
|
||||
static struct clk spi1_clk = {
|
||||
.name = "spi1_clk",
|
||||
.pmc_mask = 1 << AT91SAM9G45_ID_SPI1,
|
||||
.type = CLK_TYPE_PERIPHERAL,
|
||||
};
|
||||
static struct clk ssc0_clk = {
|
||||
.name = "ssc0_clk",
|
||||
.pmc_mask = 1 << AT91SAM9G45_ID_SSC0,
|
||||
.type = CLK_TYPE_PERIPHERAL,
|
||||
};
|
||||
static struct clk ssc1_clk = {
|
||||
.name = "ssc1_clk",
|
||||
.pmc_mask = 1 << AT91SAM9G45_ID_SSC1,
|
||||
.type = CLK_TYPE_PERIPHERAL,
|
||||
};
|
||||
static struct clk tcb_clk = {
|
||||
.name = "tcb_clk",
|
||||
.pmc_mask = 1 << AT91SAM9G45_ID_TCB,
|
||||
.type = CLK_TYPE_PERIPHERAL,
|
||||
};
|
||||
static struct clk pwm_clk = {
|
||||
.name = "pwm_clk",
|
||||
.pmc_mask = 1 << AT91SAM9G45_ID_PWMC,
|
||||
.type = CLK_TYPE_PERIPHERAL,
|
||||
};
|
||||
static struct clk tsc_clk = {
|
||||
.name = "tsc_clk",
|
||||
.pmc_mask = 1 << AT91SAM9G45_ID_TSC,
|
||||
.type = CLK_TYPE_PERIPHERAL,
|
||||
};
|
||||
static struct clk dma_clk = {
|
||||
.name = "dma_clk",
|
||||
.pmc_mask = 1 << AT91SAM9G45_ID_DMA,
|
||||
.type = CLK_TYPE_PERIPHERAL,
|
||||
};
|
||||
static struct clk uhphs_clk = {
|
||||
.name = "uhphs_clk",
|
||||
.pmc_mask = 1 << AT91SAM9G45_ID_UHPHS,
|
||||
.type = CLK_TYPE_PERIPHERAL,
|
||||
};
|
||||
static struct clk lcdc_clk = {
|
||||
.name = "lcdc_clk",
|
||||
.pmc_mask = 1 << AT91SAM9G45_ID_LCDC,
|
||||
.type = CLK_TYPE_PERIPHERAL,
|
||||
};
|
||||
static struct clk ac97_clk = {
|
||||
.name = "ac97_clk",
|
||||
.pmc_mask = 1 << AT91SAM9G45_ID_AC97C,
|
||||
.type = CLK_TYPE_PERIPHERAL,
|
||||
};
|
||||
static struct clk macb_clk = {
|
||||
.name = "macb_clk",
|
||||
.pmc_mask = 1 << AT91SAM9G45_ID_EMAC,
|
||||
.type = CLK_TYPE_PERIPHERAL,
|
||||
};
|
||||
static struct clk isi_clk = {
|
||||
.name = "isi_clk",
|
||||
.pmc_mask = 1 << AT91SAM9G45_ID_ISI,
|
||||
.type = CLK_TYPE_PERIPHERAL,
|
||||
};
|
||||
static struct clk udphs_clk = {
|
||||
.name = "udphs_clk",
|
||||
.pmc_mask = 1 << AT91SAM9G45_ID_UDPHS,
|
||||
.type = CLK_TYPE_PERIPHERAL,
|
||||
};
|
||||
static struct clk mmc1_clk = {
|
||||
.name = "mci1_clk",
|
||||
.pmc_mask = 1 << AT91SAM9G45_ID_MCI1,
|
||||
.type = CLK_TYPE_PERIPHERAL,
|
||||
};
|
||||
|
||||
/* One additional fake clock for ohci */
|
||||
static struct clk ohci_clk = {
|
||||
.name = "ohci_clk",
|
||||
.pmc_mask = 0,
|
||||
.type = CLK_TYPE_PERIPHERAL,
|
||||
.parent = &uhphs_clk,
|
||||
};
|
||||
|
||||
static struct clk *periph_clocks[] __initdata = {
|
||||
&pioA_clk,
|
||||
&pioB_clk,
|
||||
&pioC_clk,
|
||||
&pioDE_clk,
|
||||
&usart0_clk,
|
||||
&usart1_clk,
|
||||
&usart2_clk,
|
||||
&usart3_clk,
|
||||
&mmc0_clk,
|
||||
&twi0_clk,
|
||||
&twi1_clk,
|
||||
&spi0_clk,
|
||||
&spi1_clk,
|
||||
&ssc0_clk,
|
||||
&ssc1_clk,
|
||||
&tcb_clk,
|
||||
&pwm_clk,
|
||||
&tsc_clk,
|
||||
&dma_clk,
|
||||
&uhphs_clk,
|
||||
&lcdc_clk,
|
||||
&ac97_clk,
|
||||
&macb_clk,
|
||||
&isi_clk,
|
||||
&udphs_clk,
|
||||
&mmc1_clk,
|
||||
// irq0
|
||||
&ohci_clk,
|
||||
};
|
||||
|
||||
/*
|
||||
* The two programmable clocks.
|
||||
* You must configure pin multiplexing to bring these signals out.
|
||||
*/
|
||||
static struct clk pck0 = {
|
||||
.name = "pck0",
|
||||
.pmc_mask = AT91_PMC_PCK0,
|
||||
.type = CLK_TYPE_PROGRAMMABLE,
|
||||
.id = 0,
|
||||
};
|
||||
static struct clk pck1 = {
|
||||
.name = "pck1",
|
||||
.pmc_mask = AT91_PMC_PCK1,
|
||||
.type = CLK_TYPE_PROGRAMMABLE,
|
||||
.id = 1,
|
||||
};
|
||||
|
||||
static void __init at91sam9g45_register_clocks(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
|
||||
clk_register(periph_clocks[i]);
|
||||
|
||||
clk_register(&pck0);
|
||||
clk_register(&pck1);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* GPIO
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
static struct at91_gpio_bank at91sam9g45_gpio[] = {
|
||||
{
|
||||
.id = AT91SAM9G45_ID_PIOA,
|
||||
.offset = AT91_PIOA,
|
||||
.clock = &pioA_clk,
|
||||
}, {
|
||||
.id = AT91SAM9G45_ID_PIOB,
|
||||
.offset = AT91_PIOB,
|
||||
.clock = &pioB_clk,
|
||||
}, {
|
||||
.id = AT91SAM9G45_ID_PIOC,
|
||||
.offset = AT91_PIOC,
|
||||
.clock = &pioC_clk,
|
||||
}, {
|
||||
.id = AT91SAM9G45_ID_PIODE,
|
||||
.offset = AT91_PIOD,
|
||||
.clock = &pioDE_clk,
|
||||
}, {
|
||||
.id = AT91SAM9G45_ID_PIODE,
|
||||
.offset = AT91_PIOE,
|
||||
.clock = &pioDE_clk,
|
||||
}
|
||||
};
|
||||
|
||||
static void at91sam9g45_reset(void)
|
||||
{
|
||||
at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
|
||||
}
|
||||
|
||||
static void at91sam9g45_poweroff(void)
|
||||
{
|
||||
at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
|
||||
}
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* AT91SAM9G45 processor initialization
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
void __init at91sam9g45_initialize(unsigned long main_clock)
|
||||
{
|
||||
/* Map peripherals */
|
||||
iotable_init(at91sam9g45_io_desc, ARRAY_SIZE(at91sam9g45_io_desc));
|
||||
|
||||
at91_arch_reset = at91sam9g45_reset;
|
||||
pm_power_off = at91sam9g45_poweroff;
|
||||
at91_extern_irq = (1 << AT91SAM9G45_ID_IRQ0);
|
||||
|
||||
/* Init clock subsystem */
|
||||
at91_clock_init(main_clock);
|
||||
|
||||
/* Register the processor-specific clocks */
|
||||
at91sam9g45_register_clocks();
|
||||
|
||||
/* Register GPIO subsystem */
|
||||
at91_gpio_init(at91sam9g45_gpio, 5);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Interrupt initialization
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* The default interrupt priority levels (0 = lowest, 7 = highest).
|
||||
*/
|
||||
static unsigned int at91sam9g45_default_irq_priority[NR_AIC_IRQS] __initdata = {
|
||||
7, /* Advanced Interrupt Controller (FIQ) */
|
||||
7, /* System Peripherals */
|
||||
1, /* Parallel IO Controller A */
|
||||
1, /* Parallel IO Controller B */
|
||||
1, /* Parallel IO Controller C */
|
||||
1, /* Parallel IO Controller D and E */
|
||||
0,
|
||||
5, /* USART 0 */
|
||||
5, /* USART 1 */
|
||||
5, /* USART 2 */
|
||||
5, /* USART 3 */
|
||||
0, /* Multimedia Card Interface 0 */
|
||||
6, /* Two-Wire Interface 0 */
|
||||
6, /* Two-Wire Interface 1 */
|
||||
5, /* Serial Peripheral Interface 0 */
|
||||
5, /* Serial Peripheral Interface 1 */
|
||||
4, /* Serial Synchronous Controller 0 */
|
||||
4, /* Serial Synchronous Controller 1 */
|
||||
0, /* Timer Counter 0, 1, 2, 3, 4 and 5 */
|
||||
0, /* Pulse Width Modulation Controller */
|
||||
0, /* Touch Screen Controller */
|
||||
0, /* DMA Controller */
|
||||
2, /* USB Host High Speed port */
|
||||
3, /* LDC Controller */
|
||||
5, /* AC97 Controller */
|
||||
3, /* Ethernet */
|
||||
0, /* Image Sensor Interface */
|
||||
2, /* USB Device High speed port */
|
||||
0,
|
||||
0, /* Multimedia Card Interface 1 */
|
||||
0,
|
||||
0, /* Advanced Interrupt Controller (IRQ0) */
|
||||
};
|
||||
|
||||
void __init at91sam9g45_init_interrupts(unsigned int priority[NR_AIC_IRQS])
|
||||
{
|
||||
if (!priority)
|
||||
priority = at91sam9g45_default_irq_priority;
|
||||
|
||||
/* Initialize the AIC interrupt controller */
|
||||
at91_aic_init(priority);
|
||||
|
||||
/* Enable GPIO interrupts */
|
||||
at91_gpio_irq_setup();
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -174,6 +174,16 @@ static struct i2c_board_info __initdata afeb9260_i2c_devices[] = {
|
|||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* IDE (CF True IDE mode)
|
||||
*/
|
||||
static struct at91_cf_data afeb9260_cf_data = {
|
||||
.chipselect = 4,
|
||||
.irq_pin = AT91_PIN_PA6,
|
||||
.rst_pin = AT91_PIN_PA7,
|
||||
.flags = AT91_CF_TRUE_IDE,
|
||||
};
|
||||
|
||||
static void __init afeb9260_board_init(void)
|
||||
{
|
||||
/* Serial */
|
||||
|
@ -202,6 +212,8 @@ static void __init afeb9260_board_init(void)
|
|||
ARRAY_SIZE(afeb9260_i2c_devices));
|
||||
/* Audio */
|
||||
at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX);
|
||||
/* IDE */
|
||||
at91_add_device_cf(&afeb9260_cf_data);
|
||||
}
|
||||
|
||||
MACHINE_START(AFEB9260, "Custom afeb9260 board")
|
||||
|
|
|
@ -0,0 +1,385 @@
|
|||
/*
|
||||
* linux/arch/arm/mach-at91/board-cpu9krea.c
|
||||
*
|
||||
* Copyright (C) 2005 SAN People
|
||||
* Copyright (C) 2006 Atmel
|
||||
* Copyright (C) 2009 Eric Benard - eric@eukrea.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/gpio_keys.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/mtd/physmap.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mach/irq.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/board.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/at91sam9_smc.h>
|
||||
#include <mach/at91sam9260_matrix.h>
|
||||
|
||||
#include "sam9_smc.h"
|
||||
#include "generic.h"
|
||||
|
||||
static void __init cpu9krea_map_io(void)
|
||||
{
|
||||
/* Initialize processor: 18.432 MHz crystal */
|
||||
at91sam9260_initialize(18432000);
|
||||
|
||||
/* DGBU on ttyS0. (Rx & Tx only) */
|
||||
at91_register_uart(0, 0, 0);
|
||||
|
||||
/* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
|
||||
at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS |
|
||||
ATMEL_UART_RTS | ATMEL_UART_DTR | ATMEL_UART_DSR |
|
||||
ATMEL_UART_DCD | ATMEL_UART_RI);
|
||||
|
||||
/* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */
|
||||
at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS |
|
||||
ATMEL_UART_RTS);
|
||||
|
||||
/* USART2 on ttyS3. (Rx, Tx, RTS, CTS) */
|
||||
at91_register_uart(AT91SAM9260_ID_US2, 3, ATMEL_UART_CTS |
|
||||
ATMEL_UART_RTS);
|
||||
|
||||
/* USART3 on ttyS4. (Rx, Tx) */
|
||||
at91_register_uart(AT91SAM9260_ID_US3, 4, 0);
|
||||
|
||||
/* USART4 on ttyS5. (Rx, Tx) */
|
||||
at91_register_uart(AT91SAM9260_ID_US4, 5, 0);
|
||||
|
||||
/* USART5 on ttyS6. (Rx, Tx) */
|
||||
at91_register_uart(AT91SAM9260_ID_US5, 6, 0);
|
||||
|
||||
/* set serial console to ttyS0 (ie, DBGU) */
|
||||
at91_set_serial_console(0);
|
||||
}
|
||||
|
||||
static void __init cpu9krea_init_irq(void)
|
||||
{
|
||||
at91sam9260_init_interrupts(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* USB Host port
|
||||
*/
|
||||
static struct at91_usbh_data __initdata cpu9krea_usbh_data = {
|
||||
.ports = 2,
|
||||
};
|
||||
|
||||
/*
|
||||
* USB Device port
|
||||
*/
|
||||
static struct at91_udc_data __initdata cpu9krea_udc_data = {
|
||||
.vbus_pin = AT91_PIN_PC8,
|
||||
.pullup_pin = 0, /* pull-up driven by UDC */
|
||||
};
|
||||
|
||||
/*
|
||||
* MACB Ethernet device
|
||||
*/
|
||||
static struct at91_eth_data __initdata cpu9krea_macb_data = {
|
||||
.is_rmii = 1,
|
||||
};
|
||||
|
||||
/*
|
||||
* NAND flash
|
||||
*/
|
||||
static struct atmel_nand_data __initdata cpu9krea_nand_data = {
|
||||
.ale = 21,
|
||||
.cle = 22,
|
||||
.rdy_pin = AT91_PIN_PC13,
|
||||
.enable_pin = AT91_PIN_PC14,
|
||||
.bus_width_16 = 0,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MACH_CPU9260
|
||||
static struct sam9_smc_config __initdata cpu9krea_nand_smc_config = {
|
||||
.ncs_read_setup = 0,
|
||||
.nrd_setup = 1,
|
||||
.ncs_write_setup = 0,
|
||||
.nwe_setup = 1,
|
||||
|
||||
.ncs_read_pulse = 3,
|
||||
.nrd_pulse = 3,
|
||||
.ncs_write_pulse = 3,
|
||||
.nwe_pulse = 3,
|
||||
|
||||
.read_cycle = 5,
|
||||
.write_cycle = 5,
|
||||
|
||||
.mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE
|
||||
| AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
|
||||
.tdf_cycles = 2,
|
||||
};
|
||||
#else
|
||||
static struct sam9_smc_config __initdata cpu9krea_nand_smc_config = {
|
||||
.ncs_read_setup = 0,
|
||||
.nrd_setup = 2,
|
||||
.ncs_write_setup = 0,
|
||||
.nwe_setup = 2,
|
||||
|
||||
.ncs_read_pulse = 4,
|
||||
.nrd_pulse = 4,
|
||||
.ncs_write_pulse = 4,
|
||||
.nwe_pulse = 4,
|
||||
|
||||
.read_cycle = 7,
|
||||
.write_cycle = 7,
|
||||
|
||||
.mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE
|
||||
| AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
|
||||
.tdf_cycles = 3,
|
||||
};
|
||||
#endif
|
||||
|
||||
static void __init cpu9krea_add_device_nand(void)
|
||||
{
|
||||
sam9_smc_configure(3, &cpu9krea_nand_smc_config);
|
||||
at91_add_device_nand(&cpu9krea_nand_data);
|
||||
}
|
||||
|
||||
/*
|
||||
* NOR flash
|
||||
*/
|
||||
static struct physmap_flash_data cpuat9260_nor_data = {
|
||||
.width = 2,
|
||||
};
|
||||
|
||||
#define NOR_BASE AT91_CHIPSELECT_0
|
||||
#define NOR_SIZE SZ_64M
|
||||
|
||||
static struct resource nor_flash_resources[] = {
|
||||
{
|
||||
.start = NOR_BASE,
|
||||
.end = NOR_BASE + NOR_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device cpu9krea_nor_flash = {
|
||||
.name = "physmap-flash",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &cpuat9260_nor_data,
|
||||
},
|
||||
.resource = nor_flash_resources,
|
||||
.num_resources = ARRAY_SIZE(nor_flash_resources),
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MACH_CPU9260
|
||||
static struct sam9_smc_config __initdata cpu9krea_nor_smc_config = {
|
||||
.ncs_read_setup = 0,
|
||||
.nrd_setup = 1,
|
||||
.ncs_write_setup = 0,
|
||||
.nwe_setup = 1,
|
||||
|
||||
.ncs_read_pulse = 10,
|
||||
.nrd_pulse = 10,
|
||||
.ncs_write_pulse = 6,
|
||||
.nwe_pulse = 6,
|
||||
|
||||
.read_cycle = 12,
|
||||
.write_cycle = 8,
|
||||
|
||||
.mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE
|
||||
| AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE
|
||||
| AT91_SMC_DBW_16,
|
||||
.tdf_cycles = 2,
|
||||
};
|
||||
#else
|
||||
static struct sam9_smc_config __initdata cpu9krea_nor_smc_config = {
|
||||
.ncs_read_setup = 0,
|
||||
.nrd_setup = 1,
|
||||
.ncs_write_setup = 0,
|
||||
.nwe_setup = 1,
|
||||
|
||||
.ncs_read_pulse = 13,
|
||||
.nrd_pulse = 13,
|
||||
.ncs_write_pulse = 8,
|
||||
.nwe_pulse = 8,
|
||||
|
||||
.read_cycle = 15,
|
||||
.write_cycle = 10,
|
||||
|
||||
.mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE
|
||||
| AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE
|
||||
| AT91_SMC_DBW_16,
|
||||
.tdf_cycles = 2,
|
||||
};
|
||||
#endif
|
||||
|
||||
static __init void cpu9krea_add_device_nor(void)
|
||||
{
|
||||
unsigned long csa;
|
||||
|
||||
csa = at91_sys_read(AT91_MATRIX_EBICSA);
|
||||
at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_VDDIOMSEL_3_3V);
|
||||
|
||||
/* configure chip-select 0 (NOR) */
|
||||
sam9_smc_configure(0, &cpu9krea_nor_smc_config);
|
||||
|
||||
platform_device_register(&cpu9krea_nor_flash);
|
||||
}
|
||||
|
||||
/*
|
||||
* LEDs
|
||||
*/
|
||||
static struct gpio_led cpu9krea_leds[] = {
|
||||
{ /* LED1 */
|
||||
.name = "LED1",
|
||||
.gpio = AT91_PIN_PC11,
|
||||
.active_low = 1,
|
||||
.default_trigger = "timer",
|
||||
},
|
||||
{ /* LED2 */
|
||||
.name = "LED2",
|
||||
.gpio = AT91_PIN_PC12,
|
||||
.active_low = 1,
|
||||
.default_trigger = "heartbeat",
|
||||
},
|
||||
{ /* LED3 */
|
||||
.name = "LED3",
|
||||
.gpio = AT91_PIN_PC7,
|
||||
.active_low = 1,
|
||||
.default_trigger = "none",
|
||||
},
|
||||
{ /* LED4 */
|
||||
.name = "LED4",
|
||||
.gpio = AT91_PIN_PC9,
|
||||
.active_low = 1,
|
||||
.default_trigger = "none",
|
||||
}
|
||||
};
|
||||
|
||||
static struct i2c_board_info __initdata cpu9krea_i2c_devices[] = {
|
||||
{
|
||||
I2C_BOARD_INFO("rtc-ds1307", 0x68),
|
||||
.type = "ds1339",
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* GPIO Buttons
|
||||
*/
|
||||
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
|
||||
static struct gpio_keys_button cpu9krea_buttons[] = {
|
||||
{
|
||||
.gpio = AT91_PIN_PC3,
|
||||
.code = BTN_0,
|
||||
.desc = "BP1",
|
||||
.active_low = 1,
|
||||
.wakeup = 1,
|
||||
},
|
||||
{
|
||||
.gpio = AT91_PIN_PB20,
|
||||
.code = BTN_1,
|
||||
.desc = "BP2",
|
||||
.active_low = 1,
|
||||
.wakeup = 1,
|
||||
}
|
||||
};
|
||||
|
||||
static struct gpio_keys_platform_data cpu9krea_button_data = {
|
||||
.buttons = cpu9krea_buttons,
|
||||
.nbuttons = ARRAY_SIZE(cpu9krea_buttons),
|
||||
};
|
||||
|
||||
static struct platform_device cpu9krea_button_device = {
|
||||
.name = "gpio-keys",
|
||||
.id = -1,
|
||||
.num_resources = 0,
|
||||
.dev = {
|
||||
.platform_data = &cpu9krea_button_data,
|
||||
}
|
||||
};
|
||||
|
||||
static void __init cpu9krea_add_device_buttons(void)
|
||||
{
|
||||
at91_set_gpio_input(AT91_PIN_PC3, 1); /* BP1 */
|
||||
at91_set_deglitch(AT91_PIN_PC3, 1);
|
||||
at91_set_gpio_input(AT91_PIN_PB20, 1); /* BP2 */
|
||||
at91_set_deglitch(AT91_PIN_PB20, 1);
|
||||
|
||||
platform_device_register(&cpu9krea_button_device);
|
||||
}
|
||||
#else
|
||||
static void __init cpu9krea_add_device_buttons(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MCI (SD/MMC)
|
||||
*/
|
||||
static struct at91_mmc_data __initdata cpu9krea_mmc_data = {
|
||||
.slot_b = 0,
|
||||
.wire4 = 1,
|
||||
.det_pin = AT91_PIN_PA29,
|
||||
};
|
||||
|
||||
static void __init cpu9krea_board_init(void)
|
||||
{
|
||||
/* NOR */
|
||||
cpu9krea_add_device_nor();
|
||||
/* Serial */
|
||||
at91_add_device_serial();
|
||||
/* USB Host */
|
||||
at91_add_device_usbh(&cpu9krea_usbh_data);
|
||||
/* USB Device */
|
||||
at91_add_device_udc(&cpu9krea_udc_data);
|
||||
/* NAND */
|
||||
cpu9krea_add_device_nand();
|
||||
/* Ethernet */
|
||||
at91_add_device_eth(&cpu9krea_macb_data);
|
||||
/* MMC */
|
||||
at91_add_device_mmc(0, &cpu9krea_mmc_data);
|
||||
/* I2C */
|
||||
at91_add_device_i2c(cpu9krea_i2c_devices,
|
||||
ARRAY_SIZE(cpu9krea_i2c_devices));
|
||||
/* LEDs */
|
||||
at91_gpio_leds(cpu9krea_leds, ARRAY_SIZE(cpu9krea_leds));
|
||||
/* Push Buttons */
|
||||
cpu9krea_add_device_buttons();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MACH_CPU9260
|
||||
MACHINE_START(CPUAT9260, "Eukrea CPU9260")
|
||||
#else
|
||||
MACHINE_START(CPUAT9G20, "Eukrea CPU9G20")
|
||||
#endif
|
||||
/* Maintainer: Eric Benard - EUKREA Electromatique */
|
||||
.phys_io = AT91_BASE_SYS,
|
||||
.io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
|
||||
.boot_params = AT91_SDRAM_BASE + 0x100,
|
||||
.timer = &at91sam926x_timer,
|
||||
.map_io = cpu9krea_map_io,
|
||||
.init_irq = cpu9krea_init_irq,
|
||||
.init_machine = cpu9krea_board_init,
|
||||
MACHINE_END
|
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* linux/arch/arm/mach-at91/board-cpuat91.c
|
||||
*
|
||||
* Copyright (C) 2009 Eric Benard - eric@eukrea.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mtd/physmap.h>
|
||||
#include <linux/mtd/plat-ram.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mach/irq.h>
|
||||
|
||||
#include <mach/board.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/at91rm9200_mc.h>
|
||||
|
||||
#include "generic.h"
|
||||
|
||||
static struct gpio_led cpuat91_leds[] = {
|
||||
{
|
||||
.name = "led1",
|
||||
.default_trigger = "heartbeat",
|
||||
.active_low = 1,
|
||||
.gpio = AT91_PIN_PC0,
|
||||
},
|
||||
};
|
||||
|
||||
static void __init cpuat91_map_io(void)
|
||||
{
|
||||
/* Initialize processor: 18.432 MHz crystal */
|
||||
at91rm9200_initialize(18432000, AT91RM9200_PQFP);
|
||||
|
||||
/* DBGU on ttyS0. (Rx & Tx only) */
|
||||
at91_register_uart(0, 0, 0);
|
||||
|
||||
/* USART0 on ttyS1. (Rx, Tx, CTS, RTS) */
|
||||
at91_register_uart(AT91RM9200_ID_US0, 1, ATMEL_UART_CTS |
|
||||
ATMEL_UART_RTS);
|
||||
|
||||
/* USART1 on ttyS2. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
|
||||
at91_register_uart(AT91RM9200_ID_US1, 2, ATMEL_UART_CTS |
|
||||
ATMEL_UART_RTS | ATMEL_UART_DTR | ATMEL_UART_DSR |
|
||||
ATMEL_UART_DCD | ATMEL_UART_RI);
|
||||
|
||||
/* USART2 on ttyS3 (Rx, Tx) */
|
||||
at91_register_uart(AT91RM9200_ID_US2, 3, 0);
|
||||
|
||||
/* USART3 on ttyS4 (Rx, Tx, CTS, RTS) */
|
||||
at91_register_uart(AT91RM9200_ID_US3, 4, ATMEL_UART_CTS |
|
||||
ATMEL_UART_RTS);
|
||||
|
||||
/* set serial console to ttyS0 (ie, DBGU) */
|
||||
at91_set_serial_console(0);
|
||||
}
|
||||
|
||||
static void __init cpuat91_init_irq(void)
|
||||
{
|
||||
at91rm9200_init_interrupts(NULL);
|
||||
}
|
||||
|
||||
static struct at91_eth_data __initdata cpuat91_eth_data = {
|
||||
.is_rmii = 1,
|
||||
};
|
||||
|
||||
static struct at91_usbh_data __initdata cpuat91_usbh_data = {
|
||||
.ports = 1,
|
||||
};
|
||||
|
||||
static struct at91_udc_data __initdata cpuat91_udc_data = {
|
||||
.vbus_pin = AT91_PIN_PC15,
|
||||
.pullup_pin = AT91_PIN_PC14,
|
||||
};
|
||||
|
||||
static struct at91_mmc_data __initdata cpuat91_mmc_data = {
|
||||
.det_pin = AT91_PIN_PC2,
|
||||
.wire4 = 1,
|
||||
};
|
||||
|
||||
static struct physmap_flash_data cpuat91_flash_data = {
|
||||
.width = 2,
|
||||
};
|
||||
|
||||
static struct resource cpuat91_flash_resource = {
|
||||
.start = AT91_CHIPSELECT_0,
|
||||
.end = AT91_CHIPSELECT_0 + SZ_16M - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct platform_device cpuat91_norflash = {
|
||||
.name = "physmap-flash",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &cpuat91_flash_data,
|
||||
},
|
||||
.resource = &cpuat91_flash_resource,
|
||||
.num_resources = 1,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MTD_PLATRAM
|
||||
struct platdata_mtd_ram at91_sram_pdata = {
|
||||
.mapname = "SRAM",
|
||||
.bankwidth = 2,
|
||||
};
|
||||
|
||||
static struct resource at91_sram_resource[] = {
|
||||
[0] = {
|
||||
.start = AT91RM9200_SRAM_BASE,
|
||||
.end = AT91RM9200_SRAM_BASE + AT91RM9200_SRAM_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device at91_sram = {
|
||||
.name = "mtd-ram",
|
||||
.id = 0,
|
||||
.resource = at91_sram_resource,
|
||||
.num_resources = ARRAY_SIZE(at91_sram_resource),
|
||||
.dev = {
|
||||
.platform_data = &at91_sram_pdata,
|
||||
},
|
||||
};
|
||||
#endif /* MTD_PLATRAM */
|
||||
|
||||
static struct platform_device *platform_devices[] __initdata = {
|
||||
&cpuat91_norflash,
|
||||
#ifdef CONFIG_MTD_PLATRAM
|
||||
&at91_sram,
|
||||
#endif /* CONFIG_MTD_PLATRAM */
|
||||
};
|
||||
|
||||
static void __init cpuat91_board_init(void)
|
||||
{
|
||||
/* Serial */
|
||||
at91_add_device_serial();
|
||||
/* LEDs. */
|
||||
at91_gpio_leds(cpuat91_leds, ARRAY_SIZE(cpuat91_leds));
|
||||
/* Ethernet */
|
||||
at91_add_device_eth(&cpuat91_eth_data);
|
||||
/* USB Host */
|
||||
at91_add_device_usbh(&cpuat91_usbh_data);
|
||||
/* USB Device */
|
||||
at91_add_device_udc(&cpuat91_udc_data);
|
||||
/* MMC */
|
||||
at91_add_device_mmc(0, &cpuat91_mmc_data);
|
||||
/* I2C */
|
||||
at91_add_device_i2c(NULL, 0);
|
||||
/* Platform devices */
|
||||
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
|
||||
}
|
||||
|
||||
MACHINE_START(CPUAT91, "Eukrea")
|
||||
/* Maintainer: Eric Benard - EUKREA Electromatique */
|
||||
.phys_io = AT91_BASE_SYS,
|
||||
.io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
|
||||
.boot_params = AT91_SDRAM_BASE + 0x100,
|
||||
.timer = &at91rm9200_timer,
|
||||
.map_io = cpuat91_map_io,
|
||||
.init_irq = cpuat91_init_irq,
|
||||
.init_machine = cpuat91_board_init,
|
||||
MACHINE_END
|
|
@ -287,7 +287,11 @@ static void __init ek_add_device_ts(void) {}
|
|||
*/
|
||||
static struct at73c213_board_info at73c213_data = {
|
||||
.ssc_id = 1,
|
||||
#if defined(CONFIG_MACH_AT91SAM9261EK)
|
||||
.shortname = "AT91SAM9261-EK external DAC",
|
||||
#else
|
||||
.shortname = "AT91SAM9G10-EK external DAC",
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE)
|
||||
|
@ -414,6 +418,9 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
|
|||
.default_monspecs = &at91fb_default_stn_monspecs,
|
||||
.atmel_lcdfb_power_control = at91_lcdc_stn_power_control,
|
||||
.guard_time = 1,
|
||||
#if defined(CONFIG_MACH_AT91SAM9G10EK)
|
||||
.lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB,
|
||||
#endif
|
||||
};
|
||||
|
||||
#else
|
||||
|
@ -467,6 +474,9 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
|
|||
.default_monspecs = &at91fb_default_tft_monspecs,
|
||||
.atmel_lcdfb_power_control = at91_lcdc_tft_power_control,
|
||||
.guard_time = 1,
|
||||
#if defined(CONFIG_MACH_AT91SAM9G10EK)
|
||||
.lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB,
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -600,7 +610,11 @@ static void __init ek_board_init(void)
|
|||
at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
|
||||
}
|
||||
|
||||
#if defined(CONFIG_MACH_AT91SAM9261EK)
|
||||
MACHINE_START(AT91SAM9261EK, "Atmel AT91SAM9261-EK")
|
||||
#else
|
||||
MACHINE_START(AT91SAM9G10EK, "Atmel AT91SAM9G10-EK")
|
||||
#endif
|
||||
/* Maintainer: Atmel */
|
||||
.phys_io = AT91_BASE_SYS,
|
||||
.io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
|
||||
|
|
|
@ -364,9 +364,9 @@ static void __init ek_add_device_buttons(void) {}
|
|||
|
||||
/*
|
||||
* AC97
|
||||
* reset_pin is not connected: NRST
|
||||
*/
|
||||
static struct atmel_ac97_data ek_ac97_data = {
|
||||
.reset_pin = AT91_PIN_PA13,
|
||||
static struct ac97c_platform_data ek_ac97_data = {
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/at73c213.h>
|
||||
#include <linux/gpio_keys.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
|
@ -218,9 +220,60 @@ static struct gpio_led ek_leds[] = {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* GPIO Buttons
|
||||
*/
|
||||
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
|
||||
static struct gpio_keys_button ek_buttons[] = {
|
||||
{
|
||||
.gpio = AT91_PIN_PA30,
|
||||
.code = BTN_3,
|
||||
.desc = "Button 3",
|
||||
.active_low = 1,
|
||||
.wakeup = 1,
|
||||
},
|
||||
{
|
||||
.gpio = AT91_PIN_PA31,
|
||||
.code = BTN_4,
|
||||
.desc = "Button 4",
|
||||
.active_low = 1,
|
||||
.wakeup = 1,
|
||||
}
|
||||
};
|
||||
|
||||
static struct gpio_keys_platform_data ek_button_data = {
|
||||
.buttons = ek_buttons,
|
||||
.nbuttons = ARRAY_SIZE(ek_buttons),
|
||||
};
|
||||
|
||||
static struct platform_device ek_button_device = {
|
||||
.name = "gpio-keys",
|
||||
.id = -1,
|
||||
.num_resources = 0,
|
||||
.dev = {
|
||||
.platform_data = &ek_button_data,
|
||||
}
|
||||
};
|
||||
|
||||
static void __init ek_add_device_buttons(void)
|
||||
{
|
||||
at91_set_gpio_input(AT91_PIN_PA30, 1); /* btn3 */
|
||||
at91_set_deglitch(AT91_PIN_PA30, 1);
|
||||
at91_set_gpio_input(AT91_PIN_PA31, 1); /* btn4 */
|
||||
at91_set_deglitch(AT91_PIN_PA31, 1);
|
||||
|
||||
platform_device_register(&ek_button_device);
|
||||
}
|
||||
#else
|
||||
static void __init ek_add_device_buttons(void) {}
|
||||
#endif
|
||||
|
||||
|
||||
static struct i2c_board_info __initdata ek_i2c_devices[] = {
|
||||
{
|
||||
I2C_BOARD_INFO("24c512", 0x50),
|
||||
I2C_BOARD_INFO("wm8731", 0x1b),
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -245,6 +298,8 @@ static void __init ek_board_init(void)
|
|||
at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices));
|
||||
/* LEDs */
|
||||
at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
|
||||
/* Push Buttons */
|
||||
ek_add_device_buttons();
|
||||
/* PCK0 provides MCLK to the WM8731 */
|
||||
at91_set_B_periph(AT91_PIN_PC1, 0);
|
||||
/* SSC (for WM8731) */
|
||||
|
|
|
@ -0,0 +1,389 @@
|
|||
/*
|
||||
* Board-specific setup code for the AT91SAM9M10G45 Evaluation Kit family
|
||||
*
|
||||
* Covers: * AT91SAM9G45-EKES board
|
||||
* * AT91SAM9M10G45-EK board
|
||||
*
|
||||
* Copyright (C) 2009 Atmel Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/gpio_keys.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <video/atmel_lcdc.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mach/irq.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/board.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/at91sam9_smc.h>
|
||||
#include <mach/at91_shdwc.h>
|
||||
|
||||
#include "sam9_smc.h"
|
||||
#include "generic.h"
|
||||
|
||||
|
||||
static void __init ek_map_io(void)
|
||||
{
|
||||
/* Initialize processor: 12.000 MHz crystal */
|
||||
at91sam9g45_initialize(12000000);
|
||||
|
||||
/* DGBU on ttyS0. (Rx & Tx only) */
|
||||
at91_register_uart(0, 0, 0);
|
||||
|
||||
/* USART0 not connected on the -EK board */
|
||||
/* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */
|
||||
at91_register_uart(AT91SAM9G45_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS);
|
||||
|
||||
/* set serial console to ttyS0 (ie, DBGU) */
|
||||
at91_set_serial_console(0);
|
||||
}
|
||||
|
||||
static void __init ek_init_irq(void)
|
||||
{
|
||||
at91sam9g45_init_interrupts(NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* USB HS Host port (common to OHCI & EHCI)
|
||||
*/
|
||||
static struct at91_usbh_data __initdata ek_usbh_hs_data = {
|
||||
.ports = 2,
|
||||
.vbus_pin = {AT91_PIN_PD1, AT91_PIN_PD3},
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* USB HS Device port
|
||||
*/
|
||||
static struct usba_platform_data __initdata ek_usba_udc_data = {
|
||||
.vbus_pin = AT91_PIN_PB19,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* SPI devices.
|
||||
*/
|
||||
static struct spi_board_info ek_spi_devices[] = {
|
||||
{ /* DataFlash chip */
|
||||
.modalias = "mtd_dataflash",
|
||||
.chip_select = 0,
|
||||
.max_speed_hz = 15 * 1000 * 1000,
|
||||
.bus_num = 0,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* MACB Ethernet device
|
||||
*/
|
||||
static struct at91_eth_data __initdata ek_macb_data = {
|
||||
.phy_irq_pin = AT91_PIN_PD5,
|
||||
.is_rmii = 1,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* NAND flash
|
||||
*/
|
||||
static struct mtd_partition __initdata ek_nand_partition[] = {
|
||||
{
|
||||
.name = "Partition 1",
|
||||
.offset = 0,
|
||||
.size = SZ_64M,
|
||||
},
|
||||
{
|
||||
.name = "Partition 2",
|
||||
.offset = MTDPART_OFS_NXTBLK,
|
||||
.size = MTDPART_SIZ_FULL,
|
||||
},
|
||||
};
|
||||
|
||||
static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
|
||||
{
|
||||
*num_partitions = ARRAY_SIZE(ek_nand_partition);
|
||||
return ek_nand_partition;
|
||||
}
|
||||
|
||||
/* det_pin is not connected */
|
||||
static struct atmel_nand_data __initdata ek_nand_data = {
|
||||
.ale = 21,
|
||||
.cle = 22,
|
||||
.rdy_pin = AT91_PIN_PC8,
|
||||
.enable_pin = AT91_PIN_PC14,
|
||||
.partition_info = nand_partitions,
|
||||
#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16)
|
||||
.bus_width_16 = 1,
|
||||
#else
|
||||
.bus_width_16 = 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct sam9_smc_config __initdata ek_nand_smc_config = {
|
||||
.ncs_read_setup = 0,
|
||||
.nrd_setup = 2,
|
||||
.ncs_write_setup = 0,
|
||||
.nwe_setup = 2,
|
||||
|
||||
.ncs_read_pulse = 4,
|
||||
.nrd_pulse = 4,
|
||||
.ncs_write_pulse = 4,
|
||||
.nwe_pulse = 4,
|
||||
|
||||
.read_cycle = 7,
|
||||
.write_cycle = 7,
|
||||
|
||||
.mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE,
|
||||
.tdf_cycles = 3,
|
||||
};
|
||||
|
||||
static void __init ek_add_device_nand(void)
|
||||
{
|
||||
/* setup bus-width (8 or 16) */
|
||||
if (ek_nand_data.bus_width_16)
|
||||
ek_nand_smc_config.mode |= AT91_SMC_DBW_16;
|
||||
else
|
||||
ek_nand_smc_config.mode |= AT91_SMC_DBW_8;
|
||||
|
||||
/* configure chip-select 3 (NAND) */
|
||||
sam9_smc_configure(3, &ek_nand_smc_config);
|
||||
|
||||
at91_add_device_nand(&ek_nand_data);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* LCD Controller
|
||||
*/
|
||||
#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
|
||||
static struct fb_videomode at91_tft_vga_modes[] = {
|
||||
{
|
||||
.name = "LG",
|
||||
.refresh = 60,
|
||||
.xres = 480, .yres = 272,
|
||||
.pixclock = KHZ2PICOS(9000),
|
||||
|
||||
.left_margin = 1, .right_margin = 1,
|
||||
.upper_margin = 40, .lower_margin = 1,
|
||||
.hsync_len = 45, .vsync_len = 1,
|
||||
|
||||
.sync = 0,
|
||||
.vmode = FB_VMODE_NONINTERLACED,
|
||||
},
|
||||
};
|
||||
|
||||
static struct fb_monspecs at91fb_default_monspecs = {
|
||||
.manufacturer = "LG",
|
||||
.monitor = "LB043WQ1",
|
||||
|
||||
.modedb = at91_tft_vga_modes,
|
||||
.modedb_len = ARRAY_SIZE(at91_tft_vga_modes),
|
||||
.hfmin = 15000,
|
||||
.hfmax = 17640,
|
||||
.vfmin = 57,
|
||||
.vfmax = 67,
|
||||
};
|
||||
|
||||
#define AT91SAM9G45_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \
|
||||
| ATMEL_LCDC_DISTYPE_TFT \
|
||||
| ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
|
||||
|
||||
/* Driver datas */
|
||||
static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
|
||||
.lcdcon_is_backlight = true,
|
||||
.default_bpp = 32,
|
||||
.default_dmacon = ATMEL_LCDC_DMAEN,
|
||||
.default_lcdcon2 = AT91SAM9G45_DEFAULT_LCDCON2,
|
||||
.default_monspecs = &at91fb_default_monspecs,
|
||||
.guard_time = 9,
|
||||
.lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB,
|
||||
};
|
||||
|
||||
#else
|
||||
static struct atmel_lcdfb_info __initdata ek_lcdc_data;
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* GPIO Buttons
|
||||
*/
|
||||
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
|
||||
static struct gpio_keys_button ek_buttons[] = {
|
||||
{ /* BP1, "leftclic" */
|
||||
.code = BTN_LEFT,
|
||||
.gpio = AT91_PIN_PB6,
|
||||
.active_low = 1,
|
||||
.desc = "left_click",
|
||||
.wakeup = 1,
|
||||
},
|
||||
{ /* BP2, "rightclic" */
|
||||
.code = BTN_RIGHT,
|
||||
.gpio = AT91_PIN_PB7,
|
||||
.active_low = 1,
|
||||
.desc = "right_click",
|
||||
.wakeup = 1,
|
||||
},
|
||||
/* BP3, "joystick" */
|
||||
{
|
||||
.code = KEY_LEFT,
|
||||
.gpio = AT91_PIN_PB14,
|
||||
.active_low = 1,
|
||||
.desc = "Joystick Left",
|
||||
},
|
||||
{
|
||||
.code = KEY_RIGHT,
|
||||
.gpio = AT91_PIN_PB15,
|
||||
.active_low = 1,
|
||||
.desc = "Joystick Right",
|
||||
},
|
||||
{
|
||||
.code = KEY_UP,
|
||||
.gpio = AT91_PIN_PB16,
|
||||
.active_low = 1,
|
||||
.desc = "Joystick Up",
|
||||
},
|
||||
{
|
||||
.code = KEY_DOWN,
|
||||
.gpio = AT91_PIN_PB17,
|
||||
.active_low = 1,
|
||||
.desc = "Joystick Down",
|
||||
},
|
||||
{
|
||||
.code = KEY_ENTER,
|
||||
.gpio = AT91_PIN_PB18,
|
||||
.active_low = 1,
|
||||
.desc = "Joystick Press",
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_keys_platform_data ek_button_data = {
|
||||
.buttons = ek_buttons,
|
||||
.nbuttons = ARRAY_SIZE(ek_buttons),
|
||||
};
|
||||
|
||||
static struct platform_device ek_button_device = {
|
||||
.name = "gpio-keys",
|
||||
.id = -1,
|
||||
.num_resources = 0,
|
||||
.dev = {
|
||||
.platform_data = &ek_button_data,
|
||||
}
|
||||
};
|
||||
|
||||
static void __init ek_add_device_buttons(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ek_buttons); i++) {
|
||||
at91_set_GPIO_periph(ek_buttons[i].gpio, 1);
|
||||
at91_set_deglitch(ek_buttons[i].gpio, 1);
|
||||
}
|
||||
|
||||
platform_device_register(&ek_button_device);
|
||||
}
|
||||
#else
|
||||
static void __init ek_add_device_buttons(void) {}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* LEDs ... these could all be PWM-driven, for variable brightness
|
||||
*/
|
||||
static struct gpio_led ek_leds[] = {
|
||||
{ /* "top" led, red, powerled */
|
||||
.name = "d8",
|
||||
.gpio = AT91_PIN_PD30,
|
||||
.default_trigger = "heartbeat",
|
||||
},
|
||||
{ /* "left" led, green, userled2, pwm3 */
|
||||
.name = "d6",
|
||||
.gpio = AT91_PIN_PD0,
|
||||
.active_low = 1,
|
||||
.default_trigger = "nand-disk",
|
||||
},
|
||||
#if !(defined(CONFIG_LEDS_ATMEL_PWM) || defined(CONFIG_LEDS_ATMEL_PWM_MODULE))
|
||||
{ /* "right" led, green, userled1, pwm1 */
|
||||
.name = "d7",
|
||||
.gpio = AT91_PIN_PD31,
|
||||
.active_low = 1,
|
||||
.default_trigger = "mmc0",
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* PWM Leds
|
||||
*/
|
||||
static struct gpio_led ek_pwm_led[] = {
|
||||
#if defined(CONFIG_LEDS_ATMEL_PWM) || defined(CONFIG_LEDS_ATMEL_PWM_MODULE)
|
||||
{ /* "right" led, green, userled1, pwm1 */
|
||||
.name = "d7",
|
||||
.gpio = 1, /* is PWM channel number */
|
||||
.active_low = 1,
|
||||
.default_trigger = "none",
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
static void __init ek_board_init(void)
|
||||
{
|
||||
/* Serial */
|
||||
at91_add_device_serial();
|
||||
/* USB HS Host */
|
||||
at91_add_device_usbh_ohci(&ek_usbh_hs_data);
|
||||
/* USB HS Device */
|
||||
at91_add_device_usba(&ek_usba_udc_data);
|
||||
/* SPI */
|
||||
at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
|
||||
/* Ethernet */
|
||||
at91_add_device_eth(&ek_macb_data);
|
||||
/* NAND */
|
||||
ek_add_device_nand();
|
||||
/* I2C */
|
||||
at91_add_device_i2c(0, NULL, 0);
|
||||
/* LCD Controller */
|
||||
at91_add_device_lcdc(&ek_lcdc_data);
|
||||
/* Push Buttons */
|
||||
ek_add_device_buttons();
|
||||
/* LEDs */
|
||||
at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
|
||||
at91_pwm_leds(ek_pwm_led, ARRAY_SIZE(ek_pwm_led));
|
||||
}
|
||||
|
||||
MACHINE_START(AT91SAM9G45EKES, "Atmel AT91SAM9G45-EKES")
|
||||
/* Maintainer: Atmel */
|
||||
.phys_io = AT91_BASE_SYS,
|
||||
.io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
|
||||
.boot_params = AT91_SDRAM_BASE + 0x100,
|
||||
.timer = &at91sam926x_timer,
|
||||
.map_io = ek_map_io,
|
||||
.init_irq = ek_init_irq,
|
||||
.init_machine = ek_board_init,
|
||||
MACHINE_END
|
|
@ -15,6 +15,8 @@
|
|||
#include <linux/spi/spi.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/gpio_keys.h>
|
||||
|
||||
#include <video/atmel_lcdc.h>
|
||||
|
||||
|
@ -186,19 +188,21 @@ static struct fb_monspecs at91fb_default_monspecs = {
|
|||
static void at91_lcdc_power_control(int on)
|
||||
{
|
||||
if (on)
|
||||
at91_set_gpio_value(AT91_PIN_PA30, 0); /* power up */
|
||||
at91_set_gpio_value(AT91_PIN_PC1, 0); /* power up */
|
||||
else
|
||||
at91_set_gpio_value(AT91_PIN_PA30, 1); /* power down */
|
||||
at91_set_gpio_value(AT91_PIN_PC1, 1); /* power down */
|
||||
}
|
||||
|
||||
/* Driver datas */
|
||||
static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
|
||||
.lcdcon_is_backlight = true,
|
||||
.default_bpp = 16,
|
||||
.default_dmacon = ATMEL_LCDC_DMAEN,
|
||||
.default_lcdcon2 = AT91SAM9RL_DEFAULT_LCDCON2,
|
||||
.default_monspecs = &at91fb_default_monspecs,
|
||||
.atmel_lcdfb_power_control = at91_lcdc_power_control,
|
||||
.guard_time = 1,
|
||||
.lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB,
|
||||
};
|
||||
|
||||
#else
|
||||
|
@ -206,6 +210,79 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data;
|
|||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* LEDs
|
||||
*/
|
||||
static struct gpio_led ek_leds[] = {
|
||||
{ /* "bottom" led, green, userled1 to be defined */
|
||||
.name = "ds1",
|
||||
.gpio = AT91_PIN_PD15,
|
||||
.active_low = 1,
|
||||
.default_trigger = "none",
|
||||
},
|
||||
{ /* "bottom" led, green, userled2 to be defined */
|
||||
.name = "ds2",
|
||||
.gpio = AT91_PIN_PD16,
|
||||
.active_low = 1,
|
||||
.default_trigger = "none",
|
||||
},
|
||||
{ /* "power" led, yellow */
|
||||
.name = "ds3",
|
||||
.gpio = AT91_PIN_PD14,
|
||||
.default_trigger = "heartbeat",
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* GPIO Buttons
|
||||
*/
|
||||
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
|
||||
static struct gpio_keys_button ek_buttons[] = {
|
||||
{
|
||||
.gpio = AT91_PIN_PB0,
|
||||
.code = BTN_2,
|
||||
.desc = "Right Click",
|
||||
.active_low = 1,
|
||||
.wakeup = 1,
|
||||
},
|
||||
{
|
||||
.gpio = AT91_PIN_PB1,
|
||||
.code = BTN_1,
|
||||
.desc = "Left Click",
|
||||
.active_low = 1,
|
||||
.wakeup = 1,
|
||||
}
|
||||
};
|
||||
|
||||
static struct gpio_keys_platform_data ek_button_data = {
|
||||
.buttons = ek_buttons,
|
||||
.nbuttons = ARRAY_SIZE(ek_buttons),
|
||||
};
|
||||
|
||||
static struct platform_device ek_button_device = {
|
||||
.name = "gpio-keys",
|
||||
.id = -1,
|
||||
.num_resources = 0,
|
||||
.dev = {
|
||||
.platform_data = &ek_button_data,
|
||||
}
|
||||
};
|
||||
|
||||
static void __init ek_add_device_buttons(void)
|
||||
{
|
||||
at91_set_gpio_input(AT91_PIN_PB1, 1); /* btn1 */
|
||||
at91_set_deglitch(AT91_PIN_PB1, 1);
|
||||
at91_set_gpio_input(AT91_PIN_PB0, 1); /* btn2 */
|
||||
at91_set_deglitch(AT91_PIN_PB0, 1);
|
||||
|
||||
platform_device_register(&ek_button_device);
|
||||
}
|
||||
#else
|
||||
static void __init ek_add_device_buttons(void) {}
|
||||
#endif
|
||||
|
||||
|
||||
static void __init ek_board_init(void)
|
||||
{
|
||||
/* Serial */
|
||||
|
@ -224,6 +301,10 @@ static void __init ek_board_init(void)
|
|||
at91_add_device_lcdc(&ek_lcdc_data);
|
||||
/* Touch Screen Controller */
|
||||
at91_add_device_tsadcc();
|
||||
/* LEDs */
|
||||
at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
|
||||
/* Push Buttons */
|
||||
ek_add_device_buttons();
|
||||
}
|
||||
|
||||
MACHINE_START(AT91SAM9RLEK, "Atmel AT91SAM9RL-EK")
|
||||
|
|
|
@ -47,20 +47,25 @@
|
|||
* Chips have some kind of clocks : group them by functionality
|
||||
*/
|
||||
#define cpu_has_utmi() ( cpu_is_at91cap9() \
|
||||
|| cpu_is_at91sam9rl())
|
||||
|| cpu_is_at91sam9rl() \
|
||||
|| cpu_is_at91sam9g45())
|
||||
|
||||
#define cpu_has_800M_plla() (cpu_is_at91sam9g20())
|
||||
#define cpu_has_800M_plla() ( cpu_is_at91sam9g20() \
|
||||
|| cpu_is_at91sam9g45())
|
||||
|
||||
#define cpu_has_pllb() (!cpu_is_at91sam9rl())
|
||||
#define cpu_has_300M_plla() (cpu_is_at91sam9g10())
|
||||
|
||||
#define cpu_has_upll() (0)
|
||||
#define cpu_has_pllb() (!(cpu_is_at91sam9rl() \
|
||||
|| cpu_is_at91sam9g45()))
|
||||
|
||||
#define cpu_has_upll() (cpu_is_at91sam9g45())
|
||||
|
||||
/* USB host HS & FS */
|
||||
#define cpu_has_uhp() (!cpu_is_at91sam9rl())
|
||||
|
||||
/* USB device FS only */
|
||||
#define cpu_has_udpfs() (!cpu_is_at91sam9rl())
|
||||
|
||||
#define cpu_has_udpfs() (!(cpu_is_at91sam9rl() \
|
||||
|| cpu_is_at91sam9g45()))
|
||||
|
||||
static LIST_HEAD(clocks);
|
||||
static DEFINE_SPINLOCK(clk_lock);
|
||||
|
@ -133,6 +138,13 @@ static void pmc_uckr_mode(struct clk *clk, int is_on)
|
|||
{
|
||||
unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR);
|
||||
|
||||
if (cpu_is_at91sam9g45()) {
|
||||
if (is_on)
|
||||
uckr |= AT91_PMC_BIASEN;
|
||||
else
|
||||
uckr &= ~AT91_PMC_BIASEN;
|
||||
}
|
||||
|
||||
if (is_on) {
|
||||
is_on = AT91_PMC_LOCKU;
|
||||
at91_sys_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask);
|
||||
|
@ -310,6 +322,7 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
|
|||
unsigned long flags;
|
||||
unsigned prescale;
|
||||
unsigned long actual;
|
||||
unsigned long prev = ULONG_MAX;
|
||||
|
||||
if (!clk_is_programmable(clk))
|
||||
return -EINVAL;
|
||||
|
@ -317,8 +330,16 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
|
|||
|
||||
actual = clk->parent->rate_hz;
|
||||
for (prescale = 0; prescale < 7; prescale++) {
|
||||
if (actual && actual <= rate)
|
||||
if (actual > rate)
|
||||
prev = actual;
|
||||
|
||||
if (actual && actual <= rate) {
|
||||
if ((prev - rate) < (rate - actual)) {
|
||||
actual = prev;
|
||||
prescale--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
actual >>= 1;
|
||||
}
|
||||
|
||||
|
@ -373,6 +394,10 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
|
|||
return -EBUSY;
|
||||
if (!clk_is_primary(parent) || !clk_is_programmable(clk))
|
||||
return -EINVAL;
|
||||
|
||||
if (cpu_is_at91sam9rl() && parent->id == AT91_PMC_CSS_PLLB)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&clk_lock, flags);
|
||||
|
||||
clk->rate_hz = parent->rate_hz;
|
||||
|
@ -601,7 +626,9 @@ static void __init at91_pllb_usbfs_clock_init(unsigned long main_clock)
|
|||
uhpck.pmc_mask = AT91RM9200_PMC_UHP;
|
||||
udpck.pmc_mask = AT91RM9200_PMC_UDP;
|
||||
at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP);
|
||||
} else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) {
|
||||
} else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() ||
|
||||
cpu_is_at91sam9263() || cpu_is_at91sam9g20() ||
|
||||
cpu_is_at91sam9g10()) {
|
||||
uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
|
||||
udpck.pmc_mask = AT91SAM926x_PMC_UDP;
|
||||
} else if (cpu_is_at91cap9()) {
|
||||
|
@ -637,6 +664,7 @@ int __init at91_clock_init(unsigned long main_clock)
|
|||
{
|
||||
unsigned tmp, freq, mckr;
|
||||
int i;
|
||||
int pll_overclock = false;
|
||||
|
||||
/*
|
||||
* When the bootloader initialized the main oscillator correctly,
|
||||
|
@ -654,12 +682,25 @@ int __init at91_clock_init(unsigned long main_clock)
|
|||
|
||||
/* report if PLLA is more than mildly overclocked */
|
||||
plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR));
|
||||
if ((!cpu_has_800M_plla() && plla.rate_hz > 209000000)
|
||||
|| (cpu_has_800M_plla() && plla.rate_hz > 800000000))
|
||||
if (cpu_has_300M_plla()) {
|
||||
if (plla.rate_hz > 300000000)
|
||||
pll_overclock = true;
|
||||
} else if (cpu_has_800M_plla()) {
|
||||
if (plla.rate_hz > 800000000)
|
||||
pll_overclock = true;
|
||||
} else {
|
||||
if (plla.rate_hz > 209000000)
|
||||
pll_overclock = true;
|
||||
}
|
||||
if (pll_overclock)
|
||||
pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000);
|
||||
|
||||
if (cpu_is_at91sam9g45()) {
|
||||
mckr = at91_sys_read(AT91_PMC_MCKR);
|
||||
plla.rate_hz /= (1 << ((mckr & AT91_PMC_PLLADIV2) >> 12)); /* plla divisor by 2 */
|
||||
}
|
||||
|
||||
if (cpu_has_upll() && !cpu_has_pllb()) {
|
||||
if (!cpu_has_pllb() && cpu_has_upll()) {
|
||||
/* setup UTMI clock as the fourth primary clock
|
||||
* (instead of pllb) */
|
||||
utmi_clk.type |= CLK_TYPE_PRIMARY;
|
||||
|
@ -701,6 +742,9 @@ int __init at91_clock_init(unsigned long main_clock)
|
|||
freq / ((mckr & AT91_PMC_MDIV) >> 7) : freq; /* mdiv ; (x >> 7) = ((x >> 8) * 2) */
|
||||
if (mckr & AT91_PMC_PDIV)
|
||||
freq /= 2; /* processor clock division */
|
||||
} else if (cpu_is_at91sam9g45()) {
|
||||
mck.rate_hz = (mckr & AT91_PMC_MDIV) == AT91SAM9_PMC_MDIV_3 ?
|
||||
freq / 3 : freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
|
||||
} else {
|
||||
mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ extern void __init at91sam9260_initialize(unsigned long main_clock);
|
|||
extern void __init at91sam9261_initialize(unsigned long main_clock);
|
||||
extern void __init at91sam9263_initialize(unsigned long main_clock);
|
||||
extern void __init at91sam9rl_initialize(unsigned long main_clock);
|
||||
extern void __init at91sam9g45_initialize(unsigned long main_clock);
|
||||
extern void __init at91x40_initialize(unsigned long main_clock);
|
||||
extern void __init at91cap9_initialize(unsigned long main_clock);
|
||||
|
||||
|
@ -23,6 +24,7 @@ extern void __init at91sam9260_init_interrupts(unsigned int priority[]);
|
|||
extern void __init at91sam9261_init_interrupts(unsigned int priority[]);
|
||||
extern void __init at91sam9263_init_interrupts(unsigned int priority[]);
|
||||
extern void __init at91sam9rl_init_interrupts(unsigned int priority[]);
|
||||
extern void __init at91sam9g45_init_interrupts(unsigned int priority[]);
|
||||
extern void __init at91x40_init_interrupts(unsigned int priority[]);
|
||||
extern void __init at91cap9_init_interrupts(unsigned int priority[]);
|
||||
extern void __init at91_aic_init(unsigned int priority[]);
|
||||
|
|
|
@ -44,13 +44,11 @@ static int at91_gpiolib_direction_output(struct gpio_chip *chip,
|
|||
unsigned offset, int val);
|
||||
static int at91_gpiolib_direction_input(struct gpio_chip *chip,
|
||||
unsigned offset);
|
||||
static int at91_gpiolib_request(struct gpio_chip *chip, unsigned offset);
|
||||
|
||||
#define AT91_GPIO_CHIP(name, base_gpio, nr_gpio) \
|
||||
{ \
|
||||
.chip = { \
|
||||
.label = name, \
|
||||
.request = at91_gpiolib_request, \
|
||||
.direction_input = at91_gpiolib_direction_input, \
|
||||
.direction_output = at91_gpiolib_direction_output, \
|
||||
.get = at91_gpiolib_get, \
|
||||
|
@ -588,19 +586,6 @@ static void at91_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val)
|
|||
__raw_writel(mask, pio + (val ? PIO_SODR : PIO_CODR));
|
||||
}
|
||||
|
||||
static int at91_gpiolib_request(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
unsigned pin = chip->base + offset;
|
||||
void __iomem *pio = pin_to_controller(pin);
|
||||
unsigned mask = pin_to_mask(pin);
|
||||
|
||||
/* Cannot request GPIOs that are in alternate function mode */
|
||||
if (!(__raw_readl(pio + PIO_PSR) & mask))
|
||||
return -EPERM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)
|
||||
{
|
||||
int i;
|
||||
|
|
|
@ -95,6 +95,9 @@
|
|||
#define AT91SAM9261_SRAM_BASE 0x00300000 /* Internal SRAM base address */
|
||||
#define AT91SAM9261_SRAM_SIZE 0x00028000 /* Internal SRAM size (160Kb) */
|
||||
|
||||
#define AT91SAM9G10_SRAM_BASE AT91SAM9261_SRAM_BASE /* Internal SRAM base address */
|
||||
#define AT91SAM9G10_SRAM_SIZE 0x00004000 /* Internal SRAM size (16Kb) */
|
||||
|
||||
#define AT91SAM9261_ROM_BASE 0x00400000 /* Internal ROM base address */
|
||||
#define AT91SAM9261_ROM_SIZE SZ_32K /* Internal ROM size (32Kb) */
|
||||
|
||||
|
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* Chip-specific header file for the AT91SAM9G45 family
|
||||
*
|
||||
* Copyright (C) 2008-2009 Atmel Corporation.
|
||||
*
|
||||
* Common definitions.
|
||||
* Based on AT91SAM9G45 preliminary datasheet.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef AT91SAM9G45_H
|
||||
#define AT91SAM9G45_H
|
||||
|
||||
/*
|
||||
* Peripheral identifiers/interrupts.
|
||||
*/
|
||||
#define AT91_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */
|
||||
#define AT91_ID_SYS 1 /* System Controller Interrupt */
|
||||
#define AT91SAM9G45_ID_PIOA 2 /* Parallel I/O Controller A */
|
||||
#define AT91SAM9G45_ID_PIOB 3 /* Parallel I/O Controller B */
|
||||
#define AT91SAM9G45_ID_PIOC 4 /* Parallel I/O Controller C */
|
||||
#define AT91SAM9G45_ID_PIODE 5 /* Parallel I/O Controller D and E */
|
||||
#define AT91SAM9G45_ID_TRNG 6 /* True Random Number Generator */
|
||||
#define AT91SAM9G45_ID_US0 7 /* USART 0 */
|
||||
#define AT91SAM9G45_ID_US1 8 /* USART 1 */
|
||||
#define AT91SAM9G45_ID_US2 9 /* USART 2 */
|
||||
#define AT91SAM9G45_ID_US3 10 /* USART 3 */
|
||||
#define AT91SAM9G45_ID_MCI0 11 /* High Speed Multimedia Card Interface 0 */
|
||||
#define AT91SAM9G45_ID_TWI0 12 /* Two-Wire Interface 0 */
|
||||
#define AT91SAM9G45_ID_TWI1 13 /* Two-Wire Interface 1 */
|
||||
#define AT91SAM9G45_ID_SPI0 14 /* Serial Peripheral Interface 0 */
|
||||
#define AT91SAM9G45_ID_SPI1 15 /* Serial Peripheral Interface 1 */
|
||||
#define AT91SAM9G45_ID_SSC0 16 /* Synchronous Serial Controller 0 */
|
||||
#define AT91SAM9G45_ID_SSC1 17 /* Synchronous Serial Controller 1 */
|
||||
#define AT91SAM9G45_ID_TCB 18 /* Timer Counter 0, 1, 2, 3, 4 and 5 */
|
||||
#define AT91SAM9G45_ID_PWMC 19 /* Pulse Width Modulation Controller */
|
||||
#define AT91SAM9G45_ID_TSC 20 /* Touch Screen ADC Controller */
|
||||
#define AT91SAM9G45_ID_DMA 21 /* DMA Controller */
|
||||
#define AT91SAM9G45_ID_UHPHS 22 /* USB Host High Speed */
|
||||
#define AT91SAM9G45_ID_LCDC 23 /* LCD Controller */
|
||||
#define AT91SAM9G45_ID_AC97C 24 /* AC97 Controller */
|
||||
#define AT91SAM9G45_ID_EMAC 25 /* Ethernet MAC */
|
||||
#define AT91SAM9G45_ID_ISI 26 /* Image Sensor Interface */
|
||||
#define AT91SAM9G45_ID_UDPHS 27 /* USB Device High Speed */
|
||||
#define AT91SAM9G45_ID_AESTDESSHA 28 /* AES + T-DES + SHA */
|
||||
#define AT91SAM9G45_ID_MCI1 29 /* High Speed Multimedia Card Interface 1 */
|
||||
#define AT91SAM9G45_ID_VDEC 30 /* Video Decoder */
|
||||
#define AT91SAM9G45_ID_IRQ0 31 /* Advanced Interrupt Controller */
|
||||
|
||||
/*
|
||||
* User Peripheral physical base addresses.
|
||||
*/
|
||||
#define AT91SAM9G45_BASE_UDPHS 0xfff78000
|
||||
#define AT91SAM9G45_BASE_TCB0 0xfff7c000
|
||||
#define AT91SAM9G45_BASE_TC0 0xfff7c000
|
||||
#define AT91SAM9G45_BASE_TC1 0xfff7c040
|
||||
#define AT91SAM9G45_BASE_TC2 0xfff7c080
|
||||
#define AT91SAM9G45_BASE_MCI0 0xfff80000
|
||||
#define AT91SAM9G45_BASE_TWI0 0xfff84000
|
||||
#define AT91SAM9G45_BASE_TWI1 0xfff88000
|
||||
#define AT91SAM9G45_BASE_US0 0xfff8c000
|
||||
#define AT91SAM9G45_BASE_US1 0xfff90000
|
||||
#define AT91SAM9G45_BASE_US2 0xfff94000
|
||||
#define AT91SAM9G45_BASE_US3 0xfff98000
|
||||
#define AT91SAM9G45_BASE_SSC0 0xfff9c000
|
||||
#define AT91SAM9G45_BASE_SSC1 0xfffa0000
|
||||
#define AT91SAM9G45_BASE_SPI0 0xfffa4000
|
||||
#define AT91SAM9G45_BASE_SPI1 0xfffa8000
|
||||
#define AT91SAM9G45_BASE_AC97C 0xfffac000
|
||||
#define AT91SAM9G45_BASE_TSC 0xfffb0000
|
||||
#define AT91SAM9G45_BASE_ISI 0xfffb4000
|
||||
#define AT91SAM9G45_BASE_PWMC 0xfffb8000
|
||||
#define AT91SAM9G45_BASE_EMAC 0xfffbc000
|
||||
#define AT91SAM9G45_BASE_AES 0xfffc0000
|
||||
#define AT91SAM9G45_BASE_TDES 0xfffc4000
|
||||
#define AT91SAM9G45_BASE_SHA 0xfffc8000
|
||||
#define AT91SAM9G45_BASE_TRNG 0xfffcc000
|
||||
#define AT91SAM9G45_BASE_MCI1 0xfffd0000
|
||||
#define AT91SAM9G45_BASE_TCB1 0xfffd4000
|
||||
#define AT91SAM9G45_BASE_TC3 0xfffd4000
|
||||
#define AT91SAM9G45_BASE_TC4 0xfffd4040
|
||||
#define AT91SAM9G45_BASE_TC5 0xfffd4080
|
||||
#define AT91_BASE_SYS 0xffffe200
|
||||
|
||||
/*
|
||||
* System Peripherals (offset from AT91_BASE_SYS)
|
||||
*/
|
||||
#define AT91_ECC (0xffffe200 - AT91_BASE_SYS)
|
||||
#define AT91_DDRSDRC1 (0xffffe400 - AT91_BASE_SYS)
|
||||
#define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS)
|
||||
#define AT91_SMC (0xffffe800 - AT91_BASE_SYS)
|
||||
#define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS)
|
||||
#define AT91_DMA (0xffffec00 - AT91_BASE_SYS)
|
||||
#define AT91_DBGU (0xffffee00 - AT91_BASE_SYS)
|
||||
#define AT91_AIC (0xfffff000 - AT91_BASE_SYS)
|
||||
#define AT91_PIOA (0xfffff200 - AT91_BASE_SYS)
|
||||
#define AT91_PIOB (0xfffff400 - AT91_BASE_SYS)
|
||||
#define AT91_PIOC (0xfffff600 - AT91_BASE_SYS)
|
||||
#define AT91_PIOD (0xfffff800 - AT91_BASE_SYS)
|
||||
#define AT91_PIOE (0xfffffa00 - AT91_BASE_SYS)
|
||||
#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS)
|
||||
#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS)
|
||||
#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS)
|
||||
#define AT91_RTT (0xfffffd20 - AT91_BASE_SYS)
|
||||
#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS)
|
||||
#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS)
|
||||
#define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS)
|
||||
#define AT91_RTC (0xfffffdb0 - AT91_BASE_SYS)
|
||||
|
||||
#define AT91_USART0 AT91SAM9G45_BASE_US0
|
||||
#define AT91_USART1 AT91SAM9G45_BASE_US1
|
||||
#define AT91_USART2 AT91SAM9G45_BASE_US2
|
||||
#define AT91_USART3 AT91SAM9G45_BASE_US3
|
||||
|
||||
/*
|
||||
* Internal Memory.
|
||||
*/
|
||||
#define AT91SAM9G45_SRAM_BASE 0x00300000 /* Internal SRAM base address */
|
||||
#define AT91SAM9G45_SRAM_SIZE SZ_64K /* Internal SRAM size (64Kb) */
|
||||
|
||||
#define AT91SAM9G45_ROM_BASE 0x00400000 /* Internal ROM base address */
|
||||
#define AT91SAM9G45_ROM_SIZE SZ_64K /* Internal ROM size (64Kb) */
|
||||
|
||||
#define AT91SAM9G45_LCDC_BASE 0x00500000 /* LCD Controller */
|
||||
#define AT91SAM9G45_UDPHS_FIFO 0x00600000 /* USB Device HS controller */
|
||||
#define AT91SAM9G45_OHCI_BASE 0x00700000 /* USB Host controller (OHCI) */
|
||||
#define AT91SAM9G45_EHCI_BASE 0x00800000 /* USB Host controller (EHCI) */
|
||||
#define AT91SAM9G45_VDEC_BASE 0x00900000 /* Video Decoder Controller */
|
||||
|
||||
#define CONFIG_DRAM_BASE AT91_CHIPSELECT_6
|
||||
|
||||
#define CONSISTENT_DMA_SIZE SZ_4M
|
||||
|
||||
/*
|
||||
* DMA peripheral identifiers
|
||||
* for hardware handshaking interface
|
||||
*/
|
||||
#define AT_DMA_ID_MCI0 0
|
||||
#define AT_DMA_ID_SPI0_TX 1
|
||||
#define AT_DMA_ID_SPI0_RX 2
|
||||
#define AT_DMA_ID_SPI1_TX 3
|
||||
#define AT_DMA_ID_SPI1_RX 4
|
||||
#define AT_DMA_ID_SSC0_TX 5
|
||||
#define AT_DMA_ID_SSC0_RX 6
|
||||
#define AT_DMA_ID_SSC1_TX 7
|
||||
#define AT_DMA_ID_SSC1_RX 8
|
||||
#define AT_DMA_ID_AC97_TX 9
|
||||
#define AT_DMA_ID_AC97_RX 10
|
||||
#define AT_DMA_ID_MCI1 13
|
||||
|
||||
#endif
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* Matrix-centric header file for the AT91SAM9G45 family
|
||||
*
|
||||
* Copyright (C) 2008-2009 Atmel Corporation.
|
||||
*
|
||||
* Memory Controllers (MATRIX, EBI) - System peripherals registers.
|
||||
* Based on AT91SAM9G45 preliminary datasheet.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef AT91SAM9G45_MATRIX_H
|
||||
#define AT91SAM9G45_MATRIX_H
|
||||
|
||||
#define AT91_MATRIX_MCFG0 (AT91_MATRIX + 0x00) /* Master Configuration Register 0 */
|
||||
#define AT91_MATRIX_MCFG1 (AT91_MATRIX + 0x04) /* Master Configuration Register 1 */
|
||||
#define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */
|
||||
#define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */
|
||||
#define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */
|
||||
#define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x14) /* Master Configuration Register 5 */
|
||||
#define AT91_MATRIX_MCFG6 (AT91_MATRIX + 0x18) /* Master Configuration Register 6 */
|
||||
#define AT91_MATRIX_MCFG7 (AT91_MATRIX + 0x1C) /* Master Configuration Register 7 */
|
||||
#define AT91_MATRIX_MCFG8 (AT91_MATRIX + 0x20) /* Master Configuration Register 8 */
|
||||
#define AT91_MATRIX_MCFG9 (AT91_MATRIX + 0x24) /* Master Configuration Register 9 */
|
||||
#define AT91_MATRIX_MCFG10 (AT91_MATRIX + 0x28) /* Master Configuration Register 10 */
|
||||
#define AT91_MATRIX_MCFG11 (AT91_MATRIX + 0x2C) /* Master Configuration Register 11 */
|
||||
#define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */
|
||||
#define AT91_MATRIX_ULBT_INFINITE (0 << 0)
|
||||
#define AT91_MATRIX_ULBT_SINGLE (1 << 0)
|
||||
#define AT91_MATRIX_ULBT_FOUR (2 << 0)
|
||||
#define AT91_MATRIX_ULBT_EIGHT (3 << 0)
|
||||
#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0)
|
||||
#define AT91_MATRIX_ULBT_THIRTYTWO (5 << 0)
|
||||
#define AT91_MATRIX_ULBT_SIXTYFOUR (6 << 0)
|
||||
#define AT91_MATRIX_ULBT_128 (7 << 0)
|
||||
|
||||
#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x40) /* Slave Configuration Register 0 */
|
||||
#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x44) /* Slave Configuration Register 1 */
|
||||
#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x48) /* Slave Configuration Register 2 */
|
||||
#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x4C) /* Slave Configuration Register 3 */
|
||||
#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x50) /* Slave Configuration Register 4 */
|
||||
#define AT91_MATRIX_SCFG5 (AT91_MATRIX + 0x54) /* Slave Configuration Register 5 */
|
||||
#define AT91_MATRIX_SCFG6 (AT91_MATRIX + 0x58) /* Slave Configuration Register 6 */
|
||||
#define AT91_MATRIX_SCFG7 (AT91_MATRIX + 0x5C) /* Slave Configuration Register 7 */
|
||||
#define AT91_MATRIX_SLOT_CYCLE (0x1ff << 0) /* Maximum Number of Allowed Cycles for a Burst */
|
||||
#define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */
|
||||
#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16)
|
||||
#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16)
|
||||
#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16)
|
||||
#define AT91_MATRIX_FIXED_DEFMSTR (0xf << 18) /* Fixed Index of Default Master */
|
||||
|
||||
#define AT91_MATRIX_PRAS0 (AT91_MATRIX + 0x80) /* Priority Register A for Slave 0 */
|
||||
#define AT91_MATRIX_PRBS0 (AT91_MATRIX + 0x84) /* Priority Register B for Slave 0 */
|
||||
#define AT91_MATRIX_PRAS1 (AT91_MATRIX + 0x88) /* Priority Register A for Slave 1 */
|
||||
#define AT91_MATRIX_PRBS1 (AT91_MATRIX + 0x8C) /* Priority Register B for Slave 1 */
|
||||
#define AT91_MATRIX_PRAS2 (AT91_MATRIX + 0x90) /* Priority Register A for Slave 2 */
|
||||
#define AT91_MATRIX_PRBS2 (AT91_MATRIX + 0x94) /* Priority Register B for Slave 2 */
|
||||
#define AT91_MATRIX_PRAS3 (AT91_MATRIX + 0x98) /* Priority Register A for Slave 3 */
|
||||
#define AT91_MATRIX_PRBS3 (AT91_MATRIX + 0x9C) /* Priority Register B for Slave 3 */
|
||||
#define AT91_MATRIX_PRAS4 (AT91_MATRIX + 0xA0) /* Priority Register A for Slave 4 */
|
||||
#define AT91_MATRIX_PRBS4 (AT91_MATRIX + 0xA4) /* Priority Register B for Slave 4 */
|
||||
#define AT91_MATRIX_PRAS5 (AT91_MATRIX + 0xA8) /* Priority Register A for Slave 5 */
|
||||
#define AT91_MATRIX_PRBS5 (AT91_MATRIX + 0xAC) /* Priority Register B for Slave 5 */
|
||||
#define AT91_MATRIX_PRAS6 (AT91_MATRIX + 0xB0) /* Priority Register A for Slave 6 */
|
||||
#define AT91_MATRIX_PRBS6 (AT91_MATRIX + 0xB4) /* Priority Register B for Slave 6 */
|
||||
#define AT91_MATRIX_PRAS7 (AT91_MATRIX + 0xB8) /* Priority Register A for Slave 7 */
|
||||
#define AT91_MATRIX_PRBS7 (AT91_MATRIX + 0xBC) /* Priority Register B for Slave 7 */
|
||||
#define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */
|
||||
#define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */
|
||||
#define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */
|
||||
#define AT91_MATRIX_M3PR (3 << 12) /* Master 3 Priority */
|
||||
#define AT91_MATRIX_M4PR (3 << 16) /* Master 4 Priority */
|
||||
#define AT91_MATRIX_M5PR (3 << 20) /* Master 5 Priority */
|
||||
#define AT91_MATRIX_M6PR (3 << 24) /* Master 6 Priority */
|
||||
#define AT91_MATRIX_M7PR (3 << 28) /* Master 7 Priority */
|
||||
#define AT91_MATRIX_M8PR (3 << 0) /* Master 8 Priority (in Register B) */
|
||||
#define AT91_MATRIX_M9PR (3 << 4) /* Master 9 Priority (in Register B) */
|
||||
#define AT91_MATRIX_M10PR (3 << 8) /* Master 10 Priority (in Register B) */
|
||||
#define AT91_MATRIX_M11PR (3 << 12) /* Master 11 Priority (in Register B) */
|
||||
|
||||
#define AT91_MATRIX_MRCR (AT91_MATRIX + 0x100) /* Master Remap Control Register */
|
||||
#define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
|
||||
#define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
|
||||
#define AT91_MATRIX_RCB2 (1 << 2)
|
||||
#define AT91_MATRIX_RCB3 (1 << 3)
|
||||
#define AT91_MATRIX_RCB4 (1 << 4)
|
||||
#define AT91_MATRIX_RCB5 (1 << 5)
|
||||
#define AT91_MATRIX_RCB6 (1 << 6)
|
||||
#define AT91_MATRIX_RCB7 (1 << 7)
|
||||
#define AT91_MATRIX_RCB8 (1 << 8)
|
||||
#define AT91_MATRIX_RCB9 (1 << 9)
|
||||
#define AT91_MATRIX_RCB10 (1 << 10)
|
||||
#define AT91_MATRIX_RCB11 (1 << 11)
|
||||
|
||||
#define AT91_MATRIX_TCMR (AT91_MATRIX + 0x110) /* TCM Configuration Register */
|
||||
#define AT91_MATRIX_ITCM_SIZE (0xf << 0) /* Size of ITCM enabled memory block */
|
||||
#define AT91_MATRIX_ITCM_0 (0 << 0)
|
||||
#define AT91_MATRIX_ITCM_32 (6 << 0)
|
||||
#define AT91_MATRIX_DTCM_SIZE (0xf << 4) /* Size of DTCM enabled memory block */
|
||||
#define AT91_MATRIX_DTCM_0 (0 << 4)
|
||||
#define AT91_MATRIX_DTCM_32 (6 << 4)
|
||||
#define AT91_MATRIX_DTCM_64 (7 << 4)
|
||||
#define AT91_MATRIX_TCM_NWS (0x1 << 11) /* Wait state TCM register */
|
||||
#define AT91_MATRIX_TCM_NO_WS (0x0 << 11)
|
||||
#define AT91_MATRIX_TCM_ONE_WS (0x1 << 11)
|
||||
|
||||
#define AT91_MATRIX_VIDEO (AT91_MATRIX + 0x118) /* Video Mode Configuration Register */
|
||||
#define AT91C_VDEC_SEL (0x1 << 0) /* Video Mode Selection */
|
||||
#define AT91C_VDEC_SEL_OFF (0 << 0)
|
||||
#define AT91C_VDEC_SEL_ON (1 << 0)
|
||||
|
||||
#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x128) /* EBI Chip Select Assignment Register */
|
||||
#define AT91_MATRIX_EBI_CS1A (1 << 1) /* Chip Select 1 Assignment */
|
||||
#define AT91_MATRIX_EBI_CS1A_SMC (0 << 1)
|
||||
#define AT91_MATRIX_EBI_CS1A_SDRAMC (1 << 1)
|
||||
#define AT91_MATRIX_EBI_CS3A (1 << 3) /* Chip Select 3 Assignment */
|
||||
#define AT91_MATRIX_EBI_CS3A_SMC (0 << 3)
|
||||
#define AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA (1 << 3)
|
||||
#define AT91_MATRIX_EBI_CS4A (1 << 4) /* Chip Select 4 Assignment */
|
||||
#define AT91_MATRIX_EBI_CS4A_SMC (0 << 4)
|
||||
#define AT91_MATRIX_EBI_CS4A_SMC_CF0 (1 << 4)
|
||||
#define AT91_MATRIX_EBI_CS5A (1 << 5) /* Chip Select 5 Assignment */
|
||||
#define AT91_MATRIX_EBI_CS5A_SMC (0 << 5)
|
||||
#define AT91_MATRIX_EBI_CS5A_SMC_CF1 (1 << 5)
|
||||
#define AT91_MATRIX_EBI_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */
|
||||
#define AT91_MATRIX_EBI_DBPU_ON (0 << 8)
|
||||
#define AT91_MATRIX_EBI_DBPU_OFF (1 << 8)
|
||||
#define AT91_MATRIX_EBI_VDDIOMSEL (1 << 16) /* Memory voltage selection */
|
||||
#define AT91_MATRIX_EBI_VDDIOMSEL_1_8V (0 << 16)
|
||||
#define AT91_MATRIX_EBI_VDDIOMSEL_3_3V (1 << 16)
|
||||
#define AT91_MATRIX_EBI_EBI_IOSR (1 << 17) /* EBI I/O slew rate selection */
|
||||
#define AT91_MATRIX_EBI_EBI_IOSR_REDUCED (0 << 17)
|
||||
#define AT91_MATRIX_EBI_EBI_IOSR_NORMAL (1 << 17)
|
||||
#define AT91_MATRIX_EBI_DDR_IOSR (1 << 18) /* DDR2 dedicated port I/O slew rate selection */
|
||||
#define AT91_MATRIX_EBI_DDR_IOSR_REDUCED (0 << 18)
|
||||
#define AT91_MATRIX_EBI_DDR_IOSR_NORMAL (1 << 18)
|
||||
|
||||
#define AT91_MATRIX_WPMR (AT91_MATRIX + 0x1E4) /* Write Protect Mode Register */
|
||||
#define AT91_MATRIX_WPMR_WPEN (1 << 0) /* Write Protect ENable */
|
||||
#define AT91_MATRIX_WPMR_WP_WPDIS (0 << 0)
|
||||
#define AT91_MATRIX_WPMR_WP_WPEN (1 << 0)
|
||||
#define AT91_MATRIX_WPMR_WPKEY (0xFFFFFF << 8) /* Write Protect KEY */
|
||||
|
||||
#define AT91_MATRIX_WPSR (AT91_MATRIX + 0x1E8) /* Write Protect Status Register */
|
||||
#define AT91_MATRIX_WPSR_WPVS (1 << 0) /* Write Protect Violation Status */
|
||||
#define AT91_MATRIX_WPSR_NO_WPV (0 << 0)
|
||||
#define AT91_MATRIX_WPSR_WPV (1 << 0)
|
||||
#define AT91_MATRIX_WPSR_WPVSRC (0xFFFF << 8) /* Write Protect Violation Source */
|
||||
|
||||
#endif
|
|
@ -37,6 +37,7 @@
|
|||
#include <linux/leds.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/usb/atmel_usba_udc.h>
|
||||
#include <sound/atmel-ac97c.h>
|
||||
|
||||
/* USB Device */
|
||||
struct at91_udc_data {
|
||||
|
@ -80,7 +81,8 @@ struct at91_eth_data {
|
|||
};
|
||||
extern void __init at91_add_device_eth(struct at91_eth_data *data);
|
||||
|
||||
#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91SAM9G20) || defined(CONFIG_ARCH_AT91CAP9)
|
||||
#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91SAM9G20) || defined(CONFIG_ARCH_AT91CAP9) \
|
||||
|| defined(CONFIG_ARCH_AT91SAM9G45)
|
||||
#define eth_platform_data at91_eth_data
|
||||
#endif
|
||||
|
||||
|
@ -90,6 +92,7 @@ struct at91_usbh_data {
|
|||
u8 vbus_pin[2]; /* port power-control pin */
|
||||
};
|
||||
extern void __init at91_add_device_usbh(struct at91_usbh_data *data);
|
||||
extern void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data);
|
||||
|
||||
/* NAND / SmartMedia */
|
||||
struct atmel_nand_data {
|
||||
|
@ -105,7 +108,11 @@ struct atmel_nand_data {
|
|||
extern void __init at91_add_device_nand(struct atmel_nand_data *data);
|
||||
|
||||
/* I2C*/
|
||||
#if defined(CONFIG_ARCH_AT91SAM9G45)
|
||||
extern void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices);
|
||||
#else
|
||||
extern void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices);
|
||||
#endif
|
||||
|
||||
/* SPI */
|
||||
extern void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices);
|
||||
|
@ -168,10 +175,7 @@ struct atmel_lcdfb_info;
|
|||
extern void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data);
|
||||
|
||||
/* AC97 */
|
||||
struct atmel_ac97_data {
|
||||
u8 reset_pin; /* reset */
|
||||
};
|
||||
extern void __init at91_add_device_ac97(struct atmel_ac97_data *data);
|
||||
extern void __init at91_add_device_ac97(struct ac97c_platform_data *data);
|
||||
|
||||
/* ISI */
|
||||
extern void __init at91_add_device_isi(void);
|
||||
|
|
|
@ -21,8 +21,10 @@
|
|||
#define ARCH_ID_AT91SAM9260 0x019803a0
|
||||
#define ARCH_ID_AT91SAM9261 0x019703a0
|
||||
#define ARCH_ID_AT91SAM9263 0x019607a0
|
||||
#define ARCH_ID_AT91SAM9G10 0x819903a0
|
||||
#define ARCH_ID_AT91SAM9G20 0x019905a0
|
||||
#define ARCH_ID_AT91SAM9RL64 0x019b03a0
|
||||
#define ARCH_ID_AT91SAM9G45 0x819b05a0
|
||||
#define ARCH_ID_AT91CAP9 0x039A03A0
|
||||
|
||||
#define ARCH_ID_AT91SAM9XE128 0x329973a0
|
||||
|
@ -39,6 +41,15 @@ static inline unsigned long at91_cpu_identify(void)
|
|||
return (at91_sys_read(AT91_DBGU_CIDR) & ~AT91_CIDR_VERSION);
|
||||
}
|
||||
|
||||
#define ARCH_EXID_AT91SAM9M11 0x00000001
|
||||
#define ARCH_EXID_AT91SAM9M10 0x00000002
|
||||
#define ARCH_EXID_AT91SAM9G45 0x00000004
|
||||
|
||||
static inline unsigned long at91_exid_identify(void)
|
||||
{
|
||||
return at91_sys_read(AT91_DBGU_EXID);
|
||||
}
|
||||
|
||||
|
||||
#define ARCH_FAMILY_AT91X92 0x09200000
|
||||
#define ARCH_FAMILY_AT91SAM9 0x01900000
|
||||
|
@ -87,6 +98,12 @@ static inline unsigned long at91cap9_rev_identify(void)
|
|||
#define cpu_is_at91sam9261() (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_AT91SAM9G10
|
||||
#define cpu_is_at91sam9g10() (at91_cpu_identify() == ARCH_ID_AT91SAM9G10)
|
||||
#else
|
||||
#define cpu_is_at91sam9g10() (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_AT91SAM9263
|
||||
#define cpu_is_at91sam9263() (at91_cpu_identify() == ARCH_ID_AT91SAM9263)
|
||||
#else
|
||||
|
@ -99,6 +116,12 @@ static inline unsigned long at91cap9_rev_identify(void)
|
|||
#define cpu_is_at91sam9rl() (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_AT91SAM9G45
|
||||
#define cpu_is_at91sam9g45() (at91_cpu_identify() == ARCH_ID_AT91SAM9G45)
|
||||
#else
|
||||
#define cpu_is_at91sam9g45() (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_AT91CAP9
|
||||
#define cpu_is_at91cap9() (at91_cpu_identify() == ARCH_ID_AT91CAP9)
|
||||
#define cpu_is_at91cap9_revB() (at91cap9_rev_identify() == ARCH_REVISION_CAP9_B)
|
||||
|
|
|
@ -20,12 +20,14 @@
|
|||
#include <mach/at91rm9200.h>
|
||||
#elif defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20)
|
||||
#include <mach/at91sam9260.h>
|
||||
#elif defined(CONFIG_ARCH_AT91SAM9261)
|
||||
#elif defined(CONFIG_ARCH_AT91SAM9261) || defined(CONFIG_ARCH_AT91SAM9G10)
|
||||
#include <mach/at91sam9261.h>
|
||||
#elif defined(CONFIG_ARCH_AT91SAM9263)
|
||||
#include <mach/at91sam9263.h>
|
||||
#elif defined(CONFIG_ARCH_AT91SAM9RL)
|
||||
#include <mach/at91sam9rl.h>
|
||||
#elif defined(CONFIG_ARCH_AT91SAM9G45)
|
||||
#include <mach/at91sam9g45.h>
|
||||
#elif defined(CONFIG_ARCH_AT91CAP9)
|
||||
#include <mach/at91cap9.h>
|
||||
#elif defined(CONFIG_ARCH_AT91X40)
|
||||
|
|
|
@ -42,6 +42,11 @@
|
|||
#define AT91SAM9_MASTER_CLOCK 99300000
|
||||
#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16)
|
||||
|
||||
#elif defined(CONFIG_ARCH_AT91SAM9G10)
|
||||
|
||||
#define AT91SAM9_MASTER_CLOCK 133000000
|
||||
#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16)
|
||||
|
||||
#elif defined(CONFIG_ARCH_AT91SAM9263)
|
||||
|
||||
#if defined(CONFIG_MACH_USB_A9263)
|
||||
|
@ -62,6 +67,11 @@
|
|||
#define AT91SAM9_MASTER_CLOCK 132096000
|
||||
#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16)
|
||||
|
||||
#elif defined(CONFIG_ARCH_AT91SAM9G45)
|
||||
|
||||
#define AT91SAM9_MASTER_CLOCK 133333333
|
||||
#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16)
|
||||
|
||||
#elif defined(CONFIG_ARCH_AT91CAP9)
|
||||
|
||||
#define AT91CAP9_MASTER_CLOCK 100000000
|
||||
|
|
|
@ -201,7 +201,8 @@ static int at91_pm_verify_clocks(void)
|
|||
pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
|
||||
return 0;
|
||||
}
|
||||
} else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) {
|
||||
} else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263()
|
||||
|| cpu_is_at91sam9g20() || cpu_is_at91sam9g10()) {
|
||||
if ((scsr & (AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP)) != 0) {
|
||||
pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
|
||||
return 0;
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
choice
|
||||
prompt "Processor selection in BCMRING family of devices"
|
||||
depends on ARCH_BCMRING
|
||||
default ARCH_BCM11107
|
||||
|
||||
config ARCH_FPGA11107
|
||||
bool "FPGA11107"
|
||||
|
||||
config ARCH_BCM11107
|
||||
bool "BCM11107"
|
||||
endchoice
|
||||
|
||||
menu "BCMRING Options"
|
||||
depends on ARCH_BCMRING
|
||||
|
||||
config BCM_ZRELADDR
|
||||
hex "Compressed ZREL ADDR"
|
||||
|
||||
endmenu
|
||||
|
||||
# source "drivers/char/bcmring/Kconfig"
|
|
@ -0,0 +1,8 @@
|
|||
#
|
||||
# Makefile for the linux kernel.
|
||||
#
|
||||
|
||||
# Object file lists.
|
||||
|
||||
obj-y := arch.o mm.o irq.o clock.o core.o timer.o dma.o
|
||||
obj-y += csp/
|
|
@ -0,0 +1,6 @@
|
|||
# Address where decompressor will be written and eventually executed.
|
||||
#
|
||||
# default to SDRAM
|
||||
zreladdr-y := $(CONFIG_BCM_ZRELADDR)
|
||||
params_phys-y := 0x00000800
|
||||
|
|
@ -0,0 +1,157 @@
|
|||
/*****************************************************************************
|
||||
* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
* under the terms of the GNU General Public License version 2, available at
|
||||
* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
|
||||
*
|
||||
* Notwithstanding the above, under no circumstances may you combine this
|
||||
* software in any way with any other Broadcom software provided under a
|
||||
* license other than the GPL, without Broadcom's express prior written
|
||||
* consent.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/sysctl.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/time.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
#include <mach/dma.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/csp/mm_io.h>
|
||||
#include <mach/csp/chipcHw_def.h>
|
||||
#include <mach/csp/chipcHw_inline.h>
|
||||
|
||||
#include <cfg_global.h>
|
||||
|
||||
#include "core.h"
|
||||
|
||||
HW_DECLARE_SPINLOCK(arch)
|
||||
HW_DECLARE_SPINLOCK(gpio)
|
||||
#if defined(CONFIG_DEBUG_SPINLOCK)
|
||||
EXPORT_SYMBOL(bcmring_gpio_reg_lock);
|
||||
#endif
|
||||
|
||||
/* FIXME: temporary solution */
|
||||
#define BCM_SYSCTL_REBOOT_WARM 1
|
||||
#define CTL_BCM_REBOOT 112
|
||||
|
||||
/* sysctl */
|
||||
int bcmring_arch_warm_reboot; /* do a warm reboot on hard reset */
|
||||
|
||||
static struct ctl_table_header *bcmring_sysctl_header;
|
||||
|
||||
static struct ctl_table bcmring_sysctl_warm_reboot[] = {
|
||||
{
|
||||
.ctl_name = BCM_SYSCTL_REBOOT_WARM,
|
||||
.procname = "warm",
|
||||
.data = &bcmring_arch_warm_reboot,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0644,
|
||||
.proc_handler = &proc_dointvec},
|
||||
{}
|
||||
};
|
||||
|
||||
static struct ctl_table bcmring_sysctl_reboot[] = {
|
||||
{
|
||||
.ctl_name = CTL_BCM_REBOOT,
|
||||
.procname = "reboot",
|
||||
.mode = 0555,
|
||||
.child = bcmring_sysctl_warm_reboot},
|
||||
{}
|
||||
};
|
||||
|
||||
static struct platform_device nand_device = {
|
||||
.name = "bcm-nand",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static struct platform_device *devices[] __initdata = {
|
||||
&nand_device,
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Called from the customize_machine function in arch/arm/kernel/setup.c
|
||||
*
|
||||
* The customize_machine function is tagged as an arch_initcall
|
||||
* (see include/linux/init.h for the order that the various init sections
|
||||
* are called in.
|
||||
*
|
||||
*****************************************************************************/
|
||||
static void __init bcmring_init_machine(void)
|
||||
{
|
||||
|
||||
bcmring_sysctl_header = register_sysctl_table(bcmring_sysctl_reboot);
|
||||
|
||||
/* Enable spread spectrum */
|
||||
chipcHw_enableSpreadSpectrum();
|
||||
|
||||
platform_add_devices(devices, ARRAY_SIZE(devices));
|
||||
|
||||
bcmring_amba_init();
|
||||
|
||||
dma_init();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Called from setup_arch (in arch/arm/kernel/setup.c) to fixup any tags
|
||||
* passed in by the boot loader.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static void __init bcmring_fixup(struct machine_desc *desc,
|
||||
struct tag *t, char **cmdline, struct meminfo *mi) {
|
||||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
printk(KERN_NOTICE "bcmring_fixup\n");
|
||||
t->hdr.tag = ATAG_CORE;
|
||||
t->hdr.size = tag_size(tag_core);
|
||||
t->u.core.flags = 0;
|
||||
t->u.core.pagesize = PAGE_SIZE;
|
||||
t->u.core.rootdev = 31 << 8 | 0;
|
||||
t = tag_next(t);
|
||||
|
||||
t->hdr.tag = ATAG_MEM;
|
||||
t->hdr.size = tag_size(tag_mem32);
|
||||
t->u.mem.start = CFG_GLOBAL_RAM_BASE;
|
||||
t->u.mem.size = CFG_GLOBAL_RAM_SIZE;
|
||||
|
||||
t = tag_next(t);
|
||||
|
||||
t->hdr.tag = ATAG_NONE;
|
||||
t->hdr.size = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Machine Description
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
MACHINE_START(BCMRING, "BCMRING")
|
||||
/* Maintainer: Broadcom Corporation */
|
||||
.phys_io = MM_IO_START,
|
||||
.io_pg_offst = (MM_IO_BASE >> 18) & 0xfffc,
|
||||
.fixup = bcmring_fixup,
|
||||
.map_io = bcmring_map_io,
|
||||
.init_irq = bcmring_init_irq,
|
||||
.timer = &bcmring_timer,
|
||||
.init_machine = bcmring_init_machine
|
||||
MACHINE_END
|
|
@ -0,0 +1,224 @@
|
|||
/*****************************************************************************
|
||||
* Copyright 2001 - 2009 Broadcom Corporation. All rights reserved.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
* under the terms of the GNU General Public License version 2, available at
|
||||
* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
|
||||
*
|
||||
* Notwithstanding the above, under no circumstances may you combine this
|
||||
* software in any way with any other Broadcom software provided under a
|
||||
* license other than the GPL, without Broadcom's express prior written
|
||||
* consent.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <mach/csp/hw_cfg.h>
|
||||
#include <mach/csp/chipcHw_def.h>
|
||||
#include <mach/csp/chipcHw_reg.h>
|
||||
#include <mach/csp/chipcHw_inline.h>
|
||||
|
||||
#include <asm/clkdev.h>
|
||||
|
||||
#include "clock.h"
|
||||
|
||||
#define clk_is_primary(x) ((x)->type & CLK_TYPE_PRIMARY)
|
||||
#define clk_is_pll1(x) ((x)->type & CLK_TYPE_PLL1)
|
||||
#define clk_is_pll2(x) ((x)->type & CLK_TYPE_PLL2)
|
||||
#define clk_is_programmable(x) ((x)->type & CLK_TYPE_PROGRAMMABLE)
|
||||
#define clk_is_bypassable(x) ((x)->type & CLK_TYPE_BYPASSABLE)
|
||||
|
||||
#define clk_is_using_xtal(x) ((x)->mode & CLK_MODE_XTAL)
|
||||
|
||||
static DEFINE_SPINLOCK(clk_lock);
|
||||
|
||||
static void __clk_enable(struct clk *clk)
|
||||
{
|
||||
if (!clk)
|
||||
return;
|
||||
|
||||
/* enable parent clock first */
|
||||
if (clk->parent)
|
||||
__clk_enable(clk->parent);
|
||||
|
||||
if (clk->use_cnt++ == 0) {
|
||||
if (clk_is_pll1(clk)) { /* PLL1 */
|
||||
chipcHw_pll1Enable(clk->rate_hz, 0);
|
||||
} else if (clk_is_pll2(clk)) { /* PLL2 */
|
||||
chipcHw_pll2Enable(clk->rate_hz);
|
||||
} else if (clk_is_using_xtal(clk)) { /* source is crystal */
|
||||
if (!clk_is_primary(clk))
|
||||
chipcHw_bypassClockEnable(clk->csp_id);
|
||||
} else { /* source is PLL */
|
||||
chipcHw_setClockEnable(clk->csp_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int clk_enable(struct clk *clk)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (!clk)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&clk_lock, flags);
|
||||
__clk_enable(clk);
|
||||
spin_unlock_irqrestore(&clk_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_enable);
|
||||
|
||||
static void __clk_disable(struct clk *clk)
|
||||
{
|
||||
if (!clk)
|
||||
return;
|
||||
|
||||
BUG_ON(clk->use_cnt == 0);
|
||||
|
||||
if (--clk->use_cnt == 0) {
|
||||
if (clk_is_pll1(clk)) { /* PLL1 */
|
||||
chipcHw_pll1Disable();
|
||||
} else if (clk_is_pll2(clk)) { /* PLL2 */
|
||||
chipcHw_pll2Disable();
|
||||
} else if (clk_is_using_xtal(clk)) { /* source is crystal */
|
||||
if (!clk_is_primary(clk))
|
||||
chipcHw_bypassClockDisable(clk->csp_id);
|
||||
} else { /* source is PLL */
|
||||
chipcHw_setClockDisable(clk->csp_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (clk->parent)
|
||||
__clk_disable(clk->parent);
|
||||
}
|
||||
|
||||
void clk_disable(struct clk *clk)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (!clk)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&clk_lock, flags);
|
||||
__clk_disable(clk);
|
||||
spin_unlock_irqrestore(&clk_lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL(clk_disable);
|
||||
|
||||
unsigned long clk_get_rate(struct clk *clk)
|
||||
{
|
||||
if (!clk)
|
||||
return 0;
|
||||
|
||||
return clk->rate_hz;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_get_rate);
|
||||
|
||||
long clk_round_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long actual;
|
||||
unsigned long rate_hz;
|
||||
|
||||
if (!clk)
|
||||
return -EINVAL;
|
||||
|
||||
if (!clk_is_programmable(clk))
|
||||
return -EINVAL;
|
||||
|
||||
if (clk->use_cnt)
|
||||
return -EBUSY;
|
||||
|
||||
spin_lock_irqsave(&clk_lock, flags);
|
||||
actual = clk->parent->rate_hz;
|
||||
rate_hz = min(actual, rate);
|
||||
spin_unlock_irqrestore(&clk_lock, flags);
|
||||
|
||||
return rate_hz;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_round_rate);
|
||||
|
||||
int clk_set_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long actual;
|
||||
unsigned long rate_hz;
|
||||
|
||||
if (!clk)
|
||||
return -EINVAL;
|
||||
|
||||
if (!clk_is_programmable(clk))
|
||||
return -EINVAL;
|
||||
|
||||
if (clk->use_cnt)
|
||||
return -EBUSY;
|
||||
|
||||
spin_lock_irqsave(&clk_lock, flags);
|
||||
actual = clk->parent->rate_hz;
|
||||
rate_hz = min(actual, rate);
|
||||
rate_hz = chipcHw_setClockFrequency(clk->csp_id, rate_hz);
|
||||
clk->rate_hz = rate_hz;
|
||||
spin_unlock_irqrestore(&clk_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_set_rate);
|
||||
|
||||
struct clk *clk_get_parent(struct clk *clk)
|
||||
{
|
||||
if (!clk)
|
||||
return NULL;
|
||||
|
||||
return clk->parent;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_get_parent);
|
||||
|
||||
int clk_set_parent(struct clk *clk, struct clk *parent)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct clk *old_parent;
|
||||
|
||||
if (!clk || !parent)
|
||||
return -EINVAL;
|
||||
|
||||
if (!clk_is_primary(parent) || !clk_is_bypassable(clk))
|
||||
return -EINVAL;
|
||||
|
||||
/* if more than one user, parent is not allowed */
|
||||
if (clk->use_cnt > 1)
|
||||
return -EBUSY;
|
||||
|
||||
if (clk->parent == parent)
|
||||
return 0;
|
||||
|
||||
spin_lock_irqsave(&clk_lock, flags);
|
||||
old_parent = clk->parent;
|
||||
clk->parent = parent;
|
||||
if (clk_is_using_xtal(parent))
|
||||
clk->mode |= CLK_MODE_XTAL;
|
||||
else
|
||||
clk->mode &= (~CLK_MODE_XTAL);
|
||||
|
||||
/* if clock is active */
|
||||
if (clk->use_cnt != 0) {
|
||||
clk->use_cnt--;
|
||||
/* enable clock with the new parent */
|
||||
__clk_enable(clk);
|
||||
/* disable the old parent */
|
||||
__clk_disable(old_parent);
|
||||
}
|
||||
spin_unlock_irqrestore(&clk_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_set_parent);
|
|
@ -0,0 +1,33 @@
|
|||
/*****************************************************************************
|
||||
* Copyright 2001 - 2009 Broadcom Corporation. All rights reserved.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
* under the terms of the GNU General Public License version 2, available at
|
||||
* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
|
||||
*
|
||||
* Notwithstanding the above, under no circumstances may you combine this
|
||||
* software in any way with any other Broadcom software provided under a
|
||||
* license other than the GPL, without Broadcom's express prior written
|
||||
* consent.
|
||||
*****************************************************************************/
|
||||
#include <mach/csp/chipcHw_def.h>
|
||||
|
||||
#define CLK_TYPE_PRIMARY 1 /* primary clock must NOT have a parent */
|
||||
#define CLK_TYPE_PLL1 2 /* PPL1 */
|
||||
#define CLK_TYPE_PLL2 4 /* PPL2 */
|
||||
#define CLK_TYPE_PROGRAMMABLE 8 /* programmable clock rate */
|
||||
#define CLK_TYPE_BYPASSABLE 16 /* parent can be changed */
|
||||
|
||||
#define CLK_MODE_XTAL 1 /* clock source is from crystal */
|
||||
|
||||
struct clk {
|
||||
const char *name; /* clock name */
|
||||
unsigned int type; /* clock type */
|
||||
unsigned int mode; /* current mode */
|
||||
volatile int use_bypass; /* indicate if it's in bypass mode */
|
||||
chipcHw_CLOCK_e csp_id; /* clock ID for CSP CHIPC */
|
||||
unsigned long rate_hz; /* clock rate in Hz */
|
||||
unsigned int use_cnt; /* usage count */
|
||||
struct clk *parent; /* parent clock */
|
||||
};
|
|
@ -0,0 +1,367 @@
|
|||
/*
|
||||
* derived from linux/arch/arm/mach-versatile/core.c
|
||||
* linux/arch/arm/mach-bcmring/core.c
|
||||
*
|
||||
* Copyright (C) 1999 - 2003 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
|
||||
*/
|
||||
/* Portions copyright Broadcom 2008 */
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/sysdev.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/amba/bus.h>
|
||||
#include <linux/clocksource.h>
|
||||
#include <linux/clockchips.h>
|
||||
|
||||
#include <linux/amba/bus.h>
|
||||
#include <mach/csp/mm_addr.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <asm/clkdev.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/hardware/arm_timer.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/flash.h>
|
||||
#include <asm/mach/irq.h>
|
||||
#include <asm/mach/time.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mach/mmc.h>
|
||||
|
||||
#include <cfg_global.h>
|
||||
|
||||
#include "clock.h"
|
||||
|
||||
#include <csp/secHw.h>
|
||||
#include <mach/csp/secHw_def.h>
|
||||
#include <mach/csp/chipcHw_inline.h>
|
||||
#include <mach/csp/tmrHw_reg.h>
|
||||
|
||||
#define AMBA_DEVICE(name, initname, base, plat, size) \
|
||||
static struct amba_device name##_device = { \
|
||||
.dev = { \
|
||||
.coherent_dma_mask = ~0, \
|
||||
.init_name = initname, \
|
||||
.platform_data = plat \
|
||||
}, \
|
||||
.res = { \
|
||||
.start = MM_ADDR_IO_##base, \
|
||||
.end = MM_ADDR_IO_##base + (size) - 1, \
|
||||
.flags = IORESOURCE_MEM \
|
||||
}, \
|
||||
.dma_mask = ~0, \
|
||||
.irq = { \
|
||||
IRQ_##base \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
AMBA_DEVICE(uartA, "uarta", UARTA, NULL, SZ_4K);
|
||||
AMBA_DEVICE(uartB, "uartb", UARTB, NULL, SZ_4K);
|
||||
|
||||
static struct clk pll1_clk = {
|
||||
.name = "PLL1",
|
||||
.type = CLK_TYPE_PRIMARY | CLK_TYPE_PLL1,
|
||||
.rate_hz = 2000000000,
|
||||
.use_cnt = 7,
|
||||
};
|
||||
|
||||
static struct clk uart_clk = {
|
||||
.name = "UART",
|
||||
.type = CLK_TYPE_PROGRAMMABLE,
|
||||
.csp_id = chipcHw_CLOCK_UART,
|
||||
.rate_hz = HW_CFG_UART_CLK_HZ,
|
||||
.parent = &pll1_clk,
|
||||
};
|
||||
|
||||
static struct clk_lookup lookups[] = {
|
||||
{ /* UART0 */
|
||||
.dev_id = "uarta",
|
||||
.clk = &uart_clk,
|
||||
}, { /* UART1 */
|
||||
.dev_id = "uartb",
|
||||
.clk = &uart_clk,
|
||||
}
|
||||
};
|
||||
|
||||
static struct amba_device *amba_devs[] __initdata = {
|
||||
&uartA_device,
|
||||
&uartB_device,
|
||||
};
|
||||
|
||||
void __init bcmring_amba_init(void)
|
||||
{
|
||||
int i;
|
||||
u32 bus_clock;
|
||||
|
||||
/* Linux is run initially in non-secure mode. Secure peripherals */
|
||||
/* generate FIQ, and must be handled in secure mode. Until we have */
|
||||
/* a linux security monitor implementation, keep everything in */
|
||||
/* non-secure mode. */
|
||||
chipcHw_busInterfaceClockEnable(chipcHw_REG_BUS_CLOCK_SPU);
|
||||
secHw_setUnsecure(secHw_BLK_MASK_CHIP_CONTROL |
|
||||
secHw_BLK_MASK_KEY_SCAN |
|
||||
secHw_BLK_MASK_TOUCH_SCREEN |
|
||||
secHw_BLK_MASK_UART0 |
|
||||
secHw_BLK_MASK_UART1 |
|
||||
secHw_BLK_MASK_WATCHDOG |
|
||||
secHw_BLK_MASK_SPUM |
|
||||
secHw_BLK_MASK_DDR2 |
|
||||
secHw_BLK_MASK_SPU |
|
||||
secHw_BLK_MASK_PKA |
|
||||
secHw_BLK_MASK_RNG |
|
||||
secHw_BLK_MASK_RTC |
|
||||
secHw_BLK_MASK_OTP |
|
||||
secHw_BLK_MASK_BOOT |
|
||||
secHw_BLK_MASK_MPU |
|
||||
secHw_BLK_MASK_TZCTRL | secHw_BLK_MASK_INTR);
|
||||
|
||||
/* Only the devices attached to the AMBA bus are enabled just before the bus is */
|
||||
/* scanned and the drivers are loaded. The clocks need to be on for the AMBA bus */
|
||||
/* driver to access these blocks. The bus is probed, and the drivers are loaded. */
|
||||
/* FIXME Need to remove enable of PIF once CLCD clock enable used properly in FPGA. */
|
||||
bus_clock = chipcHw_REG_BUS_CLOCK_GE
|
||||
| chipcHw_REG_BUS_CLOCK_SDIO0 | chipcHw_REG_BUS_CLOCK_SDIO1;
|
||||
|
||||
chipcHw_busInterfaceClockEnable(bus_clock);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(lookups); i++)
|
||||
clkdev_add(&lookups[i]);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
|
||||
struct amba_device *d = amba_devs[i];
|
||||
amba_device_register(d, &iomem_resource);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Where is the timer (VA)?
|
||||
*/
|
||||
#define TIMER0_VA_BASE MM_IO_BASE_TMR
|
||||
#define TIMER1_VA_BASE (MM_IO_BASE_TMR + 0x20)
|
||||
#define TIMER2_VA_BASE (MM_IO_BASE_TMR + 0x40)
|
||||
#define TIMER3_VA_BASE (MM_IO_BASE_TMR + 0x60)
|
||||
|
||||
/* Timer 0 - 25 MHz, Timer3 at bus clock rate, typically 150-166 MHz */
|
||||
#if defined(CONFIG_ARCH_FPGA11107)
|
||||
/* fpga cpu/bus are currently 30 times slower so scale frequency as well to */
|
||||
/* slow down Linux's sense of time */
|
||||
#define TIMER0_FREQUENCY_MHZ (tmrHw_LOW_FREQUENCY_MHZ * 30)
|
||||
#define TIMER1_FREQUENCY_MHZ (tmrHw_LOW_FREQUENCY_MHZ * 30)
|
||||
#define TIMER3_FREQUENCY_MHZ (tmrHw_HIGH_FREQUENCY_MHZ * 30)
|
||||
#define TIMER3_FREQUENCY_KHZ (tmrHw_HIGH_FREQUENCY_HZ / 1000 * 30)
|
||||
#else
|
||||
#define TIMER0_FREQUENCY_MHZ tmrHw_LOW_FREQUENCY_MHZ
|
||||
#define TIMER1_FREQUENCY_MHZ tmrHw_LOW_FREQUENCY_MHZ
|
||||
#define TIMER3_FREQUENCY_MHZ tmrHw_HIGH_FREQUENCY_MHZ
|
||||
#define TIMER3_FREQUENCY_KHZ (tmrHw_HIGH_FREQUENCY_HZ / 1000)
|
||||
#endif
|
||||
|
||||
#define TICKS_PER_uSEC TIMER0_FREQUENCY_MHZ
|
||||
|
||||
/*
|
||||
* These are useconds NOT ticks.
|
||||
*
|
||||
*/
|
||||
#define mSEC_1 1000
|
||||
#define mSEC_5 (mSEC_1 * 5)
|
||||
#define mSEC_10 (mSEC_1 * 10)
|
||||
#define mSEC_25 (mSEC_1 * 25)
|
||||
#define SEC_1 (mSEC_1 * 1000)
|
||||
|
||||
/*
|
||||
* How long is the timer interval?
|
||||
*/
|
||||
#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10)
|
||||
#if TIMER_INTERVAL >= 0x100000
|
||||
#define TIMER_RELOAD (TIMER_INTERVAL >> 8)
|
||||
#define TIMER_DIVISOR (TIMER_CTRL_DIV256)
|
||||
#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC)
|
||||
#elif TIMER_INTERVAL >= 0x10000
|
||||
#define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */
|
||||
#define TIMER_DIVISOR (TIMER_CTRL_DIV16)
|
||||
#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC)
|
||||
#else
|
||||
#define TIMER_RELOAD (TIMER_INTERVAL)
|
||||
#define TIMER_DIVISOR (TIMER_CTRL_DIV1)
|
||||
#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
|
||||
#endif
|
||||
|
||||
static void timer_set_mode(enum clock_event_mode mode,
|
||||
struct clock_event_device *clk)
|
||||
{
|
||||
unsigned long ctrl;
|
||||
|
||||
switch (mode) {
|
||||
case CLOCK_EVT_MODE_PERIODIC:
|
||||
writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD);
|
||||
|
||||
ctrl = TIMER_CTRL_PERIODIC;
|
||||
ctrl |=
|
||||
TIMER_DIVISOR | TIMER_CTRL_32BIT | TIMER_CTRL_IE |
|
||||
TIMER_CTRL_ENABLE;
|
||||
break;
|
||||
case CLOCK_EVT_MODE_ONESHOT:
|
||||
/* period set, and timer enabled in 'next_event' hook */
|
||||
ctrl = TIMER_CTRL_ONESHOT;
|
||||
ctrl |= TIMER_DIVISOR | TIMER_CTRL_32BIT | TIMER_CTRL_IE;
|
||||
break;
|
||||
case CLOCK_EVT_MODE_UNUSED:
|
||||
case CLOCK_EVT_MODE_SHUTDOWN:
|
||||
default:
|
||||
ctrl = 0;
|
||||
}
|
||||
|
||||
writel(ctrl, TIMER0_VA_BASE + TIMER_CTRL);
|
||||
}
|
||||
|
||||
static int timer_set_next_event(unsigned long evt,
|
||||
struct clock_event_device *unused)
|
||||
{
|
||||
unsigned long ctrl = readl(TIMER0_VA_BASE + TIMER_CTRL);
|
||||
|
||||
writel(evt, TIMER0_VA_BASE + TIMER_LOAD);
|
||||
writel(ctrl | TIMER_CTRL_ENABLE, TIMER0_VA_BASE + TIMER_CTRL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clock_event_device timer0_clockevent = {
|
||||
.name = "timer0",
|
||||
.shift = 32,
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
|
||||
.set_mode = timer_set_mode,
|
||||
.set_next_event = timer_set_next_event,
|
||||
};
|
||||
|
||||
/*
|
||||
* IRQ handler for the timer
|
||||
*/
|
||||
static irqreturn_t bcmring_timer_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct clock_event_device *evt = &timer0_clockevent;
|
||||
|
||||
writel(1, TIMER0_VA_BASE + TIMER_INTCLR);
|
||||
|
||||
evt->event_handler(evt);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction bcmring_timer_irq = {
|
||||
.name = "bcmring Timer Tick",
|
||||
.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
|
||||
.handler = bcmring_timer_interrupt,
|
||||
};
|
||||
|
||||
static cycle_t bcmring_get_cycles_timer1(void)
|
||||
{
|
||||
return ~readl(TIMER1_VA_BASE + TIMER_VALUE);
|
||||
}
|
||||
|
||||
static cycle_t bcmring_get_cycles_timer3(void)
|
||||
{
|
||||
return ~readl(TIMER3_VA_BASE + TIMER_VALUE);
|
||||
}
|
||||
|
||||
static struct clocksource clocksource_bcmring_timer1 = {
|
||||
.name = "timer1",
|
||||
.rating = 200,
|
||||
.read = bcmring_get_cycles_timer1,
|
||||
.mask = CLOCKSOURCE_MASK(32),
|
||||
.shift = 20,
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||
};
|
||||
|
||||
static struct clocksource clocksource_bcmring_timer3 = {
|
||||
.name = "timer3",
|
||||
.rating = 100,
|
||||
.read = bcmring_get_cycles_timer3,
|
||||
.mask = CLOCKSOURCE_MASK(32),
|
||||
.shift = 20,
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||
};
|
||||
|
||||
static int __init bcmring_clocksource_init(void)
|
||||
{
|
||||
/* setup timer1 as free-running clocksource */
|
||||
writel(0, TIMER1_VA_BASE + TIMER_CTRL);
|
||||
writel(0xffffffff, TIMER1_VA_BASE + TIMER_LOAD);
|
||||
writel(0xffffffff, TIMER1_VA_BASE + TIMER_VALUE);
|
||||
writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
|
||||
TIMER1_VA_BASE + TIMER_CTRL);
|
||||
|
||||
clocksource_bcmring_timer1.mult =
|
||||
clocksource_khz2mult(TIMER1_FREQUENCY_MHZ * 1000,
|
||||
clocksource_bcmring_timer1.shift);
|
||||
clocksource_register(&clocksource_bcmring_timer1);
|
||||
|
||||
/* setup timer3 as free-running clocksource */
|
||||
writel(0, TIMER3_VA_BASE + TIMER_CTRL);
|
||||
writel(0xffffffff, TIMER3_VA_BASE + TIMER_LOAD);
|
||||
writel(0xffffffff, TIMER3_VA_BASE + TIMER_VALUE);
|
||||
writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
|
||||
TIMER3_VA_BASE + TIMER_CTRL);
|
||||
|
||||
clocksource_bcmring_timer3.mult =
|
||||
clocksource_khz2mult(TIMER3_FREQUENCY_KHZ,
|
||||
clocksource_bcmring_timer3.shift);
|
||||
clocksource_register(&clocksource_bcmring_timer3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up timer interrupt, and return the current time in seconds.
|
||||
*/
|
||||
void __init bcmring_init_timer(void)
|
||||
{
|
||||
printk(KERN_INFO "bcmring_init_timer\n");
|
||||
/*
|
||||
* Initialise to a known state (all timers off)
|
||||
*/
|
||||
writel(0, TIMER0_VA_BASE + TIMER_CTRL);
|
||||
writel(0, TIMER1_VA_BASE + TIMER_CTRL);
|
||||
writel(0, TIMER2_VA_BASE + TIMER_CTRL);
|
||||
writel(0, TIMER3_VA_BASE + TIMER_CTRL);
|
||||
|
||||
/*
|
||||
* Make irqs happen for the system timer
|
||||
*/
|
||||
setup_irq(IRQ_TIMER0, &bcmring_timer_irq);
|
||||
|
||||
bcmring_clocksource_init();
|
||||
|
||||
timer0_clockevent.mult =
|
||||
div_sc(1000000, NSEC_PER_SEC, timer0_clockevent.shift);
|
||||
timer0_clockevent.max_delta_ns =
|
||||
clockevent_delta2ns(0xffffffff, &timer0_clockevent);
|
||||
timer0_clockevent.min_delta_ns =
|
||||
clockevent_delta2ns(0xf, &timer0_clockevent);
|
||||
|
||||
timer0_clockevent.cpumask = cpumask_of(0);
|
||||
clockevents_register_device(&timer0_clockevent);
|
||||
}
|
||||
|
||||
struct sys_timer bcmring_timer = {
|
||||
.init = bcmring_init_timer,
|
||||
};
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* linux/arch/arm/mach-versatile/core.h
|
||||
*
|
||||
* Copyright (C) 2004 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
|
||||
*/
|
||||
/* Portions copyright Broadcom 2008 */
|
||||
#ifndef __ASM_ARCH_BCMRING_H
|
||||
#define __ASM_ARCH_BCMRING_H
|
||||
|
||||
void __init bcmring_amba_init(void);
|
||||
void __init bcmring_map_io(void);
|
||||
void __init bcmring_init_irq(void);
|
||||
|
||||
extern struct sys_timer bcmring_timer;
|
||||
#endif
|
|
@ -0,0 +1,3 @@
|
|||
obj-y += dmac/
|
||||
obj-y += tmr/
|
||||
obj-y += chipc/
|
|
@ -0,0 +1 @@
|
|||
obj-y += chipcHw.o chipcHw_str.o chipcHw_reset.o chipcHw_init.o
|
|
@ -0,0 +1,776 @@
|
|||
/*****************************************************************************
|
||||
* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
* under the terms of the GNU General Public License version 2, available at
|
||||
* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
|
||||
*
|
||||
* Notwithstanding the above, under no circumstances may you combine this
|
||||
* software in any way with any other Broadcom software provided under a
|
||||
* license other than the GPL, without Broadcom's express prior written
|
||||
* consent.
|
||||
*****************************************************************************/
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* @file chipcHw.c
|
||||
*
|
||||
* @brief Low level Various CHIP clock controlling routines
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* These routines provide basic clock controlling functionality only.
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
/* ---- Include Files ---------------------------------------------------- */
|
||||
|
||||
#include <csp/errno.h>
|
||||
#include <csp/stdint.h>
|
||||
#include <csp/module.h>
|
||||
|
||||
#include <mach/csp/chipcHw_def.h>
|
||||
#include <mach/csp/chipcHw_inline.h>
|
||||
|
||||
#include <csp/reg.h>
|
||||
#include <csp/delay.h>
|
||||
|
||||
/* ---- Private Constants and Types --------------------------------------- */
|
||||
|
||||
/* VPM alignment algorithm uses this */
|
||||
#define MAX_PHASE_ADJUST_COUNT 0xFFFF /* Max number of times allowed to adjust the phase */
|
||||
#define MAX_PHASE_ALIGN_ATTEMPTS 10 /* Max number of attempt to align the phase */
|
||||
|
||||
/* Local definition of clock type */
|
||||
#define PLL_CLOCK 1 /* PLL Clock */
|
||||
#define NON_PLL_CLOCK 2 /* Divider clock */
|
||||
|
||||
static int chipcHw_divide(int num, int denom)
|
||||
__attribute__ ((section(".aramtext")));
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* @brief Set clock fequency for miscellaneous configurable clocks
|
||||
*
|
||||
* This function sets clock frequency
|
||||
*
|
||||
* @return Configured clock frequency in hertz
|
||||
*
|
||||
*/
|
||||
/****************************************************************************/
|
||||
chipcHw_freq chipcHw_getClockFrequency(chipcHw_CLOCK_e clock /* [ IN ] Configurable clock */
|
||||
) {
|
||||
volatile uint32_t *pPLLReg = (uint32_t *) 0x0;
|
||||
volatile uint32_t *pClockCtrl = (uint32_t *) 0x0;
|
||||
volatile uint32_t *pDependentClock = (uint32_t *) 0x0;
|
||||
uint32_t vcoFreqPll1Hz = 0; /* Effective VCO frequency for PLL1 in Hz */
|
||||
uint32_t vcoFreqPll2Hz = 0; /* Effective VCO frequency for PLL2 in Hz */
|
||||
uint32_t dependentClockType = 0;
|
||||
uint32_t vcoHz = 0;
|
||||
|
||||
/* Get VCO frequencies */
|
||||
if ((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASK) != chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_INTEGER) {
|
||||
uint64_t adjustFreq = 0;
|
||||
|
||||
vcoFreqPll1Hz = chipcHw_XTAL_FREQ_Hz *
|
||||
chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) *
|
||||
((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >>
|
||||
chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT);
|
||||
|
||||
/* Adjusted frequency due to chipcHw_REG_PLL_DIVIDER_NDIV_f_SS */
|
||||
adjustFreq = (uint64_t) chipcHw_XTAL_FREQ_Hz *
|
||||
(uint64_t) chipcHw_REG_PLL_DIVIDER_NDIV_f_SS *
|
||||
chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, (chipcHw_REG_PLL_PREDIVIDER_P2 * (uint64_t) chipcHw_REG_PLL_DIVIDER_FRAC));
|
||||
vcoFreqPll1Hz += (uint32_t) adjustFreq;
|
||||
} else {
|
||||
vcoFreqPll1Hz = chipcHw_XTAL_FREQ_Hz *
|
||||
chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) *
|
||||
((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >>
|
||||
chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT);
|
||||
}
|
||||
vcoFreqPll2Hz =
|
||||
chipcHw_XTAL_FREQ_Hz *
|
||||
chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) *
|
||||
((pChipcHw->PLLPreDivider2 & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >>
|
||||
chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT);
|
||||
|
||||
switch (clock) {
|
||||
case chipcHw_CLOCK_DDR:
|
||||
pPLLReg = &pChipcHw->DDRClock;
|
||||
vcoHz = vcoFreqPll1Hz;
|
||||
break;
|
||||
case chipcHw_CLOCK_ARM:
|
||||
pPLLReg = &pChipcHw->ARMClock;
|
||||
vcoHz = vcoFreqPll1Hz;
|
||||
break;
|
||||
case chipcHw_CLOCK_ESW:
|
||||
pPLLReg = &pChipcHw->ESWClock;
|
||||
vcoHz = vcoFreqPll1Hz;
|
||||
break;
|
||||
case chipcHw_CLOCK_VPM:
|
||||
pPLLReg = &pChipcHw->VPMClock;
|
||||
vcoHz = vcoFreqPll1Hz;
|
||||
break;
|
||||
case chipcHw_CLOCK_ESW125:
|
||||
pPLLReg = &pChipcHw->ESW125Clock;
|
||||
vcoHz = vcoFreqPll1Hz;
|
||||
break;
|
||||
case chipcHw_CLOCK_UART:
|
||||
pPLLReg = &pChipcHw->UARTClock;
|
||||
vcoHz = vcoFreqPll1Hz;
|
||||
break;
|
||||
case chipcHw_CLOCK_SDIO0:
|
||||
pPLLReg = &pChipcHw->SDIO0Clock;
|
||||
vcoHz = vcoFreqPll1Hz;
|
||||
break;
|
||||
case chipcHw_CLOCK_SDIO1:
|
||||
pPLLReg = &pChipcHw->SDIO1Clock;
|
||||
vcoHz = vcoFreqPll1Hz;
|
||||
break;
|
||||
case chipcHw_CLOCK_SPI:
|
||||
pPLLReg = &pChipcHw->SPIClock;
|
||||
vcoHz = vcoFreqPll1Hz;
|
||||
break;
|
||||
case chipcHw_CLOCK_ETM:
|
||||
pPLLReg = &pChipcHw->ETMClock;
|
||||
vcoHz = vcoFreqPll1Hz;
|
||||
break;
|
||||
case chipcHw_CLOCK_USB:
|
||||
pPLLReg = &pChipcHw->USBClock;
|
||||
vcoHz = vcoFreqPll2Hz;
|
||||
break;
|
||||
case chipcHw_CLOCK_LCD:
|
||||
pPLLReg = &pChipcHw->LCDClock;
|
||||
vcoHz = vcoFreqPll2Hz;
|
||||
break;
|
||||
case chipcHw_CLOCK_APM:
|
||||
pPLLReg = &pChipcHw->APMClock;
|
||||
vcoHz = vcoFreqPll2Hz;
|
||||
break;
|
||||
case chipcHw_CLOCK_BUS:
|
||||
pClockCtrl = &pChipcHw->ACLKClock;
|
||||
pDependentClock = &pChipcHw->ARMClock;
|
||||
vcoHz = vcoFreqPll1Hz;
|
||||
dependentClockType = PLL_CLOCK;
|
||||
break;
|
||||
case chipcHw_CLOCK_OTP:
|
||||
pClockCtrl = &pChipcHw->OTPClock;
|
||||
break;
|
||||
case chipcHw_CLOCK_I2C:
|
||||
pClockCtrl = &pChipcHw->I2CClock;
|
||||
break;
|
||||
case chipcHw_CLOCK_I2S0:
|
||||
pClockCtrl = &pChipcHw->I2S0Clock;
|
||||
break;
|
||||
case chipcHw_CLOCK_RTBUS:
|
||||
pClockCtrl = &pChipcHw->RTBUSClock;
|
||||
pDependentClock = &pChipcHw->ACLKClock;
|
||||
dependentClockType = NON_PLL_CLOCK;
|
||||
break;
|
||||
case chipcHw_CLOCK_APM100:
|
||||
pClockCtrl = &pChipcHw->APM100Clock;
|
||||
pDependentClock = &pChipcHw->APMClock;
|
||||
vcoHz = vcoFreqPll2Hz;
|
||||
dependentClockType = PLL_CLOCK;
|
||||
break;
|
||||
case chipcHw_CLOCK_TSC:
|
||||
pClockCtrl = &pChipcHw->TSCClock;
|
||||
break;
|
||||
case chipcHw_CLOCK_LED:
|
||||
pClockCtrl = &pChipcHw->LEDClock;
|
||||
break;
|
||||
case chipcHw_CLOCK_I2S1:
|
||||
pClockCtrl = &pChipcHw->I2S1Clock;
|
||||
break;
|
||||
}
|
||||
|
||||
if (pPLLReg) {
|
||||
/* Obtain PLL clock frequency */
|
||||
if (*pPLLReg & chipcHw_REG_PLL_CLOCK_BYPASS_SELECT) {
|
||||
/* Return crystal clock frequency when bypassed */
|
||||
return chipcHw_XTAL_FREQ_Hz;
|
||||
} else if (clock == chipcHw_CLOCK_DDR) {
|
||||
/* DDR frequency is configured in PLLDivider register */
|
||||
return chipcHw_divide (vcoHz, (((pChipcHw->PLLDivider & 0xFF000000) >> 24) ? ((pChipcHw->PLLDivider & 0xFF000000) >> 24) : 256));
|
||||
} else {
|
||||
/* From chip revision number B0, LCD clock is internally divided by 2 */
|
||||
if ((pPLLReg == &pChipcHw->LCDClock) && (chipcHw_getChipRevisionNumber() != chipcHw_REV_NUMBER_A0)) {
|
||||
vcoHz >>= 1;
|
||||
}
|
||||
/* Obtain PLL clock frequency using VCO dividers */
|
||||
return chipcHw_divide(vcoHz, ((*pPLLReg & chipcHw_REG_PLL_CLOCK_MDIV_MASK) ? (*pPLLReg & chipcHw_REG_PLL_CLOCK_MDIV_MASK) : 256));
|
||||
}
|
||||
} else if (pClockCtrl) {
|
||||
/* Obtain divider clock frequency */
|
||||
uint32_t div;
|
||||
uint32_t freq = 0;
|
||||
|
||||
if (*pClockCtrl & chipcHw_REG_DIV_CLOCK_BYPASS_SELECT) {
|
||||
/* Return crystal clock frequency when bypassed */
|
||||
return chipcHw_XTAL_FREQ_Hz;
|
||||
} else if (pDependentClock) {
|
||||
/* Identify the dependent clock frequency */
|
||||
switch (dependentClockType) {
|
||||
case PLL_CLOCK:
|
||||
if (*pDependentClock & chipcHw_REG_PLL_CLOCK_BYPASS_SELECT) {
|
||||
/* Use crystal clock frequency when dependent PLL clock is bypassed */
|
||||
freq = chipcHw_XTAL_FREQ_Hz;
|
||||
} else {
|
||||
/* Obtain PLL clock frequency using VCO dividers */
|
||||
div = *pDependentClock & chipcHw_REG_PLL_CLOCK_MDIV_MASK;
|
||||
freq = div ? chipcHw_divide(vcoHz, div) : 0;
|
||||
}
|
||||
break;
|
||||
case NON_PLL_CLOCK:
|
||||
if (pDependentClock == (uint32_t *) &pChipcHw->ACLKClock) {
|
||||
freq = chipcHw_getClockFrequency (chipcHw_CLOCK_BUS);
|
||||
} else {
|
||||
if (*pDependentClock & chipcHw_REG_DIV_CLOCK_BYPASS_SELECT) {
|
||||
/* Use crystal clock frequency when dependent divider clock is bypassed */
|
||||
freq = chipcHw_XTAL_FREQ_Hz;
|
||||
} else {
|
||||
/* Obtain divider clock frequency using XTAL dividers */
|
||||
div = *pDependentClock & chipcHw_REG_DIV_CLOCK_DIV_MASK;
|
||||
freq = chipcHw_divide (chipcHw_XTAL_FREQ_Hz, (div ? div : 256));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* Dependent on crystal clock */
|
||||
freq = chipcHw_XTAL_FREQ_Hz;
|
||||
}
|
||||
|
||||
div = *pClockCtrl & chipcHw_REG_DIV_CLOCK_DIV_MASK;
|
||||
return chipcHw_divide(freq, (div ? div : 256));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* @brief Set clock fequency for miscellaneous configurable clocks
|
||||
*
|
||||
* This function sets clock frequency
|
||||
*
|
||||
* @return Configured clock frequency in Hz
|
||||
*
|
||||
*/
|
||||
/****************************************************************************/
|
||||
chipcHw_freq chipcHw_setClockFrequency(chipcHw_CLOCK_e clock, /* [ IN ] Configurable clock */
|
||||
uint32_t freq /* [ IN ] Clock frequency in Hz */
|
||||
) {
|
||||
volatile uint32_t *pPLLReg = (uint32_t *) 0x0;
|
||||
volatile uint32_t *pClockCtrl = (uint32_t *) 0x0;
|
||||
volatile uint32_t *pDependentClock = (uint32_t *) 0x0;
|
||||
uint32_t vcoFreqPll1Hz = 0; /* Effective VCO frequency for PLL1 in Hz */
|
||||
uint32_t desVcoFreqPll1Hz = 0; /* Desired VCO frequency for PLL1 in Hz */
|
||||
uint32_t vcoFreqPll2Hz = 0; /* Effective VCO frequency for PLL2 in Hz */
|
||||
uint32_t dependentClockType = 0;
|
||||
uint32_t vcoHz = 0;
|
||||
uint32_t desVcoHz = 0;
|
||||
|
||||
/* Get VCO frequencies */
|
||||
if ((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASK) != chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_INTEGER) {
|
||||
uint64_t adjustFreq = 0;
|
||||
|
||||
vcoFreqPll1Hz = chipcHw_XTAL_FREQ_Hz *
|
||||
chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) *
|
||||
((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >>
|
||||
chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT);
|
||||
|
||||
/* Adjusted frequency due to chipcHw_REG_PLL_DIVIDER_NDIV_f_SS */
|
||||
adjustFreq = (uint64_t) chipcHw_XTAL_FREQ_Hz *
|
||||
(uint64_t) chipcHw_REG_PLL_DIVIDER_NDIV_f_SS *
|
||||
chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, (chipcHw_REG_PLL_PREDIVIDER_P2 * (uint64_t) chipcHw_REG_PLL_DIVIDER_FRAC));
|
||||
vcoFreqPll1Hz += (uint32_t) adjustFreq;
|
||||
|
||||
/* Desired VCO frequency */
|
||||
desVcoFreqPll1Hz = chipcHw_XTAL_FREQ_Hz *
|
||||
chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) *
|
||||
(((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >>
|
||||
chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT) + 1);
|
||||
} else {
|
||||
vcoFreqPll1Hz = desVcoFreqPll1Hz = chipcHw_XTAL_FREQ_Hz *
|
||||
chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) *
|
||||
((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >>
|
||||
chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT);
|
||||
}
|
||||
vcoFreqPll2Hz = chipcHw_XTAL_FREQ_Hz * chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) *
|
||||
((pChipcHw->PLLPreDivider2 & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >>
|
||||
chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT);
|
||||
|
||||
switch (clock) {
|
||||
case chipcHw_CLOCK_DDR:
|
||||
/* Configure the DDR_ctrl:BUS ratio settings */
|
||||
{
|
||||
REG_LOCAL_IRQ_SAVE;
|
||||
/* Dvide DDR_phy by two to obtain DDR_ctrl clock */
|
||||
pChipcHw->DDRClock = (pChipcHw->DDRClock & ~chipcHw_REG_PLL_CLOCK_TO_BUS_RATIO_MASK) | ((((freq / 2) / chipcHw_getClockFrequency(chipcHw_CLOCK_BUS)) - 1)
|
||||
<< chipcHw_REG_PLL_CLOCK_TO_BUS_RATIO_SHIFT);
|
||||
REG_LOCAL_IRQ_RESTORE;
|
||||
}
|
||||
pPLLReg = &pChipcHw->DDRClock;
|
||||
vcoHz = vcoFreqPll1Hz;
|
||||
desVcoHz = desVcoFreqPll1Hz;
|
||||
break;
|
||||
case chipcHw_CLOCK_ARM:
|
||||
pPLLReg = &pChipcHw->ARMClock;
|
||||
vcoHz = vcoFreqPll1Hz;
|
||||
desVcoHz = desVcoFreqPll1Hz;
|
||||
break;
|
||||
case chipcHw_CLOCK_ESW:
|
||||
pPLLReg = &pChipcHw->ESWClock;
|
||||
vcoHz = vcoFreqPll1Hz;
|
||||
desVcoHz = desVcoFreqPll1Hz;
|
||||
break;
|
||||
case chipcHw_CLOCK_VPM:
|
||||
/* Configure the VPM:BUS ratio settings */
|
||||
{
|
||||
REG_LOCAL_IRQ_SAVE;
|
||||
pChipcHw->VPMClock = (pChipcHw->VPMClock & ~chipcHw_REG_PLL_CLOCK_TO_BUS_RATIO_MASK) | ((chipcHw_divide (freq, chipcHw_getClockFrequency(chipcHw_CLOCK_BUS)) - 1)
|
||||
<< chipcHw_REG_PLL_CLOCK_TO_BUS_RATIO_SHIFT);
|
||||
REG_LOCAL_IRQ_RESTORE;
|
||||
}
|
||||
pPLLReg = &pChipcHw->VPMClock;
|
||||
vcoHz = vcoFreqPll1Hz;
|
||||
desVcoHz = desVcoFreqPll1Hz;
|
||||
break;
|
||||
case chipcHw_CLOCK_ESW125:
|
||||
pPLLReg = &pChipcHw->ESW125Clock;
|
||||
vcoHz = vcoFreqPll1Hz;
|
||||
desVcoHz = desVcoFreqPll1Hz;
|
||||
break;
|
||||
case chipcHw_CLOCK_UART:
|
||||
pPLLReg = &pChipcHw->UARTClock;
|
||||
vcoHz = vcoFreqPll1Hz;
|
||||
desVcoHz = desVcoFreqPll1Hz;
|
||||
break;
|
||||
case chipcHw_CLOCK_SDIO0:
|
||||
pPLLReg = &pChipcHw->SDIO0Clock;
|
||||
vcoHz = vcoFreqPll1Hz;
|
||||
desVcoHz = desVcoFreqPll1Hz;
|
||||
break;
|
||||
case chipcHw_CLOCK_SDIO1:
|
||||
pPLLReg = &pChipcHw->SDIO1Clock;
|
||||
vcoHz = vcoFreqPll1Hz;
|
||||
desVcoHz = desVcoFreqPll1Hz;
|
||||
break;
|
||||
case chipcHw_CLOCK_SPI:
|
||||
pPLLReg = &pChipcHw->SPIClock;
|
||||
vcoHz = vcoFreqPll1Hz;
|
||||
desVcoHz = desVcoFreqPll1Hz;
|
||||
break;
|
||||
case chipcHw_CLOCK_ETM:
|
||||
pPLLReg = &pChipcHw->ETMClock;
|
||||
vcoHz = vcoFreqPll1Hz;
|
||||
desVcoHz = desVcoFreqPll1Hz;
|
||||
break;
|
||||
case chipcHw_CLOCK_USB:
|
||||
pPLLReg = &pChipcHw->USBClock;
|
||||
vcoHz = vcoFreqPll2Hz;
|
||||
desVcoHz = vcoFreqPll2Hz;
|
||||
break;
|
||||
case chipcHw_CLOCK_LCD:
|
||||
pPLLReg = &pChipcHw->LCDClock;
|
||||
vcoHz = vcoFreqPll2Hz;
|
||||
desVcoHz = vcoFreqPll2Hz;
|
||||
break;
|
||||
case chipcHw_CLOCK_APM:
|
||||
pPLLReg = &pChipcHw->APMClock;
|
||||
vcoHz = vcoFreqPll2Hz;
|
||||
desVcoHz = vcoFreqPll2Hz;
|
||||
break;
|
||||
case chipcHw_CLOCK_BUS:
|
||||
pClockCtrl = &pChipcHw->ACLKClock;
|
||||
pDependentClock = &pChipcHw->ARMClock;
|
||||
vcoHz = vcoFreqPll1Hz;
|
||||
desVcoHz = desVcoFreqPll1Hz;
|
||||
dependentClockType = PLL_CLOCK;
|
||||
break;
|
||||
case chipcHw_CLOCK_OTP:
|
||||
pClockCtrl = &pChipcHw->OTPClock;
|
||||
break;
|
||||
case chipcHw_CLOCK_I2C:
|
||||
pClockCtrl = &pChipcHw->I2CClock;
|
||||
break;
|
||||
case chipcHw_CLOCK_I2S0:
|
||||
pClockCtrl = &pChipcHw->I2S0Clock;
|
||||
break;
|
||||
case chipcHw_CLOCK_RTBUS:
|
||||
pClockCtrl = &pChipcHw->RTBUSClock;
|
||||
pDependentClock = &pChipcHw->ACLKClock;
|
||||
dependentClockType = NON_PLL_CLOCK;
|
||||
break;
|
||||
case chipcHw_CLOCK_APM100:
|
||||
pClockCtrl = &pChipcHw->APM100Clock;
|
||||
pDependentClock = &pChipcHw->APMClock;
|
||||
vcoHz = vcoFreqPll2Hz;
|
||||
desVcoHz = vcoFreqPll2Hz;
|
||||
dependentClockType = PLL_CLOCK;
|
||||
break;
|
||||
case chipcHw_CLOCK_TSC:
|
||||
pClockCtrl = &pChipcHw->TSCClock;
|
||||
break;
|
||||
case chipcHw_CLOCK_LED:
|
||||
pClockCtrl = &pChipcHw->LEDClock;
|
||||
break;
|
||||
case chipcHw_CLOCK_I2S1:
|
||||
pClockCtrl = &pChipcHw->I2S1Clock;
|
||||
break;
|
||||
}
|
||||
|
||||
if (pPLLReg) {
|
||||
/* Select XTAL as bypass source */
|
||||
reg32_modify_and(pPLLReg, ~chipcHw_REG_PLL_CLOCK_SOURCE_GPIO);
|
||||
reg32_modify_or(pPLLReg, chipcHw_REG_PLL_CLOCK_BYPASS_SELECT);
|
||||
/* For DDR settings use only the PLL divider clock */
|
||||
if (pPLLReg == &pChipcHw->DDRClock) {
|
||||
/* Set M1DIV for PLL1, which controls the DDR clock */
|
||||
reg32_write(&pChipcHw->PLLDivider, (pChipcHw->PLLDivider & 0x00FFFFFF) | ((chipcHw_REG_PLL_DIVIDER_MDIV (desVcoHz, freq)) << 24));
|
||||
/* Calculate expected frequency */
|
||||
freq = chipcHw_divide(vcoHz, (((pChipcHw->PLLDivider & 0xFF000000) >> 24) ? ((pChipcHw->PLLDivider & 0xFF000000) >> 24) : 256));
|
||||
} else {
|
||||
/* From chip revision number B0, LCD clock is internally divided by 2 */
|
||||
if ((pPLLReg == &pChipcHw->LCDClock) && (chipcHw_getChipRevisionNumber() != chipcHw_REV_NUMBER_A0)) {
|
||||
desVcoHz >>= 1;
|
||||
vcoHz >>= 1;
|
||||
}
|
||||
/* Set MDIV to change the frequency */
|
||||
reg32_modify_and(pPLLReg, ~(chipcHw_REG_PLL_CLOCK_MDIV_MASK));
|
||||
reg32_modify_or(pPLLReg, chipcHw_REG_PLL_DIVIDER_MDIV(desVcoHz, freq));
|
||||
/* Calculate expected frequency */
|
||||
freq = chipcHw_divide(vcoHz, ((*(pPLLReg) & chipcHw_REG_PLL_CLOCK_MDIV_MASK) ? (*(pPLLReg) & chipcHw_REG_PLL_CLOCK_MDIV_MASK) : 256));
|
||||
}
|
||||
/* Wait for for atleast 200ns as per the protocol to change frequency */
|
||||
udelay(1);
|
||||
/* Do not bypass */
|
||||
reg32_modify_and(pPLLReg, ~chipcHw_REG_PLL_CLOCK_BYPASS_SELECT);
|
||||
/* Return the configured frequency */
|
||||
return freq;
|
||||
} else if (pClockCtrl) {
|
||||
uint32_t divider = 0;
|
||||
|
||||
/* Divider clock should not be bypassed */
|
||||
reg32_modify_and(pClockCtrl,
|
||||
~chipcHw_REG_DIV_CLOCK_BYPASS_SELECT);
|
||||
|
||||
/* Identify the clock source */
|
||||
if (pDependentClock) {
|
||||
switch (dependentClockType) {
|
||||
case PLL_CLOCK:
|
||||
divider = chipcHw_divide(chipcHw_divide (desVcoHz, (*pDependentClock & chipcHw_REG_PLL_CLOCK_MDIV_MASK)), freq);
|
||||
break;
|
||||
case NON_PLL_CLOCK:
|
||||
{
|
||||
uint32_t sourceClock = 0;
|
||||
|
||||
if (pDependentClock == (uint32_t *) &pChipcHw->ACLKClock) {
|
||||
sourceClock = chipcHw_getClockFrequency (chipcHw_CLOCK_BUS);
|
||||
} else {
|
||||
uint32_t div = *pDependentClock & chipcHw_REG_DIV_CLOCK_DIV_MASK;
|
||||
sourceClock = chipcHw_divide (chipcHw_XTAL_FREQ_Hz, ((div) ? div : 256));
|
||||
}
|
||||
divider = chipcHw_divide(sourceClock, freq);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
divider = chipcHw_divide(chipcHw_XTAL_FREQ_Hz, freq);
|
||||
}
|
||||
|
||||
if (divider) {
|
||||
REG_LOCAL_IRQ_SAVE;
|
||||
/* Set the divider to obtain the required frequency */
|
||||
*pClockCtrl = (*pClockCtrl & (~chipcHw_REG_DIV_CLOCK_DIV_MASK)) | (((divider > 256) ? chipcHw_REG_DIV_CLOCK_DIV_256 : divider) & chipcHw_REG_DIV_CLOCK_DIV_MASK);
|
||||
REG_LOCAL_IRQ_RESTORE;
|
||||
return freq;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(chipcHw_setClockFrequency);
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* @brief Set VPM clock in sync with BUS clock for Chip Rev #A0
|
||||
*
|
||||
* This function does the phase adjustment between VPM and BUS clock
|
||||
*
|
||||
* @return >= 0 : On success (# of adjustment required)
|
||||
* -1 : On failure
|
||||
*
|
||||
*/
|
||||
/****************************************************************************/
|
||||
static int vpmPhaseAlignA0(void)
|
||||
{
|
||||
uint32_t phaseControl;
|
||||
uint32_t phaseValue;
|
||||
uint32_t prevPhaseComp;
|
||||
int iter = 0;
|
||||
int adjustCount = 0;
|
||||
int count = 0;
|
||||
|
||||
for (iter = 0; (iter < MAX_PHASE_ALIGN_ATTEMPTS) && (adjustCount < MAX_PHASE_ADJUST_COUNT); iter++) {
|
||||
phaseControl = (pChipcHw->VPMClock & chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK) >> chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT;
|
||||
phaseValue = 0;
|
||||
prevPhaseComp = 0;
|
||||
|
||||
/* Step 1: Look for falling PH_COMP transition */
|
||||
|
||||
/* Read the contents of VPM Clock resgister */
|
||||
phaseValue = pChipcHw->VPMClock;
|
||||
do {
|
||||
/* Store previous value of phase comparator */
|
||||
prevPhaseComp = phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP;
|
||||
/* Change the value of PH_CTRL. */
|
||||
reg32_write(&pChipcHw->VPMClock, (pChipcHw->VPMClock & (~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK)) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT));
|
||||
/* Wait atleast 20 ns */
|
||||
udelay(1);
|
||||
/* Toggle the LOAD_CH after phase control is written. */
|
||||
pChipcHw->VPMClock ^= chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE;
|
||||
/* Read the contents of VPM Clock resgister. */
|
||||
phaseValue = pChipcHw->VPMClock;
|
||||
|
||||
if ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) == 0x0) {
|
||||
phaseControl = (0x3F & (phaseControl - 1));
|
||||
} else {
|
||||
/* Increment to the Phase count value for next write, if Phase is not stable. */
|
||||
phaseControl = (0x3F & (phaseControl + 1));
|
||||
}
|
||||
/* Count number of adjustment made */
|
||||
adjustCount++;
|
||||
} while (((prevPhaseComp == (phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP)) || /* Look for a transition */
|
||||
((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) != 0x0)) && /* Look for a falling edge */
|
||||
(adjustCount < MAX_PHASE_ADJUST_COUNT) /* Do not exceed the limit while trying */
|
||||
);
|
||||
|
||||
if (adjustCount >= MAX_PHASE_ADJUST_COUNT) {
|
||||
/* Failed to align VPM phase after MAX_PHASE_ADJUST_COUNT tries */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Step 2: Keep moving forward to make sure falling PH_COMP transition was valid */
|
||||
|
||||
for (count = 0; (count < 5) && ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) == 0); count++) {
|
||||
phaseControl = (0x3F & (phaseControl + 1));
|
||||
reg32_write(&pChipcHw->VPMClock, (pChipcHw->VPMClock & (~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK)) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT));
|
||||
/* Wait atleast 20 ns */
|
||||
udelay(1);
|
||||
/* Toggle the LOAD_CH after phase control is written. */
|
||||
pChipcHw->VPMClock ^= chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE;
|
||||
phaseValue = pChipcHw->VPMClock;
|
||||
/* Count number of adjustment made */
|
||||
adjustCount++;
|
||||
}
|
||||
|
||||
if (adjustCount >= MAX_PHASE_ADJUST_COUNT) {
|
||||
/* Failed to align VPM phase after MAX_PHASE_ADJUST_COUNT tries */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (count != 5) {
|
||||
/* Detected false transition */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Step 3: Keep moving backward to make sure falling PH_COMP transition was stable */
|
||||
|
||||
for (count = 0; (count < 3) && ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) == 0); count++) {
|
||||
phaseControl = (0x3F & (phaseControl - 1));
|
||||
reg32_write(&pChipcHw->VPMClock, (pChipcHw->VPMClock & (~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK)) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT));
|
||||
/* Wait atleast 20 ns */
|
||||
udelay(1);
|
||||
/* Toggle the LOAD_CH after phase control is written. */
|
||||
pChipcHw->VPMClock ^= chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE;
|
||||
phaseValue = pChipcHw->VPMClock;
|
||||
/* Count number of adjustment made */
|
||||
adjustCount++;
|
||||
}
|
||||
|
||||
if (adjustCount >= MAX_PHASE_ADJUST_COUNT) {
|
||||
/* Failed to align VPM phase after MAX_PHASE_ADJUST_COUNT tries */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (count != 3) {
|
||||
/* Detected noisy transition */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Step 4: Keep moving backward before the original transition took place. */
|
||||
|
||||
for (count = 0; (count < 5); count++) {
|
||||
phaseControl = (0x3F & (phaseControl - 1));
|
||||
reg32_write(&pChipcHw->VPMClock, (pChipcHw->VPMClock & (~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK)) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT));
|
||||
/* Wait atleast 20 ns */
|
||||
udelay(1);
|
||||
/* Toggle the LOAD_CH after phase control is written. */
|
||||
pChipcHw->VPMClock ^= chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE;
|
||||
phaseValue = pChipcHw->VPMClock;
|
||||
/* Count number of adjustment made */
|
||||
adjustCount++;
|
||||
}
|
||||
|
||||
if (adjustCount >= MAX_PHASE_ADJUST_COUNT) {
|
||||
/* Failed to align VPM phase after MAX_PHASE_ADJUST_COUNT tries */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) == 0) {
|
||||
/* Detected false transition */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Step 5: Re discover the valid transition */
|
||||
|
||||
do {
|
||||
/* Store previous value of phase comparator */
|
||||
prevPhaseComp = phaseValue;
|
||||
/* Change the value of PH_CTRL. */
|
||||
reg32_write(&pChipcHw->VPMClock, (pChipcHw->VPMClock & (~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK)) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT));
|
||||
/* Wait atleast 20 ns */
|
||||
udelay(1);
|
||||
/* Toggle the LOAD_CH after phase control is written. */
|
||||
pChipcHw->VPMClock ^=
|
||||
chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE;
|
||||
/* Read the contents of VPM Clock resgister. */
|
||||
phaseValue = pChipcHw->VPMClock;
|
||||
|
||||
if ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) == 0x0) {
|
||||
phaseControl = (0x3F & (phaseControl - 1));
|
||||
} else {
|
||||
/* Increment to the Phase count value for next write, if Phase is not stable. */
|
||||
phaseControl = (0x3F & (phaseControl + 1));
|
||||
}
|
||||
|
||||
/* Count number of adjustment made */
|
||||
adjustCount++;
|
||||
} while (((prevPhaseComp == (phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP)) || ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) != 0x0)) && (adjustCount < MAX_PHASE_ADJUST_COUNT));
|
||||
|
||||
if (adjustCount >= MAX_PHASE_ADJUST_COUNT) {
|
||||
/* Failed to align VPM phase after MAX_PHASE_ADJUST_COUNT tries */
|
||||
return -1;
|
||||
} else {
|
||||
/* Valid phase must have detected */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* For VPM Phase should be perfectly aligned. */
|
||||
phaseControl = (((pChipcHw->VPMClock >> chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT) - 1) & 0x3F);
|
||||
{
|
||||
REG_LOCAL_IRQ_SAVE;
|
||||
|
||||
pChipcHw->VPMClock = (pChipcHw->VPMClock & ~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT);
|
||||
/* Load new phase value */
|
||||
pChipcHw->VPMClock ^= chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE;
|
||||
|
||||
REG_LOCAL_IRQ_RESTORE;
|
||||
}
|
||||
/* Return the status */
|
||||
return (int)adjustCount;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* @brief Set VPM clock in sync with BUS clock
|
||||
*
|
||||
* This function does the phase adjustment between VPM and BUS clock
|
||||
*
|
||||
* @return >= 0 : On success (# of adjustment required)
|
||||
* -1 : On failure
|
||||
*
|
||||
*/
|
||||
/****************************************************************************/
|
||||
int chipcHw_vpmPhaseAlign(void)
|
||||
{
|
||||
|
||||
if (chipcHw_getChipRevisionNumber() == chipcHw_REV_NUMBER_A0) {
|
||||
return vpmPhaseAlignA0();
|
||||
} else {
|
||||
uint32_t phaseControl = chipcHw_getVpmPhaseControl();
|
||||
uint32_t phaseValue = 0;
|
||||
int adjustCount = 0;
|
||||
|
||||
/* Disable VPM access */
|
||||
pChipcHw->Spare1 &= ~chipcHw_REG_SPARE1_VPM_BUS_ACCESS_ENABLE;
|
||||
/* Disable HW VPM phase alignment */
|
||||
chipcHw_vpmHwPhaseAlignDisable();
|
||||
/* Enable SW VPM phase alignment */
|
||||
chipcHw_vpmSwPhaseAlignEnable();
|
||||
/* Adjust VPM phase */
|
||||
while (adjustCount < MAX_PHASE_ADJUST_COUNT) {
|
||||
phaseValue = chipcHw_getVpmHwPhaseAlignStatus();
|
||||
|
||||
/* Adjust phase control value */
|
||||
if (phaseValue > 0xF) {
|
||||
/* Increment phase control value */
|
||||
phaseControl++;
|
||||
} else if (phaseValue < 0xF) {
|
||||
/* Decrement phase control value */
|
||||
phaseControl--;
|
||||
} else {
|
||||
/* Enable VPM access */
|
||||
pChipcHw->Spare1 |= chipcHw_REG_SPARE1_VPM_BUS_ACCESS_ENABLE;
|
||||
/* Return adjust count */
|
||||
return adjustCount;
|
||||
}
|
||||
/* Change the value of PH_CTRL. */
|
||||
reg32_write(&pChipcHw->VPMClock, (pChipcHw->VPMClock & (~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK)) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT));
|
||||
/* Wait atleast 20 ns */
|
||||
udelay(1);
|
||||
/* Toggle the LOAD_CH after phase control is written. */
|
||||
pChipcHw->VPMClock ^= chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE;
|
||||
/* Count adjustment */
|
||||
adjustCount++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable VPM access */
|
||||
pChipcHw->Spare1 &= ~chipcHw_REG_SPARE1_VPM_BUS_ACCESS_ENABLE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* @brief Local Divide function
|
||||
*
|
||||
* This function does the divide
|
||||
*
|
||||
* @return divide value
|
||||
*
|
||||
*/
|
||||
/****************************************************************************/
|
||||
static int chipcHw_divide(int num, int denom)
|
||||
{
|
||||
int r;
|
||||
int t = 1;
|
||||
|
||||
/* Shift denom and t up to the largest value to optimize algorithm */
|
||||
/* t contains the units of each divide */
|
||||
while ((denom & 0x40000000) == 0) { /* fails if denom=0 */
|
||||
denom = denom << 1;
|
||||
t = t << 1;
|
||||
}
|
||||
|
||||
/* Intialize the result */
|
||||
r = 0;
|
||||
|
||||
do {
|
||||
/* Determine if there exists a positive remainder */
|
||||
if ((num - denom) >= 0) {
|
||||
/* Accumlate t to the result and calculate a new remainder */
|
||||
num = num - denom;
|
||||
r = r + t;
|
||||
}
|
||||
/* Continue to shift denom and shift t down to 0 */
|
||||
denom = denom >> 1;
|
||||
t = t >> 1;
|
||||
} while (t != 0);
|
||||
|
||||
return r;
|
||||
}
|
|
@ -0,0 +1,293 @@
|
|||
/*****************************************************************************
|
||||
* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
* under the terms of the GNU General Public License version 2, available at
|
||||
* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
|
||||
*
|
||||
* Notwithstanding the above, under no circumstances may you combine this
|
||||
* software in any way with any other Broadcom software provided under a
|
||||
* license other than the GPL, without Broadcom's express prior written
|
||||
* consent.
|
||||
*****************************************************************************/
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* @file chipcHw_init.c
|
||||
*
|
||||
* @brief Low level CHIPC PLL configuration functions
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* These routines provide basic PLL controlling functionality only.
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
/* ---- Include Files ---------------------------------------------------- */
|
||||
|
||||
#include <csp/errno.h>
|
||||
#include <csp/stdint.h>
|
||||
#include <csp/module.h>
|
||||
|
||||
#include <mach/csp/chipcHw_def.h>
|
||||
#include <mach/csp/chipcHw_inline.h>
|
||||
|
||||
#include <csp/reg.h>
|
||||
#include <csp/delay.h>
|
||||
/* ---- Private Constants and Types --------------------------------------- */
|
||||
|
||||
/*
|
||||
Calculation for NDIV_i to obtain VCO frequency
|
||||
-----------------------------------------------
|
||||
|
||||
Freq_vco = Freq_ref * (P2 / P1) * (PLL_NDIV_i + PLL_NDIV_f)
|
||||
for Freq_vco = VCO_FREQ_MHz
|
||||
Freq_ref = chipcHw_XTAL_FREQ_Hz
|
||||
PLL_P1 = PLL_P2 = 1
|
||||
and
|
||||
PLL_NDIV_f = 0
|
||||
|
||||
We get:
|
||||
PLL_NDIV_i = Freq_vco / Freq_ref = VCO_FREQ_MHz / chipcHw_XTAL_FREQ_Hz
|
||||
|
||||
Calculation for PLL MDIV to obtain frequency Freq_x for channel x
|
||||
-----------------------------------------------------------------
|
||||
Freq_x = chipcHw_XTAL_FREQ_Hz * PLL_NDIV_i / PLL_MDIV_x = VCO_FREQ_MHz / PLL_MDIV_x
|
||||
|
||||
PLL_MDIV_x = VCO_FREQ_MHz / Freq_x
|
||||
*/
|
||||
|
||||
/* ---- Private Variables ------------------------------------------------- */
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* @brief Initializes the PLL2
|
||||
*
|
||||
* This function initializes the PLL2
|
||||
*
|
||||
*/
|
||||
/****************************************************************************/
|
||||
void chipcHw_pll2Enable(uint32_t vcoFreqHz)
|
||||
{
|
||||
uint32_t pllPreDivider2 = 0;
|
||||
|
||||
{
|
||||
REG_LOCAL_IRQ_SAVE;
|
||||
pChipcHw->PLLConfig2 =
|
||||
chipcHw_REG_PLL_CONFIG_D_RESET |
|
||||
chipcHw_REG_PLL_CONFIG_A_RESET;
|
||||
|
||||
pllPreDivider2 = chipcHw_REG_PLL_PREDIVIDER_POWER_DOWN |
|
||||
chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_INTEGER |
|
||||
(chipcHw_REG_PLL_PREDIVIDER_NDIV_i(vcoFreqHz) <<
|
||||
chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT) |
|
||||
(chipcHw_REG_PLL_PREDIVIDER_P1 <<
|
||||
chipcHw_REG_PLL_PREDIVIDER_P1_SHIFT) |
|
||||
(chipcHw_REG_PLL_PREDIVIDER_P2 <<
|
||||
chipcHw_REG_PLL_PREDIVIDER_P2_SHIFT);
|
||||
|
||||
/* Enable CHIPC registers to control the PLL */
|
||||
pChipcHw->PLLStatus |= chipcHw_REG_PLL_STATUS_CONTROL_ENABLE;
|
||||
|
||||
/* Set pre divider to get desired VCO frequency */
|
||||
pChipcHw->PLLPreDivider2 = pllPreDivider2;
|
||||
/* Set NDIV Frac */
|
||||
pChipcHw->PLLDivider2 = chipcHw_REG_PLL_DIVIDER_NDIV_f;
|
||||
|
||||
/* This has to be removed once the default values are fixed for PLL2. */
|
||||
pChipcHw->PLLControl12 = 0x38000700;
|
||||
pChipcHw->PLLControl22 = 0x00000015;
|
||||
|
||||
/* Reset PLL2 */
|
||||
if (vcoFreqHz > chipcHw_REG_PLL_CONFIG_VCO_SPLIT_FREQ) {
|
||||
pChipcHw->PLLConfig2 = chipcHw_REG_PLL_CONFIG_D_RESET |
|
||||
chipcHw_REG_PLL_CONFIG_A_RESET |
|
||||
chipcHw_REG_PLL_CONFIG_VCO_1601_3200 |
|
||||
chipcHw_REG_PLL_CONFIG_POWER_DOWN;
|
||||
} else {
|
||||
pChipcHw->PLLConfig2 = chipcHw_REG_PLL_CONFIG_D_RESET |
|
||||
chipcHw_REG_PLL_CONFIG_A_RESET |
|
||||
chipcHw_REG_PLL_CONFIG_VCO_800_1600 |
|
||||
chipcHw_REG_PLL_CONFIG_POWER_DOWN;
|
||||
}
|
||||
REG_LOCAL_IRQ_RESTORE;
|
||||
}
|
||||
|
||||
/* Insert certain amount of delay before deasserting ARESET. */
|
||||
udelay(1);
|
||||
|
||||
{
|
||||
REG_LOCAL_IRQ_SAVE;
|
||||
/* Remove analog reset and Power on the PLL */
|
||||
pChipcHw->PLLConfig2 &=
|
||||
~(chipcHw_REG_PLL_CONFIG_A_RESET |
|
||||
chipcHw_REG_PLL_CONFIG_POWER_DOWN);
|
||||
|
||||
REG_LOCAL_IRQ_RESTORE;
|
||||
|
||||
}
|
||||
|
||||
/* Wait until PLL is locked */
|
||||
while (!(pChipcHw->PLLStatus2 & chipcHw_REG_PLL_STATUS_LOCKED))
|
||||
;
|
||||
|
||||
{
|
||||
REG_LOCAL_IRQ_SAVE;
|
||||
/* Remove digital reset */
|
||||
pChipcHw->PLLConfig2 &= ~chipcHw_REG_PLL_CONFIG_D_RESET;
|
||||
|
||||
REG_LOCAL_IRQ_RESTORE;
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(chipcHw_pll2Enable);
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* @brief Initializes the PLL1
|
||||
*
|
||||
* This function initializes the PLL1
|
||||
*
|
||||
*/
|
||||
/****************************************************************************/
|
||||
void chipcHw_pll1Enable(uint32_t vcoFreqHz, chipcHw_SPREAD_SPECTRUM_e ssSupport)
|
||||
{
|
||||
uint32_t pllPreDivider = 0;
|
||||
|
||||
{
|
||||
REG_LOCAL_IRQ_SAVE;
|
||||
|
||||
pChipcHw->PLLConfig =
|
||||
chipcHw_REG_PLL_CONFIG_D_RESET |
|
||||
chipcHw_REG_PLL_CONFIG_A_RESET;
|
||||
/* Setting VCO frequency */
|
||||
if (ssSupport == chipcHw_SPREAD_SPECTRUM_ALLOW) {
|
||||
pllPreDivider =
|
||||
chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASH_1_8 |
|
||||
((chipcHw_REG_PLL_PREDIVIDER_NDIV_i(vcoFreqHz) -
|
||||
1) << chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT) |
|
||||
(chipcHw_REG_PLL_PREDIVIDER_P1 <<
|
||||
chipcHw_REG_PLL_PREDIVIDER_P1_SHIFT) |
|
||||
(chipcHw_REG_PLL_PREDIVIDER_P2 <<
|
||||
chipcHw_REG_PLL_PREDIVIDER_P2_SHIFT);
|
||||
} else {
|
||||
pllPreDivider = chipcHw_REG_PLL_PREDIVIDER_POWER_DOWN |
|
||||
chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_INTEGER |
|
||||
(chipcHw_REG_PLL_PREDIVIDER_NDIV_i(vcoFreqHz) <<
|
||||
chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT) |
|
||||
(chipcHw_REG_PLL_PREDIVIDER_P1 <<
|
||||
chipcHw_REG_PLL_PREDIVIDER_P1_SHIFT) |
|
||||
(chipcHw_REG_PLL_PREDIVIDER_P2 <<
|
||||
chipcHw_REG_PLL_PREDIVIDER_P2_SHIFT);
|
||||
}
|
||||
|
||||
/* Enable CHIPC registers to control the PLL */
|
||||
pChipcHw->PLLStatus |= chipcHw_REG_PLL_STATUS_CONTROL_ENABLE;
|
||||
|
||||
/* Set pre divider to get desired VCO frequency */
|
||||
pChipcHw->PLLPreDivider = pllPreDivider;
|
||||
/* Set NDIV Frac */
|
||||
if (ssSupport == chipcHw_SPREAD_SPECTRUM_ALLOW) {
|
||||
pChipcHw->PLLDivider = chipcHw_REG_PLL_DIVIDER_M1DIV |
|
||||
chipcHw_REG_PLL_DIVIDER_NDIV_f_SS;
|
||||
} else {
|
||||
pChipcHw->PLLDivider = chipcHw_REG_PLL_DIVIDER_M1DIV |
|
||||
chipcHw_REG_PLL_DIVIDER_NDIV_f;
|
||||
}
|
||||
|
||||
/* Reset PLL1 */
|
||||
if (vcoFreqHz > chipcHw_REG_PLL_CONFIG_VCO_SPLIT_FREQ) {
|
||||
pChipcHw->PLLConfig = chipcHw_REG_PLL_CONFIG_D_RESET |
|
||||
chipcHw_REG_PLL_CONFIG_A_RESET |
|
||||
chipcHw_REG_PLL_CONFIG_VCO_1601_3200 |
|
||||
chipcHw_REG_PLL_CONFIG_POWER_DOWN;
|
||||
} else {
|
||||
pChipcHw->PLLConfig = chipcHw_REG_PLL_CONFIG_D_RESET |
|
||||
chipcHw_REG_PLL_CONFIG_A_RESET |
|
||||
chipcHw_REG_PLL_CONFIG_VCO_800_1600 |
|
||||
chipcHw_REG_PLL_CONFIG_POWER_DOWN;
|
||||
}
|
||||
|
||||
REG_LOCAL_IRQ_RESTORE;
|
||||
|
||||
/* Insert certain amount of delay before deasserting ARESET. */
|
||||
udelay(1);
|
||||
|
||||
{
|
||||
REG_LOCAL_IRQ_SAVE;
|
||||
/* Remove analog reset and Power on the PLL */
|
||||
pChipcHw->PLLConfig &=
|
||||
~(chipcHw_REG_PLL_CONFIG_A_RESET |
|
||||
chipcHw_REG_PLL_CONFIG_POWER_DOWN);
|
||||
REG_LOCAL_IRQ_RESTORE;
|
||||
}
|
||||
|
||||
/* Wait until PLL is locked */
|
||||
while (!(pChipcHw->PLLStatus & chipcHw_REG_PLL_STATUS_LOCKED)
|
||||
|| !(pChipcHw->
|
||||
PLLStatus2 & chipcHw_REG_PLL_STATUS_LOCKED))
|
||||
;
|
||||
|
||||
/* Remove digital reset */
|
||||
{
|
||||
REG_LOCAL_IRQ_SAVE;
|
||||
pChipcHw->PLLConfig &= ~chipcHw_REG_PLL_CONFIG_D_RESET;
|
||||
REG_LOCAL_IRQ_RESTORE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(chipcHw_pll1Enable);
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* @brief Initializes the chipc module
|
||||
*
|
||||
* This function initializes the PLLs and core system clocks
|
||||
*
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
void chipcHw_Init(chipcHw_INIT_PARAM_t *initParam /* [ IN ] Misc chip initialization parameter */
|
||||
) {
|
||||
#if !(defined(__KERNEL__) && !defined(STANDALONE))
|
||||
delay_init();
|
||||
#endif
|
||||
|
||||
/* Do not program PLL, when warm reset */
|
||||
if (!(chipcHw_getStickyBits() & chipcHw_REG_STICKY_CHIP_WARM_RESET)) {
|
||||
chipcHw_pll1Enable(initParam->pllVcoFreqHz,
|
||||
initParam->ssSupport);
|
||||
chipcHw_pll2Enable(initParam->pll2VcoFreqHz);
|
||||
} else {
|
||||
/* Clear sticky bits */
|
||||
chipcHw_clearStickyBits(chipcHw_REG_STICKY_CHIP_WARM_RESET);
|
||||
}
|
||||
/* Clear sticky bits */
|
||||
chipcHw_clearStickyBits(chipcHw_REG_STICKY_CHIP_SOFT_RESET);
|
||||
|
||||
/* Before configuring the ARM clock, atleast we need to make sure BUS clock maintains the proper ratio with ARM clock */
|
||||
pChipcHw->ACLKClock =
|
||||
(pChipcHw->
|
||||
ACLKClock & ~chipcHw_REG_ACLKClock_CLK_DIV_MASK) | (initParam->
|
||||
armBusRatio &
|
||||
chipcHw_REG_ACLKClock_CLK_DIV_MASK);
|
||||
|
||||
/* Set various core component frequencies. The order in which this is done is important for some. */
|
||||
/* The RTBUS (DDR PHY) is derived from the BUS, and the BUS from the ARM, and VPM needs to know BUS */
|
||||
/* frequency to find its ratio with the BUS. Hence we must set the ARM first, followed by the BUS, */
|
||||
/* then VPM and RTBUS. */
|
||||
|
||||
chipcHw_setClockFrequency(chipcHw_CLOCK_ARM,
|
||||
initParam->busClockFreqHz *
|
||||
initParam->armBusRatio);
|
||||
chipcHw_setClockFrequency(chipcHw_CLOCK_BUS, initParam->busClockFreqHz);
|
||||
chipcHw_setClockFrequency(chipcHw_CLOCK_VPM,
|
||||
initParam->busClockFreqHz *
|
||||
initParam->vpmBusRatio);
|
||||
chipcHw_setClockFrequency(chipcHw_CLOCK_DDR,
|
||||
initParam->busClockFreqHz *
|
||||
initParam->ddrBusRatio);
|
||||
chipcHw_setClockFrequency(chipcHw_CLOCK_RTBUS,
|
||||
initParam->busClockFreqHz / 2);
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
/*****************************************************************************
|
||||
* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
* under the terms of the GNU General Public License version 2, available at
|
||||
* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
|
||||
*
|
||||
* Notwithstanding the above, under no circumstances may you combine this
|
||||
* software in any way with any other Broadcom software provided under a
|
||||
* license other than the GPL, without Broadcom's express prior written
|
||||
* consent.
|
||||
*****************************************************************************/
|
||||
|
||||
/* ---- Include Files ---------------------------------------------------- */
|
||||
#include <csp/stdint.h>
|
||||
#include <mach/csp/chipcHw_def.h>
|
||||
#include <mach/csp/chipcHw_inline.h>
|
||||
#include <csp/intcHw.h>
|
||||
#include <csp/cache.h>
|
||||
|
||||
/* ---- Private Constants and Types --------------------------------------- */
|
||||
/* ---- Private Variables ------------------------------------------------- */
|
||||
void chipcHw_reset_run_from_aram(void);
|
||||
|
||||
typedef void (*RUNFUNC) (void);
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* @brief warmReset
|
||||
*
|
||||
* @note warmReset configures the clocks which are not reset back to the state
|
||||
* required to execute on reset. To do so we need to copy the code into internal
|
||||
* memory to change the ARM clock while we are not executing from DDR.
|
||||
*/
|
||||
/****************************************************************************/
|
||||
void chipcHw_reset(uint32_t mask)
|
||||
{
|
||||
int i = 0;
|
||||
RUNFUNC runFunc = (RUNFUNC) (unsigned long)MM_ADDR_IO_ARAM;
|
||||
|
||||
/* Disable all interrupts */
|
||||
intcHw_irq_disable(INTCHW_INTC0, 0xffffffff);
|
||||
intcHw_irq_disable(INTCHW_INTC1, 0xffffffff);
|
||||
intcHw_irq_disable(INTCHW_SINTC, 0xffffffff);
|
||||
|
||||
{
|
||||
REG_LOCAL_IRQ_SAVE;
|
||||
if (mask & chipcHw_REG_SOFT_RESET_CHIP_SOFT) {
|
||||
chipcHw_softReset(chipcHw_REG_SOFT_RESET_CHIP_SOFT);
|
||||
}
|
||||
/* Bypass the PLL clocks before reboot */
|
||||
pChipcHw->UARTClock |= chipcHw_REG_PLL_CLOCK_BYPASS_SELECT;
|
||||
pChipcHw->SPIClock |= chipcHw_REG_PLL_CLOCK_BYPASS_SELECT;
|
||||
|
||||
/* Copy the chipcHw_warmReset_run_from_aram function into ARAM */
|
||||
do {
|
||||
((uint32_t *) MM_IO_BASE_ARAM)[i] =
|
||||
((uint32_t *) &chipcHw_reset_run_from_aram)[i];
|
||||
i++;
|
||||
} while (((uint32_t *) MM_IO_BASE_ARAM)[i - 1] != 0xe1a0f00f); /* 0xe1a0f00f == asm ("mov r15, r15"); */
|
||||
|
||||
CSP_CACHE_FLUSH_ALL;
|
||||
|
||||
/* run the function from ARAM */
|
||||
runFunc();
|
||||
|
||||
/* Code will never get here, but include it to balance REG_LOCAL_IRQ_SAVE above */
|
||||
REG_LOCAL_IRQ_RESTORE;
|
||||
}
|
||||
}
|
||||
|
||||
/* This function must run from internal memory */
|
||||
void chipcHw_reset_run_from_aram(void)
|
||||
{
|
||||
/* Make sure, pipeline is filled with instructions coming from ARAM */
|
||||
__asm (" nop \n\t"
|
||||
" nop \n\t"
|
||||
#if defined(__KERNEL__) && !defined(STANDALONE)
|
||||
" MRC p15,#0x0,r0,c1,c0,#0 \n\t"
|
||||
" BIC r0,r0,#0xd \n\t"
|
||||
" MCR p15,#0x0,r0,c1,c0,#0 \n\t"
|
||||
" nop \n\t"
|
||||
" nop \n\t"
|
||||
" nop \n\t"
|
||||
" nop \n\t"
|
||||
" nop \n\t"
|
||||
" nop \n\t"
|
||||
#endif
|
||||
" nop \n\t"
|
||||
" nop \n\t"
|
||||
/* Bypass the ARM clock and switch to XTAL clock */
|
||||
" MOV r2,#0x80000000 \n\t"
|
||||
" LDR r3,[r2,#8] \n\t"
|
||||
" ORR r3,r3,#0x20000 \n\t"
|
||||
" STR r3,[r2,#8] \n\t"
|
||||
|
||||
" nop \n\t"
|
||||
" nop \n\t"
|
||||
" nop \n\t"
|
||||
" nop \n\t"
|
||||
" nop \n\t"
|
||||
" nop \n\t"
|
||||
" nop \n\t"
|
||||
" nop \n\t"
|
||||
" nop \n\t"
|
||||
" nop \n\t"
|
||||
" nop \n\t"
|
||||
" nop \n\t"
|
||||
" nop \n\t"
|
||||
" nop \n\t"
|
||||
" nop \n\t"
|
||||
" nop \n\t"
|
||||
" nop \n\t"
|
||||
" nop \n\t"
|
||||
" nop \n\t"
|
||||
" nop \n\t"
|
||||
/* Issue reset */
|
||||
" MOV r3,#0x2 \n\t"
|
||||
" STR r3,[r2,#0x80] \n\t"
|
||||
/* End here */
|
||||
" MOV pc,pc \n\t");
|
||||
/* 0xe1a0f00f == asm ("mov r15, r15"); */
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*****************************************************************************
|
||||
* Copyright 2008 Broadcom Corporation. All rights reserved.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
* under the terms of the GNU General Public License version 2, available at
|
||||
* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
|
||||
*
|
||||
* Notwithstanding the above, under no circumstances may you combine this
|
||||
* software in any way with any other Broadcom software provided under a
|
||||
* license other than the GPL, without Broadcom's express prior written
|
||||
* consent.
|
||||
*****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* @file chipcHw_str.c
|
||||
*
|
||||
* @brief Contains strings which are useful to linux and csp
|
||||
*
|
||||
* @note
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
/* ---- Include Files ---------------------------------------------------- */
|
||||
|
||||
#include <mach/csp/chipcHw_inline.h>
|
||||
|
||||
/* ---- Private Constants and Types --------------------------------------- */
|
||||
|
||||
static const char *gMuxStr[] = {
|
||||
"GPIO", /* 0 */
|
||||
"KeyPad", /* 1 */
|
||||
"I2C-Host", /* 2 */
|
||||
"SPI", /* 3 */
|
||||
"Uart", /* 4 */
|
||||
"LED-Mtx-P", /* 5 */
|
||||
"LED-Mtx-S", /* 6 */
|
||||
"SDIO-0", /* 7 */
|
||||
"SDIO-1", /* 8 */
|
||||
"PCM", /* 9 */
|
||||
"I2S", /* 10 */
|
||||
"ETM", /* 11 */
|
||||
"Debug", /* 12 */
|
||||
"Misc", /* 13 */
|
||||
"0xE", /* 14 */
|
||||
"0xF", /* 15 */
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* @brief Retrieves a string representation of the mux setting for a pin.
|
||||
*
|
||||
* @return Pointer to a character string.
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
const char *chipcHw_getGpioPinFunctionStr(int pin)
|
||||
{
|
||||
if ((pin < 0) || (pin >= chipcHw_GPIO_COUNT)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return gMuxStr[chipcHw_getGpioPinFunction(pin)];
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
obj-y += dmacHw.o dmacHw_extra.o
|
|
@ -0,0 +1,917 @@
|
|||
/*****************************************************************************
|
||||
* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
|
||||
*
|
||||
* Unless you and Broadcom execute a separate written software license
|
||||
* agreement governing use of this software, this software is licensed to you
|
||||
* under the terms of the GNU General Public License version 2, available at
|
||||
* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
|
||||
*
|
||||
* Notwithstanding the above, under no circumstances may you combine this
|
||||
* software in any way with any other Broadcom software provided under a
|
||||
* license other than the GPL, without Broadcom's express prior written
|
||||
* consent.
|
||||
*****************************************************************************/
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* @file dmacHw.c
|
||||
*
|
||||
* @brief Low level DMA controller driver routines
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* These routines provide basic DMA functionality only.
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
/* ---- Include Files ---------------------------------------------------- */
|
||||
#include <csp/stdint.h>
|
||||
#include <csp/string.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <csp/dmacHw.h>
|
||||
#include <mach/csp/dmacHw_reg.h>
|
||||
#include <mach/csp/dmacHw_priv.h>
|
||||
#include <mach/csp/chipcHw_inline.h>
|
||||
|
||||
/* ---- External Function Prototypes ------------------------------------- */
|
||||
|
||||
/* Allocate DMA control blocks */
|
||||
dmacHw_CBLK_t dmacHw_gCblk[dmacHw_MAX_CHANNEL_COUNT];
|
||||
|
||||
uint32_t dmaChannelCount_0 = dmacHw_MAX_CHANNEL_COUNT / 2;
|
||||
uint32_t dmaChannelCount_1 = dmacHw_MAX_CHANNEL_COUNT / 2;
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* @brief Get maximum FIFO for a DMA channel
|
||||
*
|
||||
* @return Maximum allowable FIFO size
|
||||
*
|
||||
*
|
||||
*/
|
||||
/****************************************************************************/
|
||||
static uint32_t GetFifoSize(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */
|
||||
) {
|
||||
uint32_t val = 0;
|
||||
dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
|
||||
dmacHw_MISC_t *pMiscReg =
|
||||
(dmacHw_MISC_t *) dmacHw_REG_MISC_BASE(pCblk->module);
|
||||
|
||||
switch (pCblk->channel) {
|
||||
case 0:
|
||||
val = (pMiscReg->CompParm2.lo & 0x70000000) >> 28;
|
||||
break;
|
||||
case 1:
|
||||
val = (pMiscReg->CompParm3.hi & 0x70000000) >> 28;
|
||||
break;
|
||||
case 2:
|
||||
val = (pMiscReg->CompParm3.lo & 0x70000000) >> 28;
|
||||
break;
|
||||
case 3:
|
||||
val = (pMiscReg->CompParm4.hi & 0x70000000) >> 28;
|
||||
break;
|
||||
case 4:
|
||||
val = (pMiscReg->CompParm4.lo & 0x70000000) >> 28;
|
||||
break;
|
||||
case 5:
|
||||
val = (pMiscReg->CompParm5.hi & 0x70000000) >> 28;
|
||||
break;
|
||||
case 6:
|
||||
val = (pMiscReg->CompParm5.lo & 0x70000000) >> 28;
|
||||
break;
|
||||
case 7:
|
||||
val = (pMiscReg->CompParm6.hi & 0x70000000) >> 28;
|
||||
break;
|
||||
}
|
||||
|
||||
if (val <= 0x4) {
|
||||
return 8 << val;
|
||||
} else {
|
||||
dmacHw_ASSERT(0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* @brief Program channel register to initiate transfer
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
*
|
||||
* @note
|
||||
* - Descriptor buffer MUST ALWAYS be flushed before calling this function
|
||||
* - This function should also be called from ISR to program the channel with
|
||||
* pending descriptors
|
||||
*/
|
||||
/****************************************************************************/
|
||||
void dmacHw_initiateTransfer(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
|
||||
dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
|
||||
void *pDescriptor /* [ IN ] Descriptor buffer */
|
||||
) {
|
||||
dmacHw_DESC_RING_t *pRing;
|
||||
dmacHw_DESC_t *pProg;
|
||||
dmacHw_CBLK_t *pCblk;
|
||||
|
||||
pCblk = dmacHw_HANDLE_TO_CBLK(handle);
|
||||
pRing = dmacHw_GET_DESC_RING(pDescriptor);
|
||||
|
||||
if (CHANNEL_BUSY(pCblk->module, pCblk->channel)) {
|
||||
/* Not safe yet to program the channel */
|
||||
return;
|
||||
}
|
||||
|
||||
if (pCblk->varDataStarted) {
|
||||
if (pCblk->descUpdated) {
|
||||
pCblk->descUpdated = 0;
|
||||
pProg =
|
||||
(dmacHw_DESC_t *) ((uint32_t)
|
||||
dmacHw_REG_LLP(pCblk->module,
|
||||
pCblk->channel) +
|
||||
pRing->virt2PhyOffset);
|
||||
|
||||
/* Load descriptor if not loaded */
|
||||
if (!(pProg->ctl.hi & dmacHw_REG_CTL_DONE)) {
|
||||
dmacHw_SET_SAR(pCblk->module, pCblk->channel,
|
||||
pProg->sar);
|
||||
dmacHw_SET_DAR(pCblk->module, pCblk->channel,
|
||||
pProg->dar);
|
||||
dmacHw_REG_CTL_LO(pCblk->module,
|
||||
pCblk->channel) =
|
||||
pProg->ctl.lo;
|
||||
dmacHw_REG_CTL_HI(pCblk->module,
|
||||
pCblk->channel) =
|
||||
pProg->ctl.hi;
|
||||
} else if (pProg == (dmacHw_DESC_t *) pRing->pEnd->llp) {
|
||||
/* Return as end descriptor is processed */
|
||||
return;
|
||||
} else {
|
||||
dmacHw_ASSERT(0);
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (pConfig->transferMode == dmacHw_TRANSFER_MODE_PERIODIC) {
|
||||
/* Do not make a single chain, rather process one descriptor at a time */
|
||||
pProg = pRing->pHead;
|
||||
/* Point to the next descriptor for next iteration */
|
||||
dmacHw_NEXT_DESC(pRing, pHead);
|
||||
} else {
|
||||
/* Return if no more pending descriptor */
|
||||
if (pRing->pEnd == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
pProg = pRing->pProg;
|
||||
if (pConfig->transferMode ==
|
||||
dmacHw_TRANSFER_MODE_CONTINUOUS) {
|
||||
/* Make sure a complete ring can be formed */
|
||||
dmacHw_ASSERT((dmacHw_DESC_t *) pRing->pEnd->
|
||||
llp == pRing->pProg);
|
||||
/* Make sure pProg pointing to the pHead */
|
||||
dmacHw_ASSERT((dmacHw_DESC_t *) pRing->pProg ==
|
||||
pRing->pHead);
|
||||
/* Make a complete ring */
|
||||
do {
|
||||
pRing->pProg->ctl.lo |=
|
||||
(dmacHw_REG_CTL_LLP_DST_EN |
|
||||
dmacHw_REG_CTL_LLP_SRC_EN);
|
||||
pRing->pProg =
|
||||
(dmacHw_DESC_t *) pRing->pProg->llp;
|
||||
} while (pRing->pProg != pRing->pHead);
|
||||
} else {
|
||||
/* Make a single long chain */
|
||||
while (pRing->pProg != pRing->pEnd) {
|
||||
pRing->pProg->ctl.lo |=
|
||||
(dmacHw_REG_CTL_LLP_DST_EN |
|
||||
dmacHw_REG_CTL_LLP_SRC_EN);
|
||||
pRing->pProg =
|
||||
(dmacHw_DESC_t *) pRing->pProg->llp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Program the channel registers */
|
||||
dmacHw_SET_SAR(pCblk->module, pCblk->channel, pProg->sar);
|
||||
dmacHw_SET_DAR(pCblk->module, pCblk->channel, pProg->dar);
|
||||
dmacHw_SET_LLP(pCblk->module, pCblk->channel,
|
||||
(uint32_t) pProg - pRing->virt2PhyOffset);
|
||||
dmacHw_REG_CTL_LO(pCblk->module, pCblk->channel) =
|
||||
pProg->ctl.lo;
|
||||
dmacHw_REG_CTL_HI(pCblk->module, pCblk->channel) =
|
||||
pProg->ctl.hi;
|
||||
if (pRing->pEnd) {
|
||||
/* Remember the descriptor to use next */
|
||||
pRing->pProg = (dmacHw_DESC_t *) pRing->pEnd->llp;
|
||||
}
|
||||
/* Indicate no more pending descriptor */
|
||||
pRing->pEnd = (dmacHw_DESC_t *) NULL;
|
||||
}
|
||||
/* Start DMA operation */
|
||||
dmacHw_DMA_START(pCblk->module, pCblk->channel);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* @brief Initializes DMA
|
||||
*
|
||||
* This function initializes DMA CSP driver
|
||||
*
|
||||
* @note
|
||||
* Must be called before using any DMA channel
|
||||
*/
|
||||
/****************************************************************************/
|
||||
void dmacHw_initDma(void)
|
||||
{
|
||||
|
||||
uint32_t i = 0;
|
||||
|
||||
dmaChannelCount_0 = dmacHw_GET_NUM_CHANNEL(0);
|
||||
dmaChannelCount_1 = dmacHw_GET_NUM_CHANNEL(1);
|
||||
|
||||
/* Enable access to the DMA block */
|
||||
chipcHw_busInterfaceClockEnable(chipcHw_REG_BUS_CLOCK_DMAC0);
|
||||
chipcHw_busInterfaceClockEnable(chipcHw_REG_BUS_CLOCK_DMAC1);
|
||||
|
||||
if ((dmaChannelCount_0 + dmaChannelCount_1) > dmacHw_MAX_CHANNEL_COUNT) {
|
||||
dmacHw_ASSERT(0);
|
||||
}
|
||||
|
||||
memset((void *)dmacHw_gCblk, 0,
|
||||
sizeof(dmacHw_CBLK_t) * (dmaChannelCount_0 + dmaChannelCount_1));
|
||||
for (i = 0; i < dmaChannelCount_0; i++) {
|
||||
dmacHw_gCblk[i].module = 0;
|
||||
dmacHw_gCblk[i].channel = i;
|
||||
}
|
||||
for (i = 0; i < dmaChannelCount_1; i++) {
|
||||
dmacHw_gCblk[i + dmaChannelCount_0].module = 1;
|
||||
dmacHw_gCblk[i + dmaChannelCount_0].channel = i;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* @brief Exit function for DMA
|
||||
*
|
||||
* This function isolates DMA from the system
|
||||
*
|
||||
*/
|
||||
/****************************************************************************/
|
||||
void dmacHw_exitDma(void)
|
||||
{
|
||||
/* Disable access to the DMA block */
|
||||
chipcHw_busInterfaceClockDisable(chipcHw_REG_BUS_CLOCK_DMAC0);
|
||||
chipcHw_busInterfaceClockDisable(chipcHw_REG_BUS_CLOCK_DMAC1);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* @brief Gets a handle to a DMA channel
|
||||
*
|
||||
* This function returns a handle, representing a control block of a particular DMA channel
|
||||
*
|
||||
* @return -1 - On Failure
|
||||
* handle - On Success, representing a channel control block
|
||||
*
|
||||
* @note
|
||||
* None Channel ID must be created using "dmacHw_MAKE_CHANNEL_ID" macro
|
||||
*/
|
||||
/****************************************************************************/
|
||||
dmacHw_HANDLE_t dmacHw_getChannelHandle(dmacHw_ID_t channelId /* [ IN ] DMA Channel Id */
|
||||
) {
|
||||
int idx;
|
||||
|
||||
switch ((channelId >> 8)) {
|
||||
case 0:
|
||||
dmacHw_ASSERT((channelId & 0xff) < dmaChannelCount_0);
|
||||
idx = (channelId & 0xff);
|
||||
break;
|
||||
case 1:
|
||||
dmacHw_ASSERT((channelId & 0xff) < dmaChannelCount_1);
|
||||
idx = dmaChannelCount_0 + (channelId & 0xff);
|
||||
break;
|
||||
default:
|
||||
dmacHw_ASSERT(0);
|
||||
return (dmacHw_HANDLE_t) -1;
|
||||
}
|
||||
|
||||
return dmacHw_CBLK_TO_HANDLE(&dmacHw_gCblk[idx]);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* @brief Initializes a DMA channel for use
|
||||
*
|
||||
* This function initializes and resets a DMA channel for use
|
||||
*
|
||||
* @return -1 - On Failure
|
||||
* 0 - On Success
|
||||
*
|
||||
* @note
|
||||
* None
|
||||
*/
|
||||
/****************************************************************************/
|
||||
int dmacHw_initChannel(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */
|
||||
) {
|
||||
dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
|
||||
int module = pCblk->module;
|
||||
int channel = pCblk->channel;
|
||||
|
||||
/* Reinitialize the control block */
|
||||
memset((void *)pCblk, 0, sizeof(dmacHw_CBLK_t));
|
||||
pCblk->module = module;
|
||||
pCblk->channel = channel;
|
||||
|
||||
/* Enable DMA controller */
|
||||
dmacHw_DMA_ENABLE(pCblk->module);
|
||||
/* Reset DMA channel */
|
||||
dmacHw_RESET_CONTROL_LO(pCblk->module, pCblk->channel);
|
||||
dmacHw_RESET_CONTROL_HI(pCblk->module, pCblk->channel);
|
||||
dmacHw_RESET_CONFIG_LO(pCblk->module, pCblk->channel);
|
||||
dmacHw_RESET_CONFIG_HI(pCblk->module, pCblk->channel);
|
||||
|
||||
/* Clear all raw interrupt status */
|
||||
dmacHw_TRAN_INT_CLEAR(pCblk->module, pCblk->channel);
|
||||
dmacHw_BLOCK_INT_CLEAR(pCblk->module, pCblk->channel);
|
||||
dmacHw_ERROR_INT_CLEAR(pCblk->module, pCblk->channel);
|
||||
|
||||
/* Mask event specific interrupts */
|
||||
dmacHw_TRAN_INT_DISABLE(pCblk->module, pCblk->channel);
|
||||
dmacHw_BLOCK_INT_DISABLE(pCblk->module, pCblk->channel);
|
||||
dmacHw_STRAN_INT_DISABLE(pCblk->module, pCblk->channel);
|
||||
dmacHw_DTRAN_INT_DISABLE(pCblk->module, pCblk->channel);
|
||||
dmacHw_ERROR_INT_DISABLE(pCblk->module, pCblk->channel);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* @brief Finds amount of memory required to form a descriptor ring
|
||||
*
|
||||
*
|
||||
* @return Number of bytes required to form a descriptor ring
|
||||
*
|
||||
*
|
||||
*/
|
||||
/****************************************************************************/
|
||||
uint32_t dmacHw_descriptorLen(uint32_t descCnt /* [ IN ] Number of descriptor in the ring */
|
||||
) {
|
||||
/* Need extra 4 byte to ensure 32 bit alignment */
|
||||
return (descCnt * sizeof(dmacHw_DESC_t)) + sizeof(dmacHw_DESC_RING_t) +
|
||||
sizeof(uint32_t);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* @brief Initializes descriptor ring
|
||||
*
|
||||
* This function will initializes the descriptor ring of a DMA channel
|
||||
*
|
||||
*
|
||||
* @return -1 - On failure
|
||||
* 0 - On success
|
||||
* @note
|
||||
* - "len" parameter should be obtained from "dmacHw_descriptorLen"
|
||||
* - Descriptor buffer MUST be 32 bit aligned and uncached as it is
|
||||
* accessed by ARM and DMA
|
||||
*/
|
||||
/****************************************************************************/
|
||||
int dmacHw_initDescriptor(void *pDescriptorVirt, /* [ IN ] Virtual address of uncahced buffer allocated to form descriptor ring */
|
||||
uint32_t descriptorPhyAddr, /* [ IN ] Physical address of pDescriptorVirt (descriptor buffer) */
|
||||
uint32_t len, /* [ IN ] Size of the pBuf */
|
||||
uint32_t num /* [ IN ] Number of descriptor in the ring */
|
||||
) {
|
||||
uint32_t i;
|
||||
dmacHw_DESC_RING_t *pRing;
|
||||
dmacHw_DESC_t *pDesc;
|
||||
|
||||
/* Check the alignment of the descriptor */
|
||||
if ((uint32_t) pDescriptorVirt & 0x00000003) {
|
||||
dmacHw_ASSERT(0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check if enough space has been allocated for descriptor ring */
|
||||
if (len < dmacHw_descriptorLen(num)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pRing = dmacHw_GET_DESC_RING(pDescriptorVirt);
|
||||
pRing->pHead =
|
||||
(dmacHw_DESC_t *) ((uint32_t) pRing + sizeof(dmacHw_DESC_RING_t));
|
||||
pRing->pFree = pRing->pTail = pRing->pEnd = pRing->pHead;
|
||||
pRing->pProg = dmacHw_DESC_INIT;
|
||||
/* Initialize link item chain, starting from the head */
|
||||
pDesc = pRing->pHead;
|
||||
/* Find the offset between virtual to physical address */
|
||||
pRing->virt2PhyOffset = (uint32_t) pDescriptorVirt - descriptorPhyAddr;
|
||||
|
||||
/* Form the descriptor ring */
|
||||
for (i = 0; i < num - 1; i++) {
|
||||
/* Clear link list item */
|
||||
memset((void *)pDesc, 0, sizeof(dmacHw_DESC_t));
|
||||
/* Point to the next item in the physical address */
|
||||
pDesc->llpPhy = (uint32_t) (pDesc + 1) - pRing->virt2PhyOffset;
|
||||
/* Point to the next item in the virtual address */
|
||||
pDesc->llp = (uint32_t) (pDesc + 1);
|
||||
/* Mark descriptor is ready to use */
|
||||
pDesc->ctl.hi = dmacHw_DESC_FREE;
|
||||
/* Look into next link list item */
|
||||
pDesc++;
|
||||
}
|
||||
|
||||
/* Clear last link list item */
|
||||
memset((void *)pDesc, 0, sizeof(dmacHw_DESC_t));
|
||||
/* Last item pointing to the first item in the
|
||||
physical address to complete the ring */
|
||||
pDesc->llpPhy = (uint32_t) pRing->pHead - pRing->virt2PhyOffset;
|
||||
/* Last item pointing to the first item in the
|
||||
virtual address to complete the ring
|
||||
*/
|
||||
pDesc->llp = (uint32_t) pRing->pHead;
|
||||
/* Mark descriptor is ready to use */
|
||||
pDesc->ctl.hi = dmacHw_DESC_FREE;
|
||||
/* Set the number of descriptors in the ring */
|
||||
pRing->num = num;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* @brief Configure DMA channel
|
||||
*
|
||||
* @return 0 : On success
|
||||
* -1 : On failure
|
||||
*/
|
||||
/****************************************************************************/
|
||||
int dmacHw_configChannel(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
|
||||
dmacHw_CONFIG_t *pConfig /* [ IN ] Configuration settings */
|
||||
) {
|
||||
dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
|
||||
uint32_t cfgHigh = 0;
|
||||
int srcTrSize;
|
||||
int dstTrSize;
|
||||
|
||||
pCblk->varDataStarted = 0;
|
||||
pCblk->userData = NULL;
|
||||
|
||||
/* Configure
|
||||
- Burst transaction when enough data in available in FIFO
|
||||
- AHB Access protection 1
|
||||
- Source and destination peripheral ports
|
||||
*/
|
||||
cfgHigh =
|
||||
dmacHw_REG_CFG_HI_FIFO_ENOUGH | dmacHw_REG_CFG_HI_AHB_HPROT_1 |
|
||||
dmacHw_SRC_PERI_INTF(pConfig->
|
||||
srcPeripheralPort) |
|
||||
dmacHw_DST_PERI_INTF(pConfig->dstPeripheralPort);
|
||||
/* Set priority */
|
||||
dmacHw_SET_CHANNEL_PRIORITY(pCblk->module, pCblk->channel,
|
||||
pConfig->channelPriority);
|
||||
|
||||
if (pConfig->dstStatusRegisterAddress != 0) {
|
||||
/* Destination status update enable */
|
||||
cfgHigh |= dmacHw_REG_CFG_HI_UPDATE_DST_STAT;
|
||||
/* Configure status registers */
|
||||
dmacHw_SET_DSTATAR(pCblk->module, pCblk->channel,
|
||||
pConfig->dstStatusRegisterAddress);
|
||||
}
|
||||
|
||||
if (pConfig->srcStatusRegisterAddress != 0) {
|
||||
/* Source status update enable */
|
||||
cfgHigh |= dmacHw_REG_CFG_HI_UPDATE_SRC_STAT;
|
||||
/* Source status update enable */
|
||||
dmacHw_SET_SSTATAR(pCblk->module, pCblk->channel,
|
||||
pConfig->srcStatusRegisterAddress);
|
||||
}
|
||||
/* Configure the config high register */
|
||||
dmacHw_GET_CONFIG_HI(pCblk->module, pCblk->channel) = cfgHigh;
|
||||
|
||||
/* Clear all raw interrupt status */
|
||||
dmacHw_TRAN_INT_CLEAR(pCblk->module, pCblk->channel);
|
||||
dmacHw_BLOCK_INT_CLEAR(pCblk->module, pCblk->channel);
|
||||
dmacHw_ERROR_INT_CLEAR(pCblk->module, pCblk->channel);
|
||||
|
||||
/* Configure block interrupt */
|
||||
if (pConfig->blockTransferInterrupt == dmacHw_INTERRUPT_ENABLE) {
|
||||
dmacHw_BLOCK_INT_ENABLE(pCblk->module, pCblk->channel);
|
||||
} else {
|
||||
dmacHw_BLOCK_INT_DISABLE(pCblk->module, pCblk->channel);
|
||||
}
|
||||
/* Configure complete transfer interrupt */
|
||||
if (pConfig->completeTransferInterrupt == dmacHw_INTERRUPT_ENABLE) {
|
||||
dmacHw_TRAN_INT_ENABLE(pCblk->module, pCblk->channel);
|
||||
} else {
|
||||
dmacHw_TRAN_INT_DISABLE(pCblk->module, pCblk->channel);
|
||||
}
|
||||
/* Configure error interrupt */
|
||||
if (pConfig->errorInterrupt == dmacHw_INTERRUPT_ENABLE) {
|
||||
dmacHw_ERROR_INT_ENABLE(pCblk->module, pCblk->channel);
|
||||
} else {
|
||||
dmacHw_ERROR_INT_DISABLE(pCblk->module, pCblk->channel);
|
||||
}
|
||||
/* Configure gather register */
|
||||
if (pConfig->srcGatherWidth) {
|
||||
srcTrSize =
|
||||
dmacHw_GetTrWidthInBytes(pConfig->srcMaxTransactionWidth);
|
||||
if (!
|
||||
((pConfig->srcGatherWidth % srcTrSize)
|
||||
&& (pConfig->srcGatherJump % srcTrSize))) {
|
||||
dmacHw_REG_SGR_LO(pCblk->module, pCblk->channel) =
|
||||
((pConfig->srcGatherWidth /
|
||||
srcTrSize) << 20) | (pConfig->srcGatherJump /
|
||||
srcTrSize);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/* Configure scatter register */
|
||||
if (pConfig->dstScatterWidth) {
|
||||
dstTrSize =
|
||||
dmacHw_GetTrWidthInBytes(pConfig->dstMaxTransactionWidth);
|
||||
if (!
|
||||
((pConfig->dstScatterWidth % dstTrSize)
|
||||
&& (pConfig->dstScatterJump % dstTrSize))) {
|
||||
dmacHw_REG_DSR_LO(pCblk->module, pCblk->channel) =
|
||||
((pConfig->dstScatterWidth /
|
||||
dstTrSize) << 20) | (pConfig->dstScatterJump /
|
||||
dstTrSize);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* @brief Indicates whether DMA transfer is in progress or completed
|
||||
*
|
||||
* @return DMA transfer status
|
||||
* dmacHw_TRANSFER_STATUS_BUSY: DMA Transfer ongoing
|
||||
* dmacHw_TRANSFER_STATUS_DONE: DMA Transfer completed
|
||||
* dmacHw_TRANSFER_STATUS_ERROR: DMA Transfer error
|
||||
*
|
||||
*/
|
||||
/****************************************************************************/
|
||||
dmacHw_TRANSFER_STATUS_e dmacHw_transferCompleted(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */
|
||||
) {
|
||||
dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
|
||||
|
||||
if (CHANNEL_BUSY(pCblk->module, pCblk->channel)) {
|
||||
return dmacHw_TRANSFER_STATUS_BUSY;
|
||||
} else if (dmacHw_REG_INT_RAW_ERROR(pCblk->module) &
|
||||
(0x00000001 << pCblk->channel)) {
|
||||
return dmacHw_TRANSFER_STATUS_ERROR;
|
||||
}
|
||||
|
||||
return dmacHw_TRANSFER_STATUS_DONE;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* @brief Set descriptors for known data length
|
||||
*
|
||||
* When DMA has to work as a flow controller, this function prepares the
|
||||
* descriptor chain to transfer data
|
||||
*
|
||||
* from:
|
||||
* - Memory to memory
|
||||
* - Peripheral to memory
|
||||
* - Memory to Peripheral
|
||||
* - Peripheral to Peripheral
|
||||
*
|
||||
* @return -1 - On failure
|
||||
* 0 - On success
|
||||
*
|
||||
*/
|
||||
/****************************************************************************/
|
||||
int dmacHw_setDataDescriptor(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
|
||||
void *pDescriptor, /* [ IN ] Descriptor buffer */
|
||||
void *pSrcAddr, /* [ IN ] Source (Peripheral/Memory) address */
|
||||
void *pDstAddr, /* [ IN ] Destination (Peripheral/Memory) address */
|
||||
size_t dataLen /* [ IN ] Data length in bytes */
|
||||
) {
|
||||
dmacHw_TRANSACTION_WIDTH_e dstTrWidth;
|
||||
dmacHw_TRANSACTION_WIDTH_e srcTrWidth;
|
||||
dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor);
|
||||
dmacHw_DESC_t *pStart;
|
||||
dmacHw_DESC_t *pProg;
|
||||
int srcTs = 0;
|
||||
int blkTs = 0;
|
||||
int oddSize = 0;
|
||||
int descCount = 0;
|
||||
int count = 0;
|
||||
int dstTrSize = 0;
|
||||
int srcTrSize = 0;
|
||||
uint32_t maxBlockSize = dmacHw_MAX_BLOCKSIZE;
|
||||
|
||||
dstTrSize = dmacHw_GetTrWidthInBytes(pConfig->dstMaxTransactionWidth);
|
||||
srcTrSize = dmacHw_GetTrWidthInBytes(pConfig->srcMaxTransactionWidth);
|
||||
|
||||
/* Skip Tx if buffer is NULL or length is unknown */
|
||||
if ((pSrcAddr == NULL) || (pDstAddr == NULL) || (dataLen == 0)) {
|
||||
/* Do not initiate transfer */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Ensure scatter and gather are transaction aligned */
|
||||
if ((pConfig->srcGatherWidth % srcTrSize)
|
||||
|| (pConfig->dstScatterWidth % dstTrSize)) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
/*
|
||||
Background 1: DMAC can not perform DMA if source and destination addresses are
|
||||
not properly aligned with the channel's transaction width. So, for successful
|
||||
DMA transfer, transaction width must be set according to the alignment of the
|
||||
source and destination address.
|
||||
*/
|
||||
|
||||
/* Adjust destination transaction width if destination address is not aligned properly */
|
||||
dstTrWidth = pConfig->dstMaxTransactionWidth;
|
||||
while (dmacHw_ADDRESS_MASK(dstTrSize) & (uint32_t) pDstAddr) {
|
||||
dstTrWidth = dmacHw_GetNextTrWidth(dstTrWidth);
|
||||
dstTrSize = dmacHw_GetTrWidthInBytes(dstTrWidth);
|
||||
}
|
||||
|
||||
/* Adjust source transaction width if source address is not aligned properly */
|
||||
srcTrWidth = pConfig->srcMaxTransactionWidth;
|
||||
while (dmacHw_ADDRESS_MASK(srcTrSize) & (uint32_t) pSrcAddr) {
|
||||
srcTrWidth = dmacHw_GetNextTrWidth(srcTrWidth);
|
||||
srcTrSize = dmacHw_GetTrWidthInBytes(srcTrWidth);
|
||||
}
|
||||
|
||||
/* Find the maximum transaction per descriptor */
|
||||
if (pConfig->maxDataPerBlock
|
||||
&& ((pConfig->maxDataPerBlock / srcTrSize) <
|
||||
dmacHw_MAX_BLOCKSIZE)) {
|
||||
maxBlockSize = pConfig->maxDataPerBlock / srcTrSize;
|
||||
}
|
||||
|
||||
/* Find number of source transactions needed to complete the DMA transfer */
|
||||
srcTs = dataLen / srcTrSize;
|
||||
/* Find the odd number of bytes that need to be transferred as single byte transaction width */
|
||||
if (srcTs && (dstTrSize > srcTrSize)) {
|
||||
oddSize = dataLen % dstTrSize;
|
||||
/* Adjust source transaction count due to "oddSize" */
|
||||
srcTs = srcTs - (oddSize / srcTrSize);
|
||||
} else {
|
||||
oddSize = dataLen % srcTrSize;
|
||||
}
|
||||
/* Adjust "descCount" due to "oddSize" */
|
||||
if (oddSize) {
|
||||
descCount++;
|
||||
}
|
||||
/* Find the number of descriptor needed for total "srcTs" */
|
||||
if (srcTs) {
|
||||
descCount += ((srcTs - 1) / maxBlockSize) + 1;
|
||||
}
|
||||
|
||||
/* Check the availability of "descCount" discriptors in the ring */
|
||||
pProg = pRing->pHead;
|
||||
for (count = 0; (descCount <= pRing->num) && (count < descCount);
|
||||
count++) {
|
||||
if ((pProg->ctl.hi & dmacHw_DESC_FREE) == 0) {
|
||||
/* Sufficient descriptors are not available */
|
||||
return -3;
|
||||
}
|
||||
pProg = (dmacHw_DESC_t *) pProg->llp;
|
||||
}
|
||||
|
||||
/* Remember the link list item to program the channel registers */
|
||||
pStart = pProg = pRing->pHead;
|
||||
/* Make a link list with "descCount(=count)" number of descriptors */
|
||||
while (count) {
|
||||
/* Reset channel control information */
|
||||
pProg->ctl.lo = 0;
|
||||
/* Enable source gather if configured */
|
||||
if (pConfig->srcGatherWidth) {
|
||||
pProg->ctl.lo |= dmacHw_REG_CTL_SG_ENABLE;
|
||||
}
|
||||
/* Enable destination scatter if configured */
|
||||
if (pConfig->dstScatterWidth) {
|
||||
pProg->ctl.lo |= dmacHw_REG_CTL_DS_ENABLE;
|
||||
}
|
||||
/* Set source and destination address */
|
||||
pProg->sar = (uint32_t) pSrcAddr;
|
||||
pProg->dar = (uint32_t) pDstAddr;
|
||||
/* Use "devCtl" to mark that user memory need to be freed later if needed */
|
||||
if (pProg == pRing->pHead) {
|
||||
pProg->devCtl = dmacHw_FREE_USER_MEMORY;
|
||||
} else {
|
||||
pProg->devCtl = 0;
|
||||
}
|
||||
|
||||
blkTs = srcTs;
|
||||
|
||||
/* Special treatmeant for last descriptor */
|
||||
if (count == 1) {
|
||||
/* Mark the last descriptor */
|
||||
pProg->ctl.lo &=
|
||||
~(dmacHw_REG_CTL_LLP_DST_EN |
|
||||
dmacHw_REG_CTL_LLP_SRC_EN);
|
||||
/* Treatment for odd data bytes */
|
||||
if (oddSize) {
|
||||
/* Adjust for single byte transaction width */
|
||||
switch (pConfig->transferType) {
|
||||
case dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM:
|
||||
dstTrWidth =
|
||||
dmacHw_DST_TRANSACTION_WIDTH_8;
|
||||
blkTs =
|
||||
(oddSize / srcTrSize) +
|
||||
((oddSize % srcTrSize) ? 1 : 0);
|
||||
break;
|
||||
case dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL:
|
||||
srcTrWidth =
|
||||
dmacHw_SRC_TRANSACTION_WIDTH_8;
|
||||
blkTs = oddSize;
|
||||
break;
|
||||
case dmacHw_TRANSFER_TYPE_MEM_TO_MEM:
|
||||
srcTrWidth =
|
||||
dmacHw_SRC_TRANSACTION_WIDTH_8;
|
||||
dstTrWidth =
|
||||
dmacHw_DST_TRANSACTION_WIDTH_8;
|
||||
blkTs = oddSize;
|
||||
break;
|
||||
case dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_PERIPHERAL:
|
||||
/* Do not adjust the transaction width */
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
srcTs -= blkTs;
|
||||
}
|
||||
} else {
|
||||
if (srcTs / maxBlockSize) {
|
||||
blkTs = maxBlockSize;
|
||||
}
|
||||
/* Remaining source transactions for next iteration */
|
||||
srcTs -= blkTs;
|
||||
}
|
||||
/* Must have a valid source transactions */
|
||||
dmacHw_ASSERT(blkTs > 0);
|
||||
/* Set control information */
|
||||
if (pConfig->flowControler == dmacHw_FLOW_CONTROL_DMA) {
|
||||
pProg->ctl.lo |= pConfig->transferType |
|
||||
pConfig->srcUpdate |
|
||||
pConfig->dstUpdate |
|
||||
srcTrWidth |
|
||||
dstTrWidth |
|
||||
pConfig->srcMaxBurstWidth |
|
||||
pConfig->dstMaxBurstWidth |
|
||||
pConfig->srcMasterInterface |
|
||||
pConfig->dstMasterInterface | dmacHw_REG_CTL_INT_EN;
|
||||
} else {
|
||||
uint32_t transferType = 0;
|
||||
switch (pConfig->transferType) {
|
||||
case dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM:
|
||||
transferType = dmacHw_REG_CTL_TTFC_PM_PERI;
|
||||
break;
|
||||
case dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL:
|
||||
transferType = dmacHw_REG_CTL_TTFC_MP_PERI;
|
||||
break;
|
||||
default:
|
||||
dmacHw_ASSERT(0);
|
||||
}
|
||||
pProg->ctl.lo |= transferType |
|
||||
pConfig->srcUpdate |
|
||||
pConfig->dstUpdate |
|
||||
srcTrWidth |
|
||||
dstTrWidth |
|
||||
pConfig->srcMaxBurstWidth |
|
||||
pConfig->dstMaxBurstWidth |
|
||||
pConfig->srcMasterInterface |
|
||||
pConfig->dstMasterInterface | dmacHw_REG_CTL_INT_EN;
|
||||
}
|
||||
|
||||
/* Set block transaction size */
|
||||
pProg->ctl.hi = blkTs & dmacHw_REG_CTL_BLOCK_TS_MASK;
|
||||
/* Look for next descriptor */
|
||||
if (count > 1) {
|
||||
/* Point to the next descriptor */
|
||||
pProg = (dmacHw_DESC_t *) pProg->llp;
|
||||
|
||||
/* Update source and destination address for next iteration */
|
||||
switch (pConfig->transferType) {
|
||||
case dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM:
|
||||
if (pConfig->dstScatterWidth) {
|
||||
pDstAddr =
|
||||
(char *)pDstAddr +
|
||||
blkTs * srcTrSize +
|
||||
(((blkTs * srcTrSize) /
|
||||
pConfig->dstScatterWidth) *
|
||||
pConfig->dstScatterJump);
|
||||
} else {
|
||||
pDstAddr =
|
||||
(char *)pDstAddr +
|
||||
blkTs * srcTrSize;
|
||||
}
|
||||
break;
|
||||
case dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL:
|
||||
if (pConfig->srcGatherWidth) {
|
||||
pSrcAddr =
|
||||
(char *)pDstAddr +
|
||||
blkTs * srcTrSize +
|
||||
(((blkTs * srcTrSize) /
|
||||
pConfig->srcGatherWidth) *
|
||||
pConfig->srcGatherJump);
|
||||
} else {
|
||||
pSrcAddr =
|
||||
(char *)pSrcAddr +
|
||||
blkTs * srcTrSize;
|
||||
}
|
||||
break;
|
||||
case dmacHw_TRANSFER_TYPE_MEM_TO_MEM:
|
||||
if (pConfig->dstScatterWidth) {
|
||||
pDstAddr =
|
||||
(char *)pDstAddr +
|
||||
blkTs * srcTrSize +
|
||||
(((blkTs * srcTrSize) /
|
||||
pConfig->dstScatterWidth) *
|
||||
pConfig->dstScatterJump);
|
||||
} else {
|
||||
pDstAddr =
|
||||
(char *)pDstAddr +
|
||||
blkTs * srcTrSize;
|
||||
}
|
||||
|
||||
if (pConfig->srcGatherWidth) {
|
||||
pSrcAddr =
|
||||
(char *)pDstAddr +
|
||||
blkTs * srcTrSize +
|
||||
(((blkTs * srcTrSize) /
|
||||
pConfig->srcGatherWidth) *
|
||||
pConfig->srcGatherJump);
|
||||
} else {
|
||||
pSrcAddr =
|
||||
(char *)pSrcAddr +
|
||||
blkTs * srcTrSize;
|
||||
}
|
||||
break;
|
||||
case dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_PERIPHERAL:
|
||||
/* Do not adjust the address */
|
||||
break;
|
||||
default:
|
||||
dmacHw_ASSERT(0);
|
||||
}
|
||||
} else {
|
||||
/* At the end of transfer "srcTs" must be zero */
|
||||
dmacHw_ASSERT(srcTs == 0);
|
||||
}
|
||||
count--;
|
||||
}
|
||||
|
||||
/* Remember the descriptor to initialize the registers */
|
||||
if (pRing->pProg == dmacHw_DESC_INIT) {
|
||||
pRing->pProg = pStart;
|
||||
}
|
||||
/* Indicate that the descriptor is updated */
|
||||
pRing->pEnd = pProg;
|
||||
/* Head pointing to the next descriptor */
|
||||
pRing->pHead = (dmacHw_DESC_t *) pProg->llp;
|
||||
/* Update Tail pointer if destination is a peripheral,
|
||||
because no one is going to read from the pTail
|
||||
*/
|
||||
if (!dmacHw_DST_IS_MEMORY(pConfig->transferType)) {
|
||||
pRing->pTail = pRing->pHead;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* @brief Provides DMA controller attributes
|
||||
*
|
||||
*
|
||||
* @return DMA controller attributes
|
||||
*
|
||||
* @note
|
||||
* None
|
||||
*/
|
||||
/****************************************************************************/
|
||||
uint32_t dmacHw_getDmaControllerAttribute(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
|
||||
dmacHw_CONTROLLER_ATTRIB_e attr /* [ IN ] DMA Controler attribute of type dmacHw_CONTROLLER_ATTRIB_e */
|
||||
) {
|
||||
dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
|
||||
|
||||
switch (attr) {
|
||||
case dmacHw_CONTROLLER_ATTRIB_CHANNEL_NUM:
|
||||
return dmacHw_GET_NUM_CHANNEL(pCblk->module);
|
||||
case dmacHw_CONTROLLER_ATTRIB_CHANNEL_MAX_BLOCK_SIZE:
|
||||
return (1 <<
|
||||
(dmacHw_GET_MAX_BLOCK_SIZE
|
||||
(pCblk->module, pCblk->module) + 2)) - 8;
|
||||
case dmacHw_CONTROLLER_ATTRIB_MASTER_INTF_NUM:
|
||||
return dmacHw_GET_NUM_INTERFACE(pCblk->module);
|
||||
case dmacHw_CONTROLLER_ATTRIB_CHANNEL_BUS_WIDTH:
|
||||
return 32 << dmacHw_GET_CHANNEL_DATA_WIDTH(pCblk->module,
|
||||
pCblk->channel);
|
||||
case dmacHw_CONTROLLER_ATTRIB_CHANNEL_FIFO_SIZE:
|
||||
return GetFifoSize(handle);
|
||||
}
|
||||
dmacHw_ASSERT(0);
|
||||
return 0;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue