diff --git a/[refs] b/[refs] index ad67dca7373d..3e44cf4e667f 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: cf8b166d5c1c89aad6c436a954fa40fd18a75bfb +refs/heads/master: ae3b29e67ca361f0876dad6be2061699de95d126 diff --git a/trunk/Documentation/ABI/testing/sysfs-block-bcache b/trunk/Documentation/ABI/testing/sysfs-block-bcache new file mode 100644 index 000000000000..9e4bbc5d51fd --- /dev/null +++ b/trunk/Documentation/ABI/testing/sysfs-block-bcache @@ -0,0 +1,156 @@ +What: /sys/block//bcache/unregister +Date: November 2010 +Contact: Kent Overstreet +Description: + A write to this file causes the backing device or cache to be + unregistered. If a backing device had dirty data in the cache, + writeback mode is automatically disabled and all dirty data is + flushed before the device is unregistered. Caches unregister + all associated backing devices before unregistering themselves. + +What: /sys/block//bcache/clear_stats +Date: November 2010 +Contact: Kent Overstreet +Description: + Writing to this file resets all the statistics for the device. + +What: /sys/block//bcache/cache +Date: November 2010 +Contact: Kent Overstreet +Description: + For a backing device that has cache, a symlink to + the bcache/ dir of that cache. + +What: /sys/block//bcache/cache_hits +Date: November 2010 +Contact: Kent Overstreet +Description: + For backing devices: integer number of full cache hits, + counted per bio. A partial cache hit counts as a miss. + +What: /sys/block//bcache/cache_misses +Date: November 2010 +Contact: Kent Overstreet +Description: + For backing devices: integer number of cache misses. + +What: /sys/block//bcache/cache_hit_ratio +Date: November 2010 +Contact: Kent Overstreet +Description: + For backing devices: cache hits as a percentage. + +What: /sys/block//bcache/sequential_cutoff +Date: November 2010 +Contact: Kent Overstreet +Description: + For backing devices: Threshold past which sequential IO will + skip the cache. Read and written as bytes in human readable + units (i.e. echo 10M > sequntial_cutoff). + +What: /sys/block//bcache/bypassed +Date: November 2010 +Contact: Kent Overstreet +Description: + Sum of all reads and writes that have bypassed the cache (due + to the sequential cutoff). Expressed as bytes in human + readable units. + +What: /sys/block//bcache/writeback +Date: November 2010 +Contact: Kent Overstreet +Description: + For backing devices: When on, writeback caching is enabled and + writes will be buffered in the cache. When off, caching is in + writethrough mode; reads and writes will be added to the + cache but no write buffering will take place. + +What: /sys/block//bcache/writeback_running +Date: November 2010 +Contact: Kent Overstreet +Description: + For backing devices: when off, dirty data will not be written + from the cache to the backing device. The cache will still be + used to buffer writes until it is mostly full, at which point + writes transparently revert to writethrough mode. Intended only + for benchmarking/testing. + +What: /sys/block//bcache/writeback_delay +Date: November 2010 +Contact: Kent Overstreet +Description: + For backing devices: In writeback mode, when dirty data is + written to the cache and the cache held no dirty data for that + backing device, writeback from cache to backing device starts + after this delay, expressed as an integer number of seconds. + +What: /sys/block//bcache/writeback_percent +Date: November 2010 +Contact: Kent Overstreet +Description: + For backing devices: If nonzero, writeback from cache to + backing device only takes place when more than this percentage + of the cache is used, allowing more write coalescing to take + place and reducing total number of writes sent to the backing + device. Integer between 0 and 40. + +What: /sys/block//bcache/synchronous +Date: November 2010 +Contact: Kent Overstreet +Description: + For a cache, a boolean that allows synchronous mode to be + switched on and off. In synchronous mode all writes are ordered + such that the cache can reliably recover from unclean shutdown; + if disabled bcache will not generally wait for writes to + complete but if the cache is not shut down cleanly all data + will be discarded from the cache. Should not be turned off with + writeback caching enabled. + +What: /sys/block//bcache/discard +Date: November 2010 +Contact: Kent Overstreet +Description: + For a cache, a boolean allowing discard/TRIM to be turned off + or back on if the device supports it. + +What: /sys/block//bcache/bucket_size +Date: November 2010 +Contact: Kent Overstreet +Description: + For a cache, bucket size in human readable units, as set at + cache creation time; should match the erase block size of the + SSD for optimal performance. + +What: /sys/block//bcache/nbuckets +Date: November 2010 +Contact: Kent Overstreet +Description: + For a cache, the number of usable buckets. + +What: /sys/block//bcache/tree_depth +Date: November 2010 +Contact: Kent Overstreet +Description: + For a cache, height of the btree excluding leaf nodes (i.e. a + one node tree will have a depth of 0). + +What: /sys/block//bcache/btree_cache_size +Date: November 2010 +Contact: Kent Overstreet +Description: + Number of btree buckets/nodes that are currently cached in + memory; cache dynamically grows and shrinks in response to + memory pressure from the rest of the system. + +What: /sys/block//bcache/written +Date: November 2010 +Contact: Kent Overstreet +Description: + For a cache, total amount of data in human readable units + written to the cache, excluding all metadata. + +What: /sys/block//bcache/btree_written +Date: November 2010 +Contact: Kent Overstreet +Description: + For a cache, sum of all btree writes in human readable units. diff --git a/trunk/Documentation/ABI/testing/sysfs-bus-rbd b/trunk/Documentation/ABI/testing/sysfs-bus-rbd index cd9213ccf3dc..0a306476424e 100644 --- a/trunk/Documentation/ABI/testing/sysfs-bus-rbd +++ b/trunk/Documentation/ABI/testing/sysfs-bus-rbd @@ -66,27 +66,7 @@ current_snap The current snapshot for which the device is mapped. -snap_* - - A directory per each snapshot - parent Information identifying the pool, image, and snapshot id for the parent image in a layered rbd image (format 2 only). - -Entries under /sys/bus/rbd/devices//snap_ -------------------------------------------------------------- - -snap_id - - The rados internal snapshot id assigned for this snapshot - -snap_size - - The size of the image when this snapshot was taken. - -snap_features - - A hexadecimal encoding of the feature bits for this snapshot. - diff --git a/trunk/Documentation/ABI/testing/sysfs-class-mtd b/trunk/Documentation/ABI/testing/sysfs-class-mtd index 938ef71e2035..3105644b3bfc 100644 --- a/trunk/Documentation/ABI/testing/sysfs-class-mtd +++ b/trunk/Documentation/ABI/testing/sysfs-class-mtd @@ -14,8 +14,7 @@ Description: The /sys/class/mtd/mtd{0,1,2,3,...} directories correspond to each /dev/mtdX character device. These may represent physical/simulated flash devices, partitions on a flash - device, or concatenated flash devices. They exist regardless - of whether CONFIG_MTD_CHAR is actually enabled. + device, or concatenated flash devices. What: /sys/class/mtd/mtdXro/ Date: April 2009 @@ -23,8 +22,7 @@ KernelVersion: 2.6.29 Contact: linux-mtd@lists.infradead.org Description: These directories provide the corresponding read-only device - nodes for /sys/class/mtd/mtdX/ . They are only created - (for the benefit of udev) if CONFIG_MTD_CHAR is enabled. + nodes for /sys/class/mtd/mtdX/ . What: /sys/class/mtd/mtdX/dev Date: April 2009 diff --git a/trunk/Documentation/DocBook/writing-an-alsa-driver.tmpl b/trunk/Documentation/DocBook/writing-an-alsa-driver.tmpl index bd6fee22c4dd..06741e925985 100644 --- a/trunk/Documentation/DocBook/writing-an-alsa-driver.tmpl +++ b/trunk/Documentation/DocBook/writing-an-alsa-driver.tmpl @@ -6164,14 +6164,12 @@ struct _snd_pcm_runtime { The macro takes an conditional expression to evaluate. - When CONFIG_SND_DEBUG, is set, the - expression is actually evaluated. If it's non-zero, it shows - the warning message such as + When CONFIG_SND_DEBUG, is set, if the + expression is non-zero, it shows the warning message such as BUG? (xxx) - normally followed by stack trace. It returns the evaluated - value. - When no CONFIG_SND_DEBUG is set, this - macro always returns zero. + normally followed by stack trace. + + In both cases it returns the evaluated value. diff --git a/trunk/Documentation/EDID/1600x1200.S b/trunk/Documentation/EDID/1600x1200.S new file mode 100644 index 000000000000..0ded64cfd1f5 --- /dev/null +++ b/trunk/Documentation/EDID/1600x1200.S @@ -0,0 +1,44 @@ +/* + 1600x1200.S: EDID data set for standard 1600x1200 60 Hz monitor + + Copyright (C) 2013 Carsten Emde + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +/* EDID */ +#define VERSION 1 +#define REVISION 3 + +/* Display */ +#define CLOCK 162000 /* kHz */ +#define XPIX 1600 +#define YPIX 1200 +#define XY_RATIO XY_RATIO_4_3 +#define XBLANK 560 +#define YBLANK 50 +#define XOFFSET 64 +#define XPULSE 192 +#define YOFFSET (63+1) +#define YPULSE (63+3) +#define DPI 72 +#define VFREQ 60 /* Hz */ +#define TIMING_NAME "Linux UXGA" +#define ESTABLISHED_TIMINGS_BITS 0x00 /* none */ +#define HSYNC_POL 1 +#define VSYNC_POL 1 +#define CRC 0x9d + +#include "edid.S" diff --git a/trunk/Documentation/EDID/HOWTO.txt b/trunk/Documentation/EDID/HOWTO.txt index 2d0a8f09475d..7146db1d9e8c 100644 --- a/trunk/Documentation/EDID/HOWTO.txt +++ b/trunk/Documentation/EDID/HOWTO.txt @@ -18,12 +18,12 @@ CONFIG_DRM_LOAD_EDID_FIRMWARE was introduced. It allows to provide an individually prepared or corrected EDID data set in the /lib/firmware directory from where it is loaded via the firmware interface. The code (see drivers/gpu/drm/drm_edid_load.c) contains built-in data sets for -commonly used screen resolutions (1024x768, 1280x1024, 1680x1050, -1920x1080) as binary blobs, but the kernel source tree does not contain -code to create these data. In order to elucidate the origin of the -built-in binary EDID blobs and to facilitate the creation of individual -data for a specific misbehaving monitor, commented sources and a -Makefile environment are given here. +commonly used screen resolutions (1024x768, 1280x1024, 1600x1200, +1680x1050, 1920x1080) as binary blobs, but the kernel source tree does +not contain code to create these data. In order to elucidate the origin +of the built-in binary EDID blobs and to facilitate the creation of +individual data for a specific misbehaving monitor, commented sources +and a Makefile environment are given here. To create binary EDID and C source code files from the existing data material, simply type "make". diff --git a/trunk/Documentation/RCU/stallwarn.txt b/trunk/Documentation/RCU/stallwarn.txt index e38b8df3d727..8e9359de1d28 100644 --- a/trunk/Documentation/RCU/stallwarn.txt +++ b/trunk/Documentation/RCU/stallwarn.txt @@ -191,7 +191,7 @@ o A CPU-bound real-time task in a CONFIG_PREEMPT_RT kernel that o A hardware or software issue shuts off the scheduler-clock interrupt on a CPU that is not in dyntick-idle mode. This problem really has happened, and seems to be most likely to - result in RCU CPU stall warnings for CONFIG_NO_HZ=n kernels. + result in RCU CPU stall warnings for CONFIG_NO_HZ_COMMON=n kernels. o A bug in the RCU implementation. diff --git a/trunk/Documentation/acpi/enumeration.txt b/trunk/Documentation/acpi/enumeration.txt index 94a656131885..d9be7a97dff3 100644 --- a/trunk/Documentation/acpi/enumeration.txt +++ b/trunk/Documentation/acpi/enumeration.txt @@ -66,6 +66,83 @@ the ACPI device explicitly to acpi_platform_device_ids list defined in drivers/acpi/acpi_platform.c. This limitation is only for the platform devices, SPI and I2C devices are created automatically as described below. +DMA support +~~~~~~~~~~~ +DMA controllers enumerated via ACPI should be registered in the system to +provide generic access to their resources. For example, a driver that would +like to be accessible to slave devices via generic API call +dma_request_slave_channel() must register itself at the end of the probe +function like this: + + err = devm_acpi_dma_controller_register(dev, xlate_func, dw); + /* Handle the error if it's not a case of !CONFIG_ACPI */ + +and implement custom xlate function if needed (usually acpi_dma_simple_xlate() +is enough) which converts the FixedDMA resource provided by struct +acpi_dma_spec into the corresponding DMA channel. A piece of code for that case +could look like: + + #ifdef CONFIG_ACPI + struct filter_args { + /* Provide necessary information for the filter_func */ + ... + }; + + static bool filter_func(struct dma_chan *chan, void *param) + { + /* Choose the proper channel */ + ... + } + + static struct dma_chan *xlate_func(struct acpi_dma_spec *dma_spec, + struct acpi_dma *adma) + { + dma_cap_mask_t cap; + struct filter_args args; + + /* Prepare arguments for filter_func */ + ... + return dma_request_channel(cap, filter_func, &args); + } + #else + static struct dma_chan *xlate_func(struct acpi_dma_spec *dma_spec, + struct acpi_dma *adma) + { + return NULL; + } + #endif + +dma_request_slave_channel() will call xlate_func() for each registered DMA +controller. In the xlate function the proper channel must be chosen based on +information in struct acpi_dma_spec and the properties of the controller +provided by struct acpi_dma. + +Clients must call dma_request_slave_channel() with the string parameter that +corresponds to a specific FixedDMA resource. By default "tx" means the first +entry of the FixedDMA resource array, "rx" means the second entry. The table +below shows a layout: + + Device (I2C0) + { + ... + Method (_CRS, 0, NotSerialized) + { + Name (DBUF, ResourceTemplate () + { + FixedDMA (0x0018, 0x0004, Width32bit, _Y48) + FixedDMA (0x0019, 0x0005, Width32bit, ) + }) + ... + } + } + +So, the FixedDMA with request line 0x0018 is "tx" and next one is "rx" in +this example. + +In robust cases the client unfortunately needs to call +acpi_dma_request_slave_chan_by_index() directly and therefore choose the +specific FixedDMA resource by its index. + SPI serial bus support ~~~~~~~~~~~~~~~~~~~~~~ Slave devices behind SPI bus have SpiSerialBus resource attached to them. @@ -199,6 +276,8 @@ the device to the driver. For example: { Name (SBUF, ResourceTemplate() { + ... + // Used to power on/off the device GpioIo (Exclusive, PullDefault, 0x0000, 0x0000, IoRestrictionOutputOnly, "\\_SB.PCI0.GPI0", 0x00, ResourceConsumer,,) @@ -206,10 +285,20 @@ the device to the driver. For example: // Pin List 0x0055 } + + // Interrupt for the device + GpioInt (Edge, ActiveHigh, ExclusiveAndWake, PullNone, + 0x0000, "\\_SB.PCI0.GPI0", 0x00, ResourceConsumer,,) + { + // Pin list + 0x0058 + } + ... - Return (SBUF) } + + Return (SBUF) } These GPIO numbers are controller relative and path "\\_SB.PCI0.GPI0" @@ -220,6 +309,24 @@ The driver can do this by including and then calling acpi_get_gpio(path, gpio). This will return the Linux GPIO number or negative errno if there was no translation found. +In a simple case of just getting the Linux GPIO number from device +resources one can use acpi_get_gpio_by_index() helper function. It takes +pointer to the device and index of the GpioIo/GpioInt descriptor in the +device resources list. For example: + + int gpio_irq, gpio_power; + int ret; + + gpio_irq = acpi_get_gpio_by_index(dev, 1, NULL); + if (gpio_irq < 0) + /* handle error */ + + gpio_power = acpi_get_gpio_by_index(dev, 0, NULL); + if (gpio_power < 0) + /* handle error */ + + /* Now we can use the GPIO numbers */ + Other GpioIo parameters must be converted first by the driver to be suitable to the gpiolib before passing them. diff --git a/trunk/Documentation/arm/cluster-pm-race-avoidance.txt b/trunk/Documentation/arm/cluster-pm-race-avoidance.txt new file mode 100644 index 000000000000..750b6fc24af9 --- /dev/null +++ b/trunk/Documentation/arm/cluster-pm-race-avoidance.txt @@ -0,0 +1,498 @@ +Cluster-wide Power-up/power-down race avoidance algorithm +========================================================= + +This file documents the algorithm which is used to coordinate CPU and +cluster setup and teardown operations and to manage hardware coherency +controls safely. + +The section "Rationale" explains what the algorithm is for and why it is +needed. "Basic model" explains general concepts using a simplified view +of the system. The other sections explain the actual details of the +algorithm in use. + + +Rationale +--------- + +In a system containing multiple CPUs, it is desirable to have the +ability to turn off individual CPUs when the system is idle, reducing +power consumption and thermal dissipation. + +In a system containing multiple clusters of CPUs, it is also desirable +to have the ability to turn off entire clusters. + +Turning entire clusters off and on is a risky business, because it +involves performing potentially destructive operations affecting a group +of independently running CPUs, while the OS continues to run. This +means that we need some coordination in order to ensure that critical +cluster-level operations are only performed when it is truly safe to do +so. + +Simple locking may not be sufficient to solve this problem, because +mechanisms like Linux spinlocks may rely on coherency mechanisms which +are not immediately enabled when a cluster powers up. Since enabling or +disabling those mechanisms may itself be a non-atomic operation (such as +writing some hardware registers and invalidating large caches), other +methods of coordination are required in order to guarantee safe +power-down and power-up at the cluster level. + +The mechanism presented in this document describes a coherent memory +based protocol for performing the needed coordination. It aims to be as +lightweight as possible, while providing the required safety properties. + + +Basic model +----------- + +Each cluster and CPU is assigned a state, as follows: + + DOWN + COMING_UP + UP + GOING_DOWN + + +---------> UP ----------+ + | v + + COMING_UP GOING_DOWN + + ^ | + +--------- DOWN <--------+ + + +DOWN: The CPU or cluster is not coherent, and is either powered off or + suspended, or is ready to be powered off or suspended. + +COMING_UP: The CPU or cluster has committed to moving to the UP state. + It may be part way through the process of initialisation and + enabling coherency. + +UP: The CPU or cluster is active and coherent at the hardware + level. A CPU in this state is not necessarily being used + actively by the kernel. + +GOING_DOWN: The CPU or cluster has committed to moving to the DOWN + state. It may be part way through the process of teardown and + coherency exit. + + +Each CPU has one of these states assigned to it at any point in time. +The CPU states are described in the "CPU state" section, below. + +Each cluster is also assigned a state, but it is necessary to split the +state value into two parts (the "cluster" state and "inbound" state) and +to introduce additional states in order to avoid races between different +CPUs in the cluster simultaneously modifying the state. The cluster- +level states are described in the "Cluster state" section. + +To help distinguish the CPU states from cluster states in this +discussion, the state names are given a CPU_ prefix for the CPU states, +and a CLUSTER_ or INBOUND_ prefix for the cluster states. + + +CPU state +--------- + +In this algorithm, each individual core in a multi-core processor is +referred to as a "CPU". CPUs are assumed to be single-threaded: +therefore, a CPU can only be doing one thing at a single point in time. + +This means that CPUs fit the basic model closely. + +The algorithm defines the following states for each CPU in the system: + + CPU_DOWN + CPU_COMING_UP + CPU_UP + CPU_GOING_DOWN + + cluster setup and + CPU setup complete policy decision + +-----------> CPU_UP ------------+ + | v + + CPU_COMING_UP CPU_GOING_DOWN + + ^ | + +----------- CPU_DOWN <----------+ + policy decision CPU teardown complete + or hardware event + + +The definitions of the four states correspond closely to the states of +the basic model. + +Transitions between states occur as follows. + +A trigger event (spontaneous) means that the CPU can transition to the +next state as a result of making local progress only, with no +requirement for any external event to happen. + + +CPU_DOWN: + + A CPU reaches the CPU_DOWN state when it is ready for + power-down. On reaching this state, the CPU will typically + power itself down or suspend itself, via a WFI instruction or a + firmware call. + + Next state: CPU_COMING_UP + Conditions: none + + Trigger events: + + a) an explicit hardware power-up operation, resulting + from a policy decision on another CPU; + + b) a hardware event, such as an interrupt. + + +CPU_COMING_UP: + + A CPU cannot start participating in hardware coherency until the + cluster is set up and coherent. If the cluster is not ready, + then the CPU will wait in the CPU_COMING_UP state until the + cluster has been set up. + + Next state: CPU_UP + Conditions: The CPU's parent cluster must be in CLUSTER_UP. + Trigger events: Transition of the parent cluster to CLUSTER_UP. + + Refer to the "Cluster state" section for a description of the + CLUSTER_UP state. + + +CPU_UP: + When a CPU reaches the CPU_UP state, it is safe for the CPU to + start participating in local coherency. + + This is done by jumping to the kernel's CPU resume code. + + Note that the definition of this state is slightly different + from the basic model definition: CPU_UP does not mean that the + CPU is coherent yet, but it does mean that it is safe to resume + the kernel. The kernel handles the rest of the resume + procedure, so the remaining steps are not visible as part of the + race avoidance algorithm. + + The CPU remains in this state until an explicit policy decision + is made to shut down or suspend the CPU. + + Next state: CPU_GOING_DOWN + Conditions: none + Trigger events: explicit policy decision + + +CPU_GOING_DOWN: + + While in this state, the CPU exits coherency, including any + operations required to achieve this (such as cleaning data + caches). + + Next state: CPU_DOWN + Conditions: local CPU teardown complete + Trigger events: (spontaneous) + + +Cluster state +------------- + +A cluster is a group of connected CPUs with some common resources. +Because a cluster contains multiple CPUs, it can be doing multiple +things at the same time. This has some implications. In particular, a +CPU can start up while another CPU is tearing the cluster down. + +In this discussion, the "outbound side" is the view of the cluster state +as seen by a CPU tearing the cluster down. The "inbound side" is the +view of the cluster state as seen by a CPU setting the CPU up. + +In order to enable safe coordination in such situations, it is important +that a CPU which is setting up the cluster can advertise its state +independently of the CPU which is tearing down the cluster. For this +reason, the cluster state is split into two parts: + + "cluster" state: The global state of the cluster; or the state + on the outbound side: + + CLUSTER_DOWN + CLUSTER_UP + CLUSTER_GOING_DOWN + + "inbound" state: The state of the cluster on the inbound side. + + INBOUND_NOT_COMING_UP + INBOUND_COMING_UP + + + The different pairings of these states results in six possible + states for the cluster as a whole: + + CLUSTER_UP + +==========> INBOUND_NOT_COMING_UP -------------+ + # | + | + CLUSTER_UP <----+ | + INBOUND_COMING_UP | v + + ^ CLUSTER_GOING_DOWN CLUSTER_GOING_DOWN + # INBOUND_COMING_UP <=== INBOUND_NOT_COMING_UP + + CLUSTER_DOWN | | + INBOUND_COMING_UP <----+ | + | + ^ | + +=========== CLUSTER_DOWN <------------+ + INBOUND_NOT_COMING_UP + + Transitions -----> can only be made by the outbound CPU, and + only involve changes to the "cluster" state. + + Transitions ===##> can only be made by the inbound CPU, and only + involve changes to the "inbound" state, except where there is no + further transition possible on the outbound side (i.e., the + outbound CPU has put the cluster into the CLUSTER_DOWN state). + + The race avoidance algorithm does not provide a way to determine + which exact CPUs within the cluster play these roles. This must + be decided in advance by some other means. Refer to the section + "Last man and first man selection" for more explanation. + + + CLUSTER_DOWN/INBOUND_NOT_COMING_UP is the only state where the + cluster can actually be powered down. + + The parallelism of the inbound and outbound CPUs is observed by + the existence of two different paths from CLUSTER_GOING_DOWN/ + INBOUND_NOT_COMING_UP (corresponding to GOING_DOWN in the basic + model) to CLUSTER_DOWN/INBOUND_COMING_UP (corresponding to + COMING_UP in the basic model). The second path avoids cluster + teardown completely. + + CLUSTER_UP/INBOUND_COMING_UP is equivalent to UP in the basic + model. The final transition to CLUSTER_UP/INBOUND_NOT_COMING_UP + is trivial and merely resets the state machine ready for the + next cycle. + + Details of the allowable transitions follow. + + The next state in each case is notated + + / () + + where the is the side on which the transition + can occur; either the inbound or the outbound side. + + +CLUSTER_DOWN/INBOUND_NOT_COMING_UP: + + Next state: CLUSTER_DOWN/INBOUND_COMING_UP (inbound) + Conditions: none + Trigger events: + + a) an explicit hardware power-up operation, resulting + from a policy decision on another CPU; + + b) a hardware event, such as an interrupt. + + +CLUSTER_DOWN/INBOUND_COMING_UP: + + In this state, an inbound CPU sets up the cluster, including + enabling of hardware coherency at the cluster level and any + other operations (such as cache invalidation) which are required + in order to achieve this. + + The purpose of this state is to do sufficient cluster-level + setup to enable other CPUs in the cluster to enter coherency + safely. + + Next state: CLUSTER_UP/INBOUND_COMING_UP (inbound) + Conditions: cluster-level setup and hardware coherency complete + Trigger events: (spontaneous) + + +CLUSTER_UP/INBOUND_COMING_UP: + + Cluster-level setup is complete and hardware coherency is + enabled for the cluster. Other CPUs in the cluster can safely + enter coherency. + + This is a transient state, leading immediately to + CLUSTER_UP/INBOUND_NOT_COMING_UP. All other CPUs on the cluster + should consider treat these two states as equivalent. + + Next state: CLUSTER_UP/INBOUND_NOT_COMING_UP (inbound) + Conditions: none + Trigger events: (spontaneous) + + +CLUSTER_UP/INBOUND_NOT_COMING_UP: + + Cluster-level setup is complete and hardware coherency is + enabled for the cluster. Other CPUs in the cluster can safely + enter coherency. + + The cluster will remain in this state until a policy decision is + made to power the cluster down. + + Next state: CLUSTER_GOING_DOWN/INBOUND_NOT_COMING_UP (outbound) + Conditions: none + Trigger events: policy decision to power down the cluster + + +CLUSTER_GOING_DOWN/INBOUND_NOT_COMING_UP: + + An outbound CPU is tearing the cluster down. The selected CPU + must wait in this state until all CPUs in the cluster are in the + CPU_DOWN state. + + When all CPUs are in the CPU_DOWN state, the cluster can be torn + down, for example by cleaning data caches and exiting + cluster-level coherency. + + To avoid wasteful unnecessary teardown operations, the outbound + should check the inbound cluster state for asynchronous + transitions to INBOUND_COMING_UP. Alternatively, individual + CPUs can be checked for entry into CPU_COMING_UP or CPU_UP. + + + Next states: + + CLUSTER_DOWN/INBOUND_NOT_COMING_UP (outbound) + Conditions: cluster torn down and ready to power off + Trigger events: (spontaneous) + + CLUSTER_GOING_DOWN/INBOUND_COMING_UP (inbound) + Conditions: none + Trigger events: + + a) an explicit hardware power-up operation, + resulting from a policy decision on another + CPU; + + b) a hardware event, such as an interrupt. + + +CLUSTER_GOING_DOWN/INBOUND_COMING_UP: + + The cluster is (or was) being torn down, but another CPU has + come online in the meantime and is trying to set up the cluster + again. + + If the outbound CPU observes this state, it has two choices: + + a) back out of teardown, restoring the cluster to the + CLUSTER_UP state; + + b) finish tearing the cluster down and put the cluster + in the CLUSTER_DOWN state; the inbound CPU will + set up the cluster again from there. + + Choice (a) permits the removal of some latency by avoiding + unnecessary teardown and setup operations in situations where + the cluster is not really going to be powered down. + + + Next states: + + CLUSTER_UP/INBOUND_COMING_UP (outbound) + Conditions: cluster-level setup and hardware + coherency complete + Trigger events: (spontaneous) + + CLUSTER_DOWN/INBOUND_COMING_UP (outbound) + Conditions: cluster torn down and ready to power off + Trigger events: (spontaneous) + + +Last man and First man selection +-------------------------------- + +The CPU which performs cluster tear-down operations on the outbound side +is commonly referred to as the "last man". + +The CPU which performs cluster setup on the inbound side is commonly +referred to as the "first man". + +The race avoidance algorithm documented above does not provide a +mechanism to choose which CPUs should play these roles. + + +Last man: + +When shutting down the cluster, all the CPUs involved are initially +executing Linux and hence coherent. Therefore, ordinary spinlocks can +be used to select a last man safely, before the CPUs become +non-coherent. + + +First man: + +Because CPUs may power up asynchronously in response to external wake-up +events, a dynamic mechanism is needed to make sure that only one CPU +attempts to play the first man role and do the cluster-level +initialisation: any other CPUs must wait for this to complete before +proceeding. + +Cluster-level initialisation may involve actions such as configuring +coherency controls in the bus fabric. + +The current implementation in mcpm_head.S uses a separate mutual exclusion +mechanism to do this arbitration. This mechanism is documented in +detail in vlocks.txt. + + +Features and Limitations +------------------------ + +Implementation: + + The current ARM-based implementation is split between + arch/arm/common/mcpm_head.S (low-level inbound CPU operations) and + arch/arm/common/mcpm_entry.c (everything else): + + __mcpm_cpu_going_down() signals the transition of a CPU to the + CPU_GOING_DOWN state. + + __mcpm_cpu_down() signals the transition of a CPU to the CPU_DOWN + state. + + A CPU transitions to CPU_COMING_UP and then to CPU_UP via the + low-level power-up code in mcpm_head.S. This could + involve CPU-specific setup code, but in the current + implementation it does not. + + __mcpm_outbound_enter_critical() and __mcpm_outbound_leave_critical() + handle transitions from CLUSTER_UP to CLUSTER_GOING_DOWN + and from there to CLUSTER_DOWN or back to CLUSTER_UP (in + the case of an aborted cluster power-down). + + These functions are more complex than the __mcpm_cpu_*() + functions due to the extra inter-CPU coordination which + is needed for safe transitions at the cluster level. + + A cluster transitions from CLUSTER_DOWN back to CLUSTER_UP via + the low-level power-up code in mcpm_head.S. This + typically involves platform-specific setup code, + provided by the platform-specific power_up_setup + function registered via mcpm_sync_init. + +Deep topologies: + + As currently described and implemented, the algorithm does not + support CPU topologies involving more than two levels (i.e., + clusters of clusters are not supported). The algorithm could be + extended by replicating the cluster-level states for the + additional topological levels, and modifying the transition + rules for the intermediate (non-outermost) cluster levels. + + +Colophon +-------- + +Originally created and documented by Dave Martin for Linaro Limited, in +collaboration with Nicolas Pitre and Achin Gupta. + +Copyright (C) 2012-2013 Linaro Limited +Distributed under the terms of Version 2 of the GNU General Public +License, as defined in linux/COPYING. diff --git a/trunk/Documentation/arm/firmware.txt b/trunk/Documentation/arm/firmware.txt new file mode 100644 index 000000000000..c2e468fe7b0b --- /dev/null +++ b/trunk/Documentation/arm/firmware.txt @@ -0,0 +1,88 @@ +Interface for registering and calling firmware-specific operations for ARM. +---- +Written by Tomasz Figa + +Some boards are running with secure firmware running in TrustZone secure +world, which changes the way some things have to be initialized. This makes +a need to provide an interface for such platforms to specify available firmware +operations and call them when needed. + +Firmware operations can be specified using struct firmware_ops + + struct firmware_ops { + /* + * Enters CPU idle mode + */ + int (*do_idle)(void); + /* + * Sets boot address of specified physical CPU + */ + int (*set_cpu_boot_addr)(int cpu, unsigned long boot_addr); + /* + * Boots specified physical CPU + */ + int (*cpu_boot)(int cpu); + /* + * Initializes L2 cache + */ + int (*l2x0_init)(void); + }; + +and then registered with register_firmware_ops function + + void register_firmware_ops(const struct firmware_ops *ops) + +the ops pointer must be non-NULL. + +There is a default, empty set of operations provided, so there is no need to +set anything if platform does not require firmware operations. + +To call a firmware operation, a helper macro is provided + + #define call_firmware_op(op, ...) \ + ((firmware_ops->op) ? firmware_ops->op(__VA_ARGS__) : (-ENOSYS)) + +the macro checks if the operation is provided and calls it or otherwise returns +-ENOSYS to signal that given operation is not available (for example, to allow +fallback to legacy operation). + +Example of registering firmware operations: + + /* board file */ + + static int platformX_do_idle(void) + { + /* tell platformX firmware to enter idle */ + return 0; + } + + static int platformX_cpu_boot(int i) + { + /* tell platformX firmware to boot CPU i */ + return 0; + } + + static const struct firmware_ops platformX_firmware_ops = { + .do_idle = exynos_do_idle, + .cpu_boot = exynos_cpu_boot, + /* other operations not available on platformX */ + }; + + /* init_early callback of machine descriptor */ + static void __init board_init_early(void) + { + register_firmware_ops(&platformX_firmware_ops); + } + +Example of using a firmware operation: + + /* some platform code, e.g. SMP initialization */ + + __raw_writel(virt_to_phys(exynos4_secondary_startup), + CPU1_BOOT_REG); + + /* Call Exynos specific smc call */ + if (call_firmware_op(cpu_boot, cpu) == -ENOSYS) + cpu_boot_legacy(...); /* Try legacy way */ + + gic_raise_softirq(cpumask_of(cpu), 1); diff --git a/trunk/Documentation/arm/vlocks.txt b/trunk/Documentation/arm/vlocks.txt new file mode 100644 index 000000000000..415960a9bab0 --- /dev/null +++ b/trunk/Documentation/arm/vlocks.txt @@ -0,0 +1,211 @@ +vlocks for Bare-Metal Mutual Exclusion +====================================== + +Voting Locks, or "vlocks" provide a simple low-level mutual exclusion +mechanism, with reasonable but minimal requirements on the memory +system. + +These are intended to be used to coordinate critical activity among CPUs +which are otherwise non-coherent, in situations where the hardware +provides no other mechanism to support this and ordinary spinlocks +cannot be used. + + +vlocks make use of the atomicity provided by the memory system for +writes to a single memory location. To arbitrate, every CPU "votes for +itself", by storing a unique number to a common memory location. The +final value seen in that memory location when all the votes have been +cast identifies the winner. + +In order to make sure that the election produces an unambiguous result +in finite time, a CPU will only enter the election in the first place if +no winner has been chosen and the election does not appear to have +started yet. + + +Algorithm +--------- + +The easiest way to explain the vlocks algorithm is with some pseudo-code: + + + int currently_voting[NR_CPUS] = { 0, }; + int last_vote = -1; /* no votes yet */ + + bool vlock_trylock(int this_cpu) + { + /* signal our desire to vote */ + currently_voting[this_cpu] = 1; + if (last_vote != -1) { + /* someone already volunteered himself */ + currently_voting[this_cpu] = 0; + return false; /* not ourself */ + } + + /* let's suggest ourself */ + last_vote = this_cpu; + currently_voting[this_cpu] = 0; + + /* then wait until everyone else is done voting */ + for_each_cpu(i) { + while (currently_voting[i] != 0) + /* wait */; + } + + /* result */ + if (last_vote == this_cpu) + return true; /* we won */ + return false; + } + + bool vlock_unlock(void) + { + last_vote = -1; + } + + +The currently_voting[] array provides a way for the CPUs to determine +whether an election is in progress, and plays a role analogous to the +"entering" array in Lamport's bakery algorithm [1]. + +However, once the election has started, the underlying memory system +atomicity is used to pick the winner. This avoids the need for a static +priority rule to act as a tie-breaker, or any counters which could +overflow. + +As long as the last_vote variable is globally visible to all CPUs, it +will contain only one value that won't change once every CPU has cleared +its currently_voting flag. + + +Features and limitations +------------------------ + + * vlocks are not intended to be fair. In the contended case, it is the + _last_ CPU which attempts to get the lock which will be most likely + to win. + + vlocks are therefore best suited to situations where it is necessary + to pick a unique winner, but it does not matter which CPU actually + wins. + + * Like other similar mechanisms, vlocks will not scale well to a large + number of CPUs. + + vlocks can be cascaded in a voting hierarchy to permit better scaling + if necessary, as in the following hypothetical example for 4096 CPUs: + + /* first level: local election */ + my_town = towns[(this_cpu >> 4) & 0xf]; + I_won = vlock_trylock(my_town, this_cpu & 0xf); + if (I_won) { + /* we won the town election, let's go for the state */ + my_state = states[(this_cpu >> 8) & 0xf]; + I_won = vlock_lock(my_state, this_cpu & 0xf)); + if (I_won) { + /* and so on */ + I_won = vlock_lock(the_whole_country, this_cpu & 0xf]; + if (I_won) { + /* ... */ + } + vlock_unlock(the_whole_country); + } + vlock_unlock(my_state); + } + vlock_unlock(my_town); + + +ARM implementation +------------------ + +The current ARM implementation [2] contains some optimisations beyond +the basic algorithm: + + * By packing the members of the currently_voting array close together, + we can read the whole array in one transaction (providing the number + of CPUs potentially contending the lock is small enough). This + reduces the number of round-trips required to external memory. + + In the ARM implementation, this means that we can use a single load + and comparison: + + LDR Rt, [Rn] + CMP Rt, #0 + + ...in place of code equivalent to: + + LDRB Rt, [Rn] + CMP Rt, #0 + LDRBEQ Rt, [Rn, #1] + CMPEQ Rt, #0 + LDRBEQ Rt, [Rn, #2] + CMPEQ Rt, #0 + LDRBEQ Rt, [Rn, #3] + CMPEQ Rt, #0 + + This cuts down on the fast-path latency, as well as potentially + reducing bus contention in contended cases. + + The optimisation relies on the fact that the ARM memory system + guarantees coherency between overlapping memory accesses of + different sizes, similarly to many other architectures. Note that + we do not care which element of currently_voting appears in which + bits of Rt, so there is no need to worry about endianness in this + optimisation. + + If there are too many CPUs to read the currently_voting array in + one transaction then multiple transations are still required. The + implementation uses a simple loop of word-sized loads for this + case. The number of transactions is still fewer than would be + required if bytes were loaded individually. + + + In principle, we could aggregate further by using LDRD or LDM, but + to keep the code simple this was not attempted in the initial + implementation. + + + * vlocks are currently only used to coordinate between CPUs which are + unable to enable their caches yet. This means that the + implementation removes many of the barriers which would be required + when executing the algorithm in cached memory. + + packing of the currently_voting array does not work with cached + memory unless all CPUs contending the lock are cache-coherent, due + to cache writebacks from one CPU clobbering values written by other + CPUs. (Though if all the CPUs are cache-coherent, you should be + probably be using proper spinlocks instead anyway). + + + * The "no votes yet" value used for the last_vote variable is 0 (not + -1 as in the pseudocode). This allows statically-allocated vlocks + to be implicitly initialised to an unlocked state simply by putting + them in .bss. + + An offset is added to each CPU's ID for the purpose of setting this + variable, so that no CPU uses the value 0 for its ID. + + +Colophon +-------- + +Originally created and documented by Dave Martin for Linaro Limited, for +use in ARM-based big.LITTLE platforms, with review and input gratefully +received from Nicolas Pitre and Achin Gupta. Thanks to Nicolas for +grabbing most of this text out of the relevant mail thread and writing +up the pseudocode. + +Copyright (C) 2012-2013 Linaro Limited +Distributed under the terms of Version 2 of the GNU General Public +License, as defined in linux/COPYING. + + +References +---------- + +[1] Lamport, L. "A New Solution of Dijkstra's Concurrent Programming + Problem", Communications of the ACM 17, 8 (August 1974), 453-455. + + http://en.wikipedia.org/wiki/Lamport%27s_bakery_algorithm + +[2] linux/arch/arm/common/vlock.S, www.kernel.org. diff --git a/trunk/Documentation/bcache.txt b/trunk/Documentation/bcache.txt new file mode 100644 index 000000000000..77db8809bd96 --- /dev/null +++ b/trunk/Documentation/bcache.txt @@ -0,0 +1,431 @@ +Say you've got a big slow raid 6, and an X-25E or three. Wouldn't it be +nice if you could use them as cache... Hence bcache. + +Wiki and git repositories are at: + http://bcache.evilpiepirate.org + http://evilpiepirate.org/git/linux-bcache.git + http://evilpiepirate.org/git/bcache-tools.git + +It's designed around the performance characteristics of SSDs - it only allocates +in erase block sized buckets, and it uses a hybrid btree/log to track cached +extants (which can be anywhere from a single sector to the bucket size). It's +designed to avoid random writes at all costs; it fills up an erase block +sequentially, then issues a discard before reusing it. + +Both writethrough and writeback caching are supported. Writeback defaults to +off, but can be switched on and off arbitrarily at runtime. Bcache goes to +great lengths to protect your data - it reliably handles unclean shutdown. (It +doesn't even have a notion of a clean shutdown; bcache simply doesn't return +writes as completed until they're on stable storage). + +Writeback caching can use most of the cache for buffering writes - writing +dirty data to the backing device is always done sequentially, scanning from the +start to the end of the index. + +Since random IO is what SSDs excel at, there generally won't be much benefit +to caching large sequential IO. Bcache detects sequential IO and skips it; +it also keeps a rolling average of the IO sizes per task, and as long as the +average is above the cutoff it will skip all IO from that task - instead of +caching the first 512k after every seek. Backups and large file copies should +thus entirely bypass the cache. + +In the event of a data IO error on the flash it will try to recover by reading +from disk or invalidating cache entries. For unrecoverable errors (meta data +or dirty data), caching is automatically disabled; if dirty data was present +in the cache it first disables writeback caching and waits for all dirty data +to be flushed. + +Getting started: +You'll need make-bcache from the bcache-tools repository. Both the cache device +and backing device must be formatted before use. + make-bcache -B /dev/sdb + make-bcache -C /dev/sdc + +make-bcache has the ability to format multiple devices at the same time - if +you format your backing devices and cache device at the same time, you won't +have to manually attach: + make-bcache -B /dev/sda /dev/sdb -C /dev/sdc + +To make bcache devices known to the kernel, echo them to /sys/fs/bcache/register: + + echo /dev/sdb > /sys/fs/bcache/register + echo /dev/sdc > /sys/fs/bcache/register + +To register your bcache devices automatically, you could add something like +this to an init script: + + echo /dev/sd* > /sys/fs/bcache/register_quiet + +It'll look for bcache superblocks and ignore everything that doesn't have one. + +Registering the backing device makes the bcache show up in /dev; you can now +format it and use it as normal. But the first time using a new bcache device, +it'll be running in passthrough mode until you attach it to a cache. See the +section on attaching. + +The devices show up at /dev/bcacheN, and can be controlled via sysfs from +/sys/block/bcacheN/bcache: + + mkfs.ext4 /dev/bcache0 + mount /dev/bcache0 /mnt + +Cache devices are managed as sets; multiple caches per set isn't supported yet +but will allow for mirroring of metadata and dirty data in the future. Your new +cache set shows up as /sys/fs/bcache/ + +ATTACHING: + +After your cache device and backing device are registered, the backing device +must be attached to your cache set to enable caching. Attaching a backing +device to a cache set is done thusly, with the UUID of the cache set in +/sys/fs/bcache: + + echo > /sys/block/bcache0/bcache/attach + +This only has to be done once. The next time you reboot, just reregister all +your bcache devices. If a backing device has data in a cache somewhere, the +/dev/bcache# device won't be created until the cache shows up - particularly +important if you have writeback caching turned on. + +If you're booting up and your cache device is gone and never coming back, you +can force run the backing device: + + echo 1 > /sys/block/sdb/bcache/running + +(You need to use /sys/block/sdb (or whatever your backing device is called), not +/sys/block/bcache0, because bcache0 doesn't exist yet. If you're using a +partition, the bcache directory would be at /sys/block/sdb/sdb2/bcache) + +The backing device will still use that cache set if it shows up in the future, +but all the cached data will be invalidated. If there was dirty data in the +cache, don't expect the filesystem to be recoverable - you will have massive +filesystem corruption, though ext4's fsck does work miracles. + +ERROR HANDLING: + +Bcache tries to transparently handle IO errors to/from the cache device without +affecting normal operation; if it sees too many errors (the threshold is +configurable, and defaults to 0) it shuts down the cache device and switches all +the backing devices to passthrough mode. + + - For reads from the cache, if they error we just retry the read from the + backing device. + + - For writethrough writes, if the write to the cache errors we just switch to + invalidating the data at that lba in the cache (i.e. the same thing we do for + a write that bypasses the cache) + + - For writeback writes, we currently pass that error back up to the + filesystem/userspace. This could be improved - we could retry it as a write + that skips the cache so we don't have to error the write. + + - When we detach, we first try to flush any dirty data (if we were running in + writeback mode). It currently doesn't do anything intelligent if it fails to + read some of the dirty data, though. + +TROUBLESHOOTING PERFORMANCE: + +Bcache has a bunch of config options and tunables. The defaults are intended to +be reasonable for typical desktop and server workloads, but they're not what you +want for getting the best possible numbers when benchmarking. + + - Bad write performance + + If write performance is not what you expected, you probably wanted to be + running in writeback mode, which isn't the default (not due to a lack of + maturity, but simply because in writeback mode you'll lose data if something + happens to your SSD) + + # echo writeback > /sys/block/bcache0/cache_mode + + - Bad performance, or traffic not going to the SSD that you'd expect + + By default, bcache doesn't cache everything. It tries to skip sequential IO - + because you really want to be caching the random IO, and if you copy a 10 + gigabyte file you probably don't want that pushing 10 gigabytes of randomly + accessed data out of your cache. + + But if you want to benchmark reads from cache, and you start out with fio + writing an 8 gigabyte test file - so you want to disable that. + + # echo 0 > /sys/block/bcache0/bcache/sequential_cutoff + + To set it back to the default (4 mb), do + + # echo 4M > /sys/block/bcache0/bcache/sequential_cutoff + + - Traffic's still going to the spindle/still getting cache misses + + In the real world, SSDs don't always keep up with disks - particularly with + slower SSDs, many disks being cached by one SSD, or mostly sequential IO. So + you want to avoid being bottlenecked by the SSD and having it slow everything + down. + + To avoid that bcache tracks latency to the cache device, and gradually + throttles traffic if the latency exceeds a threshold (it does this by + cranking down the sequential bypass). + + You can disable this if you need to by setting the thresholds to 0: + + # echo 0 > /sys/fs/bcache//congested_read_threshold_us + # echo 0 > /sys/fs/bcache//congested_write_threshold_us + + The default is 2000 us (2 milliseconds) for reads, and 20000 for writes. + + - Still getting cache misses, of the same data + + One last issue that sometimes trips people up is actually an old bug, due to + the way cache coherency is handled for cache misses. If a btree node is full, + a cache miss won't be able to insert a key for the new data and the data + won't be written to the cache. + + In practice this isn't an issue because as soon as a write comes along it'll + cause the btree node to be split, and you need almost no write traffic for + this to not show up enough to be noticable (especially since bcache's btree + nodes are huge and index large regions of the device). But when you're + benchmarking, if you're trying to warm the cache by reading a bunch of data + and there's no other traffic - that can be a problem. + + Solution: warm the cache by doing writes, or use the testing branch (there's + a fix for the issue there). + +SYSFS - BACKING DEVICE: + +attach + Echo the UUID of a cache set to this file to enable caching. + +cache_mode + Can be one of either writethrough, writeback, writearound or none. + +clear_stats + Writing to this file resets the running total stats (not the day/hour/5 minute + decaying versions). + +detach + Write to this file to detach from a cache set. If there is dirty data in the + cache, it will be flushed first. + +dirty_data + Amount of dirty data for this backing device in the cache. Continuously + updated unlike the cache set's version, but may be slightly off. + +label + Name of underlying device. + +readahead + Size of readahead that should be performed. Defaults to 0. If set to e.g. + 1M, it will round cache miss reads up to that size, but without overlapping + existing cache entries. + +running + 1 if bcache is running (i.e. whether the /dev/bcache device exists, whether + it's in passthrough mode or caching). + +sequential_cutoff + A sequential IO will bypass the cache once it passes this threshhold; the + most recent 128 IOs are tracked so sequential IO can be detected even when + it isn't all done at once. + +sequential_merge + If non zero, bcache keeps a list of the last 128 requests submitted to compare + against all new requests to determine which new requests are sequential + continuations of previous requests for the purpose of determining sequential + cutoff. This is necessary if the sequential cutoff value is greater than the + maximum acceptable sequential size for any single request. + +state + The backing device can be in one of four different states: + + no cache: Has never been attached to a cache set. + + clean: Part of a cache set, and there is no cached dirty data. + + dirty: Part of a cache set, and there is cached dirty data. + + inconsistent: The backing device was forcibly run by the user when there was + dirty data cached but the cache set was unavailable; whatever data was on the + backing device has likely been corrupted. + +stop + Write to this file to shut down the bcache device and close the backing + device. + +writeback_delay + When dirty data is written to the cache and it previously did not contain + any, waits some number of seconds before initiating writeback. Defaults to + 30. + +writeback_percent + If nonzero, bcache tries to keep around this percentage of the cache dirty by + throttling background writeback and using a PD controller to smoothly adjust + the rate. + +writeback_rate + Rate in sectors per second - if writeback_percent is nonzero, background + writeback is throttled to this rate. Continuously adjusted by bcache but may + also be set by the user. + +writeback_running + If off, writeback of dirty data will not take place at all. Dirty data will + still be added to the cache until it is mostly full; only meant for + benchmarking. Defaults to on. + +SYSFS - BACKING DEVICE STATS: + +There are directories with these numbers for a running total, as well as +versions that decay over the past day, hour and 5 minutes; they're also +aggregated in the cache set directory as well. + +bypassed + Amount of IO (both reads and writes) that has bypassed the cache + +cache_hits +cache_misses +cache_hit_ratio + Hits and misses are counted per individual IO as bcache sees them; a + partial hit is counted as a miss. + +cache_bypass_hits +cache_bypass_misses + Hits and misses for IO that is intended to skip the cache are still counted, + but broken out here. + +cache_miss_collisions + Counts instances where data was going to be inserted into the cache from a + cache miss, but raced with a write and data was already present (usually 0 + since the synchronization for cache misses was rewritten) + +cache_readaheads + Count of times readahead occured. + +SYSFS - CACHE SET: + +average_key_size + Average data per key in the btree. + +bdev<0..n> + Symlink to each of the attached backing devices. + +block_size + Block size of the cache devices. + +btree_cache_size + Amount of memory currently used by the btree cache + +bucket_size + Size of buckets + +cache<0..n> + Symlink to each of the cache devices comprising this cache set. + +cache_available_percent + Percentage of cache device free. + +clear_stats + Clears the statistics associated with this cache + +dirty_data + Amount of dirty data is in the cache (updated when garbage collection runs). + +flash_vol_create + Echoing a size to this file (in human readable units, k/M/G) creates a thinly + provisioned volume backed by the cache set. + +io_error_halflife +io_error_limit + These determines how many errors we accept before disabling the cache. + Each error is decayed by the half life (in # ios). If the decaying count + reaches io_error_limit dirty data is written out and the cache is disabled. + +journal_delay_ms + Journal writes will delay for up to this many milliseconds, unless a cache + flush happens sooner. Defaults to 100. + +root_usage_percent + Percentage of the root btree node in use. If this gets too high the node + will split, increasing the tree depth. + +stop + Write to this file to shut down the cache set - waits until all attached + backing devices have been shut down. + +tree_depth + Depth of the btree (A single node btree has depth 0). + +unregister + Detaches all backing devices and closes the cache devices; if dirty data is + present it will disable writeback caching and wait for it to be flushed. + +SYSFS - CACHE SET INTERNAL: + +This directory also exposes timings for a number of internal operations, with +separate files for average duration, average frequency, last occurence and max +duration: garbage collection, btree read, btree node sorts and btree splits. + +active_journal_entries + Number of journal entries that are newer than the index. + +btree_nodes + Total nodes in the btree. + +btree_used_percent + Average fraction of btree in use. + +bset_tree_stats + Statistics about the auxiliary search trees + +btree_cache_max_chain + Longest chain in the btree node cache's hash table + +cache_read_races + Counts instances where while data was being read from the cache, the bucket + was reused and invalidated - i.e. where the pointer was stale after the read + completed. When this occurs the data is reread from the backing device. + +trigger_gc + Writing to this file forces garbage collection to run. + +SYSFS - CACHE DEVICE: + +block_size + Minimum granularity of writes - should match hardware sector size. + +btree_written + Sum of all btree writes, in (kilo/mega/giga) bytes + +bucket_size + Size of buckets + +cache_replacement_policy + One of either lru, fifo or random. + +discard + Boolean; if on a discard/TRIM will be issued to each bucket before it is + reused. Defaults to off, since SATA TRIM is an unqueued command (and thus + slow). + +freelist_percent + Size of the freelist as a percentage of nbuckets. Can be written to to + increase the number of buckets kept on the freelist, which lets you + artificially reduce the size of the cache at runtime. Mostly for testing + purposes (i.e. testing how different size caches affect your hit rate), but + since buckets are discarded when they move on to the freelist will also make + the SSD's garbage collection easier by effectively giving it more reserved + space. + +io_errors + Number of errors that have occured, decayed by io_error_halflife. + +metadata_written + Sum of all non data writes (btree writes and all other metadata). + +nbuckets + Total buckets in this cache + +priority_stats + Statistics about how recently data in the cache has been accessed. This can + reveal your working set size. + +written + Sum of all data that has been written to the cache; comparison with + btree_written gives the amount of write inflation in bcache. diff --git a/trunk/Documentation/block/cfq-iosched.txt b/trunk/Documentation/block/cfq-iosched.txt index a5eb7d19a65d..9887f0414c16 100644 --- a/trunk/Documentation/block/cfq-iosched.txt +++ b/trunk/Documentation/block/cfq-iosched.txt @@ -5,7 +5,7 @@ The main aim of CFQ scheduler is to provide a fair allocation of the disk I/O bandwidth for all the processes which requests an I/O operation. CFQ maintains the per process queue for the processes which request I/O -operation(syncronous requests). In case of asynchronous requests, all the +operation(synchronous requests). In case of asynchronous requests, all the requests from all the processes are batched together according to their process's I/O priority. @@ -66,6 +66,47 @@ This parameter is used to set the timeout of synchronous requests. Default value of this is 124ms. In case to favor synchronous requests over asynchronous one, this value should be decreased relative to fifo_expire_async. +group_idle +----------- +This parameter forces idling at the CFQ group level instead of CFQ +queue level. This was introduced after after a bottleneck was observed +in higher end storage due to idle on sequential queue and allow dispatch +from a single queue. The idea with this parameter is that it can be run with +slice_idle=0 and group_idle=8, so that idling does not happen on individual +queues in the group but happens overall on the group and thus still keeps the +IO controller working. +Not idling on individual queues in the group will dispatch requests from +multiple queues in the group at the same time and achieve higher throughput +on higher end storage. + +Default value for this parameter is 8ms. + +latency +------- +This parameter is used to enable/disable the latency mode of the CFQ +scheduler. If latency mode (called low_latency) is enabled, CFQ tries +to recompute the slice time for each process based on the target_latency set +for the system. This favors fairness over throughput. Disabling low +latency (setting it to 0) ignores target latency, allowing each process in the +system to get a full time slice. + +By default low latency mode is enabled. + +target_latency +-------------- +This parameter is used to calculate the time slice for a process if cfq's +latency mode is enabled. It will ensure that sync requests have an estimated +latency. But if sequential workload is higher(e.g. sequential read), +then to meet the latency constraints, throughput may decrease because of less +time for each process to issue I/O request before the cfq queue is switched. + +Though this can be overcome by disabling the latency_mode, it may increase +the read latency for some applications. This parameter allows for changing +target_latency through the sysfs interface which can provide the balanced +throughput and read latency. + +Default value for target_latency is 300ms. + slice_async ----------- This parameter is same as of slice_sync but for asynchronous queue. The @@ -98,8 +139,8 @@ in the device exceeds this parameter. This parameter is used for synchronous request. In case of storage with several disk, this setting can limit the parallel -processing of request. Therefore, increasing the value can imporve the -performace although this can cause the latency of some I/O to increase due +processing of request. Therefore, increasing the value can improve the +performance although this can cause the latency of some I/O to increase due to more number of requests. CFQ Group scheduling diff --git a/trunk/Documentation/cgroups/memory.txt b/trunk/Documentation/cgroups/memory.txt index 09027a9fece5..ddf4f93967a9 100644 --- a/trunk/Documentation/cgroups/memory.txt +++ b/trunk/Documentation/cgroups/memory.txt @@ -480,7 +480,9 @@ memory.stat file includes following statistics # per-memory cgroup local status cache - # of bytes of page cache memory. -rss - # of bytes of anonymous and swap cache memory. +rss - # of bytes of anonymous and swap cache memory (includes + transparent hugepages). +rss_huge - # of bytes of anonymous transparent hugepages. mapped_file - # of bytes of mapped file (includes tmpfs/shmem) pgpgin - # of charging events to the memory cgroup. The charging event happens each time a page is accounted as either mapped diff --git a/trunk/Documentation/coccinelle.txt b/trunk/Documentation/coccinelle.txt index dffa2d620d6d..18de78599dd4 100644 --- a/trunk/Documentation/coccinelle.txt +++ b/trunk/Documentation/coccinelle.txt @@ -114,7 +114,7 @@ To apply Coccinelle to a specific directory, M= can be used. For example, to check drivers/net/wireless/ one may write: make coccicheck M=drivers/net/wireless/ - + To apply Coccinelle on a file basis, instead of a directory basis, the following command may be used: @@ -134,6 +134,15 @@ MODE variable explained above. In this mode, there is no information about semantic patches displayed, and no commit message proposed. + Additional flags +~~~~~~~~~~~~~~~~~~ + +Additional flags can be passed to spatch through the SPFLAGS +variable. + + make SPFLAGS=--use_glimpse coccicheck + +See spatch --help to learn more about spatch options. Proposing new semantic patches ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/trunk/Documentation/cpu-freq/governors.txt b/trunk/Documentation/cpu-freq/governors.txt index 66f9cc310686..219970ba54b7 100644 --- a/trunk/Documentation/cpu-freq/governors.txt +++ b/trunk/Documentation/cpu-freq/governors.txt @@ -131,8 +131,8 @@ sampling_rate_min: The sampling rate is limited by the HW transition latency: transition_latency * 100 Or by kernel restrictions: -If CONFIG_NO_HZ is set, the limit is 10ms fixed. -If CONFIG_NO_HZ is not set or nohz=off boot parameter is used, the +If CONFIG_NO_HZ_COMMON is set, the limit is 10ms fixed. +If CONFIG_NO_HZ_COMMON is not set or nohz=off boot parameter is used, the limits depend on the CONFIG_HZ option: HZ=1000: min=20000us (20ms) HZ=250: min=80000us (80ms) diff --git a/trunk/Documentation/devicetree/bindings/arm/omap/l3-noc.txt b/trunk/Documentation/devicetree/bindings/arm/omap/l3-noc.txt index 6888a5efc860..c0105de55cbd 100644 --- a/trunk/Documentation/devicetree/bindings/arm/omap/l3-noc.txt +++ b/trunk/Documentation/devicetree/bindings/arm/omap/l3-noc.txt @@ -6,6 +6,7 @@ provided by Arteris. Required properties: - compatible : Should be "ti,omap3-l3-smx" for OMAP3 family Should be "ti,omap4-l3-noc" for OMAP4 family +- reg: Contains L3 register address range for each noc domain. - ti,hwmods: "l3_main_1", ... One hwmod for each noc domain. Examples: diff --git a/trunk/Documentation/devicetree/bindings/arm/omap/timer.txt b/trunk/Documentation/devicetree/bindings/arm/omap/timer.txt index 8732d4d41f8b..d02e27c764ec 100644 --- a/trunk/Documentation/devicetree/bindings/arm/omap/timer.txt +++ b/trunk/Documentation/devicetree/bindings/arm/omap/timer.txt @@ -1,7 +1,20 @@ OMAP Timer bindings Required properties: -- compatible: Must be "ti,omap2-timer" for OMAP2+ controllers. +- compatible: Should be set to one of the below. Please note that + OMAP44xx devices have timer instances that are 100% + register compatible with OMAP3xxx devices as well as + newer timers that are not 100% register compatible. + So for OMAP44xx devices timer instances may use + different compatible strings. + + ti,omap2420-timer (applicable to OMAP24xx devices) + ti,omap3430-timer (applicable to OMAP3xxx/44xx devices) + ti,omap4430-timer (applicable to OMAP44xx devices) + ti,omap5430-timer (applicable to OMAP543x devices) + ti,am335x-timer (applicable to AM335x devices) + ti,am335x-timer-1ms (applicable to AM335x devices) + - reg: Contains timer register address range (base address and length). - interrupts: Contains the interrupt information for the timer. The @@ -22,7 +35,7 @@ Optional properties: Example: timer12: timer@48304000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap3430-timer"; reg = <0x48304000 0x400>; interrupts = <95>; ti,hwmods = "timer12" diff --git a/trunk/Documentation/devicetree/bindings/arm/primecell.txt b/trunk/Documentation/devicetree/bindings/arm/primecell.txt index 64fc82bc8928..0df6acacfaea 100644 --- a/trunk/Documentation/devicetree/bindings/arm/primecell.txt +++ b/trunk/Documentation/devicetree/bindings/arm/primecell.txt @@ -16,14 +16,31 @@ Optional properties: - clocks : From common clock binding. First clock is phandle to clock for apb pclk. Additional clocks are optional and specific to those peripherals. - clock-names : From common clock binding. Shall be "apb_pclk" for first clock. +- dmas : From common DMA binding. If present, refers to one or more dma channels. +- dma-names : From common DMA binding, needs to match the 'dmas' property. + Devices with exactly one receive and transmit channel shall name + these "rx" and "tx", respectively. +- pinctrl- : Pinctrl states as described in bindings/pinctrl/pinctrl-bindings.txt +- pinctrl-names : Names corresponding to the numbered pinctrl states +- interrupts : one or more interrupt specifiers +- interrupt-names : names corresponding to the interrupts properties Example: serial@fff36000 { compatible = "arm,pl011", "arm,primecell"; arm,primecell-periphid = <0x00341011>; + clocks = <&pclk>; clock-names = "apb_pclk"; - + + dmas = <&dma-controller 4>, <&dma-controller 5>; + dma-names = "rx", "tx"; + + pinctrl-0 = <&uart0_default_mux>, <&uart0_default_mode>; + pinctrl-1 = <&uart0_sleep_mode>; + pinctrl-names = "default","sleep"; + + interrupts = <0 11 0x4>; }; diff --git a/trunk/Documentation/devicetree/bindings/arm/samsung-boards.txt b/trunk/Documentation/devicetree/bindings/arm/samsung-boards.txt index 0bf68be56fd1..2168ed31e1b0 100644 --- a/trunk/Documentation/devicetree/bindings/arm/samsung-boards.txt +++ b/trunk/Documentation/devicetree/bindings/arm/samsung-boards.txt @@ -6,3 +6,13 @@ Required root node properties: - compatible = should be one or more of the following. (a) "samsung,smdkv310" - for Samsung's SMDKV310 eval board. (b) "samsung,exynos4210" - for boards based on Exynos4210 SoC. + +Optional: + - firmware node, specifying presence and type of secure firmware: + - compatible: only "samsung,secure-firmware" is currently supported + - reg: address of non-secure SYSRAM used for communication with firmware + + firmware@0203F000 { + compatible = "samsung,secure-firmware"; + reg = <0x0203F000 0x1000>; + }; diff --git a/trunk/Documentation/devicetree/bindings/arm/samsung/sysreg.txt b/trunk/Documentation/devicetree/bindings/arm/samsung/sysreg.txt new file mode 100644 index 000000000000..5039c0a12f55 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/arm/samsung/sysreg.txt @@ -0,0 +1,7 @@ +SAMSUNG S5P/Exynos SoC series System Registers (SYSREG) + +Properties: + - name : should be 'sysreg'; + - compatible : should contain "samsung,-sysreg", "syscon"; + For Exynos4 SoC series it should be "samsung,exynos4-sysreg", "syscon"; + - reg : offset and length of the register set. diff --git a/trunk/Documentation/devicetree/bindings/ata/pata-arasan.txt b/trunk/Documentation/devicetree/bindings/ata/pata-arasan.txt index 95ec7f825ede..2aff154be84e 100644 --- a/trunk/Documentation/devicetree/bindings/ata/pata-arasan.txt +++ b/trunk/Documentation/devicetree/bindings/ata/pata-arasan.txt @@ -6,6 +6,26 @@ Required properties: - interrupt-parent: Should be the phandle for the interrupt controller that services interrupts for this device - interrupt: Should contain the CF interrupt number +- clock-frequency: Interface clock rate, in Hz, one of + 25000000 + 33000000 + 40000000 + 50000000 + 66000000 + 75000000 + 100000000 + 125000000 + 150000000 + 166000000 + 200000000 + +Optional properties: +- arasan,broken-udma: if present, UDMA mode is unusable +- arasan,broken-mwdma: if present, MWDMA mode is unusable +- arasan,broken-pio: if present, PIO mode is unusable +- dmas: one DMA channel, as described in bindings/dma/dma.txt + required unless both UDMA and MWDMA mode are broken +- dma-names: the corresponding channel name, must be "data" Example: @@ -14,4 +34,6 @@ Example: reg = <0xfc000000 0x1000>; interrupt-parent = <&vic1>; interrupts = <12>; + dmas = <&dma-controller 23>; + dma-names = "data"; }; diff --git a/trunk/Documentation/devicetree/bindings/bus/ti-gpmc.txt b/trunk/Documentation/devicetree/bindings/bus/ti-gpmc.txt index 5ddb2e9efaaa..4b87ea1194e3 100644 --- a/trunk/Documentation/devicetree/bindings/bus/ti-gpmc.txt +++ b/trunk/Documentation/devicetree/bindings/bus/ti-gpmc.txt @@ -35,36 +35,83 @@ Required properties: Timing properties for child nodes. All are optional and default to 0. - - gpmc,sync-clk: Minimum clock period for synchronous mode, in picoseconds - - Chip-select signal timings corresponding to GPMC_CONFIG2: - - gpmc,cs-on: Assertion time - - gpmc,cs-rd-off: Read deassertion time - - gpmc,cs-wr-off: Write deassertion time - - ADV signal timings corresponding to GPMC_CONFIG3: - - gpmc,adv-on: Assertion time - - gpmc,adv-rd-off: Read deassertion time - - gpmc,adv-wr-off: Write deassertion time - - WE signals timings corresponding to GPMC_CONFIG4: - - gpmc,we-on: Assertion time - - gpmc,we-off: Deassertion time - - OE signals timings corresponding to GPMC_CONFIG4: - - gpmc,oe-on: Assertion time - - gpmc,oe-off: Deassertion time - - Access time and cycle time timings corresponding to GPMC_CONFIG5: - - gpmc,page-burst-access: Multiple access word delay - - gpmc,access: Start-cycle to first data valid delay - - gpmc,rd-cycle: Total read cycle time - - gpmc,wr-cycle: Total write cycle time + - gpmc,sync-clk-ps: Minimum clock period for synchronous mode, in picoseconds + + Chip-select signal timings (in nanoseconds) corresponding to GPMC_CONFIG2: + - gpmc,cs-on-ns: Assertion time + - gpmc,cs-rd-off-ns: Read deassertion time + - gpmc,cs-wr-off-ns: Write deassertion time + + ADV signal timings (in nanoseconds) corresponding to GPMC_CONFIG3: + - gpmc,adv-on-ns: Assertion time + - gpmc,adv-rd-off-ns: Read deassertion time + - gpmc,adv-wr-off-ns: Write deassertion time + + WE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4: + - gpmc,we-on-ns Assertion time + - gpmc,we-off-ns: Deassertion time + + OE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4: + - gpmc,oe-on-ns: Assertion time + - gpmc,oe-off-ns: Deassertion time + + Access time and cycle time timings (in nanoseconds) corresponding to + GPMC_CONFIG5: + - gpmc,page-burst-access-ns: Multiple access word delay + - gpmc,access-ns: Start-cycle to first data valid delay + - gpmc,rd-cycle-ns: Total read cycle time + - gpmc,wr-cycle-ns: Total write cycle time + - gpmc,bus-turnaround-ns: Turn-around time between successive accesses + - gpmc,cycle2cycle-delay-ns: Delay between chip-select pulses + - gpmc,clk-activation-ns: GPMC clock activation time + - gpmc,wait-monitoring-ns: Start of wait monitoring with regard to valid + data + +Boolean timing parameters. If property is present parameter enabled and +disabled if omitted: + - gpmc,adv-extra-delay: ADV signal is delayed by half GPMC clock + - gpmc,cs-extra-delay: CS signal is delayed by half GPMC clock + - gpmc,cycle2cycle-diffcsen: Add "cycle2cycle-delay" between successive + accesses to a different CS + - gpmc,cycle2cycle-samecsen: Add "cycle2cycle-delay" between successive + accesses to the same CS + - gpmc,oe-extra-delay: OE signal is delayed by half GPMC clock + - gpmc,we-extra-delay: WE signal is delayed by half GPMC clock + - gpmc,time-para-granularity: Multiply all access times by 2 The following are only applicable to OMAP3+ and AM335x: - - gpmc,wr-access - - gpmc,wr-data-mux-bus - + - gpmc,wr-access-ns: In synchronous write mode, for single or + burst accesses, defines the number of + GPMC_FCLK cycles from start access time + to the GPMC_CLK rising edge used by the + memory device for the first data capture. + - gpmc,wr-data-mux-bus-ns: In address-data multiplex mode, specifies + the time when the first data is driven on + the address-data bus. + +GPMC chip-select settings properties for child nodes. All are optional. + +- gpmc,burst-length Page/burst length. Must be 4, 8 or 16. +- gpmc,burst-wrap Enables wrap bursting +- gpmc,burst-read Enables read page/burst mode +- gpmc,burst-write Enables write page/burst mode +- gpmc,device-nand Device is NAND +- gpmc,device-width Total width of device(s) connected to a GPMC + chip-select in bytes. The GPMC supports 8-bit + and 16-bit devices and so this property must be + 1 or 2. +- gpmc,mux-add-data Address and data multiplexing configuration. + Valid values are 1 for address-address-data + multiplexing mode and 2 for address-data + multiplexing mode. +- gpmc,sync-read Enables synchronous read. Defaults to asynchronous + is this is not set. +- gpmc,sync-write Enables synchronous writes. Defaults to asynchronous + is this is not set. +- gpmc,wait-pin Wait-pin used by client. Must be less than + "gpmc,num-waitpins". +- gpmc,wait-on-read Enables wait monitoring on reads. +- gpmc,wait-on-write Enables wait monitoring on writes. Example for an AM33xx board: diff --git a/trunk/Documentation/devicetree/bindings/clock/exynos4-clock.txt b/trunk/Documentation/devicetree/bindings/clock/exynos4-clock.txt new file mode 100644 index 000000000000..ea5e26f16aec --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/clock/exynos4-clock.txt @@ -0,0 +1,288 @@ +* Samsung Exynos4 Clock Controller + +The Exynos4 clock controller generates and supplies clock to various controllers +within the Exynos4 SoC. The clock binding described here is applicable to all +SoC's in the Exynos4 family. + +Required Properties: + +- comptible: should be one of the following. + - "samsung,exynos4210-clock" - controller compatible with Exynos4210 SoC. + - "samsung,exynos4412-clock" - controller compatible with Exynos4412 SoC. + +- reg: physical base address of the controller and length of memory mapped + region. + +- #clock-cells: should be 1. + +The following is the list of clocks generated by the controller. Each clock is +assigned an identifier and client nodes use this identifier to specify the +clock which they consume. Some of the clocks are available only on a particular +Exynos4 SoC and this is specified where applicable. + + + [Core Clocks] + + Clock ID SoC (if specific) + ----------------------------------------------- + + xxti 1 + xusbxti 2 + fin_pll 3 + fout_apll 4 + fout_mpll 5 + fout_epll 6 + fout_vpll 7 + sclk_apll 8 + sclk_mpll 9 + sclk_epll 10 + sclk_vpll 11 + arm_clk 12 + aclk200 13 + aclk100 14 + aclk160 15 + aclk133 16 + mout_mpll_user_t 17 Exynos4x12 + mout_mpll_user_c 18 Exynos4x12 + mout_core 19 + mout_apll 20 + + + [Clock Gate for Special Clocks] + + Clock ID SoC (if specific) + ----------------------------------------------- + + sclk_fimc0 128 + sclk_fimc1 129 + sclk_fimc2 130 + sclk_fimc3 131 + sclk_cam0 132 + sclk_cam1 133 + sclk_csis0 134 + sclk_csis1 135 + sclk_hdmi 136 + sclk_mixer 137 + sclk_dac 138 + sclk_pixel 139 + sclk_fimd0 140 + sclk_mdnie0 141 Exynos4412 + sclk_mdnie_pwm0 12 142 Exynos4412 + sclk_mipi0 143 + sclk_audio0 144 + sclk_mmc0 145 + sclk_mmc1 146 + sclk_mmc2 147 + sclk_mmc3 148 + sclk_mmc4 149 + sclk_sata 150 Exynos4210 + sclk_uart0 151 + sclk_uart1 152 + sclk_uart2 153 + sclk_uart3 154 + sclk_uart4 155 + sclk_audio1 156 + sclk_audio2 157 + sclk_spdif 158 + sclk_spi0 159 + sclk_spi1 160 + sclk_spi2 161 + sclk_slimbus 162 + sclk_fimd1 163 Exynos4210 + sclk_mipi1 164 Exynos4210 + sclk_pcm1 165 + sclk_pcm2 166 + sclk_i2s1 167 + sclk_i2s2 168 + sclk_mipihsi 169 Exynos4412 + sclk_mfc 170 + sclk_pcm0 171 + sclk_g3d 172 + sclk_pwm_isp 173 Exynos4x12 + sclk_spi0_isp 174 Exynos4x12 + sclk_spi1_isp 175 Exynos4x12 + sclk_uart_isp 176 Exynos4x12 + + [Peripheral Clock Gates] + + Clock ID SoC (if specific) + ----------------------------------------------- + + fimc0 256 + fimc1 257 + fimc2 258 + fimc3 259 + csis0 260 + csis1 261 + jpeg 262 + smmu_fimc0 263 + smmu_fimc1 264 + smmu_fimc2 265 + smmu_fimc3 266 + smmu_jpeg 267 + vp 268 + mixer 269 + tvenc 270 Exynos4210 + hdmi 271 + smmu_tv 272 + mfc 273 + smmu_mfcl 274 + smmu_mfcr 275 + g3d 276 + g2d 277 Exynos4210 + rotator 278 Exynos4210 + mdma 279 Exynos4210 + smmu_g2d 280 Exynos4210 + smmu_rotator 281 Exynos4210 + smmu_mdma 282 Exynos4210 + fimd0 283 + mie0 284 + mdnie0 285 Exynos4412 + dsim0 286 + smmu_fimd0 287 + fimd1 288 Exynos4210 + mie1 289 Exynos4210 + dsim1 290 Exynos4210 + smmu_fimd1 291 Exynos4210 + pdma0 292 + pdma1 293 + pcie_phy 294 + sata_phy 295 Exynos4210 + tsi 296 + sdmmc0 297 + sdmmc1 298 + sdmmc2 299 + sdmmc3 300 + sdmmc4 301 + sata 302 Exynos4210 + sromc 303 + usb_host 304 + usb_device 305 + pcie 306 + onenand 307 + nfcon 308 + smmu_pcie 309 + gps 310 + smmu_gps 311 + uart0 312 + uart1 313 + uart2 314 + uart3 315 + uart4 316 + i2c0 317 + i2c1 318 + i2c2 319 + i2c3 320 + i2c4 321 + i2c5 322 + i2c6 323 + i2c7 324 + i2c_hdmi 325 + tsadc 326 + spi0 327 + spi1 328 + spi2 329 + i2s1 330 + i2s2 331 + pcm0 332 + i2s0 333 + pcm1 334 + pcm2 335 + pwm 336 + slimbus 337 + spdif 338 + ac97 339 + modemif 340 + chipid 341 + sysreg 342 + hdmi_cec 343 + mct 344 + wdt 345 + rtc 346 + keyif 347 + audss 348 + mipi_hsi 349 Exynos4210 + mdma2 350 Exynos4210 + pixelasyncm0 351 + pixelasyncm1 352 + fimc_lite0 353 Exynos4x12 + fimc_lite1 354 Exynos4x12 + ppmuispx 355 Exynos4x12 + ppmuispmx 356 Exynos4x12 + fimc_isp 357 Exynos4x12 + fimc_drc 358 Exynos4x12 + fimc_fd 359 Exynos4x12 + mcuisp 360 Exynos4x12 + gicisp 361 Exynos4x12 + smmu_isp 362 Exynos4x12 + smmu_drc 363 Exynos4x12 + smmu_fd 364 Exynos4x12 + smmu_lite0 365 Exynos4x12 + smmu_lite1 366 Exynos4x12 + mcuctl_isp 367 Exynos4x12 + mpwm_isp 368 Exynos4x12 + i2c0_isp 369 Exynos4x12 + i2c1_isp 370 Exynos4x12 + mtcadc_isp 371 Exynos4x12 + pwm_isp 372 Exynos4x12 + wdt_isp 373 Exynos4x12 + uart_isp 374 Exynos4x12 + asyncaxim 375 Exynos4x12 + smmu_ispcx 376 Exynos4x12 + spi0_isp 377 Exynos4x12 + spi1_isp 378 Exynos4x12 + pwm_isp_sclk 379 Exynos4x12 + spi0_isp_sclk 380 Exynos4x12 + spi1_isp_sclk 381 Exynos4x12 + uart_isp_sclk 382 Exynos4x12 + + [Mux Clocks] + + Clock ID SoC (if specific) + ----------------------------------------------- + + mout_fimc0 384 + mout_fimc1 385 + mout_fimc2 386 + mout_fimc3 387 + mout_cam0 388 + mout_cam1 389 + mout_csis0 390 + mout_csis1 391 + mout_g3d0 392 + mout_g3d1 393 + mout_g3d 394 + aclk400_mcuisp 395 Exynos4x12 + + [Div Clocks] + + Clock ID SoC (if specific) + ----------------------------------------------- + + div_isp0 450 Exynos4x12 + div_isp1 451 Exynos4x12 + div_mcuisp0 452 Exynos4x12 + div_mcuisp1 453 Exynos4x12 + div_aclk200 454 Exynos4x12 + div_aclk400_mcuisp 455 Exynos4x12 + + +Example 1: An example of a clock controller node is listed below. + + clock: clock-controller@0x10030000 { + compatible = "samsung,exynos4210-clock"; + reg = <0x10030000 0x20000>; + #clock-cells = <1>; + }; + +Example 2: UART controller node that consumes the clock generated by the clock + controller. Refer to the standard clock bindings for information + about 'clocks' and 'clock-names' property. + + serial@13820000 { + compatible = "samsung,exynos4210-uart"; + reg = <0x13820000 0x100>; + interrupts = <0 54 0>; + clocks = <&clock 314>, <&clock 153>; + clock-names = "uart", "clk_uart_baud0"; + }; diff --git a/trunk/Documentation/devicetree/bindings/clock/exynos5250-clock.txt b/trunk/Documentation/devicetree/bindings/clock/exynos5250-clock.txt new file mode 100644 index 000000000000..781a6276adf7 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/clock/exynos5250-clock.txt @@ -0,0 +1,177 @@ +* Samsung Exynos5250 Clock Controller + +The Exynos5250 clock controller generates and supplies clock to various +controllers within the Exynos5250 SoC. + +Required Properties: + +- comptible: should be one of the following. + - "samsung,exynos5250-clock" - controller compatible with Exynos5250 SoC. + +- reg: physical base address of the controller and length of memory mapped + region. + +- #clock-cells: should be 1. + +The following is the list of clocks generated by the controller. Each clock is +assigned an identifier and client nodes use this identifier to specify the +clock which they consume. + + + [Core Clocks] + + Clock ID + ---------------------------- + + fin_pll 1 + + [Clock Gate for Special Clocks] + + Clock ID + ---------------------------- + + sclk_cam_bayer 128 + sclk_cam0 129 + sclk_cam1 130 + sclk_gscl_wa 131 + sclk_gscl_wb 132 + sclk_fimd1 133 + sclk_mipi1 134 + sclk_dp 135 + sclk_hdmi 136 + sclk_pixel 137 + sclk_audio0 138 + sclk_mmc0 139 + sclk_mmc1 140 + sclk_mmc2 141 + sclk_mmc3 142 + sclk_sata 143 + sclk_usb3 144 + sclk_jpeg 145 + sclk_uart0 146 + sclk_uart1 147 + sclk_uart2 148 + sclk_uart3 149 + sclk_pwm 150 + sclk_audio1 151 + sclk_audio2 152 + sclk_spdif 153 + sclk_spi0 154 + sclk_spi1 155 + sclk_spi2 156 + + + [Peripheral Clock Gates] + + Clock ID + ---------------------------- + + gscl0 256 + gscl1 257 + gscl2 258 + gscl3 259 + gscl_wa 260 + gscl_wb 261 + smmu_gscl0 262 + smmu_gscl1 263 + smmu_gscl2 264 + smmu_gscl3 265 + mfc 266 + smmu_mfcl 267 + smmu_mfcr 268 + rotator 269 + jpeg 270 + mdma1 271 + smmu_rotator 272 + smmu_jpeg 273 + smmu_mdma1 274 + pdma0 275 + pdma1 276 + sata 277 + usbotg 278 + mipi_hsi 279 + sdmmc0 280 + sdmmc1 281 + sdmmc2 282 + sdmmc3 283 + sromc 284 + usb2 285 + usb3 286 + sata_phyctrl 287 + sata_phyi2c 288 + uart0 289 + uart1 290 + uart2 291 + uart3 292 + uart4 293 + i2c0 294 + i2c1 295 + i2c2 296 + i2c3 297 + i2c4 298 + i2c5 299 + i2c6 300 + i2c7 301 + i2c_hdmi 302 + adc 303 + spi0 304 + spi1 305 + spi2 306 + i2s1 307 + i2s2 308 + pcm1 309 + pcm2 310 + pwm 311 + spdif 312 + ac97 313 + hsi2c0 314 + hsi2c1 315 + hs12c2 316 + hs12c3 317 + chipid 318 + sysreg 319 + pmu 320 + cmu_top 321 + cmu_core 322 + cmu_mem 323 + tzpc0 324 + tzpc1 325 + tzpc2 326 + tzpc3 327 + tzpc4 328 + tzpc5 329 + tzpc6 330 + tzpc7 331 + tzpc8 332 + tzpc9 333 + hdmi_cec 334 + mct 335 + wdt 336 + rtc 337 + tmu 338 + fimd1 339 + mie1 340 + dsim0 341 + dp 342 + mixer 343 + hdmi 345 + +Example 1: An example of a clock controller node is listed below. + + clock: clock-controller@0x10010000 { + compatible = "samsung,exynos5250-clock"; + reg = <0x10010000 0x30000>; + #clock-cells = <1>; + }; + +Example 2: UART controller node that consumes the clock generated by the clock + controller. Refer to the standard clock bindings for information + about 'clocks' and 'clock-names' property. + + serial@13820000 { + compatible = "samsung,exynos4210-uart"; + reg = <0x13820000 0x100>; + interrupts = <0 54 0>; + clocks = <&clock 314>, <&clock 153>; + clock-names = "uart", "clk_uart_baud0"; + }; diff --git a/trunk/Documentation/devicetree/bindings/clock/exynos5440-clock.txt b/trunk/Documentation/devicetree/bindings/clock/exynos5440-clock.txt new file mode 100644 index 000000000000..4499e9966bc9 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/clock/exynos5440-clock.txt @@ -0,0 +1,61 @@ +* Samsung Exynos5440 Clock Controller + +The Exynos5440 clock controller generates and supplies clock to various +controllers within the Exynos5440 SoC. + +Required Properties: + +- comptible: should be "samsung,exynos5440-clock". + +- reg: physical base address of the controller and length of memory mapped + region. + +- #clock-cells: should be 1. + +The following is the list of clocks generated by the controller. Each clock is +assigned an identifier and client nodes use this identifier to specify the +clock which they consume. + + + [Core Clocks] + + Clock ID + ---------------------------- + + xtal 1 + arm_clk 2 + + [Peripheral Clock Gates] + + Clock ID + ---------------------------- + + spi_baud 16 + pb0_250 17 + pr0_250 18 + pr1_250 19 + b_250 20 + b_125 21 + b_200 22 + sata 23 + usb 24 + gmac0 25 + cs250 26 + pb0_250_o 27 + pr0_250_o 28 + pr1_250_o 29 + b_250_o 30 + b_125_o 31 + b_200_o 32 + sata_o 33 + usb_o 34 + gmac0_o 35 + cs250_o 36 + +Example: An example of a clock controller node is listed below. + + clock: clock-controller@0x10010000 { + compatible = "samsung,exynos5440-clock"; + reg = <0x160000 0x10000>; + #clock-cells = <1>; + }; diff --git a/trunk/Documentation/devicetree/bindings/clock/imx5-clock.txt b/trunk/Documentation/devicetree/bindings/clock/imx5-clock.txt index 2a0c904c46ae..d71b4b2c077d 100644 --- a/trunk/Documentation/devicetree/bindings/clock/imx5-clock.txt +++ b/trunk/Documentation/devicetree/bindings/clock/imx5-clock.txt @@ -38,7 +38,6 @@ clocks and IDs. usb_phy_podf 23 cpu_podf 24 di_pred 25 - tve_di 26 tve_s 27 uart1_ipg_gate 28 uart1_per_gate 29 @@ -172,6 +171,19 @@ clocks and IDs. can1_serial_gate 157 can1_ipg_gate 158 owire_gate 159 + gpu3d_s 160 + gpu2d_s 161 + gpu3d_gate 162 + gpu2d_gate 163 + garb_gate 164 + cko1_sel 165 + cko1_podf 166 + cko1 167 + cko2_sel 168 + cko2_podf 169 + cko2 170 + srtc_gate 171 + pata_gate 172 Examples (for mx53): diff --git a/trunk/Documentation/devicetree/bindings/clock/imx6q-clock.txt b/trunk/Documentation/devicetree/bindings/clock/imx6q-clock.txt index 969b38e06ad3..6deb6fd1c7cd 100644 --- a/trunk/Documentation/devicetree/bindings/clock/imx6q-clock.txt +++ b/trunk/Documentation/devicetree/bindings/clock/imx6q-clock.txt @@ -205,6 +205,9 @@ clocks and IDs. enet_ref 190 usbphy1_gate 191 usbphy2_gate 192 + pll4_post_div 193 + pll5_post_div 194 + pll5_video_div 195 Examples: diff --git a/trunk/Documentation/devicetree/bindings/clock/nvidia,tegra114-car.txt b/trunk/Documentation/devicetree/bindings/clock/nvidia,tegra114-car.txt new file mode 100644 index 000000000000..d6cb083b90a2 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/clock/nvidia,tegra114-car.txt @@ -0,0 +1,303 @@ +NVIDIA Tegra114 Clock And Reset Controller + +This binding uses the common clock binding: +Documentation/devicetree/bindings/clock/clock-bindings.txt + +The CAR (Clock And Reset) Controller on Tegra is the HW module responsible +for muxing and gating Tegra's clocks, and setting their rates. + +Required properties : +- compatible : Should be "nvidia,tegra114-car" +- reg : Should contain CAR registers location and length +- clocks : Should contain phandle and clock specifiers for two clocks: + the 32 KHz "32k_in", and the board-specific oscillator "osc". +- #clock-cells : Should be 1. + In clock consumers, this cell represents the clock ID exposed by the CAR. + + The first 160 clocks are numbered to match the bits in the CAR's CLK_OUT_ENB + registers. These IDs often match those in the CAR's RST_DEVICES registers, + but not in all cases. Some bits in CLK_OUT_ENB affect multiple clocks. In + this case, those clocks are assigned IDs above 160 in order to highlight + this issue. Implementations that interpret these clock IDs as bit values + within the CLK_OUT_ENB or RST_DEVICES registers should be careful to + explicitly handle these special cases. + + The balance of the clocks controlled by the CAR are assigned IDs of 160 and + above. + + 0 unassigned + 1 unassigned + 2 unassigned + 3 unassigned + 4 rtc + 5 timer + 6 uarta + 7 unassigned (register bit affects uartb and vfir) + 8 unassigned + 9 sdmmc2 + 10 unassigned (register bit affects spdif_in and spdif_out) + 11 i2s1 + 12 i2c1 + 13 ndflash + 14 sdmmc1 + 15 sdmmc4 + 16 unassigned + 17 pwm + 18 i2s2 + 19 epp + 20 unassigned (register bit affects vi and vi_sensor) + 21 2d + 22 usbd + 23 isp + 24 3d + 25 unassigned + 26 disp2 + 27 disp1 + 28 host1x + 29 vcp + 30 i2s0 + 31 unassigned + + 32 unassigned + 33 unassigned + 34 apbdma + 35 unassigned + 36 kbc + 37 unassigned + 38 unassigned + 39 unassigned (register bit affects fuse and fuse_burn) + 40 kfuse + 41 sbc1 + 42 nor + 43 unassigned + 44 sbc2 + 45 unassigned + 46 sbc3 + 47 i2c5 + 48 dsia + 49 unassigned + 50 mipi + 51 hdmi + 52 csi + 53 unassigned + 54 i2c2 + 55 uartc + 56 mipi-cal + 57 emc + 58 usb2 + 59 usb3 + 60 msenc + 61 vde + 62 bsea + 63 bsev + + 64 unassigned + 65 uartd + 66 unassigned + 67 i2c3 + 68 sbc4 + 69 sdmmc3 + 70 unassigned + 71 owr + 72 afi + 73 csite + 74 unassigned + 75 unassigned + 76 la + 77 trace + 78 soc_therm + 79 dtv + 80 ndspeed + 81 i2cslow + 82 dsib + 83 tsec + 84 unassigned + 85 unassigned + 86 unassigned + 87 unassigned + 88 unassigned + 89 xusb_host + 90 unassigned + 91 msenc + 92 csus + 93 unassigned + 94 unassigned + 95 unassigned (bit affects xusb_dev and xusb_dev_src) + + 96 unassigned + 97 unassigned + 98 unassigned + 99 mselect + 100 tsensor + 101 i2s3 + 102 i2s4 + 103 i2c4 + 104 sbc5 + 105 sbc6 + 106 d_audio + 107 apbif + 108 dam0 + 109 dam1 + 110 dam2 + 111 hda2codec_2x + 112 unassigned + 113 audio0_2x + 114 audio1_2x + 115 audio2_2x + 116 audio3_2x + 117 audio4_2x + 118 spdif_2x + 119 actmon + 120 extern1 + 121 extern2 + 122 extern3 + 123 unassigned + 124 unassigned + 125 hda + 126 unassigned + 127 se + + 128 hda2hdmi + 129 unassigned + 130 unassigned + 131 unassigned + 132 unassigned + 133 unassigned + 134 unassigned + 135 unassigned + 136 unassigned + 137 unassigned + 138 unassigned + 139 unassigned + 140 unassigned + 141 unassigned + 142 unassigned + 143 unassigned (bit affects xusb_falcon_src, xusb_fs_src, + xusb_host_src and xusb_ss_src) + 144 cilab + 145 cilcd + 146 cile + 147 dsialp + 148 dsiblp + 149 unassigned + 150 dds + 151 unassigned + 152 dp2 + 153 amx + 154 adx + 155 unassigned (bit affects dfll_ref and dfll_soc) + 156 xusb_ss + + 192 uartb + 193 vfir + 194 spdif_in + 195 spdif_out + 196 vi + 197 vi_sensor + 198 fuse + 199 fuse_burn + 200 clk_32k + 201 clk_m + 202 clk_m_div2 + 203 clk_m_div4 + 204 pll_ref + 205 pll_c + 206 pll_c_out1 + 207 pll_c2 + 208 pll_c3 + 209 pll_m + 210 pll_m_out1 + 211 pll_p + 212 pll_p_out1 + 213 pll_p_out2 + 214 pll_p_out3 + 215 pll_p_out4 + 216 pll_a + 217 pll_a_out0 + 218 pll_d + 219 pll_d_out0 + 220 pll_d2 + 221 pll_d2_out0 + 222 pll_u + 223 pll_u_480M + 224 pll_u_60M + 225 pll_u_48M + 226 pll_u_12M + 227 pll_x + 228 pll_x_out0 + 229 pll_re_vco + 230 pll_re_out + 231 pll_e_out0 + 232 spdif_in_sync + 233 i2s0_sync + 234 i2s1_sync + 235 i2s2_sync + 236 i2s3_sync + 237 i2s4_sync + 238 vimclk_sync + 239 audio0 + 240 audio1 + 241 audio2 + 242 audio3 + 243 audio4 + 244 spdif + 245 clk_out_1 + 246 clk_out_2 + 247 clk_out_3 + 248 blink + 252 xusb_host_src + 253 xusb_falcon_src + 254 xusb_fs_src + 255 xusb_ss_src + 256 xusb_dev_src + 257 xusb_dev + 258 xusb_hs_src + 259 sclk + 260 hclk + 261 pclk + 262 cclk_g + 263 cclk_lp + 264 dfll_ref + 265 dfll_soc + +Example SoC include file: + +/ { + tegra_car: clock { + compatible = "nvidia,tegra114-car"; + reg = <0x60006000 0x1000>; + #clock-cells = <1>; + }; + + usb@c5004000 { + clocks = <&tegra_car 58>; /* usb2 */ + }; +}; + +Example board file: + +/ { + clocks { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + osc: clock@0 { + compatible = "fixed-clock"; + reg = <0>; + #clock-cells = <0>; + clock-frequency = <12000000>; + }; + + clk_32k: clock@1 { + compatible = "fixed-clock"; + reg = <1>; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + }; + + &tegra_car { + clocks = <&clk_32k> <&osc>; + }; +}; diff --git a/trunk/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.txt b/trunk/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.txt index 0921fac73528..e885680f6b45 100644 --- a/trunk/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.txt +++ b/trunk/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.txt @@ -120,8 +120,8 @@ Required properties : 90 clk_d 91 unassigned 92 sus - 93 cdev1 - 94 cdev2 + 93 cdev2 + 94 cdev1 95 unassigned 96 uart2 diff --git a/trunk/Documentation/devicetree/bindings/crypto/fsl-imx-sahara.txt b/trunk/Documentation/devicetree/bindings/crypto/fsl-imx-sahara.txt new file mode 100644 index 000000000000..5c65eccd0e56 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/crypto/fsl-imx-sahara.txt @@ -0,0 +1,15 @@ +Freescale SAHARA Cryptographic Accelerator included in some i.MX chips. +Currently only i.MX27 is supported. + +Required properties: +- compatible : Should be "fsl,-sahara" +- reg : Should contain SAHARA registers location and length +- interrupts : Should contain SAHARA interrupt number + +Example: + +sah@10025000 { + compatible = "fsl,imx27-sahara"; + reg = < 0x10025000 0x800>; + interrupts = <75>; +}; diff --git a/trunk/Documentation/devicetree/bindings/dma/atmel-dma.txt b/trunk/Documentation/devicetree/bindings/dma/atmel-dma.txt index 3c046ee6e8b5..c80e8a3402f0 100644 --- a/trunk/Documentation/devicetree/bindings/dma/atmel-dma.txt +++ b/trunk/Documentation/devicetree/bindings/dma/atmel-dma.txt @@ -1,14 +1,39 @@ * Atmel Direct Memory Access Controller (DMA) Required properties: -- compatible: Should be "atmel,-dma" -- reg: Should contain DMA registers location and length -- interrupts: Should contain DMA interrupt +- compatible: Should be "atmel,-dma". +- reg: Should contain DMA registers location and length. +- interrupts: Should contain DMA interrupt. +- #dma-cells: Must be <2>, used to represent the number of integer cells in +the dmas property of client devices. -Examples: +Example: -dma@ffffec00 { +dma0: dma@ffffec00 { compatible = "atmel,at91sam9g45-dma"; reg = <0xffffec00 0x200>; interrupts = <21>; + #dma-cells = <2>; +}; + +DMA clients connected to the Atmel DMA controller must use the format +described in the dma.txt file, using a three-cell specifier for each channel: +a phandle plus two interger cells. +The three cells in order are: + +1. A phandle pointing to the DMA controller. +2. The memory interface (16 most significant bits), the peripheral interface +(16 less significant bits). +3. The peripheral identifier for the hardware handshaking interface. The +identifier can be different for tx and rx. + +Example: + +i2c0@i2c@f8010000 { + compatible = "atmel,at91sam9x5-i2c"; + reg = <0xf8010000 0x100>; + interrupts = <9 4 6>; + dmas = <&dma0 1 7>, + <&dma0 1 8>; + dma-names = "tx", "rx"; }; diff --git a/trunk/Documentation/devicetree/bindings/dma/fsl-mxs-dma.txt b/trunk/Documentation/devicetree/bindings/dma/fsl-mxs-dma.txt index ded0398d3bdc..a4873e5e3e36 100644 --- a/trunk/Documentation/devicetree/bindings/dma/fsl-mxs-dma.txt +++ b/trunk/Documentation/devicetree/bindings/dma/fsl-mxs-dma.txt @@ -3,17 +3,58 @@ Required properties: - compatible : Should be "fsl,-dma-apbh" or "fsl,-dma-apbx" - reg : Should contain registers location and length +- interrupts : Should contain the interrupt numbers of DMA channels. + If a channel is empty/reserved, 0 should be filled in place. +- #dma-cells : Must be <1>. The number cell specifies the channel ID. +- dma-channels : Number of channels supported by the DMA controller + +Optional properties: +- interrupt-names : Name of DMA channel interrupts Supported chips: imx23, imx28. Examples: -dma-apbh@80004000 { + +dma_apbh: dma-apbh@80004000 { compatible = "fsl,imx28-dma-apbh"; - reg = <0x80004000 2000>; + reg = <0x80004000 0x2000>; + interrupts = <82 83 84 85 + 88 88 88 88 + 88 88 88 88 + 87 86 0 0>; + interrupt-names = "ssp0", "ssp1", "ssp2", "ssp3", + "gpmi0", "gmpi1", "gpmi2", "gmpi3", + "gpmi4", "gmpi5", "gpmi6", "gmpi7", + "hsadc", "lcdif", "empty", "empty"; + #dma-cells = <1>; + dma-channels = <16>; }; -dma-apbx@80024000 { +dma_apbx: dma-apbx@80024000 { compatible = "fsl,imx28-dma-apbx"; - reg = <0x80024000 2000>; + reg = <0x80024000 0x2000>; + interrupts = <78 79 66 0 + 80 81 68 69 + 70 71 72 73 + 74 75 76 77>; + interrupt-names = "auart4-rx", "aurat4-tx", "spdif-tx", "empty", + "saif0", "saif1", "i2c0", "i2c1", + "auart0-rx", "auart0-tx", "auart1-rx", "auart1-tx", + "auart2-rx", "auart2-tx", "auart3-rx", "auart3-tx"; + #dma-cells = <1>; + dma-channels = <16>; +}; + +DMA clients connected to the MXS DMA controller must use the format +described in the dma.txt file. + +Examples: + +auart0: serial@8006a000 { + compatible = "fsl,imx28-auart", "fsl,imx23-auart"; + reg = <0x8006a000 0x2000>; + interrupts = <112>; + dmas = <&dma_apbx 8>, <&dma_apbx 9>; + dma-names = "rx", "tx"; }; diff --git a/trunk/Documentation/devicetree/bindings/drm/exynos/g2d.txt b/trunk/Documentation/devicetree/bindings/drm/exynos/g2d.txt deleted file mode 100644 index 1eb124d35a99..000000000000 --- a/trunk/Documentation/devicetree/bindings/drm/exynos/g2d.txt +++ /dev/null @@ -1,22 +0,0 @@ -Samsung 2D Graphic Accelerator using DRM frame work - -Samsung FIMG2D is a graphics 2D accelerator which supports Bit Block Transfer. -We set the drawing-context registers for configuring rendering parameters and -then start rendering. -This driver is for SOCs which contain G2D IPs with version 4.1. - -Required properties: - -compatible: - should be "samsung,exynos-g2d-41". - -reg: - physical base address of the controller and length - of memory mapped region. - -interrupts: - interrupt combiner values. - -Example: - g2d { - compatible = "samsung,exynos-g2d-41"; - reg = <0x10850000 0x1000>; - interrupts = <0 91 0>; - }; diff --git a/trunk/Documentation/devicetree/bindings/fb/mxsfb.txt b/trunk/Documentation/devicetree/bindings/fb/mxsfb.txt index b41e5e52a676..96ec5179c8a0 100644 --- a/trunk/Documentation/devicetree/bindings/fb/mxsfb.txt +++ b/trunk/Documentation/devicetree/bindings/fb/mxsfb.txt @@ -5,9 +5,16 @@ Required properties: imx23 and imx28. - reg: Address and length of the register set for lcdif - interrupts: Should contain lcdif interrupts +- display : phandle to display node (see below for details) -Optional properties: -- panel-enable-gpios : Should specify the gpio for panel enable +* display node + +Required properties: +- bits-per-pixel : <16> for RGB565, <32> for RGB888/666. +- bus-width : number of data lines. Could be <8>, <16>, <18> or <24>. + +Required sub-node: +- display-timings : Refer to binding doc display-timing.txt for details. Examples: @@ -15,5 +22,28 @@ lcdif@80030000 { compatible = "fsl,imx28-lcdif"; reg = <0x80030000 2000>; interrupts = <38 86>; - panel-enable-gpios = <&gpio3 30 0>; + + display: display { + bits-per-pixel = <32>; + bus-width = <24>; + + display-timings { + native-mode = <&timing0>; + timing0: timing0 { + clock-frequency = <33500000>; + hactive = <800>; + vactive = <480>; + hfront-porch = <164>; + hback-porch = <89>; + hsync-len = <10>; + vback-porch = <23>; + vfront-porch = <10>; + vsync-len = <10>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <1>; + pixelclk-active = <0>; + }; + }; + }; }; diff --git a/trunk/Documentation/devicetree/bindings/gpio/gpio-grgpio.txt b/trunk/Documentation/devicetree/bindings/gpio/gpio-grgpio.txt new file mode 100644 index 000000000000..e466598105fc --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/gpio/gpio-grgpio.txt @@ -0,0 +1,26 @@ +Aeroflex Gaisler GRGPIO General Purpose I/O cores. + +The GRGPIO GPIO core is available in the GRLIB VHDL IP core library. + +Note: In the ordinary environment for the GRGPIO core, a Leon SPARC system, +these properties are built from information in the AMBA plug&play. + +Required properties: + +- name : Should be "GAISLER_GPIO" or "01_01a" + +- reg : Address and length of the register set for the device + +- interrupts : Interrupt numbers for this device + +Optional properties: + +- nbits : The number of gpio lines. If not present driver assumes 32 lines. + +- irqmap : An array with an index for each gpio line. An index is either a valid + index into the interrupts property array, or 0xffffffff that indicates + no irq for that line. Driver provides no interrupt support if not + present. + +For further information look in the documentation for the GLIB IP core library: +http://www.gaisler.com/products/grlib/grip.pdf diff --git a/trunk/Documentation/devicetree/bindings/gpio/gpio-mcp23s08.txt b/trunk/Documentation/devicetree/bindings/gpio/gpio-mcp23s08.txt new file mode 100644 index 000000000000..629d0ef17308 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/gpio/gpio-mcp23s08.txt @@ -0,0 +1,47 @@ +Microchip MCP2308/MCP23S08/MCP23017/MCP23S17 driver for +8-/16-bit I/O expander with serial interface (I2C/SPI) + +Required properties: +- compatible : Should be + - "mcp,mcp23s08" for 8 GPIO SPI version + - "mcp,mcp23s17" for 16 GPIO SPI version + - "mcp,mcp23008" for 8 GPIO I2C version or + - "mcp,mcp23017" for 16 GPIO I2C version of the chip +- #gpio-cells : Should be two. + - first cell is the pin number + - second cell is used to specify flags. Flags are currently unused. +- gpio-controller : Marks the device node as a GPIO controller. +- reg : For an address on its bus. I2C uses this a the I2C address of the chip. + SPI uses this to specify the chipselect line which the chip is + connected to. The driver and the SPI variant of the chip support + multiple chips on the same chipselect. Have a look at + mcp,spi-present-mask below. + +Required device specific properties (only for SPI chips): +- mcp,spi-present-mask : This is a present flag, that makes only sense for SPI + chips - as the name suggests. Multiple SPI chips can share the same + SPI chipselect. Set a bit in bit0-7 in this mask to 1 if there is a + chip connected with the corresponding spi address set. For example if + you have a chip with address 3 connected, you have to set bit3 to 1, + which is 0x08. mcp23s08 chip variant only supports bits 0-3. It is not + possible to mix mcp23s08 and mcp23s17 on the same chipselect. Set at + least one bit to 1 for SPI chips. +- spi-max-frequency = The maximum frequency this chip is able to handle + +Example I2C: +gpiom1: gpio@20 { + compatible = "mcp,mcp23017"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x20>; +}; + +Example SPI: +gpiom1: gpio@0 { + compatible = "mcp,mcp23s17"; + gpio-controller; + #gpio-cells = <2>; + spi-present-mask = <0x01>; + reg = <0>; + spi-max-frequency = <1000000>; +}; diff --git a/trunk/Documentation/devicetree/bindings/gpio/gpio-omap.txt b/trunk/Documentation/devicetree/bindings/gpio/gpio-omap.txt index bff51a2fee1e..8d950522e7fa 100644 --- a/trunk/Documentation/devicetree/bindings/gpio/gpio-omap.txt +++ b/trunk/Documentation/devicetree/bindings/gpio/gpio-omap.txt @@ -5,12 +5,12 @@ Required properties: - "ti,omap2-gpio" for OMAP2 controllers - "ti,omap3-gpio" for OMAP3 controllers - "ti,omap4-gpio" for OMAP4 controllers +- gpio-controller : Marks the device node as a GPIO controller. - #gpio-cells : Should be two. - first cell is the pin number - second cell is used to specify optional parameters (unused) -- gpio-controller : Marks the device node as a GPIO controller. +- interrupt-controller: Mark the device node as an interrupt controller. - #interrupt-cells : Should be 2. -- interrupt-controller: Mark the device node as an interrupt controller The first cell is the GPIO number. The second cell is used to specify flags: bits[3:0] trigger type and level flags: @@ -20,8 +20,11 @@ Required properties: 8 = active low level-sensitive. OMAP specific properties: -- ti,hwmods: Name of the hwmod associated to the GPIO: - "gpio", being the 1-based instance number from the HW spec +- ti,hwmods: Name of the hwmod associated to the GPIO: + "gpio", being the 1-based instance number + from the HW spec. +- ti,gpio-always-on: Indicates if a GPIO bank is always powered and + so will never lose its logic state. Example: @@ -29,8 +32,8 @@ Example: gpio4: gpio4 { compatible = "ti,omap4-gpio"; ti,hwmods = "gpio4"; - #gpio-cells = <2>; gpio-controller; - #interrupt-cells = <2>; + #gpio-cells = <2>; interrupt-controller; + #interrupt-cells = <2>; }; diff --git a/trunk/Documentation/devicetree/bindings/gpio/gpio-vt8500.txt b/trunk/Documentation/devicetree/bindings/gpio/gpio-vt8500.txt deleted file mode 100644 index f4dc5233167e..000000000000 --- a/trunk/Documentation/devicetree/bindings/gpio/gpio-vt8500.txt +++ /dev/null @@ -1,24 +0,0 @@ -VIA/Wondermedia VT8500 GPIO Controller ------------------------------------------------------ - -Required properties: -- compatible : "via,vt8500-gpio", "wm,wm8505-gpio" - or "wm,wm8650-gpio" depending on your SoC -- reg : Should contain 1 register range (address and length) -- #gpio-cells : should be <3>. - 1) bank - 2) pin number - 3) flags - should be 0 - -Example: - - gpio: gpio-controller@d8110000 { - compatible = "via,vt8500-gpio"; - gpio-controller; - reg = <0xd8110000 0x10000>; - #gpio-cells = <3>; - }; - - vibrate { - gpios = <&gpio 0 1 0>; /* Bank 0, Pin 1, No flags */ - }; diff --git a/trunk/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt b/trunk/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt index e13787498bcf..9b3f1d4a88d6 100644 --- a/trunk/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt +++ b/trunk/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt @@ -1,7 +1,10 @@ * Marvell PXA GPIO controller Required properties: -- compatible : Should be "mrvl,pxa-gpio" or "mrvl,mmp-gpio" +- compatible : Should be "intel,pxa25x-gpio", "intel,pxa26x-gpio", + "intel,pxa27x-gpio", "intel,pxa3xx-gpio", + "marvell,pxa93x-gpio", "marvell,mmp-gpio" or + "marvell,mmp2-gpio". - reg : Address and length of the register set for the device - interrupts : Should be the port interrupt shared by all gpio pins. There're three gpio interrupts in arch-pxa, and they're gpio0, @@ -18,7 +21,7 @@ Required properties: Example: gpio: gpio@d4019000 { - compatible = "mrvl,mmp-gpio"; + compatible = "marvell,mmp-gpio"; reg = <0xd4019000 0x1000>; interrupts = <49>; interrupt-name = "gpio_mux"; diff --git a/trunk/Documentation/devicetree/bindings/gpu/samsung-g2d.txt b/trunk/Documentation/devicetree/bindings/gpu/samsung-g2d.txt new file mode 100644 index 000000000000..2b14a940eb75 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/gpu/samsung-g2d.txt @@ -0,0 +1,20 @@ +* Samsung 2D Graphics Accelerator + +Required properties: + - compatible : value should be one among the following: + (a) "samsung,s5pv210-g2d" for G2D IP present in S5PV210 & Exynos4210 SoC + (b) "samsung,exynos4212-g2d" for G2D IP present in Exynos4x12 SoCs + (c) "samsung,exynos5250-g2d" for G2D IP present in Exynos5250 SoC + + - reg : Physical base address of the IP registers and length of memory + mapped region. + + - interrupts : G2D interrupt number to the CPU. + +Example: + g2d@12800000 { + compatible = "samsung,s5pv210-g2d"; + reg = <0x12800000 0x1000>; + interrupts = <0 89 0>; + status = "disabled"; + }; diff --git a/trunk/Documentation/devicetree/bindings/hwrng/timeriomem_rng.txt b/trunk/Documentation/devicetree/bindings/hwrng/timeriomem_rng.txt new file mode 100644 index 000000000000..6616d15866a3 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/hwrng/timeriomem_rng.txt @@ -0,0 +1,18 @@ +HWRNG support for the timeriomem_rng driver + +Required properties: +- compatible : "timeriomem_rng" +- reg : base address to sample from +- period : wait time in microseconds to use between samples + +N.B. currently 'reg' must be four bytes wide and aligned + +Example: + +hwrng@44 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "timeriomem_rng"; + reg = <0x44 0x04>; + period = <1000000>; +}; diff --git a/trunk/Documentation/devicetree/bindings/i2c/i2c-arb-gpio-challenge.txt b/trunk/Documentation/devicetree/bindings/i2c/i2c-arb-gpio-challenge.txt new file mode 100644 index 000000000000..1ac8ea8ade1d --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/i2c/i2c-arb-gpio-challenge.txt @@ -0,0 +1,80 @@ +GPIO-based I2C Arbitration Using a Challenge & Response Mechanism +================================================================= +This uses GPIO lines and a challenge & response mechanism to arbitrate who is +the master of an I2C bus in a multimaster situation. + +In many cases using GPIOs to arbitrate is not needed and a design can use +the standard I2C multi-master rules. Using GPIOs is generally useful in +the case where there is a device on the bus that has errata and/or bugs +that makes standard multimaster mode not feasible. + + +Algorithm: + +All masters on the bus have a 'bus claim' line which is an output that the +others can see. These are all active low with pull-ups enabled. We'll +describe these lines as: + +- OUR_CLAIM: output from us signaling to other hosts that we want the bus +- THEIR_CLAIMS: output from others signaling that they want the bus + +The basic algorithm is to assert your line when you want the bus, then make +sure that the other side doesn't want it also. A detailed explanation is best +done with an example. + +Let's say we want to claim the bus. We: +1. Assert OUR_CLAIM. +2. Waits a little bit for the other sides to notice (slew time, say 10 + microseconds). +3. Check THEIR_CLAIMS. If none are asserted then the we have the bus and we are + done. +4. Otherwise, wait for a few milliseconds and see if THEIR_CLAIMS are released. +5. If not, back off, release the claim and wait for a few more milliseconds. +6. Go back to 1 (until retry time has expired). + + +Required properties: +- compatible: i2c-arb-gpio-challenge +- our-claim-gpio: The GPIO that we use to claim the bus. +- their-claim-gpios: The GPIOs that the other sides use to claim the bus. + Note that some implementations may only support a single other master. +- Standard I2C mux properties. See mux.txt in this directory. +- Single I2C child bus node at reg 0. See mux.txt in this directory. + +Optional properties: +- slew-delay-us: microseconds to wait for a GPIO to go high. Default is 10 us. +- wait-retry-us: we'll attempt another claim after this many microseconds. + Default is 3000 us. +- wait-free-us: we'll give up after this many microseconds. Default is 50000 us. + + +Example: + i2c@12CA0000 { + compatible = "acme,some-i2c-device"; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c-arbitrator { + compatible = "i2c-arb-gpio-challenge"; + #address-cells = <1>; + #size-cells = <0>; + + i2c-parent = <&{/i2c@12CA0000}>; + + our-claim-gpio = <&gpf0 3 1>; + their-claim-gpios = <&gpe0 4 1>; + slew-delay-us = <10>; + wait-retry-us = <3000>; + wait-free-us = <50000>; + + i2c@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + i2c@52 { + // Normal I2C device + }; + }; + }; diff --git a/trunk/Documentation/devicetree/bindings/i2c/i2c-mxs.txt b/trunk/Documentation/devicetree/bindings/i2c/i2c-mxs.txt index 7a3fe9e5f4cb..4e1c8ac01eba 100644 --- a/trunk/Documentation/devicetree/bindings/i2c/i2c-mxs.txt +++ b/trunk/Documentation/devicetree/bindings/i2c/i2c-mxs.txt @@ -3,10 +3,13 @@ Required properties: - compatible: Should be "fsl,-i2c" - reg: Should contain registers location and length -- interrupts: Should contain ERROR and DMA interrupts +- interrupts: Should contain ERROR interrupt number - clock-frequency: Desired I2C bus clock frequency in Hz. Only 100000Hz and 400000Hz modes are supported. -- fsl,i2c-dma-channel: APBX DMA channel for the I2C +- dmas: DMA specifier, consisting of a phandle to DMA controller node + and I2C DMA channel ID. + Refer to dma.txt and fsl-mxs-dma.txt for details. +- dma-names: Must be "rx-tx". Examples: @@ -15,7 +18,8 @@ i2c0: i2c@80058000 { #size-cells = <0>; compatible = "fsl,imx28-i2c"; reg = <0x80058000 2000>; - interrupts = <111 68>; + interrupts = <111>; clock-frequency = <100000>; - fsl,i2c-dma-channel = <6>; + dmas = <&dma_apbx 6>; + dma-names = "rx-tx"; }; diff --git a/trunk/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.txt b/trunk/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.txt new file mode 100644 index 000000000000..ef77cc7a0e46 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.txt @@ -0,0 +1,60 @@ +NVIDIA Tegra20/Tegra30/Tegra114 I2C controller driver. + +Required properties: +- compatible : should be: + "nvidia,tegra114-i2c" + "nvidia,tegra30-i2c" + "nvidia,tegra20-i2c" + "nvidia,tegra20-i2c-dvc" + Details of compatible are as follows: + nvidia,tegra20-i2c-dvc: Tegra20 has specific I2C controller called as DVC I2C + controller. This only support master mode of I2C communication. Register + interface/offset and interrupts handling are different than generic I2C + controller. Driver of DVC I2C controller is only compatible with + "nvidia,tegra20-i2c-dvc". + nvidia,tegra20-i2c: Tegra20 has 4 generic I2C controller. This can support + master and slave mode of I2C communication. The i2c-tegra driver only + support master mode of I2C communication. Driver of I2C controller is + only compatible with "nvidia,tegra20-i2c". + nvidia,tegra30-i2c: Tegra30 has 5 generic I2C controller. This controller is + very much similar to Tegra20 I2C controller with additional feature: + Continue Transfer Support. This feature helps to implement M_NO_START + as per I2C core API transfer flags. Driver of I2C controller is + compatible with "nvidia,tegra30-i2c" to enable the continue transfer + support. This is also compatible with "nvidia,tegra20-i2c" without + continue transfer support. + nvidia,tegra114-i2c: Tegra114 has 5 generic I2C controller. This controller is + very much similar to Tegra30 I2C controller with some hardware + modification: + - Tegra30/Tegra20 I2C controller has 2 clock source called div-clk and + fast-clk. Tegra114 has only one clock source called as div-clk and + hence clock mechanism is changed in I2C controller. + - Tegra30/Tegra20 I2C controller has enabled per packet transfer by + default and there is no way to disable it. Tegra114 has this + interrupt disable by default and SW need to enable explicitly. + Due to above changes, Tegra114 I2C driver makes incompatible with + previous hardware driver. Hence, tegra114 I2C controller is compatible + with "nvidia,tegra114-i2c". +- reg: Should contain I2C controller registers physical address and length. +- interrupts: Should contain I2C controller interrupts. +- address-cells: Address cells for I2C device address. +- size-cells: Size of the I2C device address. +- clocks: Clock ID as per + Documentation/devicetree/bindings/clock/tegra.txt + for I2C controller. +- clock-names: Name of the clock: + Tegra20/Tegra30 I2C controller: "div-clk and "fast-clk". + Tegra114 I2C controller: "div-clk". + +Example: + + i2c@7000c000 { + compatible = "nvidia,tegra20-i2c"; + reg = <0x7000c000 0x100>; + interrupts = <0 38 0x04>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car 12>, <&tegra_car 124>; + clock-names = "div-clk", "fast-clk"; + status = "disabled"; + }; diff --git a/trunk/Documentation/devicetree/bindings/input/cros-ec-keyb.txt b/trunk/Documentation/devicetree/bindings/input/cros-ec-keyb.txt new file mode 100644 index 000000000000..0f6355ce39b5 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/input/cros-ec-keyb.txt @@ -0,0 +1,72 @@ +ChromeOS EC Keyboard + +Google's ChromeOS EC Keyboard is a simple matrix keyboard implemented on +a separate EC (Embedded Controller) device. It provides a message for reading +key scans from the EC. These are then converted into keycodes for processing +by the kernel. + +This binding is based on matrix-keymap.txt and extends/modifies it as follows: + +Required properties: +- compatible: "google,cros-ec-keyb" + +Optional properties: +- google,needs-ghost-filter: True to enable a ghost filter for the matrix +keyboard. This is recommended if the EC does not have its own logic or +hardware for this. + + +Example: + +cros-ec-keyb { + compatible = "google,cros-ec-keyb"; + keypad,num-rows = <8>; + keypad,num-columns = <13>; + google,needs-ghost-filter; + /* + * Keymap entries take the form of 0xRRCCKKKK where + * RR=Row CC=Column KKKK=Key Code + * The values below are for a US keyboard layout and + * are taken from the Linux driver. Note that the + * 102ND key is not used for US keyboards. + */ + linux,keymap = < + /* CAPSLCK F1 B F10 */ + 0x0001003a 0x0002003b 0x00030030 0x00040044 + /* N = R_ALT ESC */ + 0x00060031 0x0008000d 0x000a0064 0x01010001 + /* F4 G F7 H */ + 0x0102003e 0x01030022 0x01040041 0x01060023 + /* ' F9 BKSPACE L_CTRL */ + 0x01080028 0x01090043 0x010b000e 0x0200001d + /* TAB F3 T F6 */ + 0x0201000f 0x0202003d 0x02030014 0x02040040 + /* ] Y 102ND [ */ + 0x0205001b 0x02060015 0x02070056 0x0208001a + /* F8 GRAVE F2 5 */ + 0x02090042 0x03010029 0x0302003c 0x03030006 + /* F5 6 - \ */ + 0x0304003f 0x03060007 0x0308000c 0x030b002b + /* R_CTRL A D F */ + 0x04000061 0x0401001e 0x04020020 0x04030021 + /* S K J ; */ + 0x0404001f 0x04050025 0x04060024 0x04080027 + /* L ENTER Z C */ + 0x04090026 0x040b001c 0x0501002c 0x0502002e + /* V X , M */ + 0x0503002f 0x0504002d 0x05050033 0x05060032 + /* L_SHIFT / . SPACE */ + 0x0507002a 0x05080035 0x05090034 0x050B0039 + /* 1 3 4 2 */ + 0x06010002 0x06020004 0x06030005 0x06040003 + /* 8 7 0 9 */ + 0x06050009 0x06060008 0x0608000b 0x0609000a + /* L_ALT DOWN RIGHT Q */ + 0x060a0038 0x060b006c 0x060c006a 0x07010010 + /* E R W I */ + 0x07020012 0x07030013 0x07040011 0x07050017 + /* U R_SHIFT P O */ + 0x07060016 0x07070036 0x07080019 0x07090018 + /* UP LEFT */ + 0x070b0067 0x070c0069>; +}; diff --git a/trunk/Documentation/devicetree/bindings/interrupt-controller/samsung,s3c24xx-irq.txt b/trunk/Documentation/devicetree/bindings/interrupt-controller/samsung,s3c24xx-irq.txt new file mode 100644 index 000000000000..c54c5a9a2a90 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/interrupt-controller/samsung,s3c24xx-irq.txt @@ -0,0 +1,53 @@ +Samsung S3C24XX Interrupt Controllers + +The S3C24XX SoCs contain a custom set of interrupt controllers providing a +varying number of interrupt sources. The set consists of a main- and sub- +controller and on newer SoCs even a second main controller. + +Required properties: +- compatible: Compatible property value should be "samsung,s3c2410-irq" + for machines before s3c2416 and "samsung,s3c2416-irq" for s3c2416 and later. + +- reg: Physical base address of the controller and length of memory mapped + region. + +- interrupt-controller : Identifies the node as an interrupt controller + +- #interrupt-cells : Specifies the number of cells needed to encode an + interrupt source. The value shall be 4 and interrupt descriptor shall + have the following format: + + + ctrl_num contains the controller to use: + - 0 ... main controller + - 1 ... sub controller + - 2 ... second main controller on s3c2416 and s3c2450 + parent_irq contains the parent bit in the main controller and will be + ignored in main controllers + ctrl_irq contains the interrupt bit of the controller + type contains the trigger type to use + +Example: + + interrupt-controller@4a000000 { + compatible = "samsung,s3c2410-irq"; + reg = <0x4a000000 0x100>; + interrupt-controller; + #interrupt-cells=<4>; + }; + + [...] + + serial@50000000 { + compatible = "samsung,s3c2410-uart"; + reg = <0x50000000 0x4000>; + interrupt-parent = <&subintc>; + interrupts = <1 28 0 4>, <1 28 1 4>; + }; + + rtc@57000000 { + compatible = "samsung,s3c2410-rtc"; + reg = <0x57000000 0x100>; + interrupt-parent = <&intc>; + interrupts = <0 30 0 3>, <0 8 0 3>; + }; diff --git a/trunk/Documentation/devicetree/bindings/media/s5p-mfc.txt b/trunk/Documentation/devicetree/bindings/media/s5p-mfc.txt index 67ec3d4ccc7f..bf0182d8da25 100644 --- a/trunk/Documentation/devicetree/bindings/media/s5p-mfc.txt +++ b/trunk/Documentation/devicetree/bindings/media/s5p-mfc.txt @@ -21,3 +21,24 @@ Required properties: - samsung,mfc-l : Base address of the second memory bank used by MFC for DMA contiguous memory allocation and its size. + +Optional properties: + - samsung,power-domain : power-domain property defined with a phandle + to respective power domain. + +Example: +SoC specific DT entry: + +mfc: codec@13400000 { + compatible = "samsung,mfc-v5"; + reg = <0x13400000 0x10000>; + interrupts = <0 94 0>; + samsung,power-domain = <&pd_mfc>; +}; + +Board specific DT entry: + +codec@13400000 { + samsung,mfc-r = <0x43000000 0x800000>; + samsung,mfc-l = <0x51000000 0x800000>; +}; diff --git a/trunk/Documentation/devicetree/bindings/mfd/as3711.txt b/trunk/Documentation/devicetree/bindings/mfd/as3711.txt new file mode 100644 index 000000000000..d98cf18c721c --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/mfd/as3711.txt @@ -0,0 +1,73 @@ +AS3711 is an I2C PMIC from Austria MicroSystems with multiple DCDC and LDO power +supplies, a battery charger and an RTC. So far only bindings for the two stepup +DCDC converters are defined. Other DCDC and LDO supplies are configured, using +standard regulator properties, they must belong to a sub-node, called +"regulators" and be called "sd1" to "sd4" and "ldo1" to "ldo8." Stepup converter +configuration should be placed in a subnode, called "backlight." + +Compulsory properties: +- compatible : must be "ams,as3711" +- reg : specifies the I2C address + +To use the SU1 converter as a backlight source the following two properties must +be provided: +- su1-dev : framebuffer phandle +- su1-max-uA : maximum current + +To use the SU2 converter as a backlight source the following two properties must +be provided: +- su2-dev : framebuffer phandle +- su1-max-uA : maximum current + +Additionally one of these properties must be provided to select the type of +feedback used: +- su2-feedback-voltage : voltage feedback is used +- su2-feedback-curr1 : CURR1 input used for current feedback +- su2-feedback-curr2 : CURR2 input used for current feedback +- su2-feedback-curr3 : CURR3 input used for current feedback +- su2-feedback-curr-auto: automatic current feedback selection + +and one of these to select the over-voltage protection pin +- su2-fbprot-lx-sd4 : LX_SD4 is used for over-voltage protection +- su2-fbprot-gpio2 : GPIO2 is used for over-voltage protection +- su2-fbprot-gpio3 : GPIO3 is used for over-voltage protection +- su2-fbprot-gpio4 : GPIO4 is used for over-voltage protection + +If "su2-feedback-curr-auto" is selected, one or more of the following properties +have to be specified: +- su2-auto-curr1 : use CURR1 input for current feedback +- su2-auto-curr2 : use CURR2 input for current feedback +- su2-auto-curr3 : use CURR3 input for current feedback + +Example: + +as3711@40 { + compatible = "ams,as3711"; + reg = <0x40>; + + regulators { + sd4 { + regulator-name = "1.215V"; + regulator-min-microvolt = <1215000>; + regulator-max-microvolt = <1235000>; + }; + ldo2 { + regulator-name = "2.8V CPU"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-always-on; + regulator-boot-on; + }; + }; + + backlight { + compatible = "ams,as3711-bl"; + su2-dev = <&lcdc>; + su2-max-uA = <36000>; + su2-feedback-curr-auto; + su2-fbprot-gpio4; + su2-auto-curr1; + su2-auto-curr2; + su2-auto-curr3; + }; +}; diff --git a/trunk/Documentation/devicetree/bindings/mfd/cros-ec.txt b/trunk/Documentation/devicetree/bindings/mfd/cros-ec.txt new file mode 100644 index 000000000000..e0e59c58a1f9 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/mfd/cros-ec.txt @@ -0,0 +1,56 @@ +ChromeOS Embedded Controller + +Google's ChromeOS EC is a Cortex-M device which talks to the AP and +implements various function such as keyboard and battery charging. + +The EC can be connect through various means (I2C, SPI, LPC) and the +compatible string used depends on the inteface. Each connection method has +its own driver which connects to the top level interface-agnostic EC driver. +Other Linux driver (such as cros-ec-keyb for the matrix keyboard) connect to +the top-level driver. + +Required properties (I2C): +- compatible: "google,cros-ec-i2c" +- reg: I2C slave address + +Required properties (SPI): +- compatible: "google,cros-ec-spi" +- reg: SPI chip select + +Required properties (LPC): +- compatible: "google,cros-ec-lpc" +- reg: List of (IO address, size) pairs defining the interface uses + + +Example for I2C: + +i2c@12CA0000 { + cros-ec@1e { + reg = <0x1e>; + compatible = "google,cros-ec-i2c"; + interrupts = <14 0>; + interrupt-parent = <&wakeup_eint>; + wakeup-source; + }; + + +Example for SPI: + +spi@131b0000 { + ec@0 { + compatible = "google,cros-ec-spi"; + reg = <0x0>; + interrupts = <14 0>; + interrupt-parent = <&wakeup_eint>; + wakeup-source; + spi-max-frequency = <5000000>; + controller-data { + cs-gpio = <&gpf0 3 4 3 0>; + samsung,spi-cs; + samsung,spi-feedback-delay = <2>; + }; + }; +}; + + +Example for LPC is not supplied as it is not yet implemented. diff --git a/trunk/Documentation/devicetree/bindings/mfd/omap-usb-host.txt b/trunk/Documentation/devicetree/bindings/mfd/omap-usb-host.txt new file mode 100644 index 000000000000..b381fa696bf9 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/mfd/omap-usb-host.txt @@ -0,0 +1,80 @@ +OMAP HS USB Host + +Required properties: + +- compatible: should be "ti,usbhs-host" +- reg: should contain one register range i.e. start and length +- ti,hwmods: must contain "usb_host_hs" + +Optional properties: + +- num-ports: number of USB ports. Usually this is automatically detected + from the IP's revision register but can be overridden by specifying + this property. A maximum of 3 ports are supported at the moment. + +- portN-mode: String specifying the port mode for port N, where N can be + from 1 to 3. If the port mode is not specified, that port is treated + as unused. When specified, it must be one of the following. + "ehci-phy", + "ehci-tll", + "ehci-hsic", + "ohci-phy-6pin-datse0", + "ohci-phy-6pin-dpdm", + "ohci-phy-3pin-datse0", + "ohci-phy-4pin-dpdm", + "ohci-tll-6pin-datse0", + "ohci-tll-6pin-dpdm", + "ohci-tll-3pin-datse0", + "ohci-tll-4pin-dpdm", + "ohci-tll-2pin-datse0", + "ohci-tll-2pin-dpdm", + +- single-ulpi-bypass: Must be present if the controller contains a single + ULPI bypass control bit. e.g. OMAP3 silicon <= ES2.1 + +Required properties if child node exists: + +- #address-cells: Must be 1 +- #size-cells: Must be 1 +- ranges: must be present + +Properties for children: + +The OMAP HS USB Host subsystem contains EHCI and OHCI controllers. +See Documentation/devicetree/bindings/usb/omap-ehci.txt and +omap3-ohci.txt + +Example for OMAP4: + +usbhshost: usbhshost@4a064000 { + compatible = "ti,usbhs-host"; + reg = <0x4a064000 0x800>; + ti,hwmods = "usb_host_hs"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + usbhsohci: ohci@4a064800 { + compatible = "ti,ohci-omap3", "usb-ohci"; + reg = <0x4a064800 0x400>; + interrupt-parent = <&gic>; + interrupts = <0 76 0x4>; + }; + + usbhsehci: ehci@4a064c00 { + compatible = "ti,ehci-omap", "usb-ehci"; + reg = <0x4a064c00 0x400>; + interrupt-parent = <&gic>; + interrupts = <0 77 0x4>; + }; +}; + +&usbhshost { + port1-mode = "ehci-phy"; + port2-mode = "ehci-tll"; + port3-mode = "ehci-phy"; +}; + +&usbhsehci { + phys = <&hsusb1_phy 0 &hsusb3_phy>; +}; diff --git a/trunk/Documentation/devicetree/bindings/mfd/omap-usb-tll.txt b/trunk/Documentation/devicetree/bindings/mfd/omap-usb-tll.txt new file mode 100644 index 000000000000..62fe69724e3b --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/mfd/omap-usb-tll.txt @@ -0,0 +1,17 @@ +OMAP HS USB Host TLL (Transceiver-Less Interface) + +Required properties: + +- compatible : should be "ti,usbhs-tll" +- reg : should contain one register range i.e. start and length +- interrupts : should contain the TLL module's interrupt +- ti,hwmod : must contain "usb_tll_hs" + +Example: + + usbhstll: usbhstll@4a062000 { + compatible = "ti,usbhs-tll"; + reg = <0x4a062000 0x1000>; + interrupts = <78>; + ti,hwmods = "usb_tll_hs"; + }; diff --git a/trunk/Documentation/devicetree/bindings/mips/ralink.txt b/trunk/Documentation/devicetree/bindings/mips/ralink.txt new file mode 100644 index 000000000000..b35a8d04f8b6 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/mips/ralink.txt @@ -0,0 +1,17 @@ +Ralink MIPS SoC device tree bindings + +1. SoCs + +Each device tree must specify a compatible value for the Ralink SoC +it uses in the compatible property of the root node. The compatible +value must be one of the following values: + + ralink,rt2880-soc + ralink,rt3050-soc + ralink,rt3052-soc + ralink,rt3350-soc + ralink,rt3352-soc + ralink,rt3883-soc + ralink,rt5350-soc + ralink,mt7620a-soc + ralink,mt7620n-soc diff --git a/trunk/Documentation/devicetree/bindings/misc/smc.txt b/trunk/Documentation/devicetree/bindings/misc/smc.txt new file mode 100644 index 000000000000..02b428136177 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/misc/smc.txt @@ -0,0 +1,14 @@ +Broadcom Secure Monitor Bounce buffer +----------------------------------------------------- +This binding defines the location of the bounce buffer +used for non-secure to secure communications. + +Required properties: +- compatible : "bcm,kona-smc" +- reg : Location and size of bounce buffer + +Example: + smc@0x3404c000 { + compatible = "bcm,bcm11351-smc", "bcm,kona-smc"; + reg = <0x3404c000 0x400>; //1 KiB in SRAM + }; diff --git a/trunk/Documentation/devicetree/bindings/mmc/fsl-imx-mmc.txt b/trunk/Documentation/devicetree/bindings/mmc/fsl-imx-mmc.txt new file mode 100644 index 000000000000..db442355cd24 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/mmc/fsl-imx-mmc.txt @@ -0,0 +1,24 @@ +* Freescale Secure Digital Host Controller for i.MX2/3 series + +This file documents differences to the properties defined in mmc.txt. + +Required properties: +- compatible : Should be "fsl,-mmc", chip can be imx21 or imx31 + +Optional properties: +- dmas: One DMA phandle with arguments as defined by the devicetree bindings + of the used DMA controller. +- dma-names: Has to be "rx-tx". + +Example: + +sdhci1: sdhci@10014000 { + compatible = "fsl,imx27-mmc", "fsl,imx21-mmc"; + reg = <0x10014000 0x1000>; + interrupts = <11>; + dmas = <&dma 7>; + dma-names = "rx-tx"; + bus-width = <4>; + cd-gpios = <&gpio3 29>; + status = "okay"; +}; diff --git a/trunk/Documentation/devicetree/bindings/mmc/mxs-mmc.txt b/trunk/Documentation/devicetree/bindings/mmc/mxs-mmc.txt index 54949f6faede..515addc20070 100644 --- a/trunk/Documentation/devicetree/bindings/mmc/mxs-mmc.txt +++ b/trunk/Documentation/devicetree/bindings/mmc/mxs-mmc.txt @@ -9,15 +9,19 @@ and the properties used by the mxsmmc driver. Required properties: - compatible: Should be "fsl,-mmc". The supported chips include imx23 and imx28. -- interrupts: Should contain ERROR and DMA interrupts -- fsl,ssp-dma-channel: APBH DMA channel for the SSP +- interrupts: Should contain ERROR interrupt number +- dmas: DMA specifier, consisting of a phandle to DMA controller node + and SSP DMA channel ID. + Refer to dma.txt and fsl-mxs-dma.txt for details. +- dma-names: Must be "rx-tx". Examples: ssp0: ssp@80010000 { compatible = "fsl,imx28-mmc"; reg = <0x80010000 2000>; - interrupts = <96 82>; - fsl,ssp-dma-channel = <0>; + interrupts = <96>; + dmas = <&dma_apbh 0>; + dma-names = "rx-tx"; bus-width = <8>; }; diff --git a/trunk/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt b/trunk/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt index 3b3a1ee055ff..328e990d2546 100644 --- a/trunk/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt +++ b/trunk/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt @@ -5,13 +5,6 @@ MMC, SD and eMMC storage mediums. This file documents differences between the core mmc properties described by mmc.txt and the properties used by the Samsung implmentation of the SDHCI controller. -Note: The mmc core bindings documentation states that if none of the core -card-detect bindings are used, then the standard sdhci card detect mechanism -is used. The Samsung's SDHCI controller bindings extends this as listed below. - -[A] The property "samsung,cd-pinmux-gpio" can be used as stated in the - "Optional Board Specific Properties" section below. - Required SoC Specific Properties: - compatible: should be one of the following - "samsung,s3c6410-sdhci": For controllers compatible with s3c6410 sdhci @@ -20,18 +13,8 @@ Required SoC Specific Properties: controller. Required Board Specific Properties: -- Samsung GPIO variant (will be completely replaced by pinctrl): - - gpios: Should specify the gpios used for clock, command and data lines. The - gpio specifier format depends on the gpio controller. -- Pinctrl variant (preferred if available): - - pinctrl-0: Should specify pin control groups used for this controller. - - pinctrl-names: Should contain only one value - "default". - -Optional Board Specific Properties: -- samsung,cd-pinmux-gpio: Specifies the card detect line that is routed - through a pinmux to the card-detect pin of the card slot. This property - should be used only if none of the mmc core card-detect properties are - used. Only for Samsung GPIO variant. +- pinctrl-0: Should specify pin control groups used for this controller. +- pinctrl-names: Should contain only one value - "default". Example: sdhci@12530000 { @@ -39,19 +22,9 @@ Example: reg = <0x12530000 0x100>; interrupts = <0 75 0>; bus-width = <4>; - cd-gpios = <&gpk2 2 2 3 3>; - - /* Samsung GPIO variant */ - gpios = <&gpk2 0 2 0 3>, /* clock line */ - <&gpk2 1 2 0 3>, /* command line */ - <&gpk2 3 2 3 3>, /* data line 0 */ - <&gpk2 4 2 3 3>, /* data line 1 */ - <&gpk2 5 2 3 3>, /* data line 2 */ - <&gpk2 6 2 3 3>; /* data line 3 */ - - /* Pinctrl variant */ - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4>; + cd-gpios = <&gpk2 2 0>; pinctrl-names = "default"; + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4>; }; Note: This example shows both SoC specific and board specific properties diff --git a/trunk/Documentation/devicetree/bindings/mmc/sdhci-sirf.txt b/trunk/Documentation/devicetree/bindings/mmc/sdhci-sirf.txt new file mode 100644 index 000000000000..dd6ed464bcb8 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/mmc/sdhci-sirf.txt @@ -0,0 +1,18 @@ +* SiRFprimII/marco/atlas6 SDHCI Controller + +This file documents differences between the core properties in mmc.txt +and the properties used by the sdhci-sirf driver. + +Required properties: +- compatible: sirf,prima2-sdhc + +Optional properties: +- cd-gpios: card detect gpio, with zero flags. + +Example: + + sd0: sdhci@56000000 { + compatible = "sirf,prima2-sdhc"; + reg = <0xcd000000 0x100000>; + cd-gpios = <&gpio 6 0>; + }; diff --git a/trunk/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/trunk/Documentation/devicetree/bindings/mtd/gpmc-nand.txt index e7f8d7ed47eb..6a983c1d87cd 100644 --- a/trunk/Documentation/devicetree/bindings/mtd/gpmc-nand.txt +++ b/trunk/Documentation/devicetree/bindings/mtd/gpmc-nand.txt @@ -56,20 +56,20 @@ Example for an AM33xx board: nand-bus-width = <16>; ti,nand-ecc-opt = "bch8"; - gpmc,sync-clk = <0>; - gpmc,cs-on = <0>; - gpmc,cs-rd-off = <44>; - gpmc,cs-wr-off = <44>; - gpmc,adv-on = <6>; - gpmc,adv-rd-off = <34>; - gpmc,adv-wr-off = <44>; - gpmc,we-off = <40>; - gpmc,oe-off = <54>; - gpmc,access = <64>; - gpmc,rd-cycle = <82>; - gpmc,wr-cycle = <82>; - gpmc,wr-access = <40>; - gpmc,wr-data-mux-bus = <0>; + gpmc,sync-clk-ps = <0>; + gpmc,cs-on-ns = <0>; + gpmc,cs-rd-off-ns = <44>; + gpmc,cs-wr-off-ns = <44>; + gpmc,adv-on-ns = <6>; + gpmc,adv-rd-off-ns = <34>; + gpmc,adv-wr-off-ns = <44>; + gpmc,we-off-ns = <40>; + gpmc,oe-off-ns = <54>; + gpmc,access-ns = <64>; + gpmc,rd-cycle-ns = <82>; + gpmc,wr-cycle-ns = <82>; + gpmc,wr-access-ns = <40>; + gpmc,wr-data-mux-bus-ns = <0>; #address-cells = <1>; #size-cells = <1>; diff --git a/trunk/Documentation/devicetree/bindings/mtd/gpmc-nor.txt b/trunk/Documentation/devicetree/bindings/mtd/gpmc-nor.txt new file mode 100644 index 000000000000..420b3ab18890 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/mtd/gpmc-nor.txt @@ -0,0 +1,98 @@ +Device tree bindings for NOR flash connect to TI GPMC + +NOR flash connected to the TI GPMC (found on OMAP boards) are represented as +child nodes of the GPMC controller with a name of "nor". + +All timing relevant properties as well as generic GPMC child properties are +explained in a separate documents. Please refer to +Documentation/devicetree/bindings/bus/ti-gpmc.txt + +Required properties: +- bank-width: Width of NOR flash in bytes. GPMC supports 8-bit and + 16-bit devices and so must be either 1 or 2 bytes. +- compatible: Documentation/devicetree/bindings/mtd/mtd-physmap.txt +- gpmc,cs-on-ns: Chip-select assertion time +- gpmc,cs-rd-off-ns: Chip-select de-assertion time for reads +- gpmc,cs-wr-off-ns: Chip-select de-assertion time for writes +- gpmc,oe-on-ns: Output-enable assertion time +- gpmc,oe-off-ns: Output-enable de-assertion time +- gpmc,we-on-ns Write-enable assertion time +- gpmc,we-off-ns: Write-enable de-assertion time +- gpmc,access-ns: Start cycle to first data capture (read access) +- gpmc,rd-cycle-ns: Total read cycle time +- gpmc,wr-cycle-ns: Total write cycle time +- linux,mtd-name: Documentation/devicetree/bindings/mtd/mtd-physmap.txt +- reg: Chip-select, base address (relative to chip-select) + and size of NOR flash. Note that base address will be + typically 0 as this is the start of the chip-select. + +Optional properties: +- gpmc,XXX Additional GPMC timings and settings parameters. See + Documentation/devicetree/bindings/bus/ti-gpmc.txt + +Optional properties for partiton table parsing: +- #address-cells: should be set to 1 +- #size-cells: should be set to 1 + +Example: + +gpmc: gpmc@6e000000 { + compatible = "ti,omap3430-gpmc", "simple-bus"; + ti,hwmods = "gpmc"; + reg = <0x6e000000 0x1000>; + interrupts = <20>; + gpmc,num-cs = <8>; + gpmc,num-waitpins = <4>; + #address-cells = <2>; + #size-cells = <1>; + + ranges = <0 0 0x10000000 0x08000000>; + + nor@0,0 { + compatible = "cfi-flash"; + linux,mtd-name= "intel,pf48f6000m0y1be"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0 0 0x08000000>; + bank-width = <2>; + + gpmc,mux-add-data; + gpmc,cs-on-ns = <0>; + gpmc,cs-rd-off-ns = <186>; + gpmc,cs-wr-off-ns = <186>; + gpmc,adv-on-ns = <12>; + gpmc,adv-rd-off-ns = <48>; + gpmc,adv-wr-off-ns = <48>; + gpmc,oe-on-ns = <54>; + gpmc,oe-off-ns = <168>; + gpmc,we-on-ns = <54>; + gpmc,we-off-ns = <168>; + gpmc,rd-cycle-ns = <186>; + gpmc,wr-cycle-ns = <186>; + gpmc,access-ns = <114>; + gpmc,page-burst-access-ns = <6>; + gpmc,bus-turnaround-ns = <12>; + gpmc,cycle2cycle-delay-ns = <18>; + gpmc,wr-data-mux-bus-ns = <90>; + gpmc,wr-access-ns = <186>; + gpmc,cycle2cycle-samecsen; + gpmc,cycle2cycle-diffcsen; + + partition@0 { + label = "bootloader-nor"; + reg = <0 0x40000>; + }; + partition@0x40000 { + label = "params-nor"; + reg = <0x40000 0x40000>; + }; + partition@0x80000 { + label = "kernel-nor"; + reg = <0x80000 0x200000>; + }; + partition@0x280000 { + label = "filesystem-nor"; + reg = <0x240000 0x7d80000>; + }; + }; +}; diff --git a/trunk/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt b/trunk/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt index deec9da224a2..b7529424ac88 100644 --- a/trunk/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt +++ b/trunk/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt @@ -10,6 +10,8 @@ Documentation/devicetree/bindings/bus/ti-gpmc.txt Required properties: - reg: The CS line the peripheral is connected to + - gpmc,device-width Width of the ONENAND device connected to the GPMC + in bytes. Must be 1 or 2. Optional properties: @@ -34,6 +36,7 @@ Example for an OMAP3430 board: onenand@0 { reg = <0 0 0>; /* CS0, offset 0 */ + gpmc,device-width = <2>; #address-cells = <1>; #size-cells = <1>; diff --git a/trunk/Documentation/devicetree/bindings/mtd/gpmi-nand.txt b/trunk/Documentation/devicetree/bindings/mtd/gpmi-nand.txt index 3fb3f9015365..551b2a179d01 100644 --- a/trunk/Documentation/devicetree/bindings/mtd/gpmi-nand.txt +++ b/trunk/Documentation/devicetree/bindings/mtd/gpmi-nand.txt @@ -7,10 +7,12 @@ Required properties: - compatible : should be "fsl,-gpmi-nand" - reg : should contain registers location and length for gpmi and bch. - reg-names: Should contain the reg names "gpmi-nand" and "bch" - - interrupts : The first is the DMA interrupt number for GPMI. - The second is the BCH interrupt number. - - interrupt-names : The interrupt names "gpmi-dma", "bch"; - - fsl,gpmi-dma-channel : Should contain the dma channel it uses. + - interrupts : BCH interrupt number. + - interrupt-names : Should be "bch". + - dmas: DMA specifier, consisting of a phandle to DMA controller node + and GPMI DMA channel ID. + Refer to dma.txt and fsl-mxs-dma.txt for details. + - dma-names: Must be "rx-tx". Optional properties: - nand-on-flash-bbt: boolean to enable on flash bbt option if not @@ -27,9 +29,10 @@ gpmi-nand@8000c000 { #size-cells = <1>; reg = <0x8000c000 2000>, <0x8000a000 2000>; reg-names = "gpmi-nand", "bch"; - interrupts = <88>, <41>; - interrupt-names = "gpmi-dma", "bch"; - fsl,gpmi-dma-channel = <4>; + interrupts = <41>; + interrupt-names = "bch"; + dmas = <&dma_apbh 4>; + dma-names = "rx-tx"; partition@0 { ... diff --git a/trunk/Documentation/devicetree/bindings/mtd/partition.txt b/trunk/Documentation/devicetree/bindings/mtd/partition.txt index 6e1f61f1e789..9315ac96b49b 100644 --- a/trunk/Documentation/devicetree/bindings/mtd/partition.txt +++ b/trunk/Documentation/devicetree/bindings/mtd/partition.txt @@ -5,8 +5,12 @@ on platforms which have strong conventions about which portions of a flash are used for what purposes, but which don't use an on-flash partition table such as RedBoot. -#address-cells & #size-cells must both be present in the mtd device and be -equal to 1. +#address-cells & #size-cells must both be present in the mtd device. There are +two valid values for both: +<1>: for partitions that require a single 32-bit cell to represent their + size/address (aka the value is below 4 GiB) +<2>: for partitions that require two 32-bit cells to represent their + size/address (aka the value is 4 GiB or greater). Required properties: - reg : The partition's offset and size within the mtd bank. @@ -36,3 +40,31 @@ flash@0 { reg = <0x0100000 0x200000>; }; }; + +flash@1 { + #address-cells = <1>; + #size-cells = <2>; + + /* a 4 GiB partition */ + partition@0 { + label = "filesystem"; + reg = <0x00000000 0x1 0x00000000>; + }; +}; + +flash@2 { + #address-cells = <2>; + #size-cells = <2>; + + /* an 8 GiB partition */ + partition@0 { + label = "filesystem #1"; + reg = <0x0 0x00000000 0x2 0x00000000>; + }; + + /* a 4 GiB partition */ + partition@200000000 { + label = "filesystem #2"; + reg = <0x2 0x00000000 0x1 0x00000000>; + }; +}; diff --git a/trunk/Documentation/devicetree/bindings/net/gpmc-eth.txt b/trunk/Documentation/devicetree/bindings/net/gpmc-eth.txt new file mode 100644 index 000000000000..ace4a64b3695 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/net/gpmc-eth.txt @@ -0,0 +1,97 @@ +Device tree bindings for Ethernet chip connected to TI GPMC + +Besides being used to interface with external memory devices, the +General-Purpose Memory Controller can be used to connect Pseudo-SRAM devices +such as ethernet controllers to processors using the TI GPMC as a data bus. + +Ethernet controllers connected to TI GPMC are represented as child nodes of +the GPMC controller with an "ethernet" name. + +All timing relevant properties as well as generic GPMC child properties are +explained in a separate documents. Please refer to +Documentation/devicetree/bindings/bus/ti-gpmc.txt + +For the properties relevant to the ethernet controller connected to the GPMC +refer to the binding documentation of the device. For example, the documentation +for the SMSC 911x is Documentation/devicetree/bindings/net/smsc911x.txt + +Child nodes need to specify the GPMC bus address width using the "bank-width" +property but is possible that an ethernet controller also has a property to +specify the I/O registers address width. Even when the GPMC has a maximum 16-bit +address width, it supports devices with 32-bit word registers. +For example with an SMSC LAN911x/912x controller connected to the TI GPMC on an +OMAP2+ board, "bank-width = <2>;" and "reg-io-width = <4>;". + +Required properties: +- bank-width: Address width of the device in bytes. GPMC supports 8-bit + and 16-bit devices and so must be either 1 or 2 bytes. +- compatible: Compatible string property for the ethernet child device. +- gpmc,cs-on-ns: Chip-select assertion time +- gpmc,cs-rd-off-ns: Chip-select de-assertion time for reads +- gpmc,cs-wr-off-ns: Chip-select de-assertion time for writes +- gpmc,oe-on-ns: Output-enable assertion time +- gpmc,oe-off-ns: Output-enable de-assertion time +- gpmc,we-on-ns: Write-enable assertion time +- gpmc,we-off-ns: Write-enable de-assertion time +- gpmc,access-ns: Start cycle to first data capture (read access) +- gpmc,rd-cycle-ns: Total read cycle time +- gpmc,wr-cycle-ns: Total write cycle time +- reg: Chip-select, base address (relative to chip-select) + and size of the memory mapped for the device. + Note that base address will be typically 0 as this + is the start of the chip-select. + +Optional properties: +- gpmc,XXX Additional GPMC timings and settings parameters. See + Documentation/devicetree/bindings/bus/ti-gpmc.txt + +Example: + +gpmc: gpmc@6e000000 { + compatible = "ti,omap3430-gpmc"; + ti,hwmods = "gpmc"; + reg = <0x6e000000 0x1000>; + interrupts = <20>; + gpmc,num-cs = <8>; + gpmc,num-waitpins = <4>; + #address-cells = <2>; + #size-cells = <1>; + + ranges = <5 0 0x2c000000 0x1000000>; + + ethernet@5,0 { + compatible = "smsc,lan9221", "smsc,lan9115"; + reg = <5 0 0xff>; + bank-width = <2>; + + gpmc,mux-add-data; + gpmc,cs-on-ns = <0>; + gpmc,cs-rd-off-ns = <186>; + gpmc,cs-wr-off-ns = <186>; + gpmc,adv-on-ns = <12>; + gpmc,adv-rd-off-ns = <48>; + gpmc,adv-wr-off-ns = <48>; + gpmc,oe-on-ns = <54>; + gpmc,oe-off-ns = <168>; + gpmc,we-on-ns = <54>; + gpmc,we-off-ns = <168>; + gpmc,rd-cycle-ns = <186>; + gpmc,wr-cycle-ns = <186>; + gpmc,access-ns = <114>; + gpmc,page-burst-access-ns = <6>; + gpmc,bus-turnaround-ns = <12>; + gpmc,cycle2cycle-delay-ns = <18>; + gpmc,wr-data-mux-bus-ns = <90>; + gpmc,wr-access-ns = <186>; + gpmc,cycle2cycle-samecsen; + gpmc,cycle2cycle-diffcsen; + + interrupt-parent = <&gpio6>; + interrupts = <16>; + vmmc-supply = <&vddvario>; + vmmc_aux-supply = <&vdd33a>; + reg-io-width = <4>; + + smsc,save-mac-address; + }; +}; diff --git a/trunk/Documentation/devicetree/bindings/pinctrl/fsl,mxs-pinctrl.txt b/trunk/Documentation/devicetree/bindings/pinctrl/fsl,mxs-pinctrl.txt index f7e8e8f4d9a3..3077370c89af 100644 --- a/trunk/Documentation/devicetree/bindings/pinctrl/fsl,mxs-pinctrl.txt +++ b/trunk/Documentation/devicetree/bindings/pinctrl/fsl,mxs-pinctrl.txt @@ -70,6 +70,10 @@ Optional subnode-properties: 0: Disable the internal pull-up 1: Enable the internal pull-up +Note that when enabling the pull-up, the internal pad keeper gets disabled. +Also, some pins doesn't have a pull up, in that case, setting the fsl,pull-up +will only disable the internal pad keeper. + Examples: pinctrl@80018000 { diff --git a/trunk/Documentation/devicetree/bindings/pinctrl/pinctrl-vt8500.txt b/trunk/Documentation/devicetree/bindings/pinctrl/pinctrl-vt8500.txt new file mode 100644 index 000000000000..b3aa90f0ce44 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/pinctrl/pinctrl-vt8500.txt @@ -0,0 +1,57 @@ +VIA VT8500 and Wondermedia WM8xxx-series pinmux/gpio controller + +These SoCs contain a combined Pinmux/GPIO module. Each pin may operate as +either a GPIO in, GPIO out or as an alternate function (I2C, SPI etc). + +Required properties: +- compatible: "via,vt8500-pinctrl", "wm,wm8505-pinctrl", "wm,wm8650-pinctrl", + "wm8750-pinctrl" or "wm,wm8850-pinctrl" +- reg: Should contain the physical address of the module's registers. +- interrupt-controller: Marks the device node as an interrupt controller. +- #interrupt-cells: Should be two. +- gpio-controller: Marks the device node as a GPIO controller. +- #gpio-cells : Should be two. The first cell is the pin number and the + second cell is used to specify optional parameters. + bit 0 - active low + +Please refer to ../gpio/gpio.txt for a general description of GPIO bindings. + +Please refer to pinctrl-bindings.txt in this directory for details of the +common pinctrl bindings used by client devices, including the meaning of the +phrase "pin configuration node". + +Each pin configuration node lists the pin(s) to which it applies, and one or +more of the mux functions to select on those pin(s), and pull-up/down +configuration. Each subnode only affects those parameters that are explicitly +listed. In other words, a subnode that lists only a mux function implies no +information about any pull configuration. Similarly, a subnode that lists only +a pull parameter implies no information about the mux function. + +Required subnode-properties: +- wm,pins: An array of cells. Each cell contains the ID of a pin. + +Optional subnode-properties: +- wm,function: Integer, containing the function to mux to the pin(s): + 0: GPIO in + 1: GPIO out + 2: alternate + +- wm,pull: Integer, representing the pull-down/up to apply to the pin(s): + 0: none + 1: down + 2: up + +Each of wm,function and wm,pull may contain either a single value which +will be applied to all pins in wm,pins, or one value for each entry in +wm,pins. + +Example: + + pinctrl: pinctrl { + compatible = "wm,wm8505-pinctrl"; + reg = <0xD8110000 0x10000>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-controller; + #gpio-cells = <2>; + }; diff --git a/trunk/Documentation/devicetree/bindings/pwm/pwm-samsung.txt b/trunk/Documentation/devicetree/bindings/pwm/pwm-samsung.txt new file mode 100644 index 000000000000..ac67c687a327 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/pwm/pwm-samsung.txt @@ -0,0 +1,43 @@ +* Samsung PWM timers + +Samsung SoCs contain PWM timer blocks which can be used for system clock source +and clock event timers, as well as to drive SoC outputs with PWM signal. Each +PWM timer block provides 5 PWM channels (not all of them can drive physical +outputs - see SoC and board manual). + +Be aware that the clocksource driver supports only uniprocessor systems. + +Required properties: +- compatible : should be one of following: + samsung,s3c2410-pwm - for 16-bit timers present on S3C24xx SoCs + samsung,s3c6400-pwm - for 32-bit timers present on S3C64xx SoCs + samsung,s5p6440-pwm - for 32-bit timers present on S5P64x0 SoCs + samsung,s5pc100-pwm - for 32-bit timers present on S5PC100, S5PV210, + Exynos4210 rev0 SoCs + samsung,exynos4210-pwm - for 32-bit timers present on Exynos4210, + Exynos4x12 and Exynos5250 SoCs +- reg: base address and size of register area +- interrupts: list of timer interrupts (one interrupt per timer, starting at + timer 0) +- #pwm-cells: number of cells used for PWM specifier - must be 3 + the specifier format is as follows: + - phandle to PWM controller node + - index of PWM channel (from 0 to 4) + - PWM signal period in nanoseconds + - bitmask of optional PWM flags: + 0x1 - invert PWM signal + +Optional properties: +- samsung,pwm-outputs: list of PWM channels used as PWM outputs on particular + platform - an array of up to 5 elements being indices of PWM channels + (from 0 to 4), the order does not matter. + +Example: + pwm@7f006000 { + compatible = "samsung,s3c6400-pwm"; + reg = <0x7f006000 0x1000>; + interrupt-parent = <&vic0>; + interrupts = <23>, <24>, <25>, <27>, <28>; + samsung,pwm-outputs = <0>, <1>; + #pwm-cells = <3>; + } diff --git a/trunk/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt b/trunk/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt index 131e8c11d26f..681afad73778 100644 --- a/trunk/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt +++ b/trunk/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt @@ -1,7 +1,9 @@ TI SOC ECAP based APWM controller Required properties: -- compatible: Must be "ti,am33xx-ecap" +- compatible: Must be "ti,-ecap". + for am33xx - compatible = "ti,am33xx-ecap"; + for da850 - compatible = "ti,da850-ecap", "ti,am33xx-ecap"; - #pwm-cells: Should be 3. Number of cells being used to specify PWM property. First cell specifies the per-chip index of the PWM to use, the second cell is the period in nanoseconds and bit 0 in the third cell is used to @@ -15,9 +17,15 @@ Optional properties: Example: -ecap0: ecap@0 { +ecap0: ecap@0 { /* ECAP on am33xx */ compatible = "ti,am33xx-ecap"; #pwm-cells = <3>; reg = <0x48300100 0x80>; ti,hwmods = "ecap0"; }; + +ecap0: ecap@0 { /* ECAP on da850 */ + compatible = "ti,da850-ecap", "ti,am33xx-ecap"; + #pwm-cells = <3>; + reg = <0x306000 0x80>; +}; diff --git a/trunk/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt b/trunk/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt index 4fc7079d822e..337c6fc65d3f 100644 --- a/trunk/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt +++ b/trunk/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt @@ -1,7 +1,9 @@ TI SOC EHRPWM based PWM controller Required properties: -- compatible : Must be "ti,am33xx-ehrpwm" +- compatible: Must be "ti,-ehrpwm". + for am33xx - compatible = "ti,am33xx-ehrpwm"; + for da850 - compatible = "ti,da850-ehrpwm", "ti,am33xx-ehrpwm"; - #pwm-cells: Should be 3. Number of cells being used to specify PWM property. First cell specifies the per-chip index of the PWM to use, the second cell is the period in nanoseconds and bit 0 in the third cell is used to @@ -15,9 +17,15 @@ Optional properties: Example: -ehrpwm0: ehrpwm@0 { +ehrpwm0: ehrpwm@0 { /* EHRPWM on am33xx */ compatible = "ti,am33xx-ehrpwm"; #pwm-cells = <3>; reg = <0x48300200 0x100>; ti,hwmods = "ehrpwm0"; }; + +ehrpwm0: ehrpwm@0 { /* EHRPWM on da850 */ + compatible = "ti,da850-ehrpwm", "ti,am33xx-ehrpwm"; + #pwm-cells = <3>; + reg = <0x300000 0x2000>; +}; diff --git a/trunk/Documentation/devicetree/bindings/reset/fsl,imx-src.txt b/trunk/Documentation/devicetree/bindings/reset/fsl,imx-src.txt new file mode 100644 index 000000000000..13301777e11c --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/reset/fsl,imx-src.txt @@ -0,0 +1,49 @@ +Freescale i.MX System Reset Controller +====================================== + +Please also refer to reset.txt in this directory for common reset +controller binding usage. + +Required properties: +- compatible: Should be "fsl,-src" +- reg: should be register base and length as documented in the + datasheet +- interrupts: Should contain SRC interrupt and CPU WDOG interrupt, + in this order. +- #reset-cells: 1, see below + +example: + +src: src@020d8000 { + compatible = "fsl,imx6q-src"; + reg = <0x020d8000 0x4000>; + interrupts = <0 91 0x04 0 96 0x04>; + #reset-cells = <1>; +}; + +Specifying reset lines connected to IP modules +============================================== + +The system reset controller can be used to reset the GPU, VPU, +IPU, and OpenVG IP modules on i.MX5 and i.MX6 ICs. Those device +nodes should specify the reset line on the SRC in their resets +property, containing a phandle to the SRC device node and a +RESET_INDEX specifying which module to reset, as described in +reset.txt + +example: + + ipu1: ipu@02400000 { + resets = <&src 2>; + }; + ipu2: ipu@02800000 { + resets = <&src 4>; + }; + +The following RESET_INDEX values are valid for i.MX5: +GPU_RESET 0 +VPU_RESET 1 +IPU1_RESET 2 +OPEN_VG_RESET 3 +The following additional RESET_INDEX value is valid for i.MX6: +IPU2_RESET 4 diff --git a/trunk/Documentation/devicetree/bindings/reset/reset.txt b/trunk/Documentation/devicetree/bindings/reset/reset.txt new file mode 100644 index 000000000000..31db6ff84908 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/reset/reset.txt @@ -0,0 +1,75 @@ += Reset Signal Device Tree Bindings = + +This binding is intended to represent the hardware reset signals present +internally in most IC (SoC, FPGA, ...) designs. Reset signals for whole +standalone chips are most likely better represented as GPIOs, although there +are likely to be exceptions to this rule. + +Hardware blocks typically receive a reset signal. This signal is generated by +a reset provider (e.g. power management or clock module) and received by a +reset consumer (the module being reset, or a module managing when a sub- +ordinate module is reset). This binding exists to represent the provider and +consumer, and provide a way to couple the two together. + +A reset signal is represented by the phandle of the provider, plus a reset +specifier - a list of DT cells that represents the reset signal within the +provider. The length (number of cells) and semantics of the reset specifier +are dictated by the binding of the reset provider, although common schemes +are described below. + +A word on where to place reset signal consumers in device tree: It is possible +in hardware for a reset signal to affect multiple logically separate HW blocks +at once. In this case, it would be unwise to represent this reset signal in +the DT node of each affected HW block, since if activated, an unrelated block +may be reset. Instead, reset signals should be represented in the DT node +where it makes most sense to control it; this may be a bus node if all +children of the bus are affected by the reset signal, or an individual HW +block node for dedicated reset signals. The intent of this binding is to give +appropriate software access to the reset signals in order to manage the HW, +rather than to slavishly enumerate the reset signal that affects each HW +block. + += Reset providers = + +Required properties: +#reset-cells: Number of cells in a reset specifier; Typically 0 for nodes + with a single reset output and 1 for nodes with multiple + reset outputs. + +For example: + + rst: reset-controller { + #reset-cells = <1>; + }; + += Reset consumers = + +Required properties: +resets: List of phandle and reset specifier pairs, one pair + for each reset signal that affects the device, or that the + device manages. Note: if the reset provider specifies '0' for + #reset-cells, then only the phandle portion of the pair will + appear. + +Optional properties: +reset-names: List of reset signal name strings sorted in the same order as + the resets property. Consumers drivers will use reset-names to + match reset signal names with reset specifiers. + +For example: + + device { + resets = <&rst 20>; + reset-names = "reset"; + }; + +This represents a device with a single reset signal named "reset". + + bus { + resets = <&rst 10> <&rst 11> <&rst 12> <&rst 11>; + reset-names = "i2s1", "i2s2", "dma", "mixer"; + }; + +This represents a bus that controls the reset signal of each of four sub- +ordinate devices. Consider for example a bus that fails to operate unless no +child device has reset asserted. diff --git a/trunk/Documentation/devicetree/bindings/rng/brcm,bcm2835.txt b/trunk/Documentation/devicetree/bindings/rng/brcm,bcm2835.txt new file mode 100644 index 000000000000..07ccdaa68324 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/rng/brcm,bcm2835.txt @@ -0,0 +1,13 @@ +BCM2835 Random number generator + +Required properties: + +- compatible : should be "brcm,bcm2835-rng" +- reg : Specifies base physical address and size of the registers. + +Example: + +rng { + compatible = "brcm,bcm2835-rng"; + reg = <0x7e104000 0x10>; +}; diff --git a/trunk/Documentation/devicetree/bindings/serial/pl011.txt b/trunk/Documentation/devicetree/bindings/serial/pl011.txt new file mode 100644 index 000000000000..5d2e840ae65c --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/serial/pl011.txt @@ -0,0 +1,17 @@ +* ARM AMBA Primecell PL011 serial UART + +Required properties: +- compatible: must be "arm,primecell", "arm,pl011" +- reg: exactly one register range with length 0x1000 +- interrupts: exactly one interrupt specifier + +Optional properties: +- pinctrl: When present, must have one state named "sleep" + and one state named "default" +- clocks: When present, must refer to exactly one clock named + "apb_pclk" +- dmas: When present, may have one or two dma channels. + The first one must be named "rx", the second one + must be named "tx". + +See also bindings/arm/primecell.txt diff --git a/trunk/Documentation/devicetree/bindings/sound/ak5386.txt b/trunk/Documentation/devicetree/bindings/sound/ak5386.txt new file mode 100644 index 000000000000..dc3914fe6ce8 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/sound/ak5386.txt @@ -0,0 +1,19 @@ +AK5386 Single-ended 24-Bit 192kHz delta-sigma ADC + +This device has no control interface. + +Required properties: + + - compatible : "asahi-kasei,ak5386" + +Optional properties: + + - reset-gpio : a GPIO spec for the reset/power down pin. + If specified, it will be deasserted at probe time. + +Example: + +spdif: ak5386@0 { + compatible = "asahi-kasei,ak5386"; + reset-gpio = <&gpio0 23>; +}; diff --git a/trunk/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-alc5632.txt b/trunk/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-alc5632.txt index b77a97c9101e..05ffecb57103 100644 --- a/trunk/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-alc5632.txt +++ b/trunk/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-alc5632.txt @@ -2,6 +2,11 @@ NVIDIA Tegra audio complex Required properties: - compatible : "nvidia,tegra-audio-alc5632" +- clocks : Must contain an entry for each entry in clock-names. +- clock-names : Must include the following entries: + "pll_a" (The Tegra clock of that name), + "pll_a_out0" (The Tegra clock of that name), + "mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk) - nvidia,model : The user-visible name of this sound complex. - nvidia,audio-routing : A list of the connections between audio components. Each entry is a pair of strings, the first being the connection's sink, @@ -56,4 +61,7 @@ sound { nvidia,i2s-controller = <&tegra_i2s1>; nvidia,audio-codec = <&alc5632>; + + clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 93>; + clock-names = "pll_a", "pll_a_out0", "mclk"; }; diff --git a/trunk/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-trimslice.txt b/trunk/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-trimslice.txt index 04b14cfb1f16..ef1fe7358279 100644 --- a/trunk/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-trimslice.txt +++ b/trunk/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-trimslice.txt @@ -2,6 +2,11 @@ NVIDIA Tegra audio complex for TrimSlice Required properties: - compatible : "nvidia,tegra-audio-trimslice" +- clocks : Must contain an entry for each entry in clock-names. +- clock-names : Must include the following entries: + "pll_a" (The Tegra clock of that name), + "pll_a_out0" (The Tegra clock of that name), + "mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk) - nvidia,i2s-controller : The phandle of the Tegra I2S1 controller - nvidia,audio-codec : The phandle of the WM8903 audio codec @@ -11,4 +16,6 @@ sound { compatible = "nvidia,tegra-audio-trimslice"; nvidia,i2s-controller = <&tegra_i2s1>; nvidia,audio-codec = <&codec>; + clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 93>; + clock-names = "pll_a", "pll_a_out0", "mclk"; }; diff --git a/trunk/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8753.txt b/trunk/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8753.txt index c4dd39ce6165..d14510613a7f 100644 --- a/trunk/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8753.txt +++ b/trunk/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8753.txt @@ -2,6 +2,11 @@ NVIDIA Tegra audio complex Required properties: - compatible : "nvidia,tegra-audio-wm8753" +- clocks : Must contain an entry for each entry in clock-names. +- clock-names : Must include the following entries: + "pll_a" (The Tegra clock of that name), + "pll_a_out0" (The Tegra clock of that name), + "mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk) - nvidia,model : The user-visible name of this sound complex. - nvidia,audio-routing : A list of the connections between audio components. Each entry is a pair of strings, the first being the connection's sink, @@ -50,5 +55,8 @@ sound { nvidia,i2s-controller = <&i2s1>; nvidia,audio-codec = <&wm8753>; + + clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 93>; + clock-names = "pll_a", "pll_a_out0", "mclk"; }; diff --git a/trunk/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8903.txt b/trunk/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8903.txt index d5b0da8bf1d8..3bf722deb722 100644 --- a/trunk/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8903.txt +++ b/trunk/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8903.txt @@ -2,6 +2,11 @@ NVIDIA Tegra audio complex Required properties: - compatible : "nvidia,tegra-audio-wm8903" +- clocks : Must contain an entry for each entry in clock-names. +- clock-names : Must include the following entries: + "pll_a" (The Tegra clock of that name), + "pll_a_out0" (The Tegra clock of that name), + "mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk) - nvidia,model : The user-visible name of this sound complex. - nvidia,audio-routing : A list of the connections between audio components. Each entry is a pair of strings, the first being the connection's sink, @@ -67,5 +72,8 @@ sound { nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */ nvidia,int-mic-en-gpios = <&gpio 184 0>; /*gpio PX0 */ nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */ + + clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 93>; + clock-names = "pll_a", "pll_a_out0", "mclk"; }; diff --git a/trunk/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm9712.txt b/trunk/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm9712.txt index be35d34e8b26..ad589b163639 100644 --- a/trunk/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm9712.txt +++ b/trunk/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm9712.txt @@ -2,6 +2,11 @@ NVIDIA Tegra audio complex Required properties: - compatible : "nvidia,tegra-audio-wm9712" +- clocks : Must contain an entry for each entry in clock-names. +- clock-names : Must include the following entries: + "pll_a" (The Tegra clock of that name), + "pll_a_out0" (The Tegra clock of that name), + "mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk) - nvidia,model : The user-visible name of this sound complex. - nvidia,audio-routing : A list of the connections between audio components. Each entry is a pair of strings, the first being the connection's sink, @@ -48,4 +53,7 @@ sound { "Mic", "MIC1"; nvidia,ac97-controller = <&ac97>; + + clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 93>; + clock-names = "pll_a", "pll_a_out0", "mclk"; }; diff --git a/trunk/Documentation/devicetree/bindings/sound/nvidia,tegra30-ahub.txt b/trunk/Documentation/devicetree/bindings/sound/nvidia,tegra30-ahub.txt index 1ac7b1642186..0e5c12c66523 100644 --- a/trunk/Documentation/devicetree/bindings/sound/nvidia,tegra30-ahub.txt +++ b/trunk/Documentation/devicetree/bindings/sound/nvidia,tegra30-ahub.txt @@ -1,12 +1,22 @@ NVIDIA Tegra30 AHUB (Audio Hub) Required properties: -- compatible : "nvidia,tegra30-ahub" +- compatible : "nvidia,tegra30-ahub", "nvidia,tegra114-ahub", etc. - reg : Should contain the register physical address and length for each of - the AHUB's APBIF registers and the AHUB's own registers. + the AHUB's register blocks. + - Tegra30 requires 2 entries, for the APBIF and AHUB/AUDIO register blocks. + - Tegra114 requires an additional entry, for the APBIF2 register block. - interrupts : Should contain AHUB interrupt -- nvidia,dma-request-selector : The Tegra DMA controller's phandle and - request selector for the first APBIF channel. +- nvidia,dma-request-selector : A list of the DMA channel specifiers. Each + entry contains the Tegra DMA controller's phandle and request selector. + If a single entry is present, the request selectors for the channels are + assumed to be contiguous, and increment from this value. + If multiple values are given, one value must be given per channel. +- clocks : Must contain an entry for each required entry in clock-names. +- clock-names : Must include the following entries: + - Tegra30: Requires d_audio, apbif, i2s0, i2s1, i2s2, i2s3, i2s4, dam0, + dam1, dam2, spdif_in. + - Tegra114: Additionally requires amx, adx. - ranges : The bus address mapping for the configlink register bus. Can be empty since the mapping is 1:1. - #address-cells : For the configlink bus. Should be <1>; @@ -25,7 +35,13 @@ ahub@70080000 { reg = <0x70080000 0x200 0x70080200 0x100>; interrupts = < 0 103 0x04 >; nvidia,dma-request-selector = <&apbdma 1>; - + clocks = <&tegra_car 106>, <&tegra_car 107>, <&tegra_car 30>, + <&tegra_car 11>, <&tegra_car 18>, <&tegra_car 101>, + <&tegra_car 102>, <&tegra_car 108>, <&tegra_car 109>, + <&tegra_car 110>, <&tegra_car 162>; + clock-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2", + "i2s3", "i2s4", "dam0", "dam1", "dam2", + "spdif_in"; ranges; #address-cells = <1>; #size-cells = <1>; diff --git a/trunk/Documentation/devicetree/bindings/sound/ti,tas5086.txt b/trunk/Documentation/devicetree/bindings/sound/ti,tas5086.txt new file mode 100644 index 000000000000..8ea4f5b4818d --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/sound/ti,tas5086.txt @@ -0,0 +1,32 @@ +Texas Instruments TAS5086 6-channel PWM Processor + +Required properties: + + - compatible: Should contain "ti,tas5086". + - reg: The i2c address. Should contain <0x1b>. + +Optional properties: + + - reset-gpio: A GPIO spec to define which pin is connected to the + chip's !RESET pin. If specified, the driver will + assert a hardware reset at probe time. + + - ti,charge-period: This property should contain the time in microseconds + that closely matches the external single-ended + split-capacitor charge period. The hardware chip + waits for this period of time before starting the + PWM signals. This helps reduce pops and clicks. + + When not specified, the hardware default of 1300ms + is retained. + +Examples: + + i2c_bus { + tas5086@1b { + compatible = "ti,tas5086"; + reg = <0x1b>; + reset-gpio = <&gpio 23 0>; + ti,charge-period = <156000>; + }; + }; diff --git a/trunk/Documentation/devicetree/bindings/sound/wm8994.txt b/trunk/Documentation/devicetree/bindings/sound/wm8994.txt index 7a7eb1e7bda6..f2f3e80934d2 100644 --- a/trunk/Documentation/devicetree/bindings/sound/wm8994.txt +++ b/trunk/Documentation/devicetree/bindings/sound/wm8994.txt @@ -5,14 +5,70 @@ on the board). Required properties: - - compatible : "wlf,wm1811", "wlf,wm8994", "wlf,wm8958" + - compatible : One of "wlf,wm1811", "wlf,wm8994" or "wlf,wm8958". - reg : the I2C address of the device for I2C, the chip select number for SPI. + - gpio-controller : Indicates this device is a GPIO controller. + - #gpio-cells : Must be 2. The first cell is the pin number and the + second cell is used to specify optional parameters (currently unused). + + - AVDD2-supply, DBVDD1-supply, DBVDD2-supply, DBVDD3-supply, CPVDD-supply, + SPKVDD1-supply, SPKVDD2-supply : power supplies for the device, as covered + in Documentation/devicetree/bindings/regulator/regulator.txt + +Optional properties: + + - interrupts : The interrupt line the IRQ signal for the device is + connected to. This is optional, if it is not connected then none + of the interrupt related properties should be specified. + - interrupt-controller : These devices contain interrupt controllers + and may provide interrupt services to other devices if they have an + interrupt line connected. + - interrupt-parent : The parent interrupt controller. + - #interrupt-cells: the number of cells to describe an IRQ, this should be 2. + The first cell is the IRQ number. + The second cell is the flags, encoded as the trigger masks from + Documentation/devicetree/bindings/interrupts.txt + + - wlf,gpio-cfg : A list of GPIO configuration register values. If absent, + no configuration of these registers is performed. If any value is + over 0xffff then the register will be left as default. If present 11 + values must be supplied. + + - wlf,micbias-cfg : Two MICBIAS register values for WM1811 or + WM8958. If absent the register defaults will be used. + + - wlf,ldo1ena : GPIO specifier for control of LDO1ENA input to device. + - wlf,ldo2ena : GPIO specifier for control of LDO2ENA input to device. + + - wlf,lineout1-se : If present LINEOUT1 is in single ended mode. + - wlf,lineout2-se : If present LINEOUT2 is in single ended mode. + + - wlf,lineout1-feedback : If present LINEOUT1 has common mode feedback + connected. + - wlf,lineout2-feedback : If present LINEOUT2 has common mode feedback + connected. + + - wlf,ldoena-always-driven : If present LDOENA is always driven. + Example: codec: wm8994@1a { compatible = "wlf,wm8994"; reg = <0x1a>; + + gpio-controller; + #gpio-cells = <2>; + + lineout1-se; + + AVDD2-supply = <®ulator>; + CPVDD-supply = <®ulator>; + DBVDD1-supply = <®ulator>; + DBVDD2-supply = <®ulator>; + DBVDD3-supply = <®ulator>; + SPKVDD1-supply = <®ulator>; + SPKVDD2-supply = <®ulator>; }; diff --git a/trunk/Documentation/devicetree/bindings/spi/mxs-spi.txt b/trunk/Documentation/devicetree/bindings/spi/mxs-spi.txt index e2e13957c2a4..3499b73293c2 100644 --- a/trunk/Documentation/devicetree/bindings/spi/mxs-spi.txt +++ b/trunk/Documentation/devicetree/bindings/spi/mxs-spi.txt @@ -3,8 +3,11 @@ Required properties: - compatible: Should be "fsl,-spi", where soc is "imx23" or "imx28" - reg: Offset and length of the register set for the device -- interrupts: Should contain SSP interrupts (error irq first, dma irq second) -- fsl,ssp-dma-channel: APBX DMA channel for the SSP +- interrupts: Should contain SSP ERROR interrupt +- dmas: DMA specifier, consisting of a phandle to DMA controller node + and SSP DMA channel ID. + Refer to dma.txt and fsl-mxs-dma.txt for details. +- dma-names: Must be "rx-tx". Optional properties: - clock-frequency : Input clock frequency to the SPI block in Hz. @@ -17,6 +20,7 @@ ssp0: ssp@80010000 { #size-cells = <0>; compatible = "fsl,imx28-spi"; reg = <0x80010000 0x2000>; - interrupts = <96 82>; - fsl,ssp-dma-channel = <0>; + interrupts = <96>; + dmas = <&dma_apbh 0>; + dma-names = "rx-tx"; }; diff --git a/trunk/Documentation/devicetree/bindings/spi/spi-davinci.txt b/trunk/Documentation/devicetree/bindings/spi/spi-davinci.txt new file mode 100644 index 000000000000..6d0ac8d0ad9b --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/spi/spi-davinci.txt @@ -0,0 +1,51 @@ +Davinci SPI controller device bindings + +Required properties: +- #address-cells: number of cells required to define a chip select + address on the SPI bus. Should be set to 1. +- #size-cells: should be zero. +- compatible: + - "ti,dm6441-spi" for SPI used similar to that on DM644x SoC family + - "ti,da830-spi" for SPI used similar to that on DA8xx SoC family +- reg: Offset and length of SPI controller register space +- num-cs: Number of chip selects +- ti,davinci-spi-intr-line: interrupt line used to connect the SPI + IP to the interrupt controller within the SoC. Possible values + are 0 and 1. Manual says one of the two possible interrupt + lines can be tied to the interrupt controller. Set this + based on a specifc SoC configuration. +- interrupts: interrupt number mapped to CPU. +- clocks: spi clk phandle + +Example of a NOR flash slave device (n25q032) connected to DaVinci +SPI controller device over the SPI bus. + +spi0:spi@20BF0000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "ti,dm6446-spi"; + reg = <0x20BF0000 0x1000>; + num-cs = <4>; + ti,davinci-spi-intr-line = <0>; + interrupts = <338>; + clocks = <&clkspi>; + + flash: n25q032@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "st,m25p32"; + spi-max-frequency = <25000000>; + reg = <0>; + + partition@0 { + label = "u-boot-spl"; + reg = <0x0 0x80000>; + read-only; + }; + + partition@1 { + label = "test"; + reg = <0x80000 0x380000>; + }; + }; +}; diff --git a/trunk/Documentation/devicetree/bindings/spi/spi_pl022.txt b/trunk/Documentation/devicetree/bindings/spi/spi_pl022.txt index f158fd31cfda..22ed6797216d 100644 --- a/trunk/Documentation/devicetree/bindings/spi/spi_pl022.txt +++ b/trunk/Documentation/devicetree/bindings/spi/spi_pl022.txt @@ -16,6 +16,11 @@ Optional properties: device will be suspended immediately - pl022,rt : indicates the controller should run the message pump with realtime priority to minimise the transfer latency on the bus (boolean) +- dmas : Two or more DMA channel specifiers following the convention outlined + in bindings/dma/dma.txt +- dma-names: Names for the dma channels, if present. There must be at + least one channel named "tx" for transmit and named "rx" for + receive. SPI slave nodes must be children of the SPI master node and can @@ -32,3 +37,34 @@ contain the following properties. - pl022,wait-state : Microwire interface: Wait state - pl022,duplex : Microwire interface: Full/Half duplex + +Example: + + spi@e0100000 { + compatible = "arm,pl022", "arm,primecell"; + reg = <0xe0100000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <0 31 0x4>; + dmas = <&dma-controller 23 1>, + <&dma-controller 24 0>; + dma-names = "rx", "tx"; + + m25p80@1 { + compatible = "st,m25p80"; + reg = <1>; + spi-max-frequency = <12000000>; + spi-cpol; + spi-cpha; + pl022,hierarchy = <0>; + pl022,interface = <0>; + pl022,slave-tx-disable; + pl022,com-mode = <0x2>; + pl022,rx-level-trig = <0>; + pl022,tx-level-trig = <0>; + pl022,ctrl-len = <0x11>; + pl022,wait-state = <0>; + pl022,duplex = <0>; + }; + }; + diff --git a/trunk/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt b/trunk/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt index 8071ac20d4b3..b876d4925a57 100644 --- a/trunk/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt +++ b/trunk/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt @@ -8,6 +8,8 @@ Required properties: - interrupts: Should contain sync interrupt and error interrupt, in this order. - #crtc-cells: 1, See below +- resets: phandle pointing to the system reset controller and + reset line index, see reset/fsl,imx-src.txt for details example: @@ -16,6 +18,7 @@ ipu: ipu@18000000 { compatible = "fsl,imx53-ipu"; reg = <0x18000000 0x080000000>; interrupts = <11 10>; + resets = <&src 2>; }; Parallel display support diff --git a/trunk/Documentation/devicetree/bindings/thermal/armada-thermal.txt b/trunk/Documentation/devicetree/bindings/thermal/armada-thermal.txt new file mode 100644 index 000000000000..fff93d5f92de --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/thermal/armada-thermal.txt @@ -0,0 +1,22 @@ +* Marvell Armada 370/XP thermal management + +Required properties: + +- compatible: Should be set to one of the following: + marvell,armada370-thermal + marvell,armadaxp-thermal + +- reg: Device's register space. + Two entries are expected, see the examples below. + The first one is required for the sensor register; + the second one is required for the control register + to be used for sensor initialization (a.k.a. calibration). + +Example: + + thermal@d0018300 { + compatible = "marvell,armada370-thermal"; + reg = <0xd0018300 0x4 + 0xd0018304 0x4>; + status = "okay"; + }; diff --git a/trunk/Documentation/devicetree/bindings/timer/arm,sp804.txt b/trunk/Documentation/devicetree/bindings/timer/arm,sp804.txt new file mode 100644 index 000000000000..5cd8eee74af1 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/timer/arm,sp804.txt @@ -0,0 +1,29 @@ +ARM sp804 Dual Timers +--------------------------------------- + +Required properties: +- compatible: Should be "arm,sp804" & "arm,primecell" +- interrupts: Should contain the list of Dual Timer interrupts. This is the + interrupt for timer 1 and timer 2. In the case of a single entry, it is + the combined interrupt or if "arm,sp804-has-irq" is present that + specifies which timer interrupt is connected. +- reg: Should contain location and length for dual timer register. +- clocks: clocks driving the dual timer hardware. This list should be 1 or 3 + clocks. With 3 clocks, the order is timer0 clock, timer1 clock, + apb_pclk. A single clock can also be specified if the same clock is + used for all clock inputs. + +Optional properties: +- arm,sp804-has-irq = <#>: In the case of only 1 timer irq line connected, this + specifies if the irq connection is for timer 1 or timer 2. A value of 1 + or 2 should be used. + +Example: + + timer0: timer@fc800000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0xfc800000 0x1000>; + interrupts = <0 0 4>, <0 1 4>; + clocks = <&timclk1 &timclk2 &pclk>; + clock-names = "timer1", "timer2", "apb_pclk"; + }; diff --git a/trunk/Documentation/devicetree/bindings/timer/cadence,ttc-timer.txt b/trunk/Documentation/devicetree/bindings/timer/cadence,ttc-timer.txt new file mode 100644 index 000000000000..993695c659e1 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/timer/cadence,ttc-timer.txt @@ -0,0 +1,17 @@ +Cadence TTC - Triple Timer Counter + +Required properties: +- compatible : Should be "cdns,ttc". +- reg : Specifies base physical address and size of the registers. +- interrupts : A list of 3 interrupts; one per timer channel. +- clocks: phandle to the source clock + +Example: + +ttc0: ttc0@f8001000 { + interrupt-parent = <&intc>; + interrupts = < 0 10 4 0 11 4 0 12 4 >; + compatible = "cdns,ttc"; + reg = <0xF8001000 0x1000>; + clocks = <&cpu_clk 3>; +}; diff --git a/trunk/Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt b/trunk/Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt new file mode 100644 index 000000000000..cb47bfbcaeea --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt @@ -0,0 +1,68 @@ +Samsung's Multi Core Timer (MCT) + +The Samsung's Multi Core Timer (MCT) module includes two main blocks, the +global timer and CPU local timers. The global timer is a 64-bit free running +up-counter and can generate 4 interrupts when the counter reaches one of the +four preset counter values. The CPU local timers are 32-bit free running +down-counters and generate an interrupt when the counter expires. There is +one CPU local timer instantiated in MCT for every CPU in the system. + +Required properties: + +- compatible: should be "samsung,exynos4210-mct". + (a) "samsung,exynos4210-mct", for mct compatible with Exynos4210 mct. + (b) "samsung,exynos4412-mct", for mct compatible with Exynos4412 mct. + +- reg: base address of the mct controller and length of the address space + it occupies. + +- interrupts: the list of interrupts generated by the controller. The following + should be the order of the interrupts specified. The local timer interrupts + should be specified after the four global timer interrupts have been + specified. + + 0: Global Timer Interrupt 0 + 1: Global Timer Interrupt 1 + 2: Global Timer Interrupt 2 + 3: Global Timer Interrupt 3 + 4: Local Timer Interrupt 0 + 5: Local Timer Interrupt 1 + 6: .. + 7: .. + i: Local Timer Interrupt n + +Example 1: In this example, the system uses only the first global timer + interrupt generated by MCT and the remaining three global timer + interrupts are unused. Two local timer interrupts have been + specified. + + mct@10050000 { + compatible = "samsung,exynos4210-mct"; + reg = <0x10050000 0x800>; + interrupts = <0 57 0>, <0 0 0>, <0 0 0>, <0 0 0>, + <0 42 0>, <0 48 0>; + }; + +Example 2: In this example, the MCT global and local timer interrupts are + connected to two seperate interrupt controllers. Hence, an + interrupt-map is created to map the interrupts to the respective + interrupt controllers. + + mct@101C0000 { + compatible = "samsung,exynos4210-mct"; + reg = <0x101C0000 0x800>; + interrupt-controller; + #interrups-cells = <2>; + interrupt-parent = <&mct_map>; + interrupts = <0 0>, <1 0>, <2 0>, <3 0>, + <4 0>, <5 0>; + + mct_map: mct-map { + #interrupt-cells = <2>; + #address-cells = <0>; + #size-cells = <0>; + interrupt-map = <0x0 0 &combiner 23 3>, + <0x4 0 &gic 0 120 0>, + <0x5 0 &gic 0 121 0>; + }; + }; diff --git a/trunk/Documentation/devicetree/bindings/tty/serial/fsl-mxs-auart.txt b/trunk/Documentation/devicetree/bindings/tty/serial/fsl-mxs-auart.txt index 273a8d5b3300..2c00ec64628e 100644 --- a/trunk/Documentation/devicetree/bindings/tty/serial/fsl-mxs-auart.txt +++ b/trunk/Documentation/devicetree/bindings/tty/serial/fsl-mxs-auart.txt @@ -5,20 +5,18 @@ Required properties: imx23 and imx28. - reg : Address and length of the register set for the device - interrupts : Should contain the auart interrupt numbers - -Optional properties: -- fsl,auart-dma-channel : The DMA channels, the first is for RX, the other - is for TX. If you add this property, it also means that you - will enable the DMA support for the auart. - Note: due to the hardware bug in imx23(see errata : 2836), - only the imx28 can enable the DMA support for the auart. +- dmas: DMA specifier, consisting of a phandle to DMA controller node + and AUART DMA channel ID. + Refer to dma.txt and fsl-mxs-dma.txt for details. +- dma-names: "rx" for RX channel, "tx" for TX channel. Example: auart0: serial@8006a000 { compatible = "fsl,imx28-auart", "fsl,imx23-auart"; reg = <0x8006a000 0x2000>; - interrupts = <112 70 71>; - fsl,auart-dma-channel = <8 9>; + interrupts = <112>; + dmas = <&dma_apbx 8>, <&dma_apbx 9>; + dma-names = "rx", "tx"; }; Note: Each auart port should have an alias correctly numbered in "aliases" diff --git a/trunk/Documentation/devicetree/bindings/usb/exynos-usb.txt b/trunk/Documentation/devicetree/bindings/usb/exynos-usb.txt new file mode 100644 index 000000000000..b3abde736017 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/usb/exynos-usb.txt @@ -0,0 +1,50 @@ +Samsung Exynos SoC USB controller + +The USB devices interface with USB controllers on Exynos SOCs. +The device node has following properties. + +EHCI +Required properties: + - compatible: should be "samsung,exynos4210-ehci" for USB 2.0 + EHCI controller in host mode. + - reg: physical base address of the controller and length of memory mapped + region. + - interrupts: interrupt number to the cpu. + - clocks: from common clock binding: handle to usb clock. + - clock-names: from common clock binding: Shall be "usbhost". + +Optional properties: + - samsung,vbus-gpio: if present, specifies the GPIO that + needs to be pulled up for the bus to be powered. + +Example: + + usb@12110000 { + compatible = "samsung,exynos4210-ehci"; + reg = <0x12110000 0x100>; + interrupts = <0 71 0>; + samsung,vbus-gpio = <&gpx2 6 1 3 3>; + + clocks = <&clock 285>; + clock-names = "usbhost"; + }; + +OHCI +Required properties: + - compatible: should be "samsung,exynos4210-ohci" for USB 2.0 + OHCI companion controller in host mode. + - reg: physical base address of the controller and length of memory mapped + region. + - interrupts: interrupt number to the cpu. + - clocks: from common clock binding: handle to usb clock. + - clock-names: from common clock binding: Shall be "usbhost". + +Example: + usb@12120000 { + compatible = "samsung,exynos4210-ohci"; + reg = <0x12120000 0x100>; + interrupts = <0 71 0>; + + clocks = <&clock 285>; + clock-names = "usbhost"; + }; diff --git a/trunk/Documentation/devicetree/bindings/usb/omap-usb.txt b/trunk/Documentation/devicetree/bindings/usb/omap-usb.txt index 662f0f1d2315..d4769f343d6c 100644 --- a/trunk/Documentation/devicetree/bindings/usb/omap-usb.txt +++ b/trunk/Documentation/devicetree/bindings/usb/omap-usb.txt @@ -18,6 +18,7 @@ OMAP MUSB GLUE represents PERIPHERAL. - power : Should be "50". This signifies the controller can supply upto 100mA when operating in host mode. + - usb-phy : the phandle for the PHY device Optional properties: - ctrl-module : phandle of the control module this glue uses to write to diff --git a/trunk/Documentation/devicetree/bindings/vendor-prefixes.txt b/trunk/Documentation/devicetree/bindings/vendor-prefixes.txt index 4d1919bf2332..6931c4348d24 100644 --- a/trunk/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/trunk/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -42,6 +42,7 @@ onnn ON Semiconductor Corp. picochip Picochip Ltd powervr PowerVR (deprecated, use img) qcom Qualcomm, Inc. +ralink Mediatek/Ralink Technology Corp. ramtron Ramtron International realtek Realtek Semiconductor Corp. renesas Renesas Electronics Corporation diff --git a/trunk/Documentation/devicetree/bindings/video/samsung-fimd.txt b/trunk/Documentation/devicetree/bindings/video/samsung-fimd.txt new file mode 100644 index 000000000000..778838a0336a --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/video/samsung-fimd.txt @@ -0,0 +1,65 @@ +Device-Tree bindings for Samsung SoC display controller (FIMD) + +FIMD (Fully Interactive Mobile Display) is the Display Controller for the +Samsung series of SoCs which transfers the image data from a video memory +buffer to an external LCD interface. + +Required properties: +- compatible: value should be one of the following + "samsung,s3c2443-fimd"; /* for S3C24XX SoCs */ + "samsung,s3c6400-fimd"; /* for S3C64XX SoCs */ + "samsung,s5p6440-fimd"; /* for S5P64X0 SoCs */ + "samsung,s5pc100-fimd"; /* for S5PC100 SoC */ + "samsung,s5pv210-fimd"; /* for S5PV210 SoC */ + "samsung,exynos4210-fimd"; /* for Exynos4 SoCs */ + "samsung,exynos5250-fimd"; /* for Exynos5 SoCs */ + +- reg: physical base address and length of the FIMD registers set. + +- interrupt-parent: should be the phandle of the fimd controller's + parent interrupt controller. + +- interrupts: should contain a list of all FIMD IP block interrupts in the + order: FIFO Level, VSYNC, LCD_SYSTEM. The interrupt specifier + format depends on the interrupt controller used. + +- interrupt-names: should contain the interrupt names: "fifo", "vsync", + "lcd_sys", in the same order as they were listed in the interrupts + property. + +- pinctrl-0: pin control group to be used for this controller. + +- pinctrl-names: must contain a "default" entry. + +- clocks: must include clock specifiers corresponding to entries in the + clock-names property. + +- clock-names: list of clock names sorted in the same order as the clocks + property. Must contain "sclk_fimd" and "fimd". + +Optional Properties: +- samsung,power-domain: a phandle to FIMD power domain node. + +Example: + +SoC specific DT entry: + + fimd@11c00000 { + compatible = "samsung,exynos4210-fimd"; + interrupt-parent = <&combiner>; + reg = <0x11c00000 0x20000>; + interrupt-names = "fifo", "vsync", "lcd_sys"; + interrupts = <11 0>, <11 1>, <11 2>; + clocks = <&clock 140>, <&clock 283>; + clock-names = "sclk_fimd", "fimd"; + samsung,power-domain = <&pd_lcd0>; + status = "disabled"; + }; + +Board specific DT entry: + + fimd@11c00000 { + pinctrl-0 = <&lcd_clk &lcd_data24 &pwm1_out>; + pinctrl-names = "default"; + status = "okay"; + }; diff --git a/trunk/Documentation/dmatest.txt b/trunk/Documentation/dmatest.txt new file mode 100644 index 000000000000..279ac0a8c5b1 --- /dev/null +++ b/trunk/Documentation/dmatest.txt @@ -0,0 +1,81 @@ + DMA Test Guide + ============== + + Andy Shevchenko + +This small document introduces how to test DMA drivers using dmatest module. + + Part 1 - How to build the test module + +The menuconfig contains an option that could be found by following path: + Device Drivers -> DMA Engine support -> DMA Test client + +In the configuration file the option called CONFIG_DMATEST. The dmatest could +be built as module or inside kernel. Let's consider those cases. + + Part 2 - When dmatest is built as a module... + +After mounting debugfs and loading the module, the /sys/kernel/debug/dmatest +folder with nodes will be created. They are the same as module parameters with +addition of the 'run' node that controls run and stop phases of the test. + +Note that in this case test will not run on load automatically. + +Example of usage: + % echo dma0chan0 > /sys/kernel/debug/dmatest/channel + % echo 2000 > /sys/kernel/debug/dmatest/timeout + % echo 1 > /sys/kernel/debug/dmatest/iterations + % echo 1 > /sys/kernel/debug/dmatest/run + +Hint: available channel list could be extracted by running the following +command: + % ls -1 /sys/class/dma/ + +After a while you will start to get messages about current status or error like +in the original code. + +Note that running a new test will stop any in progress test. + +The following command should return actual state of the test. + % cat /sys/kernel/debug/dmatest/run + +To wait for test done the user may perform a busy loop that checks the state. + + % while [ $(cat /sys/kernel/debug/dmatest/run) = "Y" ] + > do + > echo -n "." + > sleep 1 + > done + > echo + + Part 3 - When built-in in the kernel... + +The module parameters that is supplied to the kernel command line will be used +for the first performed test. After user gets a control, the test could be +interrupted or re-run with same or different parameters. For the details see +the above section "Part 2 - When dmatest is built as a module..." + +In both cases the module parameters are used as initial values for the test case. +You always could check them at run-time by running + % grep -H . /sys/module/dmatest/parameters/* + + Part 4 - Gathering the test results + +The module provides a storage for the test results in the memory. The gathered +data could be used after test is done. + +The special file 'results' in the debugfs represents gathered data of the in +progress test. The messages collected are printed to the kernel log as well. + +Example of output: + % cat /sys/kernel/debug/dmatest/results + dma0chan0-copy0: #1: No errors with src_off=0x7bf dst_off=0x8ad len=0x3fea (0) + +The message format is unified across the different types of errors. A number in +the parens represents additional information, e.g. error code, error counter, +or status. + +Comparison between buffers is stored to the dedicated structure. + +Note that the verify result is now accessible only via file 'results' in the +debugfs. diff --git a/trunk/Documentation/filesystems/btrfs.txt b/trunk/Documentation/filesystems/btrfs.txt index 7671352216f1..b349d57b76ea 100644 --- a/trunk/Documentation/filesystems/btrfs.txt +++ b/trunk/Documentation/filesystems/btrfs.txt @@ -1,8 +1,8 @@ - BTRFS - ===== +BTRFS +===== -Btrfs is a new copy on write filesystem for Linux aimed at +Btrfs is a copy on write filesystem for Linux aimed at implementing advanced features while focusing on fault tolerance, repair and easy administration. Initially developed by Oracle, Btrfs is licensed under the GPL and open for contribution from anyone. @@ -34,9 +34,175 @@ The main Btrfs features include: * Online filesystem defragmentation +Mount Options +============= - MAILING LIST - ============ +When mounting a btrfs filesystem, the following option are accepted. +Unless otherwise specified, all options default to off. + + alloc_start= + Debugging option to force all block allocations above a certain + byte threshold on each block device. The value is specified in + bytes, optionally with a K, M, or G suffix, case insensitive. + Default is 1MB. + + autodefrag + Detect small random writes into files and queue them up for the + defrag process. Works best for small files; Not well suited for + large database workloads. + + check_int + check_int_data + check_int_print_mask= + These debugging options control the behavior of the integrity checking + module (the BTRFS_FS_CHECK_INTEGRITY config option required). + + check_int enables the integrity checker module, which examines all + block write requests to ensure on-disk consistency, at a large + memory and CPU cost. + + check_int_data includes extent data in the integrity checks, and + implies the check_int option. + + check_int_print_mask takes a bitmask of BTRFSIC_PRINT_MASK_* values + as defined in fs/btrfs/check-integrity.c, to control the integrity + checker module behavior. + + See comments at the top of fs/btrfs/check-integrity.c for more info. + + compress + compress= + compress-force + compress-force= + Control BTRFS file data compression. Type may be specified as "zlib" + "lzo" or "no" (for no compression, used for remounting). If no type + is specified, zlib is used. If compress-force is specified, + all files will be compressed, whether or not they compress well. + If compression is enabled, nodatacow and nodatasum are disabled. + + degraded + Allow mounts to continue with missing devices. A read-write mount may + fail with too many devices missing, for example if a stripe member + is completely missing. + + device= + Specify a device during mount so that ioctls on the control device + can be avoided. Especialy useful when trying to mount a multi-device + setup as root. May be specified multiple times for multiple devices. + + discard + Issue frequent commands to let the block device reclaim space freed by + the filesystem. This is useful for SSD devices, thinly provisioned + LUNs and virtual machine images, but may have a significant + performance impact. (The fstrim command is also available to + initiate batch trims from userspace). + + enospc_debug + Debugging option to be more verbose in some ENOSPC conditions. + + fatal_errors= + Action to take when encountering a fatal error: + "bug" - BUG() on a fatal error. This is the default. + "panic" - panic() on a fatal error. + + flushoncommit + The 'flushoncommit' mount option forces any data dirtied by a write in a + prior transaction to commit as part of the current commit. This makes + the committed state a fully consistent view of the file system from the + application's perspective (i.e., it includes all completed file system + operations). This was previously the behavior only when a snapshot is + created. + + inode_cache + Enable free inode number caching. Defaults to off due to an overflow + problem when the free space crcs don't fit inside a single page. + + max_inline= + Specify the maximum amount of space, in bytes, that can be inlined in + a metadata B-tree leaf. The value is specified in bytes, optionally + with a K, M, or G suffix, case insensitive. In practice, this value + is limited by the root sector size, with some space unavailable due + to leaf headers. For a 4k sectorsize, max inline data is ~3900 bytes. + + metadata_ratio= + Specify that 1 metadata chunk should be allocated after every + data chunks. Off by default. + + noacl + Disable support for Posix Access Control Lists (ACLs). See the + acl(5) manual page for more information about ACLs. + + nobarrier + Disables the use of block layer write barriers. Write barriers ensure + that certain IOs make it through the device cache and are on persistent + storage. If used on a device with a volatile (non-battery-backed) + write-back cache, this option will lead to filesystem corruption on a + system crash or power loss. + + nodatacow + Disable data copy-on-write for newly created files. Implies nodatasum, + and disables all compression. + + nodatasum + Disable data checksumming for newly created files. + + notreelog + Disable the tree logging used for fsync and O_SYNC writes. + + recovery + Enable autorecovery attempts if a bad tree root is found at mount time. + Currently this scans a list of several previous tree roots and tries to + use the first readable. + + skip_balance + Skip automatic resume of interrupted balance operation after mount. + May be resumed with "btrfs balance resume." + + space_cache (*) + Enable the on-disk freespace cache. + nospace_cache + Disable freespace cache loading without clearing the cache. + clear_cache + Force clearing and rebuilding of the disk space cache if something + has gone wrong. + + ssd + nossd + ssd_spread + Options to control ssd allocation schemes. By default, BTRFS will + enable or disable ssd allocation heuristics depending on whether a + rotational or nonrotational disk is in use. The ssd and nossd options + can override this autodetection. + + The ssd_spread mount option attempts to allocate into big chunks + of unused space, and may perform better on low-end ssds. ssd_spread + implies ssd, enabling all other ssd heuristics as well. + + subvol= + Mount subvolume at rather than the root subvolume. is + relative to the top level subvolume. + + subvolid= + Mount subvolume specified by an ID number rather than the root subvolume. + This allows mounting of subvolumes which are not in the root of the mounted + filesystem. + You can use "btrfs subvolume list" to see subvolume ID numbers. + + subvolrootid= (deprecated) + Mount subvolume specified by rather than the root subvolume. + This allows mounting of subvolumes which are not in the root of the mounted + filesystem. + You can use "btrfs subvolume show " to see the object ID for a subvolume. + + thread_pool= + The number of worker threads to allocate. The default number is equal + to the number of CPUs + 2, or 8, whichever is smaller. + + user_subvol_rm_allowed + Allow subvolumes to be deleted by a non-root user. Use with caution. + +MAILING LIST +============ There is a Btrfs mailing list hosted on vger.kernel.org. You can find details on how to subscribe here: @@ -49,8 +215,8 @@ http://dir.gmane.org/gmane.comp.file-systems.btrfs - IRC - === +IRC +=== Discussion of Btrfs also occurs on the #btrfs channel of the Freenode IRC network. diff --git a/trunk/Documentation/filesystems/f2fs.txt b/trunk/Documentation/filesystems/f2fs.txt index dcf338e62b71..bd3c56c67380 100644 --- a/trunk/Documentation/filesystems/f2fs.txt +++ b/trunk/Documentation/filesystems/f2fs.txt @@ -146,7 +146,7 @@ USAGE Format options -------------- --l [label] : Give a volume label, up to 256 unicode name. +-l [label] : Give a volume label, up to 512 unicode name. -a [0 or 1] : Split start location of each area for heap-based allocation. 1 is set by default, which performs this. -o [int] : Set overprovision ratio in percent over volume size. @@ -156,6 +156,8 @@ Format options -z [int] : Set the number of sections per zone. 1 is set by default. -e [str] : Set basic extension list. e.g. "mp3,gif,mov" +-t [0 or 1] : Disable discard command or not. + 1 is set by default, which conducts discard. ================================================================================ DESIGN diff --git a/trunk/Documentation/filesystems/nfs/00-INDEX b/trunk/Documentation/filesystems/nfs/00-INDEX index 1716874a651e..66eb6c8c5334 100644 --- a/trunk/Documentation/filesystems/nfs/00-INDEX +++ b/trunk/Documentation/filesystems/nfs/00-INDEX @@ -20,3 +20,5 @@ rpc-cache.txt - introduction to the caching mechanisms in the sunrpc layer. idmapper.txt - information for configuring request-keys to be used by idmapper +knfsd-rpcgss.txt + - Information on GSS authentication support in the NFS Server diff --git a/trunk/Documentation/filesystems/nfs/rpc-server-gss.txt b/trunk/Documentation/filesystems/nfs/rpc-server-gss.txt new file mode 100644 index 000000000000..716f4be8e8b3 --- /dev/null +++ b/trunk/Documentation/filesystems/nfs/rpc-server-gss.txt @@ -0,0 +1,91 @@ + +rpcsec_gss support for kernel RPC servers +========================================= + +This document gives references to the standards and protocols used to +implement RPCGSS authentication in kernel RPC servers such as the NFS +server and the NFS client's NFSv4.0 callback server. (But note that +NFSv4.1 and higher don't require the client to act as a server for the +purposes of authentication.) + +RPCGSS is specified in a few IETF documents: + - RFC2203 v1: http://tools.ietf.org/rfc/rfc2203.txt + - RFC5403 v2: http://tools.ietf.org/rfc/rfc5403.txt +and there is a 3rd version being proposed: + - http://tools.ietf.org/id/draft-williams-rpcsecgssv3.txt + (At draft n. 02 at the time of writing) + +Background +---------- + +The RPCGSS Authentication method describes a way to perform GSSAPI +Authentication for NFS. Although GSSAPI is itself completely mechanism +agnostic, in many cases only the KRB5 mechanism is supported by NFS +implementations. + +The Linux kernel, at the moment, supports only the KRB5 mechanism, and +depends on GSSAPI extensions that are KRB5 specific. + +GSSAPI is a complex library, and implementing it completely in kernel is +unwarranted. However GSSAPI operations are fundementally separable in 2 +parts: +- initial context establishment +- integrity/privacy protection (signing and encrypting of individual + packets) + +The former is more complex and policy-independent, but less +performance-sensitive. The latter is simpler and needs to be very fast. + +Therefore, we perform per-packet integrity and privacy protection in the +kernel, but leave the initial context establishment to userspace. We +need upcalls to request userspace to perform context establishment. + +NFS Server Legacy Upcall Mechanism +---------------------------------- + +The classic upcall mechanism uses a custom text based upcall mechanism +to talk to a custom daemon called rpc.svcgssd that is provide by the +nfs-utils package. + +This upcall mechanism has 2 limitations: + +A) It can handle tokens that are no bigger than 2KiB + +In some Kerberos deployment GSSAPI tokens can be quite big, up and +beyond 64KiB in size due to various authorization extensions attacked to +the Kerberos tickets, that needs to be sent through the GSS layer in +order to perform context establishment. + +B) It does not properly handle creds where the user is member of more +than a few housand groups (the current hard limit in the kernel is 65K +groups) due to limitation on the size of the buffer that can be send +back to the kernel (4KiB). + +NFS Server New RPC Upcall Mechanism +----------------------------------- + +The newer upcall mechanism uses RPC over a unix socket to a daemon +called gss-proxy, implemented by a userspace program called Gssproxy. + +The gss_proxy RPC protocol is currently documented here: + + https://fedorahosted.org/gss-proxy/wiki/ProtocolDocumentation + +This upcall mechanism uses the kernel rpc client and connects to the gssproxy +userspace program over a regular unix socket. The gssproxy protocol does not +suffer from the size limitations of the legacy protocol. + +Negotiating Upcall Mechanisms +----------------------------- + +To provide backward compatibility, the kernel defaults to using the +legacy mechanism. To switch to the new mechanism, gss-proxy must bind +to /var/run/gssproxy.sock and then write "1" to +/proc/net/rpc/use-gss-proxy. If gss-proxy dies, it must repeat both +steps. + +Once the upcall mechanism is chosen, it cannot be changed. To prevent +locking into the legacy mechanisms, the above steps must be performed +before starting nfsd. Whoever starts nfsd can guarantee this by reading +from /proc/net/rpc/use-gss-proxy and checking that it contains a +"1"--the read will block until gss-proxy has done its write to the file. diff --git a/trunk/Documentation/filesystems/xfs-self-describing-metadata.txt b/trunk/Documentation/filesystems/xfs-self-describing-metadata.txt new file mode 100644 index 000000000000..05aa455163e3 --- /dev/null +++ b/trunk/Documentation/filesystems/xfs-self-describing-metadata.txt @@ -0,0 +1,350 @@ +XFS Self Describing Metadata +---------------------------- + +Introduction +------------ + +The largest scalability problem facing XFS is not one of algorithmic +scalability, but of verification of the filesystem structure. Scalabilty of the +structures and indexes on disk and the algorithms for iterating them are +adequate for supporting PB scale filesystems with billions of inodes, however it +is this very scalability that causes the verification problem. + +Almost all metadata on XFS is dynamically allocated. The only fixed location +metadata is the allocation group headers (SB, AGF, AGFL and AGI), while all +other metadata structures need to be discovered by walking the filesystem +structure in different ways. While this is already done by userspace tools for +validating and repairing the structure, there are limits to what they can +verify, and this in turn limits the supportable size of an XFS filesystem. + +For example, it is entirely possible to manually use xfs_db and a bit of +scripting to analyse the structure of a 100TB filesystem when trying to +determine the root cause of a corruption problem, but it is still mainly a +manual task of verifying that things like single bit errors or misplaced writes +weren't the ultimate cause of a corruption event. It may take a few hours to a +few days to perform such forensic analysis, so for at this scale root cause +analysis is entirely possible. + +However, if we scale the filesystem up to 1PB, we now have 10x as much metadata +to analyse and so that analysis blows out towards weeks/months of forensic work. +Most of the analysis work is slow and tedious, so as the amount of analysis goes +up, the more likely that the cause will be lost in the noise. Hence the primary +concern for supporting PB scale filesystems is minimising the time and effort +required for basic forensic analysis of the filesystem structure. + + +Self Describing Metadata +------------------------ + +One of the problems with the current metadata format is that apart from the +magic number in the metadata block, we have no other way of identifying what it +is supposed to be. We can't even identify if it is the right place. Put simply, +you can't look at a single metadata block in isolation and say "yes, it is +supposed to be there and the contents are valid". + +Hence most of the time spent on forensic analysis is spent doing basic +verification of metadata values, looking for values that are in range (and hence +not detected by automated verification checks) but are not correct. Finding and +understanding how things like cross linked block lists (e.g. sibling +pointers in a btree end up with loops in them) are the key to understanding what +went wrong, but it is impossible to tell what order the blocks were linked into +each other or written to disk after the fact. + +Hence we need to record more information into the metadata to allow us to +quickly determine if the metadata is intact and can be ignored for the purpose +of analysis. We can't protect against every possible type of error, but we can +ensure that common types of errors are easily detectable. Hence the concept of +self describing metadata. + +The first, fundamental requirement of self describing metadata is that the +metadata object contains some form of unique identifier in a well known +location. This allows us to identify the expected contents of the block and +hence parse and verify the metadata object. IF we can't independently identify +the type of metadata in the object, then the metadata doesn't describe itself +very well at all! + +Luckily, almost all XFS metadata has magic numbers embedded already - only the +AGFL, remote symlinks and remote attribute blocks do not contain identifying +magic numbers. Hence we can change the on-disk format of all these objects to +add more identifying information and detect this simply by changing the magic +numbers in the metadata objects. That is, if it has the current magic number, +the metadata isn't self identifying. If it contains a new magic number, it is +self identifying and we can do much more expansive automated verification of the +metadata object at runtime, during forensic analysis or repair. + +As a primary concern, self describing metadata needs some form of overall +integrity checking. We cannot trust the metadata if we cannot verify that it has +not been changed as a result of external influences. Hence we need some form of +integrity check, and this is done by adding CRC32c validation to the metadata +block. If we can verify the block contains the metadata it was intended to +contain, a large amount of the manual verification work can be skipped. + +CRC32c was selected as metadata cannot be more than 64k in length in XFS and +hence a 32 bit CRC is more than sufficient to detect multi-bit errors in +metadata blocks. CRC32c is also now hardware accelerated on common CPUs so it is +fast. So while CRC32c is not the strongest of possible integrity checks that +could be used, it is more than sufficient for our needs and has relatively +little overhead. Adding support for larger integrity fields and/or algorithms +does really provide any extra value over CRC32c, but it does add a lot of +complexity and so there is no provision for changing the integrity checking +mechanism. + +Self describing metadata needs to contain enough information so that the +metadata block can be verified as being in the correct place without needing to +look at any other metadata. This means it needs to contain location information. +Just adding a block number to the metadata is not sufficient to protect against +mis-directed writes - a write might be misdirected to the wrong LUN and so be +written to the "correct block" of the wrong filesystem. Hence location +information must contain a filesystem identifier as well as a block number. + +Another key information point in forensic analysis is knowing who the metadata +block belongs to. We already know the type, the location, that it is valid +and/or corrupted, and how long ago that it was last modified. Knowing the owner +of the block is important as it allows us to find other related metadata to +determine the scope of the corruption. For example, if we have a extent btree +object, we don't know what inode it belongs to and hence have to walk the entire +filesystem to find the owner of the block. Worse, the corruption could mean that +no owner can be found (i.e. it's an orphan block), and so without an owner field +in the metadata we have no idea of the scope of the corruption. If we have an +owner field in the metadata object, we can immediately do top down validation to +determine the scope of the problem. + +Different types of metadata have different owner identifiers. For example, +directory, attribute and extent tree blocks are all owned by an inode, whilst +freespace btree blocks are owned by an allocation group. Hence the size and +contents of the owner field are determined by the type of metadata object we are +looking at. The owner information can also identify misplaced writes (e.g. +freespace btree block written to the wrong AG). + +Self describing metadata also needs to contain some indication of when it was +written to the filesystem. One of the key information points when doing forensic +analysis is how recently the block was modified. Correlation of set of corrupted +metadata blocks based on modification times is important as it can indicate +whether the corruptions are related, whether there's been multiple corruption +events that lead to the eventual failure, and even whether there are corruptions +present that the run-time verification is not detecting. + +For example, we can determine whether a metadata object is supposed to be free +space or still allocated if it is still referenced by its owner by looking at +when the free space btree block that contains the block was last written +compared to when the metadata object itself was last written. If the free space +block is more recent than the object and the object's owner, then there is a +very good chance that the block should have been removed from the owner. + +To provide this "written timestamp", each metadata block gets the Log Sequence +Number (LSN) of the most recent transaction it was modified on written into it. +This number will always increase over the life of the filesystem, and the only +thing that resets it is running xfs_repair on the filesystem. Further, by use of +the LSN we can tell if the corrupted metadata all belonged to the same log +checkpoint and hence have some idea of how much modification occurred between +the first and last instance of corrupt metadata on disk and, further, how much +modification occurred between the corruption being written and when it was +detected. + +Runtime Validation +------------------ + +Validation of self-describing metadata takes place at runtime in two places: + + - immediately after a successful read from disk + - immediately prior to write IO submission + +The verification is completely stateless - it is done independently of the +modification process, and seeks only to check that the metadata is what it says +it is and that the metadata fields are within bounds and internally consistent. +As such, we cannot catch all types of corruption that can occur within a block +as there may be certain limitations that operational state enforces of the +metadata, or there may be corruption of interblock relationships (e.g. corrupted +sibling pointer lists). Hence we still need stateful checking in the main code +body, but in general most of the per-field validation is handled by the +verifiers. + +For read verification, the caller needs to specify the expected type of metadata +that it should see, and the IO completion process verifies that the metadata +object matches what was expected. If the verification process fails, then it +marks the object being read as EFSCORRUPTED. The caller needs to catch this +error (same as for IO errors), and if it needs to take special action due to a +verification error it can do so by catching the EFSCORRUPTED error value. If we +need more discrimination of error type at higher levels, we can define new +error numbers for different errors as necessary. + +The first step in read verification is checking the magic number and determining +whether CRC validating is necessary. If it is, the CRC32c is calculated and +compared against the value stored in the object itself. Once this is validated, +further checks are made against the location information, followed by extensive +object specific metadata validation. If any of these checks fail, then the +buffer is considered corrupt and the EFSCORRUPTED error is set appropriately. + +Write verification is the opposite of the read verification - first the object +is extensively verified and if it is OK we then update the LSN from the last +modification made to the object, After this, we calculate the CRC and insert it +into the object. Once this is done the write IO is allowed to continue. If any +error occurs during this process, the buffer is again marked with a EFSCORRUPTED +error for the higher layers to catch. + +Structures +---------- + +A typical on-disk structure needs to contain the following information: + +struct xfs_ondisk_hdr { + __be32 magic; /* magic number */ + __be32 crc; /* CRC, not logged */ + uuid_t uuid; /* filesystem identifier */ + __be64 owner; /* parent object */ + __be64 blkno; /* location on disk */ + __be64 lsn; /* last modification in log, not logged */ +}; + +Depending on the metadata, this information may be part of a header structure +separate to the metadata contents, or may be distributed through an existing +structure. The latter occurs with metadata that already contains some of this +information, such as the superblock and AG headers. + +Other metadata may have different formats for the information, but the same +level of information is generally provided. For example: + + - short btree blocks have a 32 bit owner (ag number) and a 32 bit block + number for location. The two of these combined provide the same + information as @owner and @blkno in eh above structure, but using 8 + bytes less space on disk. + + - directory/attribute node blocks have a 16 bit magic number, and the + header that contains the magic number has other information in it as + well. hence the additional metadata headers change the overall format + of the metadata. + +A typical buffer read verifier is structured as follows: + +#define XFS_FOO_CRC_OFF offsetof(struct xfs_ondisk_hdr, crc) + +static void +xfs_foo_read_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + + if ((xfs_sb_version_hascrc(&mp->m_sb) && + !xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length), + XFS_FOO_CRC_OFF)) || + !xfs_foo_verify(bp)) { + XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr); + xfs_buf_ioerror(bp, EFSCORRUPTED); + } +} + +The code ensures that the CRC is only checked if the filesystem has CRCs enabled +by checking the superblock of the feature bit, and then if the CRC verifies OK +(or is not needed) it verifies the actual contents of the block. + +The verifier function will take a couple of different forms, depending on +whether the magic number can be used to determine the format of the block. In +the case it can't, the code is structured as follows: + +static bool +xfs_foo_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_ondisk_hdr *hdr = bp->b_addr; + + if (hdr->magic != cpu_to_be32(XFS_FOO_MAGIC)) + return false; + + if (!xfs_sb_version_hascrc(&mp->m_sb)) { + if (!uuid_equal(&hdr->uuid, &mp->m_sb.sb_uuid)) + return false; + if (bp->b_bn != be64_to_cpu(hdr->blkno)) + return false; + if (hdr->owner == 0) + return false; + } + + /* object specific verification checks here */ + + return true; +} + +If there are different magic numbers for the different formats, the verifier +will look like: + +static bool +xfs_foo_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_ondisk_hdr *hdr = bp->b_addr; + + if (hdr->magic == cpu_to_be32(XFS_FOO_CRC_MAGIC)) { + if (!uuid_equal(&hdr->uuid, &mp->m_sb.sb_uuid)) + return false; + if (bp->b_bn != be64_to_cpu(hdr->blkno)) + return false; + if (hdr->owner == 0) + return false; + } else if (hdr->magic != cpu_to_be32(XFS_FOO_MAGIC)) + return false; + + /* object specific verification checks here */ + + return true; +} + +Write verifiers are very similar to the read verifiers, they just do things in +the opposite order to the read verifiers. A typical write verifier: + +static void +xfs_foo_write_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_buf_log_item *bip = bp->b_fspriv; + + if (!xfs_foo_verify(bp)) { + XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr); + xfs_buf_ioerror(bp, EFSCORRUPTED); + return; + } + + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return; + + + if (bip) { + struct xfs_ondisk_hdr *hdr = bp->b_addr; + hdr->lsn = cpu_to_be64(bip->bli_item.li_lsn); + } + xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length), XFS_FOO_CRC_OFF); +} + +This will verify the internal structure of the metadata before we go any +further, detecting corruptions that have occurred as the metadata has been +modified in memory. If the metadata verifies OK, and CRCs are enabled, we then +update the LSN field (when it was last modified) and calculate the CRC on the +metadata. Once this is done, we can issue the IO. + +Inodes and Dquots +----------------- + +Inodes and dquots are special snowflakes. They have per-object CRC and +self-identifiers, but they are packed so that there are multiple objects per +buffer. Hence we do not use per-buffer verifiers to do the work of per-object +verification and CRC calculations. The per-buffer verifiers simply perform basic +identification of the buffer - that they contain inodes or dquots, and that +there are magic numbers in all the expected spots. All further CRC and +verification checks are done when each inode is read from or written back to the +buffer. + +The structure of the verifiers and the identifiers checks is very similar to the +buffer code described above. The only difference is where they are called. For +example, inode read verification is done in xfs_iread() when the inode is first +read out of the buffer and the struct xfs_inode is instantiated. The inode is +already extensively verified during writeback in xfs_iflush_int, so the only +addition here is to add the LSN and CRC to the inode as it is copied back into +the buffer. + +XXX: inode unlinked list modification doesn't recalculate the inode CRC! None of +the unlinked list modifications check or update CRCs, neither during unlink nor +log recovery. So, it's gone unnoticed until now. This won't matter immediately - +repair will probably complain about it - but it needs to be fixed. + diff --git a/trunk/Documentation/gpio.txt b/trunk/Documentation/gpio.txt index 77a1d11af723..6f83fa965b4b 100644 --- a/trunk/Documentation/gpio.txt +++ b/trunk/Documentation/gpio.txt @@ -72,11 +72,11 @@ in this document, but drivers acting as clients to the GPIO interface must not care how it's implemented.) That said, if the convention is supported on their platform, drivers should -use it when possible. Platforms must declare GENERIC_GPIO support in their -Kconfig (boolean true), and provide an file. Drivers that can't -work without standard GPIO calls should have Kconfig entries which depend -on GENERIC_GPIO. The GPIO calls are available, either as "real code" or as -optimized-away stubs, when drivers use the include file: +use it when possible. Platforms must select ARCH_REQUIRE_GPIOLIB or +ARCH_WANT_OPTIONAL_GPIOLIB in their Kconfig. Drivers that can't work without +standard GPIO calls should have Kconfig entries which depend on GPIOLIB. The +GPIO calls are available, either as "real code" or as optimized-away stubs, +when drivers use the include file: #include diff --git a/trunk/Documentation/hw_random.txt b/trunk/Documentation/hw_random.txt index 690f52550c80..026e237bbc87 100644 --- a/trunk/Documentation/hw_random.txt +++ b/trunk/Documentation/hw_random.txt @@ -63,7 +63,7 @@ Intel RNG Driver notes: * FIXME: support poll(2) - NOTE: request_mem_region was removed, for two reasons: + NOTE: request_mem_region was removed, for three reasons: 1) Only one RNG is supported by this driver, 2) The location used by the RNG is a fixed location in MMIO-addressable memory, 3) users with properly working BIOS e820 handling will always diff --git a/trunk/Documentation/hwmon/lm75 b/trunk/Documentation/hwmon/lm75 index 69af1c7db6b7..2560a9c6d445 100644 --- a/trunk/Documentation/hwmon/lm75 +++ b/trunk/Documentation/hwmon/lm75 @@ -12,11 +12,11 @@ Supported chips: Addresses scanned: I2C 0x48 - 0x4f Datasheet: Publicly available at the National Semiconductor website http://www.national.com/ - * Dallas Semiconductor DS75, DS1775 - Prefixes: 'ds75', 'ds1775' + * Dallas Semiconductor (now Maxim) DS75, DS1775, DS7505 + Prefixes: 'ds75', 'ds1775', 'ds7505' Addresses scanned: none - Datasheet: Publicly available at the Dallas Semiconductor website - http://www.maxim-ic.com/ + Datasheet: Publicly available at the Maxim website + http://www.maximintegrated.com/ * Maxim MAX6625, MAX6626 Prefixes: 'max6625', 'max6626' Addresses scanned: none @@ -67,7 +67,8 @@ the temperature falls below the Hysteresis value. All temperatures are in degrees Celsius, and are guaranteed within a range of -55 to +125 degrees. -The LM75 only updates its values each 1.5 seconds; reading it more often +The driver caches the values for a period varying between 1 second for the +slowest chips and 125 ms for the fastest chips; reading it more often will do no harm, but will return 'old' values. The original LM75 was typically used in combination with LM78-like chips @@ -78,8 +79,8 @@ The LM75 is essentially an industry standard; there may be other LM75 clones not listed here, with or without various enhancements, that are supported. The clones are not detected by the driver, unless they reproduce the exact register tricks of the original LM75, and must -therefore be instantiated explicitly. The specific enhancements (such as -higher resolution) are not currently supported by the driver. +therefore be instantiated explicitly. Higher resolution up to 12-bit +is supported by this driver, other specific enhancements are not. The LM77 is not supported, contrary to what we pretended for a long time. Both chips are simply not compatible, value encoding differs. diff --git a/trunk/Documentation/kbuild/kconfig.txt b/trunk/Documentation/kbuild/kconfig.txt index b8b77bbc784f..3f429ed8b3b8 100644 --- a/trunk/Documentation/kbuild/kconfig.txt +++ b/trunk/Documentation/kbuild/kconfig.txt @@ -89,6 +89,42 @@ These examples will disable most options (allnoconfig) but enable or disable the options that are explicitly listed in the specified mini-config files. +______________________________________________________________________ +Environment variables for 'randconfig' + +KCONFIG_SEED +-------------------------------------------------- +You can set this to the integer value used to seed the RNG, if you want +to somehow debug the behaviour of the kconfig parser/frontends. +If not set, the current time will be used. + +KCONFIG_PROBABILITY +-------------------------------------------------- +This variable can be used to skew the probabilities. This variable can +be unset or empty, or set to three different formats: + KCONFIG_PROBABILITY y:n split y:m:n split + ----------------------------------------------------------------- + unset or empty 50 : 50 33 : 33 : 34 + N N : 100-N N/2 : N/2 : 100-N + [1] N:M N+M : 100-(N+M) N : M : 100-(N+M) + [2] N:M:L N : 100-N M : L : 100-(M+L) + +where N, M and L are integers (in base 10) in the range [0,100], and so +that: + [1] N+M is in the range [0,100] + [2] M+L is in the range [0,100] + +Examples: + KCONFIG_PROBABILITY=10 + 10% of booleans will be set to 'y', 90% to 'n' + 5% of tristates will be set to 'y', 5% to 'm', 90% to 'n' + KCONFIG_PROBABILITY=15:25 + 40% of booleans will be set to 'y', 60% to 'n' + 15% of tristates will be set to 'y', 25% to 'm', 60% to 'n' + KCONFIG_PROBABILITY=10:15:15 + 10% of booleans will be set to 'y', 90% to 'n' + 15% of tristates will be set to 'y', 15% to 'm', 70% to 'n' + ______________________________________________________________________ Environment variables for 'silentoldconfig' diff --git a/trunk/Documentation/kbuild/makefiles.txt b/trunk/Documentation/kbuild/makefiles.txt index 5198b742fde1..d567a7cc552b 100644 --- a/trunk/Documentation/kbuild/makefiles.txt +++ b/trunk/Documentation/kbuild/makefiles.txt @@ -593,7 +593,7 @@ more details, with real examples. Example: #Makefile - LDFLAGS_vmlinux += $(call really-ld-option, -X) + LDFLAGS_vmlinux += $(call ld-option, -X) === 4 Host Program support @@ -921,8 +921,9 @@ When kbuild executes, the following steps are followed (roughly): Often, the KBUILD_CFLAGS variable depends on the configuration. Example: - #arch/x86/Makefile - cflags-$(CONFIG_M386) += -march=i386 + #arch/x86/boot/compressed/Makefile + cflags-$(CONFIG_X86_32) := -march=i386 + cflags-$(CONFIG_X86_64) := -mcmodel=small KBUILD_CFLAGS += $(cflags-y) Many arch Makefiles dynamically run the target C compiler to diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index 9653cf2f9727..c3bfacb92910 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -1277,6 +1277,20 @@ bytes respectively. Such letter suffixes can also be entirely omitted. iucv= [HW,NET] + ivrs_ioapic [HW,X86_64] + Provide an override to the IOAPIC-ID<->DEVICE-ID + mapping provided in the IVRS ACPI table. For + example, to map IOAPIC-ID decimal 10 to + PCI device 00:14.0 write the parameter as: + ivrs_ioapic[10]=00:14.0 + + ivrs_hpet [HW,X86_64] + Provide an override to the HPET-ID<->DEVICE-ID + mapping provided in the IVRS ACPI table. For + example, to map HPET-ID decimal 0 to + PCI device 00:14.0 write the parameter as: + ivrs_hpet[0]=00:14.0 + js= [HW,JOY] Analog joystick See Documentation/input/joystick.txt. @@ -1964,6 +1978,14 @@ bytes respectively. Such letter suffixes can also be entirely omitted. Valid arguments: on, off Default: on + nohz_full= [KNL,BOOT] + In kernels built with CONFIG_NO_HZ_FULL=y, set + the specified list of CPUs whose tick will be stopped + whenever possible. The boot CPU will be forced outside + the range to maintain the timekeeping. + The CPUs in this range must also be included in the + rcu_nocbs= set. + noiotrap [SH] Disables trapped I/O port accesses. noirqdebug [X86-32] Disables the code which attempts to detect and diff --git a/trunk/Documentation/kernel-per-CPU-kthreads.txt b/trunk/Documentation/kernel-per-CPU-kthreads.txt new file mode 100644 index 000000000000..cbf7ae412da4 --- /dev/null +++ b/trunk/Documentation/kernel-per-CPU-kthreads.txt @@ -0,0 +1,202 @@ +REDUCING OS JITTER DUE TO PER-CPU KTHREADS + +This document lists per-CPU kthreads in the Linux kernel and presents +options to control their OS jitter. Note that non-per-CPU kthreads are +not listed here. To reduce OS jitter from non-per-CPU kthreads, bind +them to a "housekeeping" CPU dedicated to such work. + + +REFERENCES + +o Documentation/IRQ-affinity.txt: Binding interrupts to sets of CPUs. + +o Documentation/cgroups: Using cgroups to bind tasks to sets of CPUs. + +o man taskset: Using the taskset command to bind tasks to sets + of CPUs. + +o man sched_setaffinity: Using the sched_setaffinity() system + call to bind tasks to sets of CPUs. + +o /sys/devices/system/cpu/cpuN/online: Control CPU N's hotplug state, + writing "0" to offline and "1" to online. + +o In order to locate kernel-generated OS jitter on CPU N: + + cd /sys/kernel/debug/tracing + echo 1 > max_graph_depth # Increase the "1" for more detail + echo function_graph > current_tracer + # run workload + cat per_cpu/cpuN/trace + + +KTHREADS + +Name: ehca_comp/%u +Purpose: Periodically process Infiniband-related work. +To reduce its OS jitter, do any of the following: +1. Don't use eHCA Infiniband hardware, instead choosing hardware + that does not require per-CPU kthreads. This will prevent these + kthreads from being created in the first place. (This will + work for most people, as this hardware, though important, is + relatively old and is produced in relatively low unit volumes.) +2. Do all eHCA-Infiniband-related work on other CPUs, including + interrupts. +3. Rework the eHCA driver so that its per-CPU kthreads are + provisioned only on selected CPUs. + + +Name: irq/%d-%s +Purpose: Handle threaded interrupts. +To reduce its OS jitter, do the following: +1. Use irq affinity to force the irq threads to execute on + some other CPU. + +Name: kcmtpd_ctr_%d +Purpose: Handle Bluetooth work. +To reduce its OS jitter, do one of the following: +1. Don't use Bluetooth, in which case these kthreads won't be + created in the first place. +2. Use irq affinity to force Bluetooth-related interrupts to + occur on some other CPU and furthermore initiate all + Bluetooth activity on some other CPU. + +Name: ksoftirqd/%u +Purpose: Execute softirq handlers when threaded or when under heavy load. +To reduce its OS jitter, each softirq vector must be handled +separately as follows: +TIMER_SOFTIRQ: Do all of the following: +1. To the extent possible, keep the CPU out of the kernel when it + is non-idle, for example, by avoiding system calls and by forcing + both kernel threads and interrupts to execute elsewhere. +2. Build with CONFIG_HOTPLUG_CPU=y. After boot completes, force + the CPU offline, then bring it back online. This forces + recurring timers to migrate elsewhere. If you are concerned + with multiple CPUs, force them all offline before bringing the + first one back online. Once you have onlined the CPUs in question, + do not offline any other CPUs, because doing so could force the + timer back onto one of the CPUs in question. +NET_TX_SOFTIRQ and NET_RX_SOFTIRQ: Do all of the following: +1. Force networking interrupts onto other CPUs. +2. Initiate any network I/O on other CPUs. +3. Once your application has started, prevent CPU-hotplug operations + from being initiated from tasks that might run on the CPU to + be de-jittered. (It is OK to force this CPU offline and then + bring it back online before you start your application.) +BLOCK_SOFTIRQ: Do all of the following: +1. Force block-device interrupts onto some other CPU. +2. Initiate any block I/O on other CPUs. +3. Once your application has started, prevent CPU-hotplug operations + from being initiated from tasks that might run on the CPU to + be de-jittered. (It is OK to force this CPU offline and then + bring it back online before you start your application.) +BLOCK_IOPOLL_SOFTIRQ: Do all of the following: +1. Force block-device interrupts onto some other CPU. +2. Initiate any block I/O and block-I/O polling on other CPUs. +3. Once your application has started, prevent CPU-hotplug operations + from being initiated from tasks that might run on the CPU to + be de-jittered. (It is OK to force this CPU offline and then + bring it back online before you start your application.) +TASKLET_SOFTIRQ: Do one or more of the following: +1. Avoid use of drivers that use tasklets. (Such drivers will contain + calls to things like tasklet_schedule().) +2. Convert all drivers that you must use from tasklets to workqueues. +3. Force interrupts for drivers using tasklets onto other CPUs, + and also do I/O involving these drivers on other CPUs. +SCHED_SOFTIRQ: Do all of the following: +1. Avoid sending scheduler IPIs to the CPU to be de-jittered, + for example, ensure that at most one runnable kthread is present + on that CPU. If a thread that expects to run on the de-jittered + CPU awakens, the scheduler will send an IPI that can result in + a subsequent SCHED_SOFTIRQ. +2. Build with CONFIG_RCU_NOCB_CPU=y, CONFIG_RCU_NOCB_CPU_ALL=y, + CONFIG_NO_HZ_FULL=y, and, in addition, ensure that the CPU + to be de-jittered is marked as an adaptive-ticks CPU using the + "nohz_full=" boot parameter. This reduces the number of + scheduler-clock interrupts that the de-jittered CPU receives, + minimizing its chances of being selected to do the load balancing + work that runs in SCHED_SOFTIRQ context. +3. To the extent possible, keep the CPU out of the kernel when it + is non-idle, for example, by avoiding system calls and by + forcing both kernel threads and interrupts to execute elsewhere. + This further reduces the number of scheduler-clock interrupts + received by the de-jittered CPU. +HRTIMER_SOFTIRQ: Do all of the following: +1. To the extent possible, keep the CPU out of the kernel when it + is non-idle. For example, avoid system calls and force both + kernel threads and interrupts to execute elsewhere. +2. Build with CONFIG_HOTPLUG_CPU=y. Once boot completes, force the + CPU offline, then bring it back online. This forces recurring + timers to migrate elsewhere. If you are concerned with multiple + CPUs, force them all offline before bringing the first one + back online. Once you have onlined the CPUs in question, do not + offline any other CPUs, because doing so could force the timer + back onto one of the CPUs in question. +RCU_SOFTIRQ: Do at least one of the following: +1. Offload callbacks and keep the CPU in either dyntick-idle or + adaptive-ticks state by doing all of the following: + a. Build with CONFIG_RCU_NOCB_CPU=y, CONFIG_RCU_NOCB_CPU_ALL=y, + CONFIG_NO_HZ_FULL=y, and, in addition ensure that the CPU + to be de-jittered is marked as an adaptive-ticks CPU using + the "nohz_full=" boot parameter. Bind the rcuo kthreads + to housekeeping CPUs, which can tolerate OS jitter. + b. To the extent possible, keep the CPU out of the kernel + when it is non-idle, for example, by avoiding system + calls and by forcing both kernel threads and interrupts + to execute elsewhere. +2. Enable RCU to do its processing remotely via dyntick-idle by + doing all of the following: + a. Build with CONFIG_NO_HZ=y and CONFIG_RCU_FAST_NO_HZ=y. + b. Ensure that the CPU goes idle frequently, allowing other + CPUs to detect that it has passed through an RCU quiescent + state. If the kernel is built with CONFIG_NO_HZ_FULL=y, + userspace execution also allows other CPUs to detect that + the CPU in question has passed through a quiescent state. + c. To the extent possible, keep the CPU out of the kernel + when it is non-idle, for example, by avoiding system + calls and by forcing both kernel threads and interrupts + to execute elsewhere. + +Name: rcuc/%u +Purpose: Execute RCU callbacks in CONFIG_RCU_BOOST=y kernels. +To reduce its OS jitter, do at least one of the following: +1. Build the kernel with CONFIG_PREEMPT=n. This prevents these + kthreads from being created in the first place, and also obviates + the need for RCU priority boosting. This approach is feasible + for workloads that do not require high degrees of responsiveness. +2. Build the kernel with CONFIG_RCU_BOOST=n. This prevents these + kthreads from being created in the first place. This approach + is feasible only if your workload never requires RCU priority + boosting, for example, if you ensure frequent idle time on all + CPUs that might execute within the kernel. +3. Build with CONFIG_RCU_NOCB_CPU=y and CONFIG_RCU_NOCB_CPU_ALL=y, + which offloads all RCU callbacks to kthreads that can be moved + off of CPUs susceptible to OS jitter. This approach prevents the + rcuc/%u kthreads from having any work to do, so that they are + never awakened. +4. Ensure that the CPU never enters the kernel, and, in particular, + avoid initiating any CPU hotplug operations on this CPU. This is + another way of preventing any callbacks from being queued on the + CPU, again preventing the rcuc/%u kthreads from having any work + to do. + +Name: rcuob/%d, rcuop/%d, and rcuos/%d +Purpose: Offload RCU callbacks from the corresponding CPU. +To reduce its OS jitter, do at least one of the following: +1. Use affinity, cgroups, or other mechanism to force these kthreads + to execute on some other CPU. +2. Build with CONFIG_RCU_NOCB_CPUS=n, which will prevent these + kthreads from being created in the first place. However, please + note that this will not eliminate OS jitter, but will instead + shift it to RCU_SOFTIRQ. + +Name: watchdog/%u +Purpose: Detect software lockups on each CPU. +To reduce its OS jitter, do at least one of the following: +1. Build with CONFIG_LOCKUP_DETECTOR=n, which will prevent these + kthreads from being created in the first place. +2. Echo a zero to /proc/sys/kernel/watchdog to disable the + watchdog timer. +3. Echo a large number of /proc/sys/kernel/watchdog_thresh in + order to reduce the frequency of OS jitter due to the watchdog + timer down to a level that is acceptable for your workload. diff --git a/trunk/Documentation/leds/00-INDEX b/trunk/Documentation/leds/00-INDEX index 5246090ef15c..1ecd1596633e 100644 --- a/trunk/Documentation/leds/00-INDEX +++ b/trunk/Documentation/leds/00-INDEX @@ -6,6 +6,8 @@ leds-lp5521.txt - notes on how to use the leds-lp5521 driver. leds-lp5523.txt - notes on how to use the leds-lp5523 driver. +leds-lp5562.txt + - notes on how to use the leds-lp5562 driver. leds-lp55xx.txt - description about lp55xx common driver. leds-lm3556.txt diff --git a/trunk/Documentation/leds/leds-lp5521.txt b/trunk/Documentation/leds/leds-lp5521.txt index 270f57196339..79e4c2e6e5e8 100644 --- a/trunk/Documentation/leds/leds-lp5521.txt +++ b/trunk/Documentation/leds/leds-lp5521.txt @@ -81,22 +81,3 @@ static struct lp55xx_platform_data lp5521_platform_data = { If the current is set to 0 in the platform data, that channel is disabled and it is not visible in the sysfs. - -The 'update_config' : CONFIG register (ADDR 08h) -This value is platform-specific data. -If update_config is not defined, the CONFIG register is set with -'LP5521_PWRSAVE_EN | LP5521_CP_MODE_AUTO | LP5521_R_TO_BATT'. -(Enable auto-powersave, set charge pump to auto, red to battery) - -example of update_config : - -#define LP5521_CONFIGS (LP5521_PWM_HF | LP5521_PWRSAVE_EN | \ - LP5521_CP_MODE_AUTO | LP5521_R_TO_BATT | \ - LP5521_CLK_INT) - -static struct lp55xx_platform_data lp5521_pdata = { - .led_config = lp5521_led_config, - .num_channels = ARRAY_SIZE(lp5521_led_config), - .clock_mode = LP55XX_CLOCK_INT, - .update_config = LP5521_CONFIGS, -}; diff --git a/trunk/Documentation/leds/leds-lp5562.txt b/trunk/Documentation/leds/leds-lp5562.txt new file mode 100644 index 000000000000..5a823ff6b393 --- /dev/null +++ b/trunk/Documentation/leds/leds-lp5562.txt @@ -0,0 +1,120 @@ +Kernel driver for LP5562 +======================== + +* TI LP5562 LED Driver + +Author: Milo(Woogyom) Kim + +Description + + LP5562 can drive up to 4 channels. R/G/B and White. + LEDs can be controlled directly via the led class control interface. + + All four channels can be also controlled using the engine micro programs. + LP5562 has the internal program memory for running various LED patterns. + For the details, please refer to 'firmware' section in leds-lp55xx.txt + +Device attribute: engine_mux + + 3 Engines are allocated in LP5562, but the number of channel is 4. + Therefore each channel should be mapped to the engine number. + Value : RGB or W + + This attribute is used for programming LED data with the firmware interface. + Unlike the LP5521/LP5523/55231, LP5562 has unique feature for the engine mux, + so additional sysfs is required. + + LED Map + Red ... Engine 1 (fixed) + Green ... Engine 2 (fixed) + Blue ... Engine 3 (fixed) + White ... Engine 1 or 2 or 3 (selective) + +How to load the program data using engine_mux + + Before loading the LP5562 program data, engine_mux should be written between + the engine selection and loading the firmware. + Engine mux has two different mode, RGB and W. + RGB is used for loading RGB program data, W is used for W program data. + + For example, run blinking green channel pattern, + echo 2 > /sys/bus/i2c/devices/xxxx/select_engine # 2 is for green channel + echo "RGB" > /sys/bus/i2c/devices/xxxx/engine_mux # engine mux for RGB + echo 1 > /sys/class/firmware/lp5562/loading + echo "4000600040FF6000" > /sys/class/firmware/lp5562/data + echo 0 > /sys/class/firmware/lp5562/loading + echo 1 > /sys/bus/i2c/devices/xxxx/run_engine + + To run a blinking white pattern, + echo 1 or 2 or 3 > /sys/bus/i2c/devices/xxxx/select_engine + echo "W" > /sys/bus/i2c/devices/xxxx/engine_mux + echo 1 > /sys/class/firmware/lp5562/loading + echo "4000600040FF6000" > /sys/class/firmware/lp5562/data + echo 0 > /sys/class/firmware/lp5562/loading + echo 1 > /sys/bus/i2c/devices/xxxx/run_engine + +How to load the predefined patterns + + Please refer to 'leds-lp55xx.txt" + +Setting Current of Each Channel + + Like LP5521 and LP5523/55231, LP5562 provides LED current settings. + The 'led_current' and 'max_current' are used. + +(Example of Platform data) + +To configure the platform specific data, lp55xx_platform_data structure is used. + +static struct lp55xx_led_config lp5562_led_config[] = { + { + .name = "R", + .chan_nr = 0, + .led_current = 20, + .max_current = 40, + }, + { + .name = "G", + .chan_nr = 1, + .led_current = 20, + .max_current = 40, + }, + { + .name = "B", + .chan_nr = 2, + .led_current = 20, + .max_current = 40, + }, + { + .name = "W", + .chan_nr = 3, + .led_current = 20, + .max_current = 40, + }, +}; + +static int lp5562_setup(void) +{ + /* setup HW resources */ +} + +static void lp5562_release(void) +{ + /* Release HW resources */ +} + +static void lp5562_enable(bool state) +{ + /* Control of chip enable signal */ +} + +static struct lp55xx_platform_data lp5562_platform_data = { + .led_config = lp5562_led_config, + .num_channels = ARRAY_SIZE(lp5562_led_config), + .setup_resources = lp5562_setup, + .release_resources = lp5562_release, + .enable = lp5562_enable, +}; + +If the current is set to 0 in the platform data, that channel is +disabled and it is not visible in the sysfs. diff --git a/trunk/Documentation/leds/leds-lp55xx.txt b/trunk/Documentation/leds/leds-lp55xx.txt index ced41868d2d1..eec8fa2ffe4e 100644 --- a/trunk/Documentation/leds/leds-lp55xx.txt +++ b/trunk/Documentation/leds/leds-lp55xx.txt @@ -5,7 +5,7 @@ Authors: Milo(Woogyom) Kim Description ----------- -LP5521, LP5523/55231 have common features as below. +LP5521, LP5523/55231 and LP5562 have common features as below. Register access via the I2C Device initialization/deinitialization @@ -116,3 +116,47 @@ To support this, 'run_engine' and 'firmware_cb' are configurable in each driver. run_engine : Control the selected engine firmware_cb : The callback function after loading the firmware is done. Chip specific commands for loading and updating program memory. + +( Predefined pattern data ) + +Without the firmware interface, LP55xx driver provides another method for +loading a LED pattern. That is 'predefined' pattern. +A predefined pattern is defined in the platform data and load it(or them) +via the sysfs if needed. +To use the predefined pattern concept, 'patterns' and 'num_patterns' should be +configured. + + Example of predefined pattern data: + + /* mode_1: blinking data */ + static const u8 mode_1[] = { + 0x40, 0x00, 0x60, 0x00, 0x40, 0xFF, 0x60, 0x00, + }; + + /* mode_2: always on */ + static const u8 mode_2[] = { 0x40, 0xFF, }; + + struct lp55xx_predef_pattern board_led_patterns[] = { + { + .r = mode_1, + .size_r = ARRAY_SIZE(mode_1), + }, + { + .b = mode_2, + .size_b = ARRAY_SIZE(mode_2), + }, + } + + struct lp55xx_platform_data lp5562_pdata = { + ... + .patterns = board_led_patterns, + .num_patterns = ARRAY_SIZE(board_led_patterns), + }; + +Then, mode_1 and mode_2 can be run via through the sysfs. + + echo 1 > /sys/bus/i2c/devices/xxxx/led_pattern # red blinking LED pattern + echo 2 > /sys/bus/i2c/devices/xxxx/led_pattern # blue LED always on + +To stop running pattern, + echo 0 > /sys/bus/i2c/devices/xxxx/led_pattern diff --git a/trunk/Documentation/mmc/mmc-dev-attrs.txt b/trunk/Documentation/mmc/mmc-dev-attrs.txt index 0d98fac8893b..189bab09255a 100644 --- a/trunk/Documentation/mmc/mmc-dev-attrs.txt +++ b/trunk/Documentation/mmc/mmc-dev-attrs.txt @@ -22,6 +22,7 @@ All attributes are read-only. manfid Manufacturer ID (from CID Register) name Product Name (from CID Register) oemid OEM/Application ID (from CID Register) + prv Product Revision (from CID Register) (SD and MMCv4 only) serial Product Serial Number (from CID Register) erase_size Erase group size preferred_erase_size Preferred erase size diff --git a/trunk/Documentation/s390/CommonIO b/trunk/Documentation/s390/CommonIO index d378cba66456..6e0f63f343b4 100644 --- a/trunk/Documentation/s390/CommonIO +++ b/trunk/Documentation/s390/CommonIO @@ -8,9 +8,9 @@ Command line parameters Enable logging of debug information in case of ccw device timeouts. -* cio_ignore = {all} | - { | } | - {! | !} +* cio_ignore = device[,device[,..]] + + device := {all | [!]ipldev | [!]condev | [!] | [!]-} The given devices will be ignored by the common I/O-layer; no detection and device sensing will be done on any of those devices. The subchannel to @@ -24,8 +24,10 @@ Command line parameters device numbers (0xabcd or abcd, for 2.4 backward compatibility). If you give a device number 0xabcd, it will be interpreted as 0.0.abcd. - You can use the 'all' keyword to ignore all devices. - The '!' operator will cause the I/O-layer to _not_ ignore a device. + You can use the 'all' keyword to ignore all devices. The 'ipldev' and 'condev' + keywords can be used to refer to the CCW based boot device and CCW console + device respectively (these are probably useful only when combined with the '!' + operator). The '!' operator will cause the I/O-layer to _not_ ignore a device. The command line is parsed from left to right. For example, diff --git a/trunk/Documentation/sound/alsa/HD-Audio.txt b/trunk/Documentation/sound/alsa/HD-Audio.txt index d4faa63ff352..c3c912d023cc 100644 --- a/trunk/Documentation/sound/alsa/HD-Audio.txt +++ b/trunk/Documentation/sound/alsa/HD-Audio.txt @@ -461,11 +461,13 @@ The generic parser supports the following hints: the corresponding mixer control, if available - add_stereo_mix_input (bool): add the stereo mix (analog-loopback mix) to the input mux if available -- add_out_jack_modes (bool): add "xxx Jack Mode" enum controls to each - output jack for allowing to change the headphone amp capability -- add_in_jack_modes (bool): add "xxx Jack Mode" enum controls to each - input jack for allowing to change the mic bias vref +- add_jack_modes (bool): add "xxx Jack Mode" enum controls to each + I/O jack for allowing to change the headphone amp and mic bias VREF + capabilities - power_down_unused (bool): power down the unused widgets +- add_hp_mic (bool): add the headphone to capture source if possible +- hp_mic_detect (bool): enable/disable the hp/mic shared input for a + single built-in mic case; default true - mixer_nid (int): specifies the widget NID of the analog-loopback mixer diff --git a/trunk/Documentation/thermal/exynos_thermal_emulation b/trunk/Documentation/thermal/exynos_thermal_emulation index b73bbfb697bb..36a3e79c1203 100644 --- a/trunk/Documentation/thermal/exynos_thermal_emulation +++ b/trunk/Documentation/thermal/exynos_thermal_emulation @@ -13,11 +13,11 @@ Thermal emulation mode supports software debug for TMU's operation. User can set manually with software code and TMU will read current temperature from user value not from sensor's value. -Enabling CONFIG_EXYNOS_THERMAL_EMUL option will make this support in available. -When it's enabled, sysfs node will be created under -/sys/bus/platform/devices/'exynos device name'/ with name of 'emulation'. +Enabling CONFIG_THERMAL_EMULATION option will make this support available. +When it's enabled, sysfs node will be created as +/sys/devices/virtual/thermal/thermal_zone'zone id'/emul_temp. -The sysfs node, 'emulation', will contain value 0 for the initial state. When you input any +The sysfs node, 'emul_node', will contain value 0 for the initial state. When you input any temperature you want to update to sysfs node, it automatically enable emulation mode and current temperature will be changed into it. (Exynos also supports user changable delay time which would be used to delay of diff --git a/trunk/Documentation/thermal/sysfs-api.txt b/trunk/Documentation/thermal/sysfs-api.txt index 6859661c9d31..a71bd5b90fe8 100644 --- a/trunk/Documentation/thermal/sysfs-api.txt +++ b/trunk/Documentation/thermal/sysfs-api.txt @@ -31,15 +31,17 @@ temperature) and throttle appropriate devices. 1. thermal sysfs driver interface functions 1.1 thermal zone device interface -1.1.1 struct thermal_zone_device *thermal_zone_device_register(char *name, +1.1.1 struct thermal_zone_device *thermal_zone_device_register(char *type, int trips, int mask, void *devdata, - struct thermal_zone_device_ops *ops) + struct thermal_zone_device_ops *ops, + const struct thermal_zone_params *tzp, + int passive_delay, int polling_delay)) This interface function adds a new thermal zone device (sensor) to /sys/class/thermal folder as thermal_zone[0-*]. It tries to bind all the thermal cooling devices registered at the same time. - name: the thermal zone name. + type: the thermal zone type. trips: the total number of trip points this thermal zone supports. mask: Bit string: If 'n'th bit is set, then trip point 'n' is writeable. devdata: device private data @@ -57,6 +59,12 @@ temperature) and throttle appropriate devices. will be fired. .set_emul_temp: set the emulation temperature which helps in debugging different threshold temperature points. + tzp: thermal zone platform parameters. + passive_delay: number of milliseconds to wait between polls when + performing passive cooling. + polling_delay: number of milliseconds to wait between polls when checking + whether trip points have been crossed (0 for interrupt driven systems). + 1.1.2 void thermal_zone_device_unregister(struct thermal_zone_device *tz) @@ -265,6 +273,10 @@ emul_temp Unit: millidegree Celsius WO, Optional + WARNING: Be careful while enabling this option on production systems, + because userland can easily disable the thermal policy by simply + flooding this sysfs node with low temperature values. + ***************************** * Cooling device attributes * ***************************** @@ -363,7 +375,7 @@ This function returns the thermal_instance corresponding to a given {thermal_zone, cooling_device, trip_point} combination. Returns NULL if such an instance does not exist. -5.3:notify_thermal_framework: +5.3:thermal_notify_framework: This function handles the trip events from sensor drivers. It starts throttling the cooling devices according to the policy configured. For CRITICAL and HOT trip points, this notifies the respective drivers, @@ -375,11 +387,3 @@ platform data is provided, this uses the step_wise throttling policy. This function serves as an arbitrator to set the state of a cooling device. It sets the cooling device to the deepest cooling state if possible. - -5.5:thermal_register_governor: -This function lets the various thermal governors to register themselves -with the Thermal framework. At run time, depending on a zone's platform -data, a particular governor is used for throttling. - -5.6:thermal_unregister_governor: -This function unregisters a governor from the thermal framework. diff --git a/trunk/Documentation/timers/NO_HZ.txt b/trunk/Documentation/timers/NO_HZ.txt new file mode 100644 index 000000000000..5b5322024067 --- /dev/null +++ b/trunk/Documentation/timers/NO_HZ.txt @@ -0,0 +1,273 @@ + NO_HZ: Reducing Scheduling-Clock Ticks + + +This document describes Kconfig options and boot parameters that can +reduce the number of scheduling-clock interrupts, thereby improving energy +efficiency and reducing OS jitter. Reducing OS jitter is important for +some types of computationally intensive high-performance computing (HPC) +applications and for real-time applications. + +There are two main contexts in which the number of scheduling-clock +interrupts can be reduced compared to the old-school approach of sending +a scheduling-clock interrupt to all CPUs every jiffy whether they need +it or not (CONFIG_HZ_PERIODIC=y or CONFIG_NO_HZ=n for older kernels): + +1. Idle CPUs (CONFIG_NO_HZ_IDLE=y or CONFIG_NO_HZ=y for older kernels). + +2. CPUs having only one runnable task (CONFIG_NO_HZ_FULL=y). + +These two cases are described in the following two sections, followed +by a third section on RCU-specific considerations and a fourth and final +section listing known issues. + + +IDLE CPUs + +If a CPU is idle, there is little point in sending it a scheduling-clock +interrupt. After all, the primary purpose of a scheduling-clock interrupt +is to force a busy CPU to shift its attention among multiple duties, +and an idle CPU has no duties to shift its attention among. + +The CONFIG_NO_HZ_IDLE=y Kconfig option causes the kernel to avoid sending +scheduling-clock interrupts to idle CPUs, which is critically important +both to battery-powered devices and to highly virtualized mainframes. +A battery-powered device running a CONFIG_HZ_PERIODIC=y kernel would +drain its battery very quickly, easily 2-3 times as fast as would the +same device running a CONFIG_NO_HZ_IDLE=y kernel. A mainframe running +1,500 OS instances might find that half of its CPU time was consumed by +unnecessary scheduling-clock interrupts. In these situations, there +is strong motivation to avoid sending scheduling-clock interrupts to +idle CPUs. That said, dyntick-idle mode is not free: + +1. It increases the number of instructions executed on the path + to and from the idle loop. + +2. On many architectures, dyntick-idle mode also increases the + number of expensive clock-reprogramming operations. + +Therefore, systems with aggressive real-time response constraints often +run CONFIG_HZ_PERIODIC=y kernels (or CONFIG_NO_HZ=n for older kernels) +in order to avoid degrading from-idle transition latencies. + +An idle CPU that is not receiving scheduling-clock interrupts is said to +be "dyntick-idle", "in dyntick-idle mode", "in nohz mode", or "running +tickless". The remainder of this document will use "dyntick-idle mode". + +There is also a boot parameter "nohz=" that can be used to disable +dyntick-idle mode in CONFIG_NO_HZ_IDLE=y kernels by specifying "nohz=off". +By default, CONFIG_NO_HZ_IDLE=y kernels boot with "nohz=on", enabling +dyntick-idle mode. + + +CPUs WITH ONLY ONE RUNNABLE TASK + +If a CPU has only one runnable task, there is little point in sending it +a scheduling-clock interrupt because there is no other task to switch to. + +The CONFIG_NO_HZ_FULL=y Kconfig option causes the kernel to avoid +sending scheduling-clock interrupts to CPUs with a single runnable task, +and such CPUs are said to be "adaptive-ticks CPUs". This is important +for applications with aggressive real-time response constraints because +it allows them to improve their worst-case response times by the maximum +duration of a scheduling-clock interrupt. It is also important for +computationally intensive short-iteration workloads: If any CPU is +delayed during a given iteration, all the other CPUs will be forced to +wait idle while the delayed CPU finishes. Thus, the delay is multiplied +by one less than the number of CPUs. In these situations, there is +again strong motivation to avoid sending scheduling-clock interrupts. + +By default, no CPU will be an adaptive-ticks CPU. The "nohz_full=" +boot parameter specifies the adaptive-ticks CPUs. For example, +"nohz_full=1,6-8" says that CPUs 1, 6, 7, and 8 are to be adaptive-ticks +CPUs. Note that you are prohibited from marking all of the CPUs as +adaptive-tick CPUs: At least one non-adaptive-tick CPU must remain +online to handle timekeeping tasks in order to ensure that system calls +like gettimeofday() returns accurate values on adaptive-tick CPUs. +(This is not an issue for CONFIG_NO_HZ_IDLE=y because there are no +running user processes to observe slight drifts in clock rate.) +Therefore, the boot CPU is prohibited from entering adaptive-ticks +mode. Specifying a "nohz_full=" mask that includes the boot CPU will +result in a boot-time error message, and the boot CPU will be removed +from the mask. + +Alternatively, the CONFIG_NO_HZ_FULL_ALL=y Kconfig parameter specifies +that all CPUs other than the boot CPU are adaptive-ticks CPUs. This +Kconfig parameter will be overridden by the "nohz_full=" boot parameter, +so that if both the CONFIG_NO_HZ_FULL_ALL=y Kconfig parameter and +the "nohz_full=1" boot parameter is specified, the boot parameter will +prevail so that only CPU 1 will be an adaptive-ticks CPU. + +Finally, adaptive-ticks CPUs must have their RCU callbacks offloaded. +This is covered in the "RCU IMPLICATIONS" section below. + +Normally, a CPU remains in adaptive-ticks mode as long as possible. +In particular, transitioning to kernel mode does not automatically change +the mode. Instead, the CPU will exit adaptive-ticks mode only if needed, +for example, if that CPU enqueues an RCU callback. + +Just as with dyntick-idle mode, the benefits of adaptive-tick mode do +not come for free: + +1. CONFIG_NO_HZ_FULL selects CONFIG_NO_HZ_COMMON, so you cannot run + adaptive ticks without also running dyntick idle. This dependency + extends down into the implementation, so that all of the costs + of CONFIG_NO_HZ_IDLE are also incurred by CONFIG_NO_HZ_FULL. + +2. The user/kernel transitions are slightly more expensive due + to the need to inform kernel subsystems (such as RCU) about + the change in mode. + +3. POSIX CPU timers on adaptive-tick CPUs may miss their deadlines + (perhaps indefinitely) because they currently rely on + scheduling-tick interrupts. This will likely be fixed in + one of two ways: (1) Prevent CPUs with POSIX CPU timers from + entering adaptive-tick mode, or (2) Use hrtimers or other + adaptive-ticks-immune mechanism to cause the POSIX CPU timer to + fire properly. + +4. If there are more perf events pending than the hardware can + accommodate, they are normally round-robined so as to collect + all of them over time. Adaptive-tick mode may prevent this + round-robining from happening. This will likely be fixed by + preventing CPUs with large numbers of perf events pending from + entering adaptive-tick mode. + +5. Scheduler statistics for adaptive-tick CPUs may be computed + slightly differently than those for non-adaptive-tick CPUs. + This might in turn perturb load-balancing of real-time tasks. + +6. The LB_BIAS scheduler feature is disabled by adaptive ticks. + +Although improvements are expected over time, adaptive ticks is quite +useful for many types of real-time and compute-intensive applications. +However, the drawbacks listed above mean that adaptive ticks should not +(yet) be enabled by default. + + +RCU IMPLICATIONS + +There are situations in which idle CPUs cannot be permitted to +enter either dyntick-idle mode or adaptive-tick mode, the most +common being when that CPU has RCU callbacks pending. + +The CONFIG_RCU_FAST_NO_HZ=y Kconfig option may be used to cause such CPUs +to enter dyntick-idle mode or adaptive-tick mode anyway. In this case, +a timer will awaken these CPUs every four jiffies in order to ensure +that the RCU callbacks are processed in a timely fashion. + +Another approach is to offload RCU callback processing to "rcuo" kthreads +using the CONFIG_RCU_NOCB_CPU=y Kconfig option. The specific CPUs to +offload may be selected via several methods: + +1. One of three mutually exclusive Kconfig options specify a + build-time default for the CPUs to offload: + + a. The CONFIG_RCU_NOCB_CPU_NONE=y Kconfig option results in + no CPUs being offloaded. + + b. The CONFIG_RCU_NOCB_CPU_ZERO=y Kconfig option causes + CPU 0 to be offloaded. + + c. The CONFIG_RCU_NOCB_CPU_ALL=y Kconfig option causes all + CPUs to be offloaded. Note that the callbacks will be + offloaded to "rcuo" kthreads, and that those kthreads + will in fact run on some CPU. However, this approach + gives fine-grained control on exactly which CPUs the + callbacks run on, along with their scheduling priority + (including the default of SCHED_OTHER), and it further + allows this control to be varied dynamically at runtime. + +2. The "rcu_nocbs=" kernel boot parameter, which takes a comma-separated + list of CPUs and CPU ranges, for example, "1,3-5" selects CPUs 1, + 3, 4, and 5. The specified CPUs will be offloaded in addition to + any CPUs specified as offloaded by CONFIG_RCU_NOCB_CPU_ZERO=y or + CONFIG_RCU_NOCB_CPU_ALL=y. This means that the "rcu_nocbs=" boot + parameter has no effect for kernels built with RCU_NOCB_CPU_ALL=y. + +The offloaded CPUs will never queue RCU callbacks, and therefore RCU +never prevents offloaded CPUs from entering either dyntick-idle mode +or adaptive-tick mode. That said, note that it is up to userspace to +pin the "rcuo" kthreads to specific CPUs if desired. Otherwise, the +scheduler will decide where to run them, which might or might not be +where you want them to run. + + +KNOWN ISSUES + +o Dyntick-idle slows transitions to and from idle slightly. + In practice, this has not been a problem except for the most + aggressive real-time workloads, which have the option of disabling + dyntick-idle mode, an option that most of them take. However, + some workloads will no doubt want to use adaptive ticks to + eliminate scheduling-clock interrupt latencies. Here are some + options for these workloads: + + a. Use PMQOS from userspace to inform the kernel of your + latency requirements (preferred). + + b. On x86 systems, use the "idle=mwait" boot parameter. + + c. On x86 systems, use the "intel_idle.max_cstate=" to limit + ` the maximum C-state depth. + + d. On x86 systems, use the "idle=poll" boot parameter. + However, please note that use of this parameter can cause + your CPU to overheat, which may cause thermal throttling + to degrade your latencies -- and that this degradation can + be even worse than that of dyntick-idle. Furthermore, + this parameter effectively disables Turbo Mode on Intel + CPUs, which can significantly reduce maximum performance. + +o Adaptive-ticks slows user/kernel transitions slightly. + This is not expected to be a problem for computationally intensive + workloads, which have few such transitions. Careful benchmarking + will be required to determine whether or not other workloads + are significantly affected by this effect. + +o Adaptive-ticks does not do anything unless there is only one + runnable task for a given CPU, even though there are a number + of other situations where the scheduling-clock tick is not + needed. To give but one example, consider a CPU that has one + runnable high-priority SCHED_FIFO task and an arbitrary number + of low-priority SCHED_OTHER tasks. In this case, the CPU is + required to run the SCHED_FIFO task until it either blocks or + some other higher-priority task awakens on (or is assigned to) + this CPU, so there is no point in sending a scheduling-clock + interrupt to this CPU. However, the current implementation + nevertheless sends scheduling-clock interrupts to CPUs having a + single runnable SCHED_FIFO task and multiple runnable SCHED_OTHER + tasks, even though these interrupts are unnecessary. + + Better handling of these sorts of situations is future work. + +o A reboot is required to reconfigure both adaptive idle and RCU + callback offloading. Runtime reconfiguration could be provided + if needed, however, due to the complexity of reconfiguring RCU at + runtime, there would need to be an earthshakingly good reason. + Especially given that you have the straightforward option of + simply offloading RCU callbacks from all CPUs and pinning them + where you want them whenever you want them pinned. + +o Additional configuration is required to deal with other sources + of OS jitter, including interrupts and system-utility tasks + and processes. This configuration normally involves binding + interrupts and tasks to particular CPUs. + +o Some sources of OS jitter can currently be eliminated only by + constraining the workload. For example, the only way to eliminate + OS jitter due to global TLB shootdowns is to avoid the unmapping + operations (such as kernel module unload operations) that + result in these shootdowns. For another example, page faults + and TLB misses can be reduced (and in some cases eliminated) by + using huge pages and by constraining the amount of memory used + by the application. Pre-faulting the working set can also be + helpful, especially when combined with the mlock() and mlockall() + system calls. + +o Unless all CPUs are idle, at least one CPU must keep the + scheduling-clock interrupt going in order to support accurate + timekeeping. + +o If there are adaptive-ticks CPUs, there will be at least one + CPU keeping the scheduling-clock interrupt going, even if all + CPUs are otherwise idle. diff --git a/trunk/Documentation/virtual/00-INDEX b/trunk/Documentation/virtual/00-INDEX index 924bd462675e..e952d30bbf0f 100644 --- a/trunk/Documentation/virtual/00-INDEX +++ b/trunk/Documentation/virtual/00-INDEX @@ -6,6 +6,3 @@ kvm/ - Kernel Virtual Machine. See also http://linux-kvm.org uml/ - User Mode Linux, builds/runs Linux kernel as a userspace program. -virtio.txt - - Text version of draft virtio spec. - See http://ozlabs.org/~rusty/virtio-spec diff --git a/trunk/Documentation/virtual/kvm/api.txt b/trunk/Documentation/virtual/kvm/api.txt index 119358dfb742..5f91eda91647 100644 --- a/trunk/Documentation/virtual/kvm/api.txt +++ b/trunk/Documentation/virtual/kvm/api.txt @@ -1486,15 +1486,23 @@ struct kvm_ioeventfd { __u8 pad[36]; }; +For the special case of virtio-ccw devices on s390, the ioevent is matched +to a subchannel/virtqueue tuple instead. + The following flags are defined: #define KVM_IOEVENTFD_FLAG_DATAMATCH (1 << kvm_ioeventfd_flag_nr_datamatch) #define KVM_IOEVENTFD_FLAG_PIO (1 << kvm_ioeventfd_flag_nr_pio) #define KVM_IOEVENTFD_FLAG_DEASSIGN (1 << kvm_ioeventfd_flag_nr_deassign) +#define KVM_IOEVENTFD_FLAG_VIRTIO_CCW_NOTIFY \ + (1 << kvm_ioeventfd_flag_nr_virtio_ccw_notify) If datamatch flag is set, the event will be signaled only if the written value to the registered address is equal to datamatch in struct kvm_ioeventfd. +For virtio-ccw devices, addr contains the subchannel id and datamatch the +virtqueue index. + 4.60 KVM_DIRTY_TLB @@ -1780,27 +1788,48 @@ registers, find a list below: PPC | KVM_REG_PPC_VPA_DTL | 128 PPC | KVM_REG_PPC_EPCR | 32 PPC | KVM_REG_PPC_EPR | 32 + PPC | KVM_REG_PPC_TCR | 32 + PPC | KVM_REG_PPC_TSR | 32 + PPC | KVM_REG_PPC_OR_TSR | 32 + PPC | KVM_REG_PPC_CLEAR_TSR | 32 + PPC | KVM_REG_PPC_MAS0 | 32 + PPC | KVM_REG_PPC_MAS1 | 32 + PPC | KVM_REG_PPC_MAS2 | 64 + PPC | KVM_REG_PPC_MAS7_3 | 64 + PPC | KVM_REG_PPC_MAS4 | 32 + PPC | KVM_REG_PPC_MAS6 | 32 + PPC | KVM_REG_PPC_MMUCFG | 32 + PPC | KVM_REG_PPC_TLB0CFG | 32 + PPC | KVM_REG_PPC_TLB1CFG | 32 + PPC | KVM_REG_PPC_TLB2CFG | 32 + PPC | KVM_REG_PPC_TLB3CFG | 32 + PPC | KVM_REG_PPC_TLB0PS | 32 + PPC | KVM_REG_PPC_TLB1PS | 32 + PPC | KVM_REG_PPC_TLB2PS | 32 + PPC | KVM_REG_PPC_TLB3PS | 32 + PPC | KVM_REG_PPC_EPTCFG | 32 + PPC | KVM_REG_PPC_ICP_STATE | 64 ARM registers are mapped using the lower 32 bits. The upper 16 of that is the register group type, or coprocessor number: ARM core registers have the following id bit patterns: - 0x4002 0000 0010 + 0x4020 0000 0010 ARM 32-bit CP15 registers have the following id bit patterns: - 0x4002 0000 000F + 0x4020 0000 000F ARM 64-bit CP15 registers have the following id bit patterns: - 0x4003 0000 000F + 0x4030 0000 000F ARM CCSIDR registers are demultiplexed by CSSELR value: - 0x4002 0000 0011 00 + 0x4020 0000 0011 00 ARM 32-bit VFP control registers have the following id bit patterns: - 0x4002 0000 0012 1 + 0x4020 0000 0012 1 ARM 64-bit FP registers have the following id bit patterns: - 0x4002 0000 0012 0 + 0x4030 0000 0012 0 4.69 KVM_GET_ONE_REG @@ -2161,6 +2190,76 @@ header; first `n_valid' valid entries with contents from the data written, then `n_invalid' invalid entries, invalidating any previously valid entries found. +4.79 KVM_CREATE_DEVICE + +Capability: KVM_CAP_DEVICE_CTRL +Type: vm ioctl +Parameters: struct kvm_create_device (in/out) +Returns: 0 on success, -1 on error +Errors: + ENODEV: The device type is unknown or unsupported + EEXIST: Device already created, and this type of device may not + be instantiated multiple times + + Other error conditions may be defined by individual device types or + have their standard meanings. + +Creates an emulated device in the kernel. The file descriptor returned +in fd can be used with KVM_SET/GET/HAS_DEVICE_ATTR. + +If the KVM_CREATE_DEVICE_TEST flag is set, only test whether the +device type is supported (not necessarily whether it can be created +in the current vm). + +Individual devices should not define flags. Attributes should be used +for specifying any behavior that is not implied by the device type +number. + +struct kvm_create_device { + __u32 type; /* in: KVM_DEV_TYPE_xxx */ + __u32 fd; /* out: device handle */ + __u32 flags; /* in: KVM_CREATE_DEVICE_xxx */ +}; + +4.80 KVM_SET_DEVICE_ATTR/KVM_GET_DEVICE_ATTR + +Capability: KVM_CAP_DEVICE_CTRL +Type: device ioctl +Parameters: struct kvm_device_attr +Returns: 0 on success, -1 on error +Errors: + ENXIO: The group or attribute is unknown/unsupported for this device + EPERM: The attribute cannot (currently) be accessed this way + (e.g. read-only attribute, or attribute that only makes + sense when the device is in a different state) + + Other error conditions may be defined by individual device types. + +Gets/sets a specified piece of device configuration and/or state. The +semantics are device-specific. See individual device documentation in +the "devices" directory. As with ONE_REG, the size of the data +transferred is defined by the particular attribute. + +struct kvm_device_attr { + __u32 flags; /* no flags currently defined */ + __u32 group; /* device-defined */ + __u64 attr; /* group-defined */ + __u64 addr; /* userspace address of attr data */ +}; + +4.81 KVM_HAS_DEVICE_ATTR + +Capability: KVM_CAP_DEVICE_CTRL +Type: device ioctl +Parameters: struct kvm_device_attr +Returns: 0 on success, -1 on error +Errors: + ENXIO: The group or attribute is unknown/unsupported for this device + +Tests whether a device supports a particular attribute. A successful +return indicates the attribute is implemented. It does not necessarily +indicate that the attribute can be read or written in the device's +current state. "addr" is ignored. 4.77 KVM_ARM_VCPU_INIT @@ -2243,6 +2342,25 @@ and distributor interface, the ioctl must be called after calling KVM_CREATE_IRQCHIP, but before calling KVM_RUN on any of the VCPUs. Calling this ioctl twice for any of the base addresses will return -EEXIST. +4.82 KVM_PPC_RTAS_DEFINE_TOKEN + +Capability: KVM_CAP_PPC_RTAS +Architectures: ppc +Type: vm ioctl +Parameters: struct kvm_rtas_token_args +Returns: 0 on success, -1 on error + +Defines a token value for a RTAS (Run Time Abstraction Services) +service in order to allow it to be handled in the kernel. The +argument struct gives the name of the service, which must be the name +of a service that has a kernel-side implementation. If the token +value is non-zero, it will be associated with that service, and +subsequent RTAS calls by the guest specifying that token will be +handled by the kernel. If the token value is 0, then any token +associated with the service will be forgotten, and subsequent RTAS +calls by the guest for that service will be passed to userspace to be +handled. + 5. The kvm_run structure ------------------------ @@ -2646,3 +2764,19 @@ to receive the topmost interrupt vector. When disabled (args[0] == 0), behavior is as if this facility is unsupported. When this capability is enabled, KVM_EXIT_EPR can occur. + +6.6 KVM_CAP_IRQ_MPIC + +Architectures: ppc +Parameters: args[0] is the MPIC device fd + args[1] is the MPIC CPU number for this vcpu + +This capability connects the vcpu to an in-kernel MPIC device. + +6.7 KVM_CAP_IRQ_XICS + +Architectures: ppc +Parameters: args[0] is the XICS device fd + args[1] is the XICS CPU number (server ID) for this vcpu + +This capability connects the vcpu to an in-kernel XICS device. diff --git a/trunk/Documentation/virtual/kvm/devices/README b/trunk/Documentation/virtual/kvm/devices/README new file mode 100644 index 000000000000..34a69834124a --- /dev/null +++ b/trunk/Documentation/virtual/kvm/devices/README @@ -0,0 +1 @@ +This directory contains specific device bindings for KVM_CAP_DEVICE_CTRL. diff --git a/trunk/Documentation/virtual/kvm/devices/mpic.txt b/trunk/Documentation/virtual/kvm/devices/mpic.txt new file mode 100644 index 000000000000..8257397adc3c --- /dev/null +++ b/trunk/Documentation/virtual/kvm/devices/mpic.txt @@ -0,0 +1,53 @@ +MPIC interrupt controller +========================= + +Device types supported: + KVM_DEV_TYPE_FSL_MPIC_20 Freescale MPIC v2.0 + KVM_DEV_TYPE_FSL_MPIC_42 Freescale MPIC v4.2 + +Only one MPIC instance, of any type, may be instantiated. The created +MPIC will act as the system interrupt controller, connecting to each +vcpu's interrupt inputs. + +Groups: + KVM_DEV_MPIC_GRP_MISC + Attributes: + KVM_DEV_MPIC_BASE_ADDR (rw, 64-bit) + Base address of the 256 KiB MPIC register space. Must be + naturally aligned. A value of zero disables the mapping. + Reset value is zero. + + KVM_DEV_MPIC_GRP_REGISTER (rw, 32-bit) + Access an MPIC register, as if the access were made from the guest. + "attr" is the byte offset into the MPIC register space. Accesses + must be 4-byte aligned. + + MSIs may be signaled by using this attribute group to write + to the relevant MSIIR. + + KVM_DEV_MPIC_GRP_IRQ_ACTIVE (rw, 32-bit) + IRQ input line for each standard openpic source. 0 is inactive and 1 + is active, regardless of interrupt sense. + + For edge-triggered interrupts: Writing 1 is considered an activating + edge, and writing 0 is ignored. Reading returns 1 if a previously + signaled edge has not been acknowledged, and 0 otherwise. + + "attr" is the IRQ number. IRQ numbers for standard sources are the + byte offset of the relevant IVPR from EIVPR0, divided by 32. + +IRQ Routing: + + The MPIC emulation supports IRQ routing. Only a single MPIC device can + be instantiated. Once that device has been created, it's available as + irqchip id 0. + + This irqchip 0 has 256 interrupt pins, which expose the interrupts in + the main array of interrupt sources (a.k.a. "SRC" interrupts). + + The numbering is the same as the MPIC device tree binding -- based on + the register offset from the beginning of the sources array, without + regard to any subdivisions in chip documentation such as "internal" + or "external" interrupts. + + Access to non-SRC interrupts is not implemented through IRQ routing mechanisms. diff --git a/trunk/Documentation/virtual/kvm/devices/xics.txt b/trunk/Documentation/virtual/kvm/devices/xics.txt new file mode 100644 index 000000000000..42864935ac5d --- /dev/null +++ b/trunk/Documentation/virtual/kvm/devices/xics.txt @@ -0,0 +1,66 @@ +XICS interrupt controller + +Device type supported: KVM_DEV_TYPE_XICS + +Groups: + KVM_DEV_XICS_SOURCES + Attributes: One per interrupt source, indexed by the source number. + +This device emulates the XICS (eXternal Interrupt Controller +Specification) defined in PAPR. The XICS has a set of interrupt +sources, each identified by a 20-bit source number, and a set of +Interrupt Control Presentation (ICP) entities, also called "servers", +each associated with a virtual CPU. + +The ICP entities are created by enabling the KVM_CAP_IRQ_ARCH +capability for each vcpu, specifying KVM_CAP_IRQ_XICS in args[0] and +the interrupt server number (i.e. the vcpu number from the XICS's +point of view) in args[1] of the kvm_enable_cap struct. Each ICP has +64 bits of state which can be read and written using the +KVM_GET_ONE_REG and KVM_SET_ONE_REG ioctls on the vcpu. The 64 bit +state word has the following bitfields, starting at the +least-significant end of the word: + +* Unused, 16 bits + +* Pending interrupt priority, 8 bits + Zero is the highest priority, 255 means no interrupt is pending. + +* Pending IPI (inter-processor interrupt) priority, 8 bits + Zero is the highest priority, 255 means no IPI is pending. + +* Pending interrupt source number, 24 bits + Zero means no interrupt pending, 2 means an IPI is pending + +* Current processor priority, 8 bits + Zero is the highest priority, meaning no interrupts can be + delivered, and 255 is the lowest priority. + +Each source has 64 bits of state that can be read and written using +the KVM_GET_DEVICE_ATTR and KVM_SET_DEVICE_ATTR ioctls, specifying the +KVM_DEV_XICS_SOURCES attribute group, with the attribute number being +the interrupt source number. The 64 bit state word has the following +bitfields, starting from the least-significant end of the word: + +* Destination (server number), 32 bits + This specifies where the interrupt should be sent, and is the + interrupt server number specified for the destination vcpu. + +* Priority, 8 bits + This is the priority specified for this interrupt source, where 0 is + the highest priority and 255 is the lowest. An interrupt with a + priority of 255 will never be delivered. + +* Level sensitive flag, 1 bit + This bit is 1 for a level-sensitive interrupt source, or 0 for + edge-sensitive (or MSI). + +* Masked flag, 1 bit + This bit is set to 1 if the interrupt is masked (cannot be delivered + regardless of its priority), for example by the ibm,int-off RTAS + call, or 0 if it is not masked. + +* Pending flag, 1 bit + This bit is 1 if the source has a pending interrupt, otherwise 0. + +Only one XICS instance may be created per VM. diff --git a/trunk/Documentation/virtual/virtio-spec.txt b/trunk/Documentation/virtual/virtio-spec.txt deleted file mode 100644 index eb094039b50d..000000000000 --- a/trunk/Documentation/virtual/virtio-spec.txt +++ /dev/null @@ -1,3210 +0,0 @@ -[Generated file: see http://ozlabs.org/~rusty/virtio-spec/] -Virtio PCI Card Specification -v0.9.5 DRAFT -- - -Rusty Russell IBM Corporation (Editor) - -2012 May 7. - -Purpose and Description - -This document describes the specifications of the “virtio” family -of PCI[LaTeX Command: nomenclature] devices. These are devices -are found in virtual environments[LaTeX Command: nomenclature], -yet by design they are not all that different from physical PCI -devices, and this document treats them as such. This allows the -guest to use standard PCI drivers and discovery mechanisms. - -The purpose of virtio and this specification is that virtual -environments and guests should have a straightforward, efficient, -standard and extensible mechanism for virtual devices, rather -than boutique per-environment or per-OS mechanisms. - - Straightforward: Virtio PCI devices use normal PCI mechanisms - of interrupts and DMA which should be familiar to any device - driver author. There is no exotic page-flipping or COW - mechanism: it's just a PCI device.[footnote: -This lack of page-sharing implies that the implementation of the -device (e.g. the hypervisor or host) needs full access to the -guest memory. Communication with untrusted parties (i.e. -inter-guest communication) requires copying. -] - - Efficient: Virtio PCI devices consist of rings of descriptors - for input and output, which are neatly separated to avoid cache - effects from both guest and device writing to the same cache - lines. - - Standard: Virtio PCI makes no assumptions about the environment - in which it operates, beyond supporting PCI. In fact the virtio - devices specified in the appendices do not require PCI at all: - they have been implemented on non-PCI buses.[footnote: -The Linux implementation further separates the PCI virtio code -from the specific virtio drivers: these drivers are shared with -the non-PCI implementations (currently lguest and S/390). -] - - Extensible: Virtio PCI devices contain feature bits which are - acknowledged by the guest operating system during device setup. - This allows forwards and backwards compatibility: the device - offers all the features it knows about, and the driver - acknowledges those it understands and wishes to use. - - Virtqueues - -The mechanism for bulk data transport on virtio PCI devices is -pretentiously called a virtqueue. Each device can have zero or -more virtqueues: for example, the network device has one for -transmit and one for receive. - -Each virtqueue occupies two or more physically-contiguous pages -(defined, for the purposes of this specification, as 4096 bytes), -and consists of three parts: - - -+-------------------+-----------------------------------+-----------+ -| Descriptor Table | Available Ring (padding) | Used Ring | -+-------------------+-----------------------------------+-----------+ - - -When the driver wants to send a buffer to the device, it fills in -a slot in the descriptor table (or chains several together), and -writes the descriptor index into the available ring. It then -notifies the device. When the device has finished a buffer, it -writes the descriptor into the used ring, and sends an interrupt. - -Specification - - PCI Discovery - -Any PCI device with Vendor ID 0x1AF4, and Device ID 0x1000 -through 0x103F inclusive is a virtio device[footnote: -The actual value within this range is ignored -]. The device must also have a Revision ID of 0 to match this -specification. - -The Subsystem Device ID indicates which virtio device is -supported by the device. The Subsystem Vendor ID should reflect -the PCI Vendor ID of the environment (it's currently only used -for informational purposes by the guest). - - -+----------------------+--------------------+---------------+ -| Subsystem Device ID | Virtio Device | Specification | -+----------------------+--------------------+---------------+ -+----------------------+--------------------+---------------+ -| 1 | network card | Appendix C | -+----------------------+--------------------+---------------+ -| 2 | block device | Appendix D | -+----------------------+--------------------+---------------+ -| 3 | console | Appendix E | -+----------------------+--------------------+---------------+ -| 4 | entropy source | Appendix F | -+----------------------+--------------------+---------------+ -| 5 | memory ballooning | Appendix G | -+----------------------+--------------------+---------------+ -| 6 | ioMemory | - | -+----------------------+--------------------+---------------+ -| 7 | rpmsg | Appendix H | -+----------------------+--------------------+---------------+ -| 8 | SCSI host | Appendix I | -+----------------------+--------------------+---------------+ -| 9 | 9P transport | - | -+----------------------+--------------------+---------------+ -| 10 | mac80211 wlan | - | -+----------------------+--------------------+---------------+ - - - Device Configuration - -To configure the device, we use the first I/O region of the PCI -device. This contains a virtio header followed by a -device-specific region. - -There may be different widths of accesses to the I/O region; the “ -natural” access method for each field in the virtio header must -be used (i.e. 32-bit accesses for 32-bit fields, etc), but the -device-specific region can be accessed using any width accesses, -and should obtain the same results. - -Note that this is possible because while the virtio header is PCI -(i.e. little) endian, the device-specific region is encoded in -the native endian of the guest (where such distinction is -applicable). - - Device Initialization Sequence - -We start with an overview of device initialization, then expand -on the details of the device and how each step is preformed. - - Reset the device. This is not required on initial start up. - - The ACKNOWLEDGE status bit is set: we have noticed the device. - - The DRIVER status bit is set: we know how to drive the device. - - Device-specific setup, including reading the Device Feature - Bits, discovery of virtqueues for the device, optional MSI-X - setup, and reading and possibly writing the virtio - configuration space. - - The subset of Device Feature Bits understood by the driver is - written to the device. - - The DRIVER_OK status bit is set. - - The device can now be used (ie. buffers added to the - virtqueues)[footnote: -Historically, drivers have used the device before steps 5 and 6. -This is only allowed if the driver does not use any features -which would alter this early use of the device. -] - -If any of these steps go irrecoverably wrong, the guest should -set the FAILED status bit to indicate that it has given up on the -device (it can reset the device later to restart if desired). - -We now cover the fields required for general setup in detail. - - Virtio Header - -The virtio header looks as follows: - - -+------------++---------------------+---------------------+----------+--------+---------+---------+---------+--------+ -| Bits || 32 | 32 | 32 | 16 | 16 | 16 | 8 | 8 | -+------------++---------------------+---------------------+----------+--------+---------+---------+---------+--------+ -| Read/Write || R | R+W | R+W | R | R+W | R+W | R+W | R | -+------------++---------------------+---------------------+----------+--------+---------+---------+---------+--------+ -| Purpose || Device | Guest | Queue | Queue | Queue | Queue | Device | ISR | -| || Features bits 0:31 | Features bits 0:31 | Address | Size | Select | Notify | Status | Status | -+------------++---------------------+---------------------+----------+--------+---------+---------+---------+--------+ - - -If MSI-X is enabled for the device, two additional fields -immediately follow this header:[footnote: -ie. once you enable MSI-X on the device, the other fields move. -If you turn it off again, they move back! -] - - -+------------++----------------+--------+ -| Bits || 16 | 16 | - +----------------+--------+ -+------------++----------------+--------+ -| Read/Write || R+W | R+W | -+------------++----------------+--------+ -| Purpose || Configuration | Queue | -| (MSI-X) || Vector | Vector | -+------------++----------------+--------+ - - -Immediately following these general headers, there may be -device-specific headers: - - -+------------++--------------------+ -| Bits || Device Specific | - +--------------------+ -+------------++--------------------+ -| Read/Write || Device Specific | -+------------++--------------------+ -| Purpose || Device Specific... | -| || | -+------------++--------------------+ - - - Device Status - -The Device Status field is updated by the guest to indicate its -progress. This provides a simple low-level diagnostic: it's most -useful to imagine them hooked up to traffic lights on the console -indicating the status of each device. - -The device can be reset by writing a 0 to this field, otherwise -at least one bit should be set: - - ACKNOWLEDGE (1) Indicates that the guest OS has found the - device and recognized it as a valid virtio device. - - DRIVER (2) Indicates that the guest OS knows how to drive the - device. Under Linux, drivers can be loadable modules so there - may be a significant (or infinite) delay before setting this - bit. - - DRIVER_OK (4) Indicates that the driver is set up and ready to - drive the device. - - FAILED (128) Indicates that something went wrong in the guest, - and it has given up on the device. This could be an internal - error, or the driver didn't like the device for some reason, or - even a fatal error during device operation. The device must be - reset before attempting to re-initialize. - - Feature Bits - -Thefirst configuration field indicates the features that the -device supports. The bits are allocated as follows: - - 0 to 23 Feature bits for the specific device type - - 24 to 32 Feature bits reserved for extensions to the queue and - feature negotiation mechanisms - -For example, feature bit 0 for a network device (i.e. Subsystem -Device ID 1) indicates that the device supports checksumming of -packets. - -The feature bits are negotiated: the device lists all the -features it understands in the Device Features field, and the -guest writes the subset that it understands into the Guest -Features field. The only way to renegotiate is to reset the -device. - -In particular, new fields in the device configuration header are -indicated by offering a feature bit, so the guest can check -before accessing that part of the configuration space. - -This allows for forwards and backwards compatibility: if the -device is enhanced with a new feature bit, older guests will not -write that feature bit back to the Guest Features field and it -can go into backwards compatibility mode. Similarly, if a guest -is enhanced with a feature that the device doesn't support, it -will not see that feature bit in the Device Features field and -can go into backwards compatibility mode (or, for poor -implementations, set the FAILED Device Status bit). - - Configuration/Queue Vectors - -When MSI-X capability is present and enabled in the device -(through standard PCI configuration space) 4 bytes at byte offset -20 are used to map configuration change and queue interrupts to -MSI-X vectors. In this case, the ISR Status field is unused, and -device specific configuration starts at byte offset 24 in virtio -header structure. When MSI-X capability is not enabled, device -specific configuration starts at byte offset 20 in virtio header. - -Writing a valid MSI-X Table entry number, 0 to 0x7FF, to one of -Configuration/Queue Vector registers, maps interrupts triggered -by the configuration change/selected queue events respectively to -the corresponding MSI-X vector. To disable interrupts for a -specific event type, unmap it by writing a special NO_VECTOR -value: - -/* Vector value used to disable MSI for queue */ - -#define VIRTIO_MSI_NO_VECTOR 0xffff - -Reading these registers returns vector mapped to a given event, -or NO_VECTOR if unmapped. All queue and configuration change -events are unmapped by default. - -Note that mapping an event to vector might require allocating -internal device resources, and might fail. Devices report such -failures by returning the NO_VECTOR value when the relevant -Vector field is read. After mapping an event to vector, the -driver must verify success by reading the Vector field value: on -success, the previously written value is returned, and on -failure, NO_VECTOR is returned. If a mapping failure is detected, -the driver can retry mapping with fewervectors, or disable MSI-X. - - Virtqueue Configuration - -As a device can have zero or more virtqueues for bulk data -transport (for example, the network driver has two), the driver -needs to configure them as part of the device-specific -configuration. - -This is done as follows, for each virtqueue a device has: - - Write the virtqueue index (first queue is 0) to the Queue - Select field. - - Read the virtqueue size from the Queue Size field, which is - always a power of 2. This controls how big the virtqueue is - (see below). If this field is 0, the virtqueue does not exist. - - Allocate and zero virtqueue in contiguous physical memory, on a - 4096 byte alignment. Write the physical address, divided by - 4096 to the Queue Address field.[footnote: -The 4096 is based on the x86 page size, but it's also large -enough to ensure that the separate parts of the virtqueue are on -separate cache lines. -] - - Optionally, if MSI-X capability is present and enabled on the - device, select a vector to use to request interrupts triggered - by virtqueue events. Write the MSI-X Table entry number - corresponding to this vector in Queue Vector field. Read the - Queue Vector field: on success, previously written value is - returned; on failure, NO_VECTOR value is returned. - -The Queue Size field controls the total number of bytes required -for the virtqueue according to the following formula: - -#define ALIGN(x) (((x) + 4095) & ~4095) - -static inline unsigned vring_size(unsigned int qsz) - -{ - - return ALIGN(sizeof(struct vring_desc)*qsz + sizeof(u16)*(2 -+ qsz)) - - + ALIGN(sizeof(struct vring_used_elem)*qsz); - -} - -This currently wastes some space with padding, but also allows -future extensions. The virtqueue layout structure looks like this -(qsz is the Queue Size field, which is a variable, so this code -won't compile): - -struct vring { - - /* The actual descriptors (16 bytes each) */ - - struct vring_desc desc[qsz]; - - - - /* A ring of available descriptor heads with free-running -index. */ - - struct vring_avail avail; - - - - // Padding to the next 4096 boundary. - - char pad[]; - - - - // A ring of used descriptor heads with free-running index. - - struct vring_used used; - -}; - - A Note on Virtqueue Endianness - -Note that the endian of these fields and everything else in the -virtqueue is the native endian of the guest, not little-endian as -PCI normally is. This makes for simpler guest code, and it is -assumed that the host already has to be deeply aware of the guest -endian so such an “endian-aware” device is not a significant -issue. - - Descriptor Table - -The descriptor table refers to the buffers the guest is using for -the device. The addresses are physical addresses, and the buffers -can be chained via the next field. Each descriptor describes a -buffer which is read-only or write-only, but a chain of -descriptors can contain both read-only and write-only buffers. - -No descriptor chain may be more than 2^32 bytes long in total.struct vring_desc { - - /* Address (guest-physical). */ - - u64 addr; - - /* Length. */ - - u32 len; - -/* This marks a buffer as continuing via the next field. */ - -#define VRING_DESC_F_NEXT 1 - -/* This marks a buffer as write-only (otherwise read-only). */ - -#define VRING_DESC_F_WRITE 2 - -/* This means the buffer contains a list of buffer descriptors. -*/ - -#define VRING_DESC_F_INDIRECT 4 - - /* The flags as indicated above. */ - - u16 flags; - - /* Next field if flags & NEXT */ - - u16 next; - -}; - -The number of descriptors in the table is specified by the Queue -Size field for this virtqueue. - - Indirect Descriptors - -Some devices benefit by concurrently dispatching a large number -of large requests. The VIRTIO_RING_F_INDIRECT_DESC feature can be -used to allow this (see [cha:Reserved-Feature-Bits]). To increase -ring capacity it is possible to store a table of indirect -descriptors anywhere in memory, and insert a descriptor in main -virtqueue (with flags&INDIRECT on) that refers to memory buffer -containing this indirect descriptor table; fields addr and len -refer to the indirect table address and length in bytes, -respectively. The indirect table layout structure looks like this -(len is the length of the descriptor that refers to this table, -which is a variable, so this code won't compile): - -struct indirect_descriptor_table { - - /* The actual descriptors (16 bytes each) */ - - struct vring_desc desc[len / 16]; - -}; - -The first indirect descriptor is located at start of the indirect -descriptor table (index 0), additional indirect descriptors are -chained by next field. An indirect descriptor without next field -(with flags&NEXT off) signals the end of the indirect descriptor -table, and transfers control back to the main virtqueue. An -indirect descriptor can not refer to another indirect descriptor -table (flags&INDIRECT must be off). A single indirect descriptor -table can include both read-only and write-only descriptors; -write-only flag (flags&WRITE) in the descriptor that refers to it -is ignored. - - Available Ring - -The available ring refers to what descriptors we are offering the -device: it refers to the head of a descriptor chain. The “flags” -field is currently 0 or 1: 1 indicating that we do not need an -interrupt when the device consumes a descriptor from the -available ring. Alternatively, the guest can ask the device to -delay interrupts until an entry with an index specified by the “ -used_event” field is written in the used ring (equivalently, -until the idx field in the used ring will reach the value -used_event + 1). The method employed by the device is controlled -by the VIRTIO_RING_F_EVENT_IDX feature bit (see [cha:Reserved-Feature-Bits] -). This interrupt suppression is merely an optimization; it may -not suppress interrupts entirely. - -The “idx” field indicates where we would put the next descriptor -entry (modulo the ring size). This starts at 0, and increases. - -struct vring_avail { - -#define VRING_AVAIL_F_NO_INTERRUPT 1 - - u16 flags; - - u16 idx; - - u16 ring[qsz]; /* qsz is the Queue Size field read from device -*/ - - u16 used_event; - -}; - - Used Ring - -The used ring is where the device returns buffers once it is done -with them. The flags field can be used by the device to hint that -no notification is necessary when the guest adds to the available -ring. Alternatively, the “avail_event” field can be used by the -device to hint that no notification is necessary until an entry -with an index specified by the “avail_event” is written in the -available ring (equivalently, until the idx field in the -available ring will reach the value avail_event + 1). The method -employed by the device is controlled by the guest through the -VIRTIO_RING_F_EVENT_IDX feature bit (see [cha:Reserved-Feature-Bits] -). [footnote: -These fields are kept here because this is the only part of the -virtqueue written by the device -]. - -Each entry in the ring is a pair: the head entry of the -descriptor chain describing the buffer (this matches an entry -placed in the available ring by the guest earlier), and the total -of bytes written into the buffer. The latter is extremely useful -for guests using untrusted buffers: if you do not know exactly -how much has been written by the device, you usually have to zero -the buffer to ensure no data leakage occurs. - -/* u32 is used here for ids for padding reasons. */ - -struct vring_used_elem { - - /* Index of start of used descriptor chain. */ - - u32 id; - - /* Total length of the descriptor chain which was used -(written to) */ - - u32 len; - -}; - - - -struct vring_used { - -#define VRING_USED_F_NO_NOTIFY 1 - - u16 flags; - - u16 idx; - - struct vring_used_elem ring[qsz]; - - u16 avail_event; - -}; - - Helpers for Managing Virtqueues - -The Linux Kernel Source code contains the definitions above and -helper routines in a more usable form, in -include/linux/virtio_ring.h. This was explicitly licensed by IBM -and Red Hat under the (3-clause) BSD license so that it can be -freely used by all other projects, and is reproduced (with slight -variation to remove Linux assumptions) in Appendix A. - - Device Operation - -There are two parts to device operation: supplying new buffers to -the device, and processing used buffers from the device. As an -example, the virtio network device has two virtqueues: the -transmit virtqueue and the receive virtqueue. The driver adds -outgoing (read-only) packets to the transmit virtqueue, and then -frees them after they are used. Similarly, incoming (write-only) -buffers are added to the receive virtqueue, and processed after -they are used. - - Supplying Buffers to The Device - -Actual transfer of buffers from the guest OS to the device -operates as follows: - - Place the buffer(s) into free descriptor(s). - - If there are no free descriptors, the guest may choose to - notify the device even if notifications are suppressed (to - reduce latency).[footnote: -The Linux drivers do this only for read-only buffers: for -write-only buffers, it is assumed that the driver is merely -trying to keep the receive buffer ring full, and no notification -of this expected condition is necessary. -] - - Place the id of the buffer in the next ring entry of the - available ring. - - The steps (1) and (2) may be performed repeatedly if batching - is possible. - - A memory barrier should be executed to ensure the device sees - the updated descriptor table and available ring before the next - step. - - The available “idx” field should be increased by the number of - entries added to the available ring. - - A memory barrier should be executed to ensure that we update - the idx field before checking for notification suppression. - - If notifications are not suppressed, the device should be - notified of the new buffers. - -Note that the above code does not take precautions against the -available ring buffer wrapping around: this is not possible since -the ring buffer is the same size as the descriptor table, so step -(1) will prevent such a condition. - -In addition, the maximum queue size is 32768 (it must be a power -of 2 which fits in 16 bits), so the 16-bit “idx” value can always -distinguish between a full and empty buffer. - -Here is a description of each stage in more detail. - - Placing Buffers Into The Descriptor Table - -A buffer consists of zero or more read-only physically-contiguous -elements followed by zero or more physically-contiguous -write-only elements (it must have at least one element). This -algorithm maps it into the descriptor table: - - for each buffer element, b: - - Get the next free descriptor table entry, d - - Set d.addr to the physical address of the start of b - - Set d.len to the length of b. - - If b is write-only, set d.flags to VRING_DESC_F_WRITE, - otherwise 0. - - If there is a buffer element after this: - - Set d.next to the index of the next free descriptor element. - - Set the VRING_DESC_F_NEXT bit in d.flags. - -In practice, the d.next fields are usually used to chain free -descriptors, and a separate count kept to check there are enough -free descriptors before beginning the mappings. - - Updating The Available Ring - -The head of the buffer we mapped is the first d in the algorithm -above. A naive implementation would do the following: - -avail->ring[avail->idx % qsz] = head; - -However, in general we can add many descriptors before we update -the “idx” field (at which point they become visible to the -device), so we keep a counter of how many we've added: - -avail->ring[(avail->idx + added++) % qsz] = head; - - Updating The Index Field - -Once the idx field of the virtqueue is updated, the device will -be able to access the descriptor entries we've created and the -memory they refer to. This is why a memory barrier is generally -used before the idx update, to ensure it sees the most up-to-date -copy. - -The idx field always increments, and we let it wrap naturally at -65536: - -avail->idx += added; - - Notifying The Device - -Device notification occurs by writing the 16-bit virtqueue index -of this virtqueue to the Queue Notify field of the virtio header -in the first I/O region of the PCI device. This can be expensive, -however, so the device can suppress such notifications if it -doesn't need them. We have to be careful to expose the new idx -value before checking the suppression flag: it's OK to notify -gratuitously, but not to omit a required notification. So again, -we use a memory barrier here before reading the flags or the -avail_event field. - -If the VIRTIO_F_RING_EVENT_IDX feature is not negotiated, and if -the VRING_USED_F_NOTIFY flag is not set, we go ahead and write to -the PCI configuration space. - -If the VIRTIO_F_RING_EVENT_IDX feature is negotiated, we read the -avail_event field in the available ring structure. If the -available index crossed_the avail_event field value since the -last notification, we go ahead and write to the PCI configuration -space. The avail_event field wraps naturally at 65536 as well: - -(u16)(new_idx - avail_event - 1) < (u16)(new_idx - old_idx) - - Receiving Used Buffers From The - Device - -Once the device has used a buffer (read from or written to it, or -parts of both, depending on the nature of the virtqueue and the -device), it sends an interrupt, following an algorithm very -similar to the algorithm used for the driver to send the device a -buffer: - - Write the head descriptor number to the next field in the used - ring. - - Update the used ring idx. - - Determine whether an interrupt is necessary: - - If the VIRTIO_F_RING_EVENT_IDX feature is not negotiated: check - if f the VRING_AVAIL_F_NO_INTERRUPT flag is not set in avail- - >flags - - If the VIRTIO_F_RING_EVENT_IDX feature is negotiated: check - whether the used index crossed the used_event field value - since the last update. The used_event field wraps naturally - at 65536 as well:(u16)(new_idx - used_event - 1) < (u16)(new_idx - old_idx) - - If an interrupt is necessary: - - If MSI-X capability is disabled: - - Set the lower bit of the ISR Status field for the device. - - Send the appropriate PCI interrupt for the device. - - If MSI-X capability is enabled: - - Request the appropriate MSI-X interrupt message for the - device, Queue Vector field sets the MSI-X Table entry - number. - - If Queue Vector field value is NO_VECTOR, no interrupt - message is requested for this event. - -The guest interrupt handler should: - - If MSI-X capability is disabled: read the ISR Status field, - which will reset it to zero. If the lower bit is zero, the - interrupt was not for this device. Otherwise, the guest driver - should look through the used rings of each virtqueue for the - device, to see if any progress has been made by the device - which requires servicing. - - If MSI-X capability is enabled: look through the used rings of - each virtqueue mapped to the specific MSI-X vector for the - device, to see if any progress has been made by the device - which requires servicing. - -For each ring, guest should then disable interrupts by writing -VRING_AVAIL_F_NO_INTERRUPT flag in avail structure, if required. -It can then process used ring entries finally enabling interrupts -by clearing the VRING_AVAIL_F_NO_INTERRUPT flag or updating the -EVENT_IDX field in the available structure, Guest should then -execute a memory barrier, and then recheck the ring empty -condition. This is necessary to handle the case where, after the -last check and before enabling interrupts, an interrupt has been -suppressed by the device: - -vring_disable_interrupts(vq); - -for (;;) { - - if (vq->last_seen_used != vring->used.idx) { - - vring_enable_interrupts(vq); - - mb(); - - if (vq->last_seen_used != vring->used.idx) - - break; - - } - - struct vring_used_elem *e = -vring.used->ring[vq->last_seen_used%vsz]; - - process_buffer(e); - - vq->last_seen_used++; - -} - - Dealing With Configuration Changes - -Some virtio PCI devices can change the device configuration -state, as reflected in the virtio header in the PCI configuration -space. In this case: - - If MSI-X capability is disabled: an interrupt is delivered and - the second highest bit is set in the ISR Status field to - indicate that the driver should re-examine the configuration - space.Note that a single interrupt can indicate both that one - or more virtqueue has been used and that the configuration - space has changed: even if the config bit is set, virtqueues - must be scanned. - - If MSI-X capability is enabled: an interrupt message is - requested. The Configuration Vector field sets the MSI-X Table - entry number to use. If Configuration Vector field value is - NO_VECTOR, no interrupt message is requested for this event. - -Creating New Device Types - -Various considerations are necessary when creating a new device -type: - - How Many Virtqueues? - -It is possible that a very simple device will operate entirely -through its configuration space, but most will need at least one -virtqueue in which it will place requests. A device with both -input and output (eg. console and network devices described here) -need two queues: one which the driver fills with buffers to -receive input, and one which the driver places buffers to -transmit output. - - What Configuration Space Layout? - -Configuration space is generally used for rarely-changing or -initialization-time parameters. But it is a limited resource, so -it might be better to use a virtqueue to update configuration -information (the network device does this for filtering, -otherwise the table in the config space could potentially be very -large). - -Note that this space is generally the guest's native endian, -rather than PCI's little-endian. - - What Device Number? - -Currently device numbers are assigned quite freely: a simple -request mail to the author of this document or the Linux -virtualization mailing list[footnote: - -https://lists.linux-foundation.org/mailman/listinfo/virtualization -] will be sufficient to secure a unique one. - -Meanwhile for experimental drivers, use 65535 and work backwards. - - How many MSI-X vectors? - -Using the optional MSI-X capability devices can speed up -interrupt processing by removing the need to read ISR Status -register by guest driver (which might be an expensive operation), -reducing interrupt sharing between devices and queues within the -device, and handling interrupts from multiple CPUs. However, some -systems impose a limit (which might be as low as 256) on the -total number of MSI-X vectors that can be allocated to all -devices. Devices and/or device drivers should take this into -account, limiting the number of vectors used unless the device is -expected to cause a high volume of interrupts. Devices can -control the number of vectors used by limiting the MSI-X Table -Size or not presenting MSI-X capability in PCI configuration -space. Drivers can control this by mapping events to as small -number of vectors as possible, or disabling MSI-X capability -altogether. - - Message Framing - -The descriptors used for a buffer should not effect the semantics -of the message, except for the total length of the buffer. For -example, a network buffer consists of a 10 byte header followed -by the network packet. Whether this is presented in the ring -descriptor chain as (say) a 10 byte buffer and a 1514 byte -buffer, or a single 1524 byte buffer, or even three buffers, -should have no effect. - -In particular, no implementation should use the descriptor -boundaries to determine the size of any header in a request.[footnote: -The current qemu device implementations mistakenly insist that -the first descriptor cover the header in these cases exactly, so -a cautious driver should arrange it so. -] - - Device Improvements - -Any change to configuration space, or new virtqueues, or -behavioural changes, should be indicated by negotiation of a new -feature bit. This establishes clarity[footnote: -Even if it does mean documenting design or implementation -mistakes! -] and avoids future expansion problems. - -Clusters of functionality which are always implemented together -can use a single bit, but if one feature makes sense without the -others they should not be gratuitously grouped together to -conserve feature bits. We can always extend the spec when the -first person needs more than 24 feature bits for their device. - -[LaTeX Command: printnomenclature] - -Appendix A: virtio_ring.h - -#ifndef VIRTIO_RING_H - -#define VIRTIO_RING_H - -/* An interface for efficient virtio implementation. - - * - - * This header is BSD licensed so anyone can use the definitions - - * to implement compatible drivers/servers. - - * - - * Copyright 2007, 2009, IBM Corporation - - * Copyright 2011, Red Hat, Inc - - * All rights reserved. - - * - - * Redistribution and use in source and binary forms, with or -without - - * modification, are permitted provided that the following -conditions - - * are met: - - * 1. Redistributions of source code must retain the above -copyright - - * notice, this list of conditions and the following -disclaimer. - - * 2. Redistributions in binary form must reproduce the above -copyright - - * notice, this list of conditions and the following -disclaimer in the - - * documentation and/or other materials provided with the -distribution. - - * 3. Neither the name of IBM nor the names of its contributors - - * may be used to endorse or promote products derived from -this software - - * without specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND -CONTRIBUTORS ``AS IS'' AND - - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -TO, THE - - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE - - * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE -LIABLE - - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL - - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS - - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) - - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT - - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY - - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF - - * SUCH DAMAGE. - - */ - - - -/* This marks a buffer as continuing via the next field. */ - -#define VRING_DESC_F_NEXT 1 - -/* This marks a buffer as write-only (otherwise read-only). */ - -#define VRING_DESC_F_WRITE 2 - - - -/* The Host uses this in used->flags to advise the Guest: don't -kick me - - * when you add a buffer. It's unreliable, so it's simply an - - * optimization. Guest will still kick if it's out of buffers. -*/ - -#define VRING_USED_F_NO_NOTIFY 1 - -/* The Guest uses this in avail->flags to advise the Host: don't - - * interrupt me when you consume a buffer. It's unreliable, so -it's - - * simply an optimization. */ - -#define VRING_AVAIL_F_NO_INTERRUPT 1 - - - -/* Virtio ring descriptors: 16 bytes. - - * These can chain together via "next". */ - -struct vring_desc { - - /* Address (guest-physical). */ - - uint64_t addr; - - /* Length. */ - - uint32_t len; - - /* The flags as indicated above. */ - - uint16_t flags; - - /* We chain unused descriptors via this, too */ - - uint16_t next; - -}; - - - -struct vring_avail { - - uint16_t flags; - - uint16_t idx; - - uint16_t ring[]; - - uint16_t used_event; - -}; - - - -/* u32 is used here for ids for padding reasons. */ - -struct vring_used_elem { - - /* Index of start of used descriptor chain. */ - - uint32_t id; - - /* Total length of the descriptor chain which was written -to. */ - - uint32_t len; - -}; - - - -struct vring_used { - - uint16_t flags; - - uint16_t idx; - - struct vring_used_elem ring[]; - - uint16_t avail_event; - -}; - - - -struct vring { - - unsigned int num; - - - - struct vring_desc *desc; - - struct vring_avail *avail; - - struct vring_used *used; - -}; - - - -/* The standard layout for the ring is a continuous chunk of -memory which - - * looks like this. We assume num is a power of 2. - - * - - * struct vring { - - * // The actual descriptors (16 bytes each) - - * struct vring_desc desc[num]; - - * - - * // A ring of available descriptor heads with free-running -index. - - * __u16 avail_flags; - - * __u16 avail_idx; - - * __u16 available[num]; - - * - - * // Padding to the next align boundary. - - * char pad[]; - - * - - * // A ring of used descriptor heads with free-running -index. - - * __u16 used_flags; - - * __u16 EVENT_IDX; - - * struct vring_used_elem used[num]; - - * }; - - * Note: for virtio PCI, align is 4096. - - */ - -static inline void vring_init(struct vring *vr, unsigned int num, -void *p, - - unsigned long align) - -{ - - vr->num = num; - - vr->desc = p; - - vr->avail = p + num*sizeof(struct vring_desc); - - vr->used = (void *)(((unsigned long)&vr->avail->ring[num] - - + align-1) - - & ~(align - 1)); - -} - - - -static inline unsigned vring_size(unsigned int num, unsigned long -align) - -{ - - return ((sizeof(struct vring_desc)*num + -sizeof(uint16_t)*(2+num) - - + align - 1) & ~(align - 1)) - - + sizeof(uint16_t)*3 + sizeof(struct -vring_used_elem)*num; - -} - - - -static inline int vring_need_event(uint16_t event_idx, uint16_t -new_idx, uint16_t old_idx) - -{ - - return (uint16_t)(new_idx - event_idx - 1) < -(uint16_t)(new_idx - old_idx); - -} - -#endif /* VIRTIO_RING_H */ - -Appendix B: Reserved Feature Bits - -Currently there are five device-independent feature bits defined: - - VIRTIO_F_NOTIFY_ON_EMPTY (24) Negotiating this feature - indicates that the driver wants an interrupt if the device runs - out of available descriptors on a virtqueue, even though - interrupts are suppressed using the VRING_AVAIL_F_NO_INTERRUPT - flag or the used_event field. An example of this is the - networking driver: it doesn't need to know every time a packet - is transmitted, but it does need to free the transmitted - packets a finite time after they are transmitted. It can avoid - using a timer if the device interrupts it when all the packets - are transmitted. - - VIRTIO_F_RING_INDIRECT_DESC (28) Negotiating this feature - indicates that the driver can use descriptors with the - VRING_DESC_F_INDIRECT flag set, as described in [sub:Indirect-Descriptors] - . - - VIRTIO_F_RING_EVENT_IDX(29) This feature enables the used_event - and the avail_event fields. If set, it indicates that the - device should ignore the flags field in the available ring - structure. Instead, the used_event field in this structure is - used by guest to suppress device interrupts. Further, the - driver should ignore the flags field in the used ring - structure. Instead, the avail_event field in this structure is - used by the device to suppress notifications. If unset, the - driver should ignore the used_event field; the device should - ignore the avail_event field; the flags field is used - -Appendix C: Network Device - -The virtio network device is a virtual ethernet card, and is the -most complex of the devices supported so far by virtio. It has -enhanced rapidly and demonstrates clearly how support for new -features should be added to an existing device. Empty buffers are -placed in one virtqueue for receiving packets, and outgoing -packets are enqueued into another for transmission in that order. -A third command queue is used to control advanced filtering -features. - - Configuration - - Subsystem Device ID 1 - - Virtqueues 0:receiveq. 1:transmitq. 2:controlq[footnote: -Only if VIRTIO_NET_F_CTRL_VQ set -] - - Feature bits - - VIRTIO_NET_F_CSUM (0) Device handles packets with partial - checksum - - VIRTIO_NET_F_GUEST_CSUM (1) Guest handles packets with partial - checksum - - VIRTIO_NET_F_MAC (5) Device has given MAC address. - - VIRTIO_NET_F_GSO (6) (Deprecated) device handles packets with - any GSO type.[footnote: -It was supposed to indicate segmentation offload support, but -upon further investigation it became clear that multiple bits -were required. -] - - VIRTIO_NET_F_GUEST_TSO4 (7) Guest can receive TSOv4. - - VIRTIO_NET_F_GUEST_TSO6 (8) Guest can receive TSOv6. - - VIRTIO_NET_F_GUEST_ECN (9) Guest can receive TSO with ECN. - - VIRTIO_NET_F_GUEST_UFO (10) Guest can receive UFO. - - VIRTIO_NET_F_HOST_TSO4 (11) Device can receive TSOv4. - - VIRTIO_NET_F_HOST_TSO6 (12) Device can receive TSOv6. - - VIRTIO_NET_F_HOST_ECN (13) Device can receive TSO with ECN. - - VIRTIO_NET_F_HOST_UFO (14) Device can receive UFO. - - VIRTIO_NET_F_MRG_RXBUF (15) Guest can merge receive buffers. - - VIRTIO_NET_F_STATUS (16) Configuration status field is - available. - - VIRTIO_NET_F_CTRL_VQ (17) Control channel is available. - - VIRTIO_NET_F_CTRL_RX (18) Control channel RX mode support. - - VIRTIO_NET_F_CTRL_VLAN (19) Control channel VLAN filtering. - - VIRTIO_NET_F_GUEST_ANNOUNCE(21) Guest can send gratuitous - packets. - - Device configuration layout Two configuration fields are - currently defined. The mac address field always exists (though - is only valid if VIRTIO_NET_F_MAC is set), and the status field - only exists if VIRTIO_NET_F_STATUS is set. Two read-only bits - are currently defined for the status field: - VIRTIO_NET_S_LINK_UP and VIRTIO_NET_S_ANNOUNCE. #define VIRTIO_NET_S_LINK_UP 1 - -#define VIRTIO_NET_S_ANNOUNCE 2 - - - -struct virtio_net_config { - - u8 mac[6]; - - u16 status; - -}; - - Device Initialization - - The initialization routine should identify the receive and - transmission virtqueues. - - If the VIRTIO_NET_F_MAC feature bit is set, the configuration - space “mac” entry indicates the “physical” address of the the - network card, otherwise a private MAC address should be - assigned. All guests are expected to negotiate this feature if - it is set. - - If the VIRTIO_NET_F_CTRL_VQ feature bit is negotiated, identify - the control virtqueue. - - If the VIRTIO_NET_F_STATUS feature bit is negotiated, the link - status can be read from the bottom bit of the “status” config - field. Otherwise, the link should be assumed active. - - The receive virtqueue should be filled with receive buffers. - This is described in detail below in “Setting Up Receive - Buffers”. - - A driver can indicate that it will generate checksumless - packets by negotating the VIRTIO_NET_F_CSUM feature. This “ - checksum offload” is a common feature on modern network cards. - - If that feature is negotiated[footnote: -ie. VIRTIO_NET_F_HOST_TSO* and VIRTIO_NET_F_HOST_UFO are -dependent on VIRTIO_NET_F_CSUM; a dvice which offers the offload -features must offer the checksum feature, and a driver which -accepts the offload features must accept the checksum feature. -Similar logic applies to the VIRTIO_NET_F_GUEST_TSO4 features -depending on VIRTIO_NET_F_GUEST_CSUM. -], a driver can use TCP or UDP segmentation offload by - negotiating the VIRTIO_NET_F_HOST_TSO4 (IPv4 TCP), - VIRTIO_NET_F_HOST_TSO6 (IPv6 TCP) and VIRTIO_NET_F_HOST_UFO - (UDP fragmentation) features. It should not send TCP packets - requiring segmentation offload which have the Explicit - Congestion Notification bit set, unless the - VIRTIO_NET_F_HOST_ECN feature is negotiated.[footnote: -This is a common restriction in real, older network cards. -] - - The converse features are also available: a driver can save the - virtual device some work by negotiating these features.[footnote: -For example, a network packet transported between two guests on -the same system may not require checksumming at all, nor -segmentation, if both guests are amenable. -] The VIRTIO_NET_F_GUEST_CSUM feature indicates that partially - checksummed packets can be received, and if it can do that then - the VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6, - VIRTIO_NET_F_GUEST_UFO and VIRTIO_NET_F_GUEST_ECN are the input - equivalents of the features described above. See “Receiving - Packets” below. - - Device Operation - -Packets are transmitted by placing them in the transmitq, and -buffers for incoming packets are placed in the receiveq. In each -case, the packet itself is preceded by a header: - -struct virtio_net_hdr { - -#define VIRTIO_NET_HDR_F_NEEDS_CSUM 1 - - u8 flags; - -#define VIRTIO_NET_HDR_GSO_NONE 0 - -#define VIRTIO_NET_HDR_GSO_TCPV4 1 - -#define VIRTIO_NET_HDR_GSO_UDP 3 - -#define VIRTIO_NET_HDR_GSO_TCPV6 4 - -#define VIRTIO_NET_HDR_GSO_ECN 0x80 - - u8 gso_type; - - u16 hdr_len; - - u16 gso_size; - - u16 csum_start; - - u16 csum_offset; - -/* Only if VIRTIO_NET_F_MRG_RXBUF: */ - - u16 num_buffers - -}; - -The controlq is used to control device features such as -filtering. - - Packet Transmission - -Transmitting a single packet is simple, but varies depending on -the different features the driver negotiated. - - If the driver negotiated VIRTIO_NET_F_CSUM, and the packet has - not been fully checksummed, then the virtio_net_hdr's fields - are set as follows. Otherwise, the packet must be fully - checksummed, and flags is zero. - - flags has the VIRTIO_NET_HDR_F_NEEDS_CSUM set, - - csum_start is set to the offset within - the packet to begin checksumming, and - - csum_offset indicates how many bytes after the csum_start the - new (16 bit ones' complement) checksum should be placed.[footnote: -For example, consider a partially checksummed TCP (IPv4) packet. -It will have a 14 byte ethernet header and 20 byte IP header -followed by the TCP header (with the TCP checksum field 16 bytes -into that header). csum_start will be 14+20 = 34 (the TCP -checksum includes the header), and csum_offset will be 16. The -value in the TCP checksum field should be initialized to the sum -of the TCP pseudo header, so that replacing it by the ones' -complement checksum of the TCP header and body will give the -correct result. -] - - If the driver negotiated - VIRTIO_NET_F_HOST_TSO4, TSO6 or UFO, and the packet requires - TCP segmentation or UDP fragmentation, then the “gso_type” - field is set to VIRTIO_NET_HDR_GSO_TCPV4, TCPV6 or UDP. - (Otherwise, it is set to VIRTIO_NET_HDR_GSO_NONE). In this - case, packets larger than 1514 bytes can be transmitted: the - metadata indicates how to replicate the packet header to cut it - into smaller packets. The other gso fields are set: - - hdr_len is a hint to the device as to how much of the header - needs to be kept to copy into each packet, usually set to the - length of the headers, including the transport header.[footnote: -Due to various bugs in implementations, this field is not useful -as a guarantee of the transport header size. -] - - gso_size is the maximum size of each packet beyond that header - (ie. MSS). - - If the driver negotiated the VIRTIO_NET_F_HOST_ECN feature, the - VIRTIO_NET_HDR_GSO_ECN bit may be set in “gso_type” as well, - indicating that the TCP packet has the ECN bit set.[footnote: -This case is not handled by some older hardware, so is called out -specifically in the protocol. -] - - If the driver negotiated the VIRTIO_NET_F_MRG_RXBUF feature, - the num_buffers field is set to zero. - - The header and packet are added as one output buffer to the - transmitq, and the device is notified of the new entry (see [sub:Notifying-The-Device] - ).[footnote: -Note that the header will be two bytes longer for the -VIRTIO_NET_F_MRG_RXBUF case. -] - - Packet Transmission Interrupt - -Often a driver will suppress transmission interrupts using the -VRING_AVAIL_F_NO_INTERRUPT flag (see [sub:Receiving-Used-Buffers] -) and check for used packets in the transmit path of following -packets. However, it will still receive interrupts if the -VIRTIO_F_NOTIFY_ON_EMPTY feature is negotiated, indicating that -the transmission queue is completely emptied. - -The normal behavior in this interrupt handler is to retrieve and -new descriptors from the used ring and free the corresponding -headers and packets. - - Setting Up Receive Buffers - -It is generally a good idea to keep the receive virtqueue as -fully populated as possible: if it runs out, network performance -will suffer. - -If the VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6 or -VIRTIO_NET_F_GUEST_UFO features are used, the Guest will need to -accept packets of up to 65550 bytes long (the maximum size of a -TCP or UDP packet, plus the 14 byte ethernet header), otherwise -1514 bytes. So unless VIRTIO_NET_F_MRG_RXBUF is negotiated, every -buffer in the receive queue needs to be at least this length [footnote: -Obviously each one can be split across multiple descriptor -elements. -]. - -If VIRTIO_NET_F_MRG_RXBUF is negotiated, each buffer must be at -least the size of the struct virtio_net_hdr. - - Packet Receive Interrupt - -When a packet is copied into a buffer in the receiveq, the -optimal path is to disable further interrupts for the receiveq -(see [sub:Receiving-Used-Buffers]) and process packets until no -more are found, then re-enable them. - -Processing packet involves: - - If the driver negotiated the VIRTIO_NET_F_MRG_RXBUF feature, - then the “num_buffers” field indicates how many descriptors - this packet is spread over (including this one). This allows - receipt of large packets without having to allocate large - buffers. In this case, there will be at least “num_buffers” in - the used ring, and they should be chained together to form a - single packet. The other buffers will not begin with a struct - virtio_net_hdr. - - If the VIRTIO_NET_F_MRG_RXBUF feature was not negotiated, or - the “num_buffers” field is one, then the entire packet will be - contained within this buffer, immediately following the struct - virtio_net_hdr. - - If the VIRTIO_NET_F_GUEST_CSUM feature was negotiated, the - VIRTIO_NET_HDR_F_NEEDS_CSUM bit in the “flags” field may be - set: if so, the checksum on the packet is incomplete and the “ - csum_start” and “csum_offset” fields indicate how to calculate - it (see [ite:csum_start-is-set]). - - If the VIRTIO_NET_F_GUEST_TSO4, TSO6 or UFO options were - negotiated, then the “gso_type” may be something other than - VIRTIO_NET_HDR_GSO_NONE, and the “gso_size” field indicates the - desired MSS (see [enu:If-the-driver]). - - Control Virtqueue - -The driver uses the control virtqueue (if VIRTIO_NET_F_VTRL_VQ is -negotiated) to send commands to manipulate various features of -the device which would not easily map into the configuration -space. - -All commands are of the following form: - -struct virtio_net_ctrl { - - u8 class; - - u8 command; - - u8 command-specific-data[]; - - u8 ack; - -}; - - - -/* ack values */ - -#define VIRTIO_NET_OK 0 - -#define VIRTIO_NET_ERR 1 - -The class, command and command-specific-data are set by the -driver, and the device sets the ack byte. There is little it can -do except issue a diagnostic if the ack byte is not -VIRTIO_NET_OK. - - Packet Receive Filtering - -If the VIRTIO_NET_F_CTRL_RX feature is negotiated, the driver can -send control commands for promiscuous mode, multicast receiving, -and filtering of MAC addresses. - -Note that in general, these commands are best-effort: unwanted -packets may still arrive. - - Setting Promiscuous Mode - -#define VIRTIO_NET_CTRL_RX 0 - - #define VIRTIO_NET_CTRL_RX_PROMISC 0 - - #define VIRTIO_NET_CTRL_RX_ALLMULTI 1 - -The class VIRTIO_NET_CTRL_RX has two commands: -VIRTIO_NET_CTRL_RX_PROMISC turns promiscuous mode on and off, and -VIRTIO_NET_CTRL_RX_ALLMULTI turns all-multicast receive on and -off. The command-specific-data is one byte containing 0 (off) or -1 (on). - - Setting MAC Address Filtering - -struct virtio_net_ctrl_mac { - - u32 entries; - - u8 macs[entries][ETH_ALEN]; - -}; - - - -#define VIRTIO_NET_CTRL_MAC 1 - - #define VIRTIO_NET_CTRL_MAC_TABLE_SET 0 - -The device can filter incoming packets by any number of -destination MAC addresses.[footnote: -Since there are no guarantees, it can use a hash filter -orsilently switch to allmulti or promiscuous mode if it is given -too many addresses. -] This table is set using the class VIRTIO_NET_CTRL_MAC and the -command VIRTIO_NET_CTRL_MAC_TABLE_SET. The command-specific-data -is two variable length tables of 6-byte MAC addresses. The first -table contains unicast addresses, and the second contains -multicast addresses. - - VLAN Filtering - -If the driver negotiates the VIRTION_NET_F_CTRL_VLAN feature, it -can control a VLAN filter table in the device. - -#define VIRTIO_NET_CTRL_VLAN 2 - - #define VIRTIO_NET_CTRL_VLAN_ADD 0 - - #define VIRTIO_NET_CTRL_VLAN_DEL 1 - -Both the VIRTIO_NET_CTRL_VLAN_ADD and VIRTIO_NET_CTRL_VLAN_DEL -command take a 16-bit VLAN id as the command-specific-data. - - Gratuitous Packet Sending - -If the driver negotiates the VIRTIO_NET_F_GUEST_ANNOUNCE (depends -on VIRTIO_NET_F_CTRL_VQ), it can ask the guest to send gratuitous -packets; this is usually done after the guest has been physically -migrated, and needs to announce its presence on the new network -links. (As hypervisor does not have the knowledge of guest -network configuration (eg. tagged vlan) it is simplest to prod -the guest in this way). - -#define VIRTIO_NET_CTRL_ANNOUNCE 3 - - #define VIRTIO_NET_CTRL_ANNOUNCE_ACK 0 - -The Guest needs to check VIRTIO_NET_S_ANNOUNCE bit in status -field when it notices the changes of device configuration. The -command VIRTIO_NET_CTRL_ANNOUNCE_ACK is used to indicate that -driver has recevied the notification and device would clear the -VIRTIO_NET_S_ANNOUNCE bit in the status filed after it received -this command. - -Processing this notification involves: - - Sending the gratuitous packets or marking there are pending - gratuitous packets to be sent and letting deferred routine to - send them. - - Sending VIRTIO_NET_CTRL_ANNOUNCE_ACK command through control - vq. - - . - -Appendix D: Block Device - -The virtio block device is a simple virtual block device (ie. -disk). Read and write requests (and other exotic requests) are -placed in the queue, and serviced (probably out of order) by the -device except where noted. - - Configuration - - Subsystem Device ID 2 - - Virtqueues 0:requestq. - - Feature bits - - VIRTIO_BLK_F_BARRIER (0) Host supports request barriers. - - VIRTIO_BLK_F_SIZE_MAX (1) Maximum size of any single segment is - in “size_max”. - - VIRTIO_BLK_F_SEG_MAX (2) Maximum number of segments in a - request is in “seg_max”. - - VIRTIO_BLK_F_GEOMETRY (4) Disk-style geometry specified in “ - geometry”. - - VIRTIO_BLK_F_RO (5) Device is read-only. - - VIRTIO_BLK_F_BLK_SIZE (6) Block size of disk is in “blk_size”. - - VIRTIO_BLK_F_SCSI (7) Device supports scsi packet commands. - - VIRTIO_BLK_F_FLUSH (9) Cache flush command support. - - Device configuration layout The capacity of the device - (expressed in 512-byte sectors) is always present. The - availability of the others all depend on various feature bits - as indicated above. struct virtio_blk_config { - - u64 capacity; - - u32 size_max; - - u32 seg_max; - - struct virtio_blk_geometry { - - u16 cylinders; - - u8 heads; - - u8 sectors; - - } geometry; - - u32 blk_size; - - - -}; - - Device Initialization - - The device size should be read from the “capacity” - configuration field. No requests should be submitted which goes - beyond this limit. - - If the VIRTIO_BLK_F_BLK_SIZE feature is negotiated, the - blk_size field can be read to determine the optimal sector size - for the driver to use. This does not effect the units used in - the protocol (always 512 bytes), but awareness of the correct - value can effect performance. - - If the VIRTIO_BLK_F_RO feature is set by the device, any write - requests will fail. - - Device Operation - -The driver queues requests to the virtqueue, and they are used by -the device (not necessarily in order). Each request is of form: - -struct virtio_blk_req { - - - - u32 type; - - u32 ioprio; - - u64 sector; - - char data[][512]; - - u8 status; - -}; - -If the device has VIRTIO_BLK_F_SCSI feature, it can also support -scsi packet command requests, each of these requests is of form:struct virtio_scsi_pc_req { - - u32 type; - - u32 ioprio; - - u64 sector; - - char cmd[]; - - char data[][512]; - -#define SCSI_SENSE_BUFFERSIZE 96 - - u8 sense[SCSI_SENSE_BUFFERSIZE]; - - u32 errors; - - u32 data_len; - - u32 sense_len; - - u32 residual; - - u8 status; - -}; - -The type of the request is either a read (VIRTIO_BLK_T_IN), a -write (VIRTIO_BLK_T_OUT), a scsi packet command -(VIRTIO_BLK_T_SCSI_CMD or VIRTIO_BLK_T_SCSI_CMD_OUT[footnote: -the SCSI_CMD and SCSI_CMD_OUT types are equivalent, the device -does not distinguish between them -]) or a flush (VIRTIO_BLK_T_FLUSH or VIRTIO_BLK_T_FLUSH_OUT[footnote: -the FLUSH and FLUSH_OUT types are equivalent, the device does not -distinguish between them -]). If the device has VIRTIO_BLK_F_BARRIER feature the high bit -(VIRTIO_BLK_T_BARRIER) indicates that this request acts as a -barrier and that all preceding requests must be complete before -this one, and all following requests must not be started until -this is complete. Note that a barrier does not flush caches in -the underlying backend device in host, and thus does not serve as -data consistency guarantee. Driver must use FLUSH request to -flush the host cache. - -#define VIRTIO_BLK_T_IN 0 - -#define VIRTIO_BLK_T_OUT 1 - -#define VIRTIO_BLK_T_SCSI_CMD 2 - -#define VIRTIO_BLK_T_SCSI_CMD_OUT 3 - -#define VIRTIO_BLK_T_FLUSH 4 - -#define VIRTIO_BLK_T_FLUSH_OUT 5 - -#define VIRTIO_BLK_T_BARRIER 0x80000000 - -The ioprio field is a hint about the relative priorities of -requests to the device: higher numbers indicate more important -requests. - -The sector number indicates the offset (multiplied by 512) where -the read or write is to occur. This field is unused and set to 0 -for scsi packet commands and for flush commands. - -The cmd field is only present for scsi packet command requests, -and indicates the command to perform. This field must reside in a -single, separate read-only buffer; command length can be derived -from the length of this buffer. - -Note that these first three (four for scsi packet commands) -fields are always read-only: the data field is either read-only -or write-only, depending on the request. The size of the read or -write can be derived from the total size of the request buffers. - -The sense field is only present for scsi packet command requests, -and indicates the buffer for scsi sense data. - -The data_len field is only present for scsi packet command -requests, this field is deprecated, and should be ignored by the -driver. Historically, devices copied data length there. - -The sense_len field is only present for scsi packet command -requests and indicates the number of bytes actually written to -the sense buffer. - -The residual field is only present for scsi packet command -requests and indicates the residual size, calculated as data -length - number of bytes actually transferred. - -The final status byte is written by the device: either -VIRTIO_BLK_S_OK for success, VIRTIO_BLK_S_IOERR for host or guest -error or VIRTIO_BLK_S_UNSUPP for a request unsupported by host:#define VIRTIO_BLK_S_OK 0 - -#define VIRTIO_BLK_S_IOERR 1 - -#define VIRTIO_BLK_S_UNSUPP 2 - -Historically, devices assumed that the fields type, ioprio and -sector reside in a single, separate read-only buffer; the fields -errors, data_len, sense_len and residual reside in a single, -separate write-only buffer; the sense field in a separate -write-only buffer of size 96 bytes, by itself; the fields errors, -data_len, sense_len and residual in a single write-only buffer; -and the status field is a separate read-only buffer of size 1 -byte, by itself. - -Appendix E: Console Device - -The virtio console device is a simple device for data input and -output. A device may have one or more ports. Each port has a pair -of input and output virtqueues. Moreover, a device has a pair of -control IO virtqueues. The control virtqueues are used to -communicate information between the device and the driver about -ports being opened and closed on either side of the connection, -indication from the host about whether a particular port is a -console port, adding new ports, port hot-plug/unplug, etc., and -indication from the guest about whether a port or a device was -successfully added, port open/close, etc.. For data IO, one or -more empty buffers are placed in the receive queue for incoming -data and outgoing characters are placed in the transmit queue. - - Configuration - - Subsystem Device ID 3 - - Virtqueues 0:receiveq(port0). 1:transmitq(port0), 2:control - receiveq[footnote: -Ports 2 onwards only if VIRTIO_CONSOLE_F_MULTIPORT is set -], 3:control transmitq, 4:receiveq(port1), 5:transmitq(port1), - ... - - Feature bits - - VIRTIO_CONSOLE_F_SIZE (0) Configuration cols and rows fields - are valid. - - VIRTIO_CONSOLE_F_MULTIPORT(1) Device has support for multiple - ports; configuration fields nr_ports and max_nr_ports are - valid and control virtqueues will be used. - - Device configuration layout The size of the console is supplied - in the configuration space if the VIRTIO_CONSOLE_F_SIZE feature - is set. Furthermore, if the VIRTIO_CONSOLE_F_MULTIPORT feature - is set, the maximum number of ports supported by the device can - be fetched.struct virtio_console_config { - - u16 cols; - - u16 rows; - - - - u32 max_nr_ports; - -}; - - Device Initialization - - If the VIRTIO_CONSOLE_F_SIZE feature is negotiated, the driver - can read the console dimensions from the configuration fields. - - If the VIRTIO_CONSOLE_F_MULTIPORT feature is negotiated, the - driver can spawn multiple ports, not all of which may be - attached to a console. Some could be generic ports. In this - case, the control virtqueues are enabled and according to the - max_nr_ports configuration-space value, the appropriate number - of virtqueues are created. A control message indicating the - driver is ready is sent to the host. The host can then send - control messages for adding new ports to the device. After - creating and initializing each port, a - VIRTIO_CONSOLE_PORT_READY control message is sent to the host - for that port so the host can let us know of any additional - configuration options set for that port. - - The receiveq for each port is populated with one or more - receive buffers. - - Device Operation - - For output, a buffer containing the characters is placed in the - port's transmitq.[footnote: -Because this is high importance and low bandwidth, the current -Linux implementation polls for the buffer to be used, rather than -waiting for an interrupt, simplifying the implementation -significantly. However, for generic serial ports with the -O_NONBLOCK flag set, the polling limitation is relaxed and the -consumed buffers are freed upon the next write or poll call or -when a port is closed or hot-unplugged. -] - - When a buffer is used in the receiveq (signalled by an - interrupt), the contents is the input to the port associated - with the virtqueue for which the notification was received. - - If the driver negotiated the VIRTIO_CONSOLE_F_SIZE feature, a - configuration change interrupt may occur. The updated size can - be read from the configuration fields. - - If the driver negotiated the VIRTIO_CONSOLE_F_MULTIPORT - feature, active ports are announced by the host using the - VIRTIO_CONSOLE_PORT_ADD control message. The same message is - used for port hot-plug as well. - - If the host specified a port `name', a sysfs attribute is - created with the name filled in, so that udev rules can be - written that can create a symlink from the port's name to the - char device for port discovery by applications in the guest. - - Changes to ports' state are effected by control messages. - Appropriate action is taken on the port indicated in the - control message. The layout of the structure of the control - buffer and the events associated are:struct virtio_console_control { - - uint32_t id; /* Port number */ - - uint16_t event; /* The kind of control event */ - - uint16_t value; /* Extra information for the event */ - -}; - - - -/* Some events for the internal messages (control packets) */ - - - -#define VIRTIO_CONSOLE_DEVICE_READY 0 - -#define VIRTIO_CONSOLE_PORT_ADD 1 - -#define VIRTIO_CONSOLE_PORT_REMOVE 2 - -#define VIRTIO_CONSOLE_PORT_READY 3 - -#define VIRTIO_CONSOLE_CONSOLE_PORT 4 - -#define VIRTIO_CONSOLE_RESIZE 5 - -#define VIRTIO_CONSOLE_PORT_OPEN 6 - -#define VIRTIO_CONSOLE_PORT_NAME 7 - -Appendix F: Entropy Device - -The virtio entropy device supplies high-quality randomness for -guest use. - - Configuration - - Subsystem Device ID 4 - - Virtqueues 0:requestq. - - Feature bits None currently defined - - Device configuration layout None currently defined. - - Device Initialization - - The virtqueue is initialized - - Device Operation - -When the driver requires random bytes, it places the descriptor -of one or more buffers in the queue. It will be completely filled -by random data by the device. - -Appendix G: Memory Balloon Device - -The virtio memory balloon device is a primitive device for -managing guest memory: the device asks for a certain amount of -memory, and the guest supplies it (or withdraws it, if the device -has more than it asks for). This allows the guest to adapt to -changes in allowance of underlying physical memory. If the -feature is negotiated, the device can also be used to communicate -guest memory statistics to the host. - - Configuration - - Subsystem Device ID 5 - - Virtqueues 0:inflateq. 1:deflateq. 2:statsq.[footnote: -Only if VIRTIO_BALLON_F_STATS_VQ set -] - - Feature bits - - VIRTIO_BALLOON_F_MUST_TELL_HOST (0) Host must be told before - pages from the balloon are used. - - VIRTIO_BALLOON_F_STATS_VQ (1) A virtqueue for reporting guest - memory statistics is present. - - Device configuration layout Both fields of this configuration - are always available. Note that they are little endian, despite - convention that device fields are guest endian:struct virtio_balloon_config { - - u32 num_pages; - - u32 actual; - -}; - - Device Initialization - - The inflate and deflate virtqueues are identified. - - If the VIRTIO_BALLOON_F_STATS_VQ feature bit is negotiated: - - Identify the stats virtqueue. - - Add one empty buffer to the stats virtqueue and notify the - host. - -Device operation begins immediately. - - Device Operation - - Memory Ballooning The device is driven by the receipt of a - configuration change interrupt. - - The “num_pages” configuration field is examined. If this is - greater than the “actual” number of pages, memory must be given - to the balloon. If it is less than the “actual” number of - pages, memory may be taken back from the balloon for general - use. - - To supply memory to the balloon (aka. inflate): - - The driver constructs an array of addresses of unused memory - pages. These addresses are divided by 4096[footnote: -This is historical, and independent of the guest page size -] and the descriptor describing the resulting 32-bit array is - added to the inflateq. - - To remove memory from the balloon (aka. deflate): - - The driver constructs an array of addresses of memory pages it - has previously given to the balloon, as described above. This - descriptor is added to the deflateq. - - If the VIRTIO_BALLOON_F_MUST_TELL_HOST feature is set, the - guest may not use these requested pages until that descriptor - in the deflateq has been used by the device. - - Otherwise, the guest may begin to re-use pages previously given - to the balloon before the device has acknowledged their - withdrawl. [footnote: -In this case, deflation advice is merely a courtesy -] - - In either case, once the device has completed the inflation or - deflation, the “actual” field of the configuration should be - updated to reflect the new number of pages in the balloon.[footnote: -As updates to configuration space are not atomic, this field -isn't particularly reliable, but can be used to diagnose buggy -guests. -] - - Memory Statistics - -The stats virtqueue is atypical because communication is driven -by the device (not the driver). The channel becomes active at -driver initialization time when the driver adds an empty buffer -and notifies the device. A request for memory statistics proceeds -as follows: - - The device pushes the buffer onto the used ring and sends an - interrupt. - - The driver pops the used buffer and discards it. - - The driver collects memory statistics and writes them into a - new buffer. - - The driver adds the buffer to the virtqueue and notifies the - device. - - The device pops the buffer (retaining it to initiate a - subsequent request) and consumes the statistics. - - Memory Statistics Format Each statistic consists of a 16 bit - tag and a 64 bit value. Both quantities are represented in the - native endian of the guest. All statistics are optional and the - driver may choose which ones to supply. To guarantee backwards - compatibility, unsupported statistics should be omitted. - - struct virtio_balloon_stat { - -#define VIRTIO_BALLOON_S_SWAP_IN 0 - -#define VIRTIO_BALLOON_S_SWAP_OUT 1 - -#define VIRTIO_BALLOON_S_MAJFLT 2 - -#define VIRTIO_BALLOON_S_MINFLT 3 - -#define VIRTIO_BALLOON_S_MEMFREE 4 - -#define VIRTIO_BALLOON_S_MEMTOT 5 - - u16 tag; - - u64 val; - -} __attribute__((packed)); - - Tags - - VIRTIO_BALLOON_S_SWAP_IN The amount of memory that has been - swapped in (in bytes). - - VIRTIO_BALLOON_S_SWAP_OUT The amount of memory that has been - swapped out to disk (in bytes). - - VIRTIO_BALLOON_S_MAJFLT The number of major page faults that - have occurred. - - VIRTIO_BALLOON_S_MINFLT The number of minor page faults that - have occurred. - - VIRTIO_BALLOON_S_MEMFREE The amount of memory not being used - for any purpose (in bytes). - - VIRTIO_BALLOON_S_MEMTOT The total amount of memory available - (in bytes). - -Appendix H: Rpmsg: Remote Processor Messaging - -Virtio rpmsg devices represent remote processors on the system -which run in asymmetric multi-processing (AMP) configuration, and -which are usually used to offload cpu-intensive tasks from the -main application processor (a typical SoC methodology). - -Virtio is being used to communicate with those remote processors; -empty buffers are placed in one virtqueue for receiving messages, -and non-empty buffers, containing outbound messages, are enqueued -in a second virtqueue for transmission. - -Numerous communication channels can be multiplexed over those two -virtqueues, so different entities, running on the application and -remote processor, can directly communicate in a point-to-point -fashion. - - Configuration - - Subsystem Device ID 7 - - Virtqueues 0:receiveq. 1:transmitq. - - Feature bits - - VIRTIO_RPMSG_F_NS (0) Device sends (and capable of receiving) - name service messages announcing the creation (or - destruction) of a channel:/** - - * struct rpmsg_ns_msg - dynamic name service announcement -message - - * @name: name of remote service that is published - - * @addr: address of remote service that is published - - * @flags: indicates whether service is created or destroyed - - * - - * This message is sent across to publish a new service (or -announce - - * about its removal). When we receives these messages, an -appropriate - - * rpmsg channel (i.e device) is created/destroyed. - - */ - -struct rpmsg_ns_msgoon_config { - - char name[RPMSG_NAME_SIZE]; - - u32 addr; - - u32 flags; - -} __packed; - - - -/** - - * enum rpmsg_ns_flags - dynamic name service announcement flags - - * - - * @RPMSG_NS_CREATE: a new remote service was just created - - * @RPMSG_NS_DESTROY: a remote service was just destroyed - - */ - -enum rpmsg_ns_flags { - - RPMSG_NS_CREATE = 0, - - RPMSG_NS_DESTROY = 1, - -}; - - Device configuration layout - -At his point none currently defined. - - Device Initialization - - The initialization routine should identify the receive and - transmission virtqueues. - - The receive virtqueue should be filled with receive buffers. - - Device Operation - -Messages are transmitted by placing them in the transmitq, and -buffers for inbound messages are placed in the receiveq. In any -case, messages are always preceded by the following header: /** - - * struct rpmsg_hdr - common header for all rpmsg messages - - * @src: source address - - * @dst: destination address - - * @reserved: reserved for future use - - * @len: length of payload (in bytes) - - * @flags: message flags - - * @data: @len bytes of message payload data - - * - - * Every message sent(/received) on the rpmsg bus begins with -this header. - - */ - -struct rpmsg_hdr { - - u32 src; - - u32 dst; - - u32 reserved; - - u16 len; - - u16 flags; - - u8 data[0]; - -} __packed; - -Appendix I: SCSI Host Device - -The virtio SCSI host device groups together one or more virtual -logical units (such as disks), and allows communicating to them -using the SCSI protocol. An instance of the device represents a -SCSI host to which many targets and LUNs are attached. - -The virtio SCSI device services two kinds of requests: - - command requests for a logical unit; - - task management functions related to a logical unit, target or - command. - -The device is also able to send out notifications about added and -removed logical units. Together, these capabilities provide a -SCSI transport protocol that uses virtqueues as the transfer -medium. In the transport protocol, the virtio driver acts as the -initiator, while the virtio SCSI host provides one or more -targets that receive and process the requests. - - Configuration - - Subsystem Device ID 8 - - Virtqueues 0:controlq; 1:eventq; 2..n:request queues. - - Feature bits - - VIRTIO_SCSI_F_INOUT (0) A single request can include both - read-only and write-only data buffers. - - VIRTIO_SCSI_F_HOTPLUG (1) The host should enable - hot-plug/hot-unplug of new LUNs and targets on the SCSI bus. - - Device configuration layout All fields of this configuration - are always available. sense_size and cdb_size are writable by - the guest.struct virtio_scsi_config { - - u32 num_queues; - - u32 seg_max; - - u32 max_sectors; - - u32 cmd_per_lun; - - u32 event_info_size; - - u32 sense_size; - - u32 cdb_size; - - u16 max_channel; - - u16 max_target; - - u32 max_lun; - -}; - - num_queues is the total number of request virtqueues exposed by - the device. The driver is free to use only one request queue, - or it can use more to achieve better performance. - - seg_max is the maximum number of segments that can be in a - command. A bidirectional command can include seg_max input - segments and seg_max output segments. - - max_sectors is a hint to the guest about the maximum transfer - size it should use. - - cmd_per_lun is a hint to the guest about the maximum number of - linked commands it should send to one LUN. The actual value - to be used is the minimum of cmd_per_lun and the virtqueue - size. - - event_info_size is the maximum size that the device will fill - for buffers that the driver places in the eventq. The driver - should always put buffers at least of this size. It is - written by the device depending on the set of negotated - features. - - sense_size is the maximum size of the sense data that the - device will write. The default value is written by the device - and will always be 96, but the driver can modify it. It is - restored to the default when the device is reset. - - cdb_size is the maximum size of the CDB that the driver will - write. The default value is written by the device and will - always be 32, but the driver can likewise modify it. It is - restored to the default when the device is reset. - - max_channel, max_target and max_lun can be used by the driver - as hints to constrain scanning the logical units on the - host.h - - Device Initialization - -The initialization routine should first of all discover the -device's virtqueues. - -If the driver uses the eventq, it should then place at least a -buffer in the eventq. - -The driver can immediately issue requests (for example, INQUIRY -or REPORT LUNS) or task management functions (for example, I_T -RESET). - - Device Operation: request queues - -The driver queues requests to an arbitrary request queue, and -they are used by the device on that same queue. It is the -responsibility of the driver to ensure strict request ordering -for commands placed on different queues, because they will be -consumed with no order constraints. - -Requests have the following format: - -struct virtio_scsi_req_cmd { - - // Read-only - - u8 lun[8]; - - u64 id; - - u8 task_attr; - - u8 prio; - - u8 crn; - - char cdb[cdb_size]; - - char dataout[]; - - // Write-only part - - u32 sense_len; - - u32 residual; - - u16 status_qualifier; - - u8 status; - - u8 response; - - u8 sense[sense_size]; - - char datain[]; - -}; - - - -/* command-specific response values */ - -#define VIRTIO_SCSI_S_OK 0 - -#define VIRTIO_SCSI_S_OVERRUN 1 - -#define VIRTIO_SCSI_S_ABORTED 2 - -#define VIRTIO_SCSI_S_BAD_TARGET 3 - -#define VIRTIO_SCSI_S_RESET 4 - -#define VIRTIO_SCSI_S_BUSY 5 - -#define VIRTIO_SCSI_S_TRANSPORT_FAILURE 6 - -#define VIRTIO_SCSI_S_TARGET_FAILURE 7 - -#define VIRTIO_SCSI_S_NEXUS_FAILURE 8 - -#define VIRTIO_SCSI_S_FAILURE 9 - - - -/* task_attr */ - -#define VIRTIO_SCSI_S_SIMPLE 0 - -#define VIRTIO_SCSI_S_ORDERED 1 - -#define VIRTIO_SCSI_S_HEAD 2 - -#define VIRTIO_SCSI_S_ACA 3 - -The lun field addresses a target and logical unit in the -virtio-scsi device's SCSI domain. The only supported format for -the LUN field is: first byte set to 1, second byte set to target, -third and fourth byte representing a single level LUN structure, -followed by four zero bytes. With this representation, a -virtio-scsi device can serve up to 256 targets and 16384 LUNs per -target. - -The id field is the command identifier (“tag”). - -task_attr, prio and crn should be left to zero. task_attr defines -the task attribute as in the table above, but all task attributes -may be mapped to SIMPLE by the device; crn may also be provided -by clients, but is generally expected to be 0. The maximum CRN -value defined by the protocol is 255, since CRN is stored in an -8-bit integer. - -All of these fields are defined in SAM. They are always -read-only, as are the cdb and dataout field. The cdb_size is -taken from the configuration space. - -sense and subsequent fields are always write-only. The sense_len -field indicates the number of bytes actually written to the sense -buffer. The residual field indicates the residual size, -calculated as “data_length - number_of_transferred_bytes”, for -read or write operations. For bidirectional commands, the -number_of_transferred_bytes includes both read and written bytes. -A residual field that is less than the size of datain means that -the dataout field was processed entirely. A residual field that -exceeds the size of datain means that the dataout field was -processed partially and the datain field was not processed at -all. - -The status byte is written by the device to be the status code as -defined in SAM. - -The response byte is written by the device to be one of the -following: - - VIRTIO_SCSI_S_OK when the request was completed and the status - byte is filled with a SCSI status code (not necessarily - "GOOD"). - - VIRTIO_SCSI_S_OVERRUN if the content of the CDB requires - transferring more data than is available in the data buffers. - - VIRTIO_SCSI_S_ABORTED if the request was cancelled due to an - ABORT TASK or ABORT TASK SET task management function. - - VIRTIO_SCSI_S_BAD_TARGET if the request was never processed - because the target indicated by the lun field does not exist. - - VIRTIO_SCSI_S_RESET if the request was cancelled due to a bus - or device reset (including a task management function). - - VIRTIO_SCSI_S_TRANSPORT_FAILURE if the request failed due to a - problem in the connection between the host and the target - (severed link). - - VIRTIO_SCSI_S_TARGET_FAILURE if the target is suffering a - failure and the guest should not retry on other paths. - - VIRTIO_SCSI_S_NEXUS_FAILURE if the nexus is suffering a failure - but retrying on other paths might yield a different result. - - VIRTIO_SCSI_S_BUSY if the request failed but retrying on the - same path should work. - - VIRTIO_SCSI_S_FAILURE for other host or guest error. In - particular, if neither dataout nor datain is empty, and the - VIRTIO_SCSI_F_INOUT feature has not been negotiated, the - request will be immediately returned with a response equal to - VIRTIO_SCSI_S_FAILURE. - - Device Operation: controlq - -The controlq is used for other SCSI transport operations. -Requests have the following format: - -struct virtio_scsi_ctrl { - - u32 type; - - ... - - u8 response; - -}; - - - -/* response values valid for all commands */ - -#define VIRTIO_SCSI_S_OK 0 - -#define VIRTIO_SCSI_S_BAD_TARGET 3 - -#define VIRTIO_SCSI_S_BUSY 5 - -#define VIRTIO_SCSI_S_TRANSPORT_FAILURE 6 - -#define VIRTIO_SCSI_S_TARGET_FAILURE 7 - -#define VIRTIO_SCSI_S_NEXUS_FAILURE 8 - -#define VIRTIO_SCSI_S_FAILURE 9 - -#define VIRTIO_SCSI_S_INCORRECT_LUN 12 - -The type identifies the remaining fields. - -The following commands are defined: - - Task management function -#define VIRTIO_SCSI_T_TMF 0 - - - -#define VIRTIO_SCSI_T_TMF_ABORT_TASK 0 - -#define VIRTIO_SCSI_T_TMF_ABORT_TASK_SET 1 - -#define VIRTIO_SCSI_T_TMF_CLEAR_ACA 2 - -#define VIRTIO_SCSI_T_TMF_CLEAR_TASK_SET 3 - -#define VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET 4 - -#define VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET 5 - -#define VIRTIO_SCSI_T_TMF_QUERY_TASK 6 - -#define VIRTIO_SCSI_T_TMF_QUERY_TASK_SET 7 - - - -struct virtio_scsi_ctrl_tmf - -{ - - // Read-only part - - u32 type; - - u32 subtype; - - u8 lun[8]; - - u64 id; - - // Write-only part - - u8 response; - -} - - - -/* command-specific response values */ - -#define VIRTIO_SCSI_S_FUNCTION_COMPLETE 0 - -#define VIRTIO_SCSI_S_FUNCTION_SUCCEEDED 10 - -#define VIRTIO_SCSI_S_FUNCTION_REJECTED 11 - - The type is VIRTIO_SCSI_T_TMF; the subtype field defines. All - fields except response are filled by the driver. The subtype - field must always be specified and identifies the requested - task management function. - - Other fields may be irrelevant for the requested TMF; if so, - they are ignored but they should still be present. The lun - field is in the same format specified for request queues; the - single level LUN is ignored when the task management function - addresses a whole I_T nexus. When relevant, the value of the id - field is matched against the id values passed on the requestq. - - The outcome of the task management function is written by the - device in the response field. The command-specific response - values map 1-to-1 with those defined in SAM. - - Asynchronous notification query -#define VIRTIO_SCSI_T_AN_QUERY 1 - - - -struct virtio_scsi_ctrl_an { - - // Read-only part - - u32 type; - - u8 lun[8]; - - u32 event_requested; - - // Write-only part - - u32 event_actual; - - u8 response; - -} - - - -#define VIRTIO_SCSI_EVT_ASYNC_OPERATIONAL_CHANGE 2 - -#define VIRTIO_SCSI_EVT_ASYNC_POWER_MGMT 4 - -#define VIRTIO_SCSI_EVT_ASYNC_EXTERNAL_REQUEST 8 - -#define VIRTIO_SCSI_EVT_ASYNC_MEDIA_CHANGE 16 - -#define VIRTIO_SCSI_EVT_ASYNC_MULTI_HOST 32 - -#define VIRTIO_SCSI_EVT_ASYNC_DEVICE_BUSY 64 - - By sending this command, the driver asks the device which - events the given LUN can report, as described in paragraphs 6.6 - and A.6 of the SCSI MMC specification. The driver writes the - events it is interested in into the event_requested; the device - responds by writing the events that it supports into - event_actual. - - The type is VIRTIO_SCSI_T_AN_QUERY. The lun and event_requested - fields are written by the driver. The event_actual and response - fields are written by the device. - - No command-specific values are defined for the response byte. - - Asynchronous notification subscription -#define VIRTIO_SCSI_T_AN_SUBSCRIBE 2 - - - -struct virtio_scsi_ctrl_an { - - // Read-only part - - u32 type; - - u8 lun[8]; - - u32 event_requested; - - // Write-only part - - u32 event_actual; - - u8 response; - -} - - By sending this command, the driver asks the specified LUN to - report events for its physical interface, again as described in - the SCSI MMC specification. The driver writes the events it is - interested in into the event_requested; the device responds by - writing the events that it supports into event_actual. - - Event types are the same as for the asynchronous notification - query message. - - The type is VIRTIO_SCSI_T_AN_SUBSCRIBE. The lun and - event_requested fields are written by the driver. The - event_actual and response fields are written by the device. - - No command-specific values are defined for the response byte. - - Device Operation: eventq - -The eventq is used by the device to report information on logical -units that are attached to it. The driver should always leave a -few buffers ready in the eventq. In general, the device will not -queue events to cope with an empty eventq, and will end up -dropping events if it finds no buffer ready. However, when -reporting events for many LUNs (e.g. when a whole target -disappears), the device can throttle events to avoid dropping -them. For this reason, placing 10-15 buffers on the event queue -should be enough. - -Buffers are placed in the eventq and filled by the device when -interesting events occur. The buffers should be strictly -write-only (device-filled) and the size of the buffers should be -at least the value given in the device's configuration -information. - -Buffers returned by the device on the eventq will be referred to -as "events" in the rest of this section. Events have the -following format: - -#define VIRTIO_SCSI_T_EVENTS_MISSED 0x80000000 - - - -struct virtio_scsi_event { - - // Write-only part - - u32 event; - - ... - -} - -If bit 31 is set in the event field, the device failed to report -an event due to missing buffers. In this case, the driver should -poll the logical units for unit attention conditions, and/or do -whatever form of bus scan is appropriate for the guest operating -system. - -Other data that the device writes to the buffer depends on the -contents of the event field. The following events are defined: - - No event -#define VIRTIO_SCSI_T_NO_EVENT 0 - - This event is fired in the following cases: - - When the device detects in the eventq a buffer that is shorter - than what is indicated in the configuration field, it might - use it immediately and put this dummy value in the event - field. A well-written driver will never observe this - situation. - - When events are dropped, the device may signal this event as - soon as the drivers makes a buffer available, in order to - request action from the driver. In this case, of course, this - event will be reported with the VIRTIO_SCSI_T_EVENTS_MISSED - flag. - - Transport reset -#define VIRTIO_SCSI_T_TRANSPORT_RESET 1 - - - -struct virtio_scsi_event_reset { - - // Write-only part - - u32 event; - - u8 lun[8]; - - u32 reason; - -} - - - -#define VIRTIO_SCSI_EVT_RESET_HARD 0 - -#define VIRTIO_SCSI_EVT_RESET_RESCAN 1 - -#define VIRTIO_SCSI_EVT_RESET_REMOVED 2 - - By sending this event, the device signals that a logical unit - on a target has been reset, including the case of a new device - appearing or disappearing on the bus.The device fills in all - fields. The event field is set to - VIRTIO_SCSI_T_TRANSPORT_RESET. The lun field addresses a - logical unit in the SCSI host. - - The reason value is one of the three #define values appearing - above: - - VIRTIO_SCSI_EVT_RESET_REMOVED (“LUN/target removed”) is used if - the target or logical unit is no longer able to receive - commands. - - VIRTIO_SCSI_EVT_RESET_HARD (“LUN hard reset”) is used if the - logical unit has been reset, but is still present. - - VIRTIO_SCSI_EVT_RESET_RESCAN (“rescan LUN/target”) is used if a - target or logical unit has just appeared on the device. - - The “removed” and “rescan” events, when sent for LUN 0, may - apply to the entire target. After receiving them the driver - should ask the initiator to rescan the target, in order to - detect the case when an entire target has appeared or - disappeared. These two events will never be reported unless the - VIRTIO_SCSI_F_HOTPLUG feature was negotiated between the host - and the guest. - - Events will also be reported via sense codes (this obviously - does not apply to newly appeared buses or targets, since the - application has never discovered them): - - “LUN/target removed” maps to sense key ILLEGAL REQUEST, asc - 0x25, ascq 0x00 (LOGICAL UNIT NOT SUPPORTED) - - “LUN hard reset” maps to sense key UNIT ATTENTION, asc 0x29 - (POWER ON, RESET OR BUS DEVICE RESET OCCURRED) - - “rescan LUN/target” maps to sense key UNIT ATTENTION, asc 0x3f, - ascq 0x0e (REPORTED LUNS DATA HAS CHANGED) - - The preferred way to detect transport reset is always to use - events, because sense codes are only seen by the driver when it - sends a SCSI command to the logical unit or target. However, in - case events are dropped, the initiator will still be able to - synchronize with the actual state of the controller if the - driver asks the initiator to rescan of the SCSI bus. During the - rescan, the initiator will be able to observe the above sense - codes, and it will process them as if it the driver had - received the equivalent event. - - Asynchronous notification -#define VIRTIO_SCSI_T_ASYNC_NOTIFY 2 - - - -struct virtio_scsi_event_an { - - // Write-only part - - u32 event; - - u8 lun[8]; - - u32 reason; - -} - - By sending this event, the device signals that an asynchronous - event was fired from a physical interface. - - All fields are written by the device. The event field is set to - VIRTIO_SCSI_T_ASYNC_NOTIFY. The lun field addresses a logical - unit in the SCSI host. The reason field is a subset of the - events that the driver has subscribed to via the "Asynchronous - notification subscription" command. - - When dropped events are reported, the driver should poll for - asynchronous events manually using SCSI commands. - -Appendix X: virtio-mmio - -Virtual environments without PCI support (a common situation in -embedded devices models) might use simple memory mapped device (“ -virtio-mmio”) instead of the PCI device. - -The memory mapped virtio device behaviour is based on the PCI -device specification. Therefore most of operations like device -initialization, queues configuration and buffer transfers are -nearly identical. Existing differences are described in the -following sections. - - Device Initialization - -Instead of using the PCI IO space for virtio header, the “ -virtio-mmio” device provides a set of memory mapped control -registers, all 32 bits wide, followed by device-specific -configuration space. The following list presents their layout: - - Offset from the device base address | Direction | Name - Description - - 0x000 | R | MagicValue - “virt” string. - - 0x004 | R | Version - Device version number. Currently must be 1. - - 0x008 | R | DeviceID - Virtio Subsystem Device ID (ie. 1 for network card). - - 0x00c | R | VendorID - Virtio Subsystem Vendor ID. - - 0x010 | R | HostFeatures - Flags representing features the device supports. - Reading from this register returns 32 consecutive flag bits, - first bit depending on the last value written to - HostFeaturesSel register. Access to this register returns bits HostFeaturesSel*32 - - to (HostFeaturesSel*32)+31 -, eg. feature bits 0 to 31 if - HostFeaturesSel is set to 0 and features bits 32 to 63 if - HostFeaturesSel is set to 1. Also see [sub:Feature-Bits] - - 0x014 | W | HostFeaturesSel - Device (Host) features word selection. - Writing to this register selects a set of 32 device feature bits - accessible by reading from HostFeatures register. Device driver - must write a value to the HostFeaturesSel register before - reading from the HostFeatures register. - - 0x020 | W | GuestFeatures - Flags representing device features understood and activated by - the driver. - Writing to this register sets 32 consecutive flag bits, first - bit depending on the last value written to GuestFeaturesSel - register. Access to this register sets bits GuestFeaturesSel*32 - - to (GuestFeaturesSel*32)+31 -, eg. feature bits 0 to 31 if - GuestFeaturesSel is set to 0 and features bits 32 to 63 if - GuestFeaturesSel is set to 1. Also see [sub:Feature-Bits] - - 0x024 | W | GuestFeaturesSel - Activated (Guest) features word selection. - Writing to this register selects a set of 32 activated feature - bits accessible by writing to the GuestFeatures register. - Device driver must write a value to the GuestFeaturesSel - register before writing to the GuestFeatures register. - - 0x028 | W | GuestPageSize - Guest page size. - Device driver must write the guest page size in bytes to the - register during initialization, before any queues are used. - This value must be a power of 2 and is used by the Host to - calculate Guest address of the first queue page (see QueuePFN). - - 0x030 | W | QueueSel - Virtual queue index (first queue is 0). - Writing to this register selects the virtual queue that the - following operations on QueueNum, QueueAlign and QueuePFN apply - to. - - 0x034 | R | QueueNumMax - Maximum virtual queue size. - Reading from the register returns the maximum size of the queue - the Host is ready to process or zero (0x0) if the queue is not - available. This applies to the queue selected by writing to - QueueSel and is allowed only when QueuePFN is set to zero - (0x0), so when the queue is not actively used. - - 0x038 | W | QueueNum - Virtual queue size. - Queue size is a number of elements in the queue, therefore size - of the descriptor table and both available and used rings. - Writing to this register notifies the Host what size of the - queue the Guest will use. This applies to the queue selected by - writing to QueueSel. - - 0x03c | W | QueueAlign - Used Ring alignment in the virtual queue. - Writing to this register notifies the Host about alignment - boundary of the Used Ring in bytes. This value must be a power - of 2 and applies to the queue selected by writing to QueueSel. - - 0x040 | RW | QueuePFN - Guest physical page number of the virtual queue. - Writing to this register notifies the host about location of the - virtual queue in the Guest's physical address space. This value - is the index number of a page starting with the queue - Descriptor Table. Value zero (0x0) means physical address zero - (0x00000000) and is illegal. When the Guest stops using the - queue it must write zero (0x0) to this register. - Reading from this register returns the currently used page - number of the queue, therefore a value other than zero (0x0) - means that the queue is in use. - Both read and write accesses apply to the queue selected by - writing to QueueSel. - - 0x050 | W | QueueNotify - Queue notifier. - Writing a queue index to this register notifies the Host that - there are new buffers to process in the queue. - - 0x60 | R | InterruptStatus -Interrupt status. -Reading from this register returns a bit mask of interrupts - asserted by the device. An interrupt is asserted if the - corresponding bit is set, ie. equals one (1). - - Bit 0 | Used Ring Update -This interrupt is asserted when the Host has updated the Used - Ring in at least one of the active virtual queues. - - Bit 1 | Configuration change -This interrupt is asserted when configuration of the device has - changed. - - 0x064 | W | InterruptACK - Interrupt acknowledge. - Writing to this register notifies the Host that the Guest - finished handling interrupts. Set bits in the value clear the - corresponding bits of the InterruptStatus register. - - 0x070 | RW | Status - Device status. - Reading from this register returns the current device status - flags. - Writing non-zero values to this register sets the status flags, - indicating the Guest progress. Writing zero (0x0) to this - register triggers a device reset. - Also see [sub:Device-Initialization-Sequence] - - 0x100+ | RW | Config - Device-specific configuration space starts at an offset 0x100 - and is accessed with byte alignment. Its meaning and size - depends on the device and the driver. - -Virtual queue size is a number of elements in the queue, -therefore size of the descriptor table and both available and -used rings. - -The endianness of the registers follows the native endianness of -the Guest. Writing to registers described as “R” and reading from -registers described as “W” is not permitted and can cause -undefined behavior. - -The device initialization is performed as described in [sub:Device-Initialization-Sequence] - with one exception: the Guest must notify the Host about its -page size, writing the size in bytes to GuestPageSize register -before the initialization is finished. - -The memory mapped virtio devices generate single interrupt only, -therefore no special configuration is required. - - Virtqueue Configuration - -The virtual queue configuration is performed in a similar way to -the one described in [sec:Virtqueue-Configuration] with a few -additional operations: - - Select the queue writing its index (first queue is 0) to the - QueueSel register. - - Check if the queue is not already in use: read QueuePFN - register, returned value should be zero (0x0). - - Read maximum queue size (number of elements) from the - QueueNumMax register. If the returned value is zero (0x0) the - queue is not available. - - Allocate and zero the queue pages in contiguous virtual memory, - aligning the Used Ring to an optimal boundary (usually page - size). Size of the allocated queue may be smaller than or equal - to the maximum size returned by the Host. - - Notify the Host about the queue size by writing the size to - QueueNum register. - - Notify the Host about the used alignment by writing its value - in bytes to QueueAlign register. - - Write the physical number of the first page of the queue to the - QueuePFN register. - -The queue and the device are ready to begin normal operations -now. - - Device Operation - -The memory mapped virtio device behaves in the same way as -described in [sec:Device-Operation], with the following -exceptions: - - The device is notified about new buffers available in a queue - by writing the queue index to register QueueNum instead of the - virtio header in PCI I/O space ([sub:Notifying-The-Device]). - - The memory mapped virtio device is using single, dedicated - interrupt signal, which is raised when at least one of the - interrupts described in the InterruptStatus register - description is asserted. After receiving an interrupt, the - driver must read the InterruptStatus register to check what - caused the interrupt (see the register description). After the - interrupt is handled, the driver must acknowledge it by writing - a bit mask corresponding to the serviced interrupt to the - InterruptACK register. - diff --git a/trunk/Documentation/xtensa/mmu.txt b/trunk/Documentation/xtensa/mmu.txt new file mode 100644 index 000000000000..2b1af7606d57 --- /dev/null +++ b/trunk/Documentation/xtensa/mmu.txt @@ -0,0 +1,46 @@ +MMUv3 initialization sequence. + +The code in the initialize_mmu macro sets up MMUv3 memory mapping +identically to MMUv2 fixed memory mapping. Depending on +CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX symbol this code is +located in one of the following address ranges: + + 0xF0000000..0xFFFFFFFF (will keep same address in MMU v2 layout; + typically ROM) + 0x00000000..0x07FFFFFF (system RAM; this code is actually linked + at 0xD0000000..0xD7FFFFFF [cached] + or 0xD8000000..0xDFFFFFFF [uncached]; + in any case, initially runs elsewhere + than linked, so have to be careful) + +The code has the following assumptions: + This code fragment is run only on an MMU v3. + TLBs are in their reset state. + ITLBCFG and DTLBCFG are zero (reset state). + RASID is 0x04030201 (reset state). + PS.RING is zero (reset state). + LITBASE is zero (reset state, PC-relative literals); required to be PIC. + +TLB setup proceeds along the following steps. + + Legend: + VA = virtual address (two upper nibbles of it); + PA = physical address (two upper nibbles of it); + pc = physical range that contains this code; + +After step 2, we jump to virtual address in 0x40000000..0x5fffffff +that corresponds to next instruction to execute in this code. +After step 4, we jump to intended (linked) address of this code. + + Step 0 Step1 Step 2 Step3 Step 4 Step5 + ============ ===== ============ ===== ============ ===== + VA PA PA VA PA PA VA PA PA + ------ -- -- ------ -- -- ------ -- -- + E0..FF -> E0 -> E0 E0..FF -> E0 F0..FF -> F0 -> F0 + C0..DF -> C0 -> C0 C0..DF -> C0 E0..EF -> F0 -> F0 + A0..BF -> A0 -> A0 A0..BF -> A0 D8..DF -> 00 -> 00 + 80..9F -> 80 -> 80 80..9F -> 80 D0..D7 -> 00 -> 00 + 60..7F -> 60 -> 60 60..7F -> 60 + 40..5F -> 40 40..5F -> pc -> pc 40..5F -> pc + 20..3F -> 20 -> 20 20..3F -> 20 + 00..1F -> 00 -> 00 00..1F -> 00 diff --git a/trunk/Documentation/zh_CN/gpio.txt b/trunk/Documentation/zh_CN/gpio.txt index 4fa7b4e6f856..d5b8f01833f4 100644 --- a/trunk/Documentation/zh_CN/gpio.txt +++ b/trunk/Documentation/zh_CN/gpio.txt @@ -84,10 +84,10 @@ GPIO 公约 控制器的抽象函数来实现它。(有一些可选的代码能支持这种策略的实现,本文档 后面会介绍,但作为 GPIO 接口的客户端驱动程序必须与它的实现无关。) -也就是说,如果在他们的平台上支持这个公约,驱动应尽可能的使用它。平台 -必须在 Kconfig 中声明对 GENERIC_GPIO的支持 (布尔型 true),并提供 -一个 文件。那些调用标准 GPIO 函数的驱动应该在 Kconfig -入口中声明依赖GENERIC_GPIO。当驱动包含文件: +也就是说,如果在他们的平台上支持这个公约,驱动应尽可能的使用它。同时,平台 +必须在 Kconfig 中选择 ARCH_REQUIRE_GPIOLIB 或者 ARCH_WANT_OPTIONAL_GPIOLIB +选项。那些调用标准 GPIO 函数的驱动应该在 Kconfig 入口中声明依赖GENERIC_GPIO。 +当驱动包含文件: #include diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index ee468fac7dbf..3d7782b9f90d 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -801,6 +801,7 @@ S: Maintained F: arch/arm/mach-prima2/ F: drivers/dma/sirf-dma.c F: drivers/i2c/busses/i2c-sirf.c +F: drivers/mmc/host/sdhci-sirf.c F: drivers/pinctrl/pinctrl-sirf.c F: drivers/spi/spi-sirf.c @@ -1619,6 +1620,13 @@ W: http://www.baycom.org/~tom/ham/ham.html S: Maintained F: drivers/net/hamradio/baycom* +BCACHE (BLOCK LAYER CACHE) +M: Kent Overstreet +L: linux-bcache@vger.kernel.org +W: http://bcache.evilpiepirate.org +S: Maintained: +F: drivers/md/bcache/ + BEFS FILE SYSTEM S: Orphan F: Documentation/filesystems/befs.txt @@ -3919,7 +3927,6 @@ F: drivers/i2c/i2c-stub.c I2C SUBSYSTEM M: Wolfram Sang -M: "Ben Dooks (embedded platforms)" L: linux-i2c@vger.kernel.org W: http://i2c.wiki.kernel.org/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git @@ -6716,6 +6723,14 @@ F: drivers/remoteproc/ F: Documentation/remoteproc.txt F: include/linux/remoteproc.h +REMOTE PROCESSOR MESSAGING (RPMSG) SUBSYSTEM +M: Ohad Ben-Cohen +T: git git://git.kernel.org/pub/scm/linux/kernel/git/ohad/rpmsg.git +S: Maintained +F: drivers/rpmsg/ +F: Documentation/rpmsg.txt +F: include/linux/rpmsg.h + RFKILL M: Johannes Berg L: linux-wireless@vger.kernel.org @@ -7140,9 +7155,9 @@ F: drivers/misc/phantom.c F: include/uapi/linux/phantom.h SERIAL ATA (SATA) SUBSYSTEM -M: Jeff Garzik +M: Tejun Heo L: linux-ide@vger.kernel.org -T: git git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata.git S: Supported F: drivers/ata/ F: include/linux/ata.h @@ -8014,11 +8029,14 @@ F: arch/xtensa/ THERMAL M: Zhang Rui +M: Eduardo Valentin L: linux-pm@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux.git +Q: https://patchwork.kernel.org/project/linux-pm/list/ S: Supported F: drivers/thermal/ F: include/linux/thermal.h +F: include/linux/cpu_cooling.h THINGM BLINK(1) USB RGB LED DRIVER M: Vivien Didelot @@ -8743,6 +8761,7 @@ F: drivers/virtio/ F: drivers/net/virtio_net.c F: drivers/block/virtio_blk.c F: include/linux/virtio_*.h +F: include/uapi/linux/virtio_*.h VIRTIO HOST (VHOST) M: "Michael S. Tsirkin" diff --git a/trunk/Makefile b/trunk/Makefile index 4572f106e30b..cd11e8857604 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 3 -PATCHLEVEL = 9 +PATCHLEVEL = 10 SUBLEVEL = 0 -EXTRAVERSION = +EXTRAVERSION = -rc1 NAME = Unicycling Gorilla # *DOCUMENTATION* @@ -757,6 +757,8 @@ export KBUILD_VMLINUX_INIT := $(head-y) $(init-y) export KBUILD_VMLINUX_MAIN := $(core-y) $(libs-y) $(drivers-y) $(net-y) export KBUILD_LDS := arch/$(SRCARCH)/kernel/vmlinux.lds export LDFLAGS_vmlinux +# used by scripts/pacmage/Makefile +export KBUILD_ALLDIRS := $(sort $(filter-out arch/%,$(vmlinux-alldirs)) arch Documentation include samples scripts tools virt) vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_INIT) $(KBUILD_VMLINUX_MAIN) @@ -1399,7 +1401,7 @@ quiet_cmd_rmfiles = $(if $(wildcard $(rm-files)),CLEAN $(wildcard $(rm-files)) # Run depmod only if we have System.map and depmod is executable quiet_cmd_depmod = DEPMOD $(KERNELRELEASE) cmd_depmod = $(CONFIG_SHELL) $(srctree)/scripts/depmod.sh $(DEPMOD) \ - $(KERNELRELEASE) "$(patsubst "%",%,$(CONFIG_SYMBOL_PREFIX))" + $(KERNELRELEASE) "$(patsubst y,_,$(CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX))" # Create temporary dir for module support files # clean it up only when building all modules diff --git a/trunk/REPORTING-BUGS b/trunk/REPORTING-BUGS index 55a6074ccbb7..0cb8cdfa63bc 100644 --- a/trunk/REPORTING-BUGS +++ b/trunk/REPORTING-BUGS @@ -1,39 +1,103 @@ -[Some of this is taken from Frohwalt Egerer's original linux-kernel FAQ] +Background +========== - What follows is a suggested procedure for reporting Linux bugs. You -aren't obliged to use the bug reporting format, it is provided as a guide -to the kind of information that can be useful to developers - no more. +The upstream Linux kernel maintainers only fix bugs for specific kernel +versions. Those versions include the current "release candidate" (or -rc) +kernel, any "stable" kernel versions, and any "long term" kernels. - If the failure includes an "OOPS:" type message in your log or on -screen please read "Documentation/oops-tracing.txt" before posting your -bug report. This explains what you should do with the "Oops" information -to make it useful to the recipient. +Please see https://www.kernel.org/ for a list of supported kernels. Any +kernel marked with [EOL] is "end of life" and will not have any fixes +backported to it. + +If you've found a bug on a kernel version isn't listed on kernel.org, +contact your Linux distribution or embedded vendor for support. +Alternatively, you can attempt to run one of the supported stable or -rc +kernels, and see if you can reproduce the bug on that. It's preferable +to reproduce the bug on the latest -rc kernel. + + +How to report Linux kernel bugs +=============================== + + +Identify the problematic subsystem +---------------------------------- + +Identifying which part of the Linux kernel might be causing your issue +increases your chances of getting your bug fixed. Simply posting to the +generic linux-kernel mailing list (LKML) may cause your bug report to be +lost in the noise of a mailing list that gets 1000+ emails a day. - Send the output to the maintainer of the kernel area that seems to -be involved with the problem, and cc the relevant mailing list. Don't -worry too much about getting the wrong person. If you are unsure send it -to the person responsible for the code relevant to what you were doing. -If it occurs repeatably try and describe how to recreate it. That is -worth even more than the oops itself. The list of maintainers and -mailing lists is in the MAINTAINERS file in this directory. If you -know the file name that causes the problem you can use the following -command in this directory to find some of the maintainers of that file: +Instead, try to figure out which kernel subsystem is causing the issue, +and email that subsystem's maintainer and mailing list. If the subsystem +maintainer doesn't answer, then expand your scope to mailing lists like +LKML. + + +Identify who to notify +---------------------- + +Once you know the subsystem that is causing the issue, you should send a +bug report. Some maintainers prefer bugs to be reported via bugzilla +(https://bugzilla.kernel.org), while others prefer that bugs be reported +via the subsystem mailing list. + +To find out where to send an emailed bug report, find your subsystem or +device driver in the MAINTAINERS file. Search in the file for relevant +entries, and send your bug report to the person(s) listed in the "M:" +lines, making sure to Cc the mailing list(s) in the "L:" lines. When the +maintainer replies to you, make sure to 'Reply-all' in order to keep the +public mailing list(s) in the email thread. + +If you know which driver is causing issues, you can pass one of the driver +files to the get_maintainer.pl script: perl scripts/get_maintainer.pl -f - If it is a security bug, please copy the Security Contact listed -in the MAINTAINERS file. They can help coordinate bugfix and disclosure. -See Documentation/SecurityBugs for more information. +If it is a security bug, please copy the Security Contact listed in the +MAINTAINERS file. They can help coordinate bugfix and disclosure. See +Documentation/SecurityBugs for more information. + +If you can't figure out which subsystem caused the issue, you should file +a bug in kernel.org bugzilla and send email to +linux-kernel@vger.kernel.org, referencing the bugzilla URL. (For more +information on the linux-kernel mailing list see +http://www.tux.org/lkml/). + + +Tips for reporting bugs +----------------------- + +If you haven't reported a bug before, please read: - If you are totally stumped as to whom to send the report, send it to -linux-kernel@vger.kernel.org. (For more information on the linux-kernel -mailing list see http://www.tux.org/lkml/). +http://www.chiark.greenend.org.uk/~sgtatham/bugs.html +http://www.catb.org/esr/faqs/smart-questions.html -This is a suggested format for a bug report sent to the Linux kernel mailing -list. Having a standardized bug report form makes it easier for you not to +It's REALLY important to report bugs that seem unrelated as separate email +threads or separate bugzilla entries. If you report several unrelated +bugs at once, it's difficult for maintainers to tease apart the relevant +data. + + +Gather information +------------------ + +The most important information in a bug report is how to reproduce the +bug. This includes system information, and (most importantly) +step-by-step instructions for how a user can trigger the bug. + +If the failure includes an "OOPS:", take a picture of the screen, capture +a netconsole trace, or type the message from your screen into the bug +report. Please read "Documentation/oops-tracing.txt" before posting your +bug report. This explains what you should do with the "Oops" information +to make it useful to the recipient. + +This is a suggested format for a bug report sent via email or bugzilla. +Having a standardized bug report form makes it easier for you not to overlook things, and easier for the developers to find the pieces of -information they're really interested in. Don't feel you have to follow it. +information they're really interested in. If some information is not +relevant to your bug, feel free to exclude it. - First run the ver_linux script included as scripts/ver_linux, which +First run the ver_linux script included as scripts/ver_linux, which reports the version of some important subsystems. Run this script with the command "sh scripts/ver_linux". @@ -65,4 +129,46 @@ summary from [1.]>" for easy identification by the developers. [X.] Other notes, patches, fixes, workarounds: -Thank you +Follow up +========= + +Expectations for bug reporters +------------------------------ + +Linux kernel maintainers expect bug reporters to be able to follow up on +bug reports. That may include running new tests, applying patches, +recompiling your kernel, and/or re-triggering your bug. The most +frustrating thing for maintainers is for someone to report a bug, and then +never follow up on a request to try out a fix. + +That said, it's still useful for a kernel maintainer to know a bug exists +on a supported kernel, even if you can't follow up with retests. Follow +up reports, such as replying to the email thread with "I tried the latest +kernel and I can't reproduce my bug anymore" are also helpful, because +maintainers have to assume silence means things are still broken. + +Expectations for kernel maintainers +----------------------------------- + +Linux kernel maintainers are busy, overworked human beings. Some times +they may not be able to address your bug in a day, a week, or two weeks. +If they don't answer your email, they may be on vacation, or at a Linux +conference. Check the conference schedule at LWN.net for more info: + https://lwn.net/Calendar/ + +In general, kernel maintainers take 1 to 5 business days to respond to +bugs. The majority of kernel maintainers are employed to work on the +kernel, and they may not work on the weekends. Maintainers are scattered +around the world, and they may not work in your time zone. Unless you +have a high priority bug, please wait at least a week after the first bug +report before sending the maintainer a reminder email. + +The exceptions to this rule are regressions, kernel crashes, security holes, +or userspace breakage caused by new kernel behavior. Those bugs should be +addressed by the maintainers ASAP. If you suspect a maintainer is not +responding to these types of bugs in a timely manner (especially during a +merge window), escalate the bug to LKML and Linus Torvalds. + +Thank you! + +[Some of this is taken from Frohwalt Egerer's original linux-kernel FAQ] diff --git a/trunk/arch/Kconfig b/trunk/arch/Kconfig index 99f0e17df429..a4429bcd609e 100644 --- a/trunk/arch/Kconfig +++ b/trunk/arch/Kconfig @@ -213,6 +213,9 @@ config USE_GENERIC_SMP_HELPERS config GENERIC_SMP_IDLE_THREAD bool +config GENERIC_IDLE_POLL_SETUP + bool + # Select if arch init_task initializer is different to init/init_task.c config ARCH_INIT_TASK bool @@ -381,6 +384,12 @@ config MODULES_USE_ELF_REL Modules only use ELF REL relocations. Modules with ELF RELA relocations will give an error. +config HAVE_UNDERSCORE_SYMBOL_PREFIX + bool + help + Some architectures generate an _ in front of C symbols; things like + module loading and assembly files need to know about this. + # # ABI hall of shame # diff --git a/trunk/arch/alpha/Kconfig b/trunk/arch/alpha/Kconfig index 8629127640cf..837a1f2d8b96 100644 --- a/trunk/arch/alpha/Kconfig +++ b/trunk/arch/alpha/Kconfig @@ -55,9 +55,6 @@ config GENERIC_CALIBRATE_DELAY bool default y -config GENERIC_GPIO - bool - config ZONE_DMA bool default y diff --git a/trunk/arch/arc/Kconfig b/trunk/arch/arc/Kconfig index e6f4eca09ee3..5917099470ea 100644 --- a/trunk/arch/arc/Kconfig +++ b/trunk/arch/arc/Kconfig @@ -16,8 +16,6 @@ config ARC select GENERIC_FIND_FIRST_BIT # for now, we don't need GENERIC_IRQ_PROBE, CONFIG_GENERIC_IRQ_CHIP select GENERIC_IRQ_SHOW - select GENERIC_KERNEL_EXECVE - select GENERIC_KERNEL_THREAD select GENERIC_PENDING_IRQ if SMP select GENERIC_SMP_IDLE_THREAD select HAVE_ARCH_KGDB @@ -61,9 +59,6 @@ config GENERIC_CALIBRATE_DELAY config GENERIC_HWEIGHT def_bool y -config BINFMT_ELF - def_bool y - config STACKTRACE_SUPPORT def_bool y select STACKTRACE @@ -82,6 +77,7 @@ menu "ARC Architecture Configuration" menu "ARC Platform/SoC/Board" source "arch/arc/plat-arcfpga/Kconfig" +source "arch/arc/plat-tb10x/Kconfig" #New platform adds here endmenu @@ -134,9 +130,6 @@ if SMP config ARC_HAS_COH_CACHES def_bool n -config ARC_HAS_COH_LLSC - def_bool n - config ARC_HAS_COH_RTSC def_bool n @@ -189,6 +182,10 @@ config ARC_CACHE_PAGES Note that Global I/D ENABLE + Per Page DISABLE works but corollary Global DISABLE + Per Page ENABLE won't work +config ARC_CACHE_VIPT_ALIASING + bool "Support VIPT Aliasing D$" + default n + endif #ARC_CACHE config ARC_HAS_ICCM @@ -304,6 +301,9 @@ config ARC_FPU_SAVE_RESTORE based on actual usage of FPU by a task. Thus our implemn does this for all tasks in system. +config ARC_CANT_LLSC + def_bool n + menuconfig ARC_CPU_REL_4_10 bool "Enable support for Rel 4.10 features" default n @@ -314,9 +314,7 @@ menuconfig ARC_CPU_REL_4_10 config ARC_HAS_LLSC bool "Insn: LLOCK/SCOND (efficient atomic ops)" default y - depends on ARC_CPU_770 - # if SMP, enable LLSC ONLY if ARC implementation has coherent atomics - depends on !SMP || ARC_HAS_COH_LLSC + depends on ARC_CPU_770 && !ARC_CANT_LLSC config ARC_HAS_SWAPE bool "Insn: SWAPE (endian-swap)" @@ -415,13 +413,6 @@ config ARC_DBG_TLB_MISS_COUNT Counts number of I and D TLB Misses and exports them via Debugfs The counters can be cleared via Debugfs as well -config CMDLINE - string "Kernel command line to built-in" - default "print-fatal-signals=1" - help - The default command line which will be appended to the optional - u-boot provided command line (see below) - config CMDLINE_UBOOT bool "Support U-boot kernel command line passing" default n @@ -430,8 +421,8 @@ config CMDLINE_UBOOT command line from the U-boot environment to the Linux kernel then switch this option on. ARC U-boot will setup the cmdline in RAM/flash and set r2 to point - to it. kernel startup code will copy the string into cmdline buffer - and also append CONFIG_CMDLINE. + to it. kernel startup code will append this to DeviceTree + /bootargs provided cmdline args. config ARC_BUILTIN_DTB_NAME string "Built in DTB" @@ -441,6 +432,10 @@ config ARC_BUILTIN_DTB_NAME source "kernel/Kconfig.preempt" +menu "Executable file formats" +source "fs/Kconfig.binfmt" +endmenu + endmenu # "ARC Architecture Configuration" source "mm/Kconfig" diff --git a/trunk/arch/arc/Makefile b/trunk/arch/arc/Makefile index 92379c7cbc1a..183397fd289e 100644 --- a/trunk/arch/arc/Makefile +++ b/trunk/arch/arc/Makefile @@ -8,6 +8,10 @@ UTS_MACHINE := arc +ifeq ($(CROSS_COMPILE),) +CROSS_COMPILE := arc-elf32- +endif + KBUILD_DEFCONFIG := fpga_defconfig cflags-y += -mA7 -fno-common -pipe -fno-builtin -D__linux__ @@ -87,20 +91,23 @@ core-y += arch/arc/ core-y += arch/arc/boot/dts/ core-$(CONFIG_ARC_PLAT_FPGA_LEGACY) += arch/arc/plat-arcfpga/ +core-$(CONFIG_ARC_PLAT_TB10X) += arch/arc/plat-tb10x/ drivers-$(CONFIG_OPROFILE) += arch/arc/oprofile/ libs-y += arch/arc/lib/ $(LIBGCC) +boot := arch/arc/boot + #default target for make without any arguements. -KBUILD_IMAGE := bootpImage +KBUILD_IMAGE := bootpImage all: $(KBUILD_IMAGE) -boot := arch/arc/boot - bootpImage: vmlinux -uImage: vmlinux +boot_targets += uImage uImage.bin uImage.gz + +$(boot_targets): vmlinux $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ %.dtb %.dtb.S %.dtb.o: scripts diff --git a/trunk/arch/arc/boot/Makefile b/trunk/arch/arc/boot/Makefile index 7d514c24e095..e597cb34c16a 100644 --- a/trunk/arch/arc/boot/Makefile +++ b/trunk/arch/arc/boot/Makefile @@ -3,7 +3,6 @@ targets := vmlinux.bin vmlinux.bin.gz uImage # uImage build relies on mkimage being availble on your host for ARC target # You will need to build u-boot for ARC, rename mkimage to arc-elf32-mkimage # and make sure it's reacable from your PATH -MKIMAGE := $(srctree)/scripts/mkuboot.sh OBJCOPYFLAGS= -O binary -R .note -R .note.gnu.build-id -R .comment -S @@ -12,7 +11,12 @@ LINUX_START_TEXT = $$(readelf -h vmlinux | \ UIMAGE_LOADADDR = $(CONFIG_LINUX_LINK_BASE) UIMAGE_ENTRYADDR = $(LINUX_START_TEXT) -UIMAGE_COMPRESSION = gzip + +suffix-y := bin +suffix-$(CONFIG_KERNEL_GZIP) := gz + +targets += uImage uImage.bin uImage.gz +extra-y += vmlinux.bin vmlinux.bin.gz $(obj)/vmlinux.bin: vmlinux FORCE $(call if_changed,objcopy) @@ -20,7 +24,12 @@ $(obj)/vmlinux.bin: vmlinux FORCE $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE $(call if_changed,gzip) -$(obj)/uImage: $(obj)/vmlinux.bin.gz FORCE - $(call if_changed,uimage) +$(obj)/uImage.bin: $(obj)/vmlinux.bin FORCE + $(call if_changed,uimage,none) + +$(obj)/uImage.gz: $(obj)/vmlinux.bin.gz FORCE + $(call if_changed,uimage,gzip) -PHONY += FORCE +$(obj)/uImage: $(obj)/uImage.$(suffix-y) + @ln -sf $(notdir $<) $@ + @echo ' Image $@ is ready' diff --git a/trunk/arch/arc/boot/dts/Makefile b/trunk/arch/arc/boot/dts/Makefile index 5776835d583f..faf240e29ec2 100644 --- a/trunk/arch/arc/boot/dts/Makefile +++ b/trunk/arch/arc/boot/dts/Makefile @@ -8,6 +8,8 @@ endif obj-y += $(builtindtb-y).dtb.o targets += $(builtindtb-y).dtb +.SECONDARY: $(obj)/$(builtindtb-y).dtb.S + dtbs: $(addprefix $(obj)/, $(builtindtb-y).dtb) -clean-files := *.dtb +clean-files := *.dtb *.dtb.S diff --git a/trunk/arch/arc/boot/dts/abilis_tb100.dtsi b/trunk/arch/arc/boot/dts/abilis_tb100.dtsi new file mode 100644 index 000000000000..941ad118a7e7 --- /dev/null +++ b/trunk/arch/arc/boot/dts/abilis_tb100.dtsi @@ -0,0 +1,340 @@ +/* + * Abilis Systems TB100 SOC device tree + * + * Copyright (C) Abilis Systems 2013 + * + * Author: Christian Ruppert + * + * 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. + * + * 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/ "abilis_tb10x.dtsi" + +/* interrupt specifiers + * -------------------- + * 0: rising, 1: low, 2: high, 3: falling, + */ + +/ { + clock-frequency = <500000000>; /* 500 MHZ */ + + soc100 { + bus-frequency = <166666666>; + + pll0: oscillator { + clock-frequency = <1000000000>; + }; + cpu_clk: clkdiv_cpu { + clock-mult = <1>; + clock-div = <2>; + }; + ahb_clk: clkdiv_ahb { + clock-mult = <1>; + clock-div = <6>; + }; + + iomux: iomux@FF10601c { + /* Port 1 */ + pctl_tsin_s0: pctl-tsin-s0 { /* Serial TS-in 0 */ + pingrp = "mis0_pins"; + }; + pctl_tsin_s1: pctl-tsin-s1 { /* Serial TS-in 1 */ + pingrp = "mis1_pins"; + }; + pctl_gpio_a: pctl-gpio-a { /* GPIO bank A */ + pingrp = "gpioa_pins"; + }; + pctl_tsin_p1: pctl-tsin-p1 { /* Parallel TS-in 1 */ + pingrp = "mip1_pins"; + }; + /* Port 2 */ + pctl_tsin_s2: pctl-tsin-s2 { /* Serial TS-in 2 */ + pingrp = "mis2_pins"; + }; + pctl_tsin_s3: pctl-tsin-s3 { /* Serial TS-in 3 */ + pingrp = "mis3_pins"; + }; + pctl_gpio_c: pctl-gpio-c { /* GPIO bank C */ + pingrp = "gpioc_pins"; + }; + pctl_tsin_p3: pctl-tsin-p3 { /* Parallel TS-in 3 */ + pingrp = "mip3_pins"; + }; + /* Port 3 */ + pctl_tsin_s4: pctl-tsin-s4 { /* Serial TS-in 4 */ + pingrp = "mis4_pins"; + }; + pctl_tsin_s5: pctl-tsin-s5 { /* Serial TS-in 5 */ + pingrp = "mis5_pins"; + }; + pctl_gpio_e: pctl-gpio-e { /* GPIO bank E */ + pingrp = "gpioe_pins"; + }; + pctl_tsin_p5: pctl-tsin-p5 { /* Parallel TS-in 5 */ + pingrp = "mip5_pins"; + }; + /* Port 4 */ + pctl_tsin_s6: pctl-tsin-s6 { /* Serial TS-in 6 */ + pingrp = "mis6_pins"; + }; + pctl_tsin_s7: pctl-tsin-s7 { /* Serial TS-in 7 */ + pingrp = "mis7_pins"; + }; + pctl_gpio_g: pctl-gpio-g { /* GPIO bank G */ + pingrp = "gpiog_pins"; + }; + pctl_tsin_p7: pctl-tsin-p7 { /* Parallel TS-in 7 */ + pingrp = "mip7_pins"; + }; + /* Port 5 */ + pctl_gpio_j: pctl-gpio-j { /* GPIO bank J */ + pingrp = "gpioj_pins"; + }; + pctl_gpio_k: pctl-gpio-k { /* GPIO bank K */ + pingrp = "gpiok_pins"; + }; + pctl_ciplus: pctl-ciplus { /* CI+ interface */ + pingrp = "ciplus_pins"; + }; + pctl_mcard: pctl-mcard { /* M-Card interface */ + pingrp = "mcard_pins"; + }; + /* Port 6 */ + pctl_tsout_p: pctl-tsout-p { /* Parallel TS-out */ + pingrp = "mop_pins"; + }; + pctl_tsout_s0: pctl-tsout-s0 { /* Serial TS-out 0 */ + pingrp = "mos0_pins"; + }; + pctl_tsout_s1: pctl-tsout-s1 { /* Serial TS-out 1 */ + pingrp = "mos1_pins"; + }; + pctl_tsout_s2: pctl-tsout-s2 { /* Serial TS-out 2 */ + pingrp = "mos2_pins"; + }; + pctl_tsout_s3: pctl-tsout-s3 { /* Serial TS-out 3 */ + pingrp = "mos3_pins"; + }; + /* Port 7 */ + pctl_uart0: pctl-uart0 { /* UART 0 */ + pingrp = "uart0_pins"; + }; + pctl_uart1: pctl-uart1 { /* UART 1 */ + pingrp = "uart1_pins"; + }; + pctl_gpio_l: pctl-gpio-l { /* GPIO bank L */ + pingrp = "gpiol_pins"; + }; + pctl_gpio_m: pctl-gpio-m { /* GPIO bank M */ + pingrp = "gpiom_pins"; + }; + /* Port 8 */ + pctl_spi3: pctl-spi3 { + pingrp = "spi3_pins"; + }; + /* Port 9 */ + pctl_spi1: pctl-spi1 { + pingrp = "spi1_pins"; + }; + pctl_gpio_n: pctl-gpio-n { + pingrp = "gpion_pins"; + }; + /* Unmuxed GPIOs */ + pctl_gpio_b: pctl-gpio-b { + pingrp = "gpiob_pins"; + }; + pctl_gpio_d: pctl-gpio-d { + pingrp = "gpiod_pins"; + }; + pctl_gpio_f: pctl-gpio-f { + pingrp = "gpiof_pins"; + }; + pctl_gpio_h: pctl-gpio-h { + pingrp = "gpioh_pins"; + }; + pctl_gpio_i: pctl-gpio-i { + pingrp = "gpioi_pins"; + }; + }; + + gpioa: gpio@FF140000 { + compatible = "abilis,tb10x-gpio"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <27 1>; + reg = <0xFF140000 0x1000>; + gpio-controller; + #gpio-cells = <1>; + gpio-base = <0>; + gpio-pins = <&pctl_gpio_a>; + }; + gpiob: gpio@FF141000 { + compatible = "abilis,tb10x-gpio"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <27 1>; + reg = <0xFF141000 0x1000>; + gpio-controller; + #gpio-cells = <1>; + gpio-base = <3>; + gpio-pins = <&pctl_gpio_b>; + }; + gpioc: gpio@FF142000 { + compatible = "abilis,tb10x-gpio"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <27 1>; + reg = <0xFF142000 0x1000>; + gpio-controller; + #gpio-cells = <1>; + gpio-base = <5>; + gpio-pins = <&pctl_gpio_c>; + }; + gpiod: gpio@FF143000 { + compatible = "abilis,tb10x-gpio"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <27 1>; + reg = <0xFF143000 0x1000>; + gpio-controller; + #gpio-cells = <1>; + gpio-base = <8>; + gpio-pins = <&pctl_gpio_d>; + }; + gpioe: gpio@FF144000 { + compatible = "abilis,tb10x-gpio"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <27 1>; + reg = <0xFF144000 0x1000>; + gpio-controller; + #gpio-cells = <1>; + gpio-base = <10>; + gpio-pins = <&pctl_gpio_e>; + }; + gpiof: gpio@FF145000 { + compatible = "abilis,tb10x-gpio"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <27 1>; + reg = <0xFF145000 0x1000>; + gpio-controller; + #gpio-cells = <1>; + gpio-base = <13>; + gpio-pins = <&pctl_gpio_f>; + }; + gpiog: gpio@FF146000 { + compatible = "abilis,tb10x-gpio"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <27 1>; + reg = <0xFF146000 0x1000>; + gpio-controller; + #gpio-cells = <1>; + gpio-base = <15>; + gpio-pins = <&pctl_gpio_g>; + }; + gpioh: gpio@FF147000 { + compatible = "abilis,tb10x-gpio"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <27 1>; + reg = <0xFF147000 0x1000>; + gpio-controller; + #gpio-cells = <1>; + gpio-base = <18>; + gpio-pins = <&pctl_gpio_h>; + }; + gpioi: gpio@FF148000 { + compatible = "abilis,tb10x-gpio"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <27 1>; + reg = <0xFF148000 0x1000>; + gpio-controller; + #gpio-cells = <1>; + gpio-base = <20>; + gpio-pins = <&pctl_gpio_i>; + }; + gpioj: gpio@FF149000 { + compatible = "abilis,tb10x-gpio"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <27 1>; + reg = <0xFF149000 0x1000>; + gpio-controller; + #gpio-cells = <1>; + gpio-base = <32>; + gpio-pins = <&pctl_gpio_j>; + }; + gpiok: gpio@FF14a000 { + compatible = "abilis,tb10x-gpio"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <27 1>; + reg = <0xFF14A000 0x1000>; + gpio-controller; + #gpio-cells = <1>; + gpio-base = <64>; + gpio-pins = <&pctl_gpio_k>; + }; + gpiol: gpio@FF14b000 { + compatible = "abilis,tb10x-gpio"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <27 1>; + reg = <0xFF14B000 0x1000>; + gpio-controller; + #gpio-cells = <1>; + gpio-base = <86>; + gpio-pins = <&pctl_gpio_l>; + }; + gpiom: gpio@FF14c000 { + compatible = "abilis,tb10x-gpio"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <27 1>; + reg = <0xFF14C000 0x1000>; + gpio-controller; + #gpio-cells = <1>; + gpio-base = <90>; + gpio-pins = <&pctl_gpio_m>; + }; + gpion: gpio@FF14d000 { + compatible = "abilis,tb10x-gpio"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <27 1>; + reg = <0xFF14D000 0x1000>; + gpio-controller; + #gpio-cells = <1>; + gpio-base = <94>; + gpio-pins = <&pctl_gpio_n>; + }; + }; +}; diff --git a/trunk/arch/arc/boot/dts/abilis_tb100_dvk.dts b/trunk/arch/arc/boot/dts/abilis_tb100_dvk.dts new file mode 100644 index 000000000000..c0fd3623c393 --- /dev/null +++ b/trunk/arch/arc/boot/dts/abilis_tb100_dvk.dts @@ -0,0 +1,127 @@ +/* + * Abilis Systems TB100 Development Kit PCB device tree + * + * Copyright (C) Abilis Systems 2013 + * + * Author: Christian Ruppert + * + * 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. + * + * 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 + */ + +/dts-v1/; + +/include/ "abilis_tb100.dtsi" + +/ { + chosen { + bootargs = "earlycon=uart8250,mmio32,0xff100000,9600n8 console=ttyS0,9600n8"; + }; + + aliases { }; + + memory { + device_type = "memory"; + reg = <0x80000000 0x08000000>; /* 128M */ + }; + + soc100 { + uart@FF100000 { + pinctrl-names = "abilis,simple-default"; + pinctrl-0 = <&pctl_uart0>; + }; + ethernet@FE100000 { + phy-mode = "rgmii"; + }; + + i2c0: i2c@FF120000 { + sda-hold-time = <432>; + }; + i2c1: i2c@FF121000 { + sda-hold-time = <432>; + }; + i2c2: i2c@FF122000 { + sda-hold-time = <432>; + }; + i2c3: i2c@FF123000 { + sda-hold-time = <432>; + }; + i2c4: i2c@FF124000 { + sda-hold-time = <432>; + }; + + leds { + compatible = "gpio-leds"; + power { + label = "Power"; + gpios = <&gpioi 0>; + linux,default-trigger = "default-on"; + }; + heartbeat { + label = "Heartbeat"; + gpios = <&gpioi 1>; + linux,default-trigger = "heartbeat"; + }; + led2 { + label = "LED2"; + gpios = <&gpioi 2>; + default-state = "off"; + }; + led3 { + label = "LED3"; + gpios = <&gpioi 3>; + default-state = "off"; + }; + led4 { + label = "LED4"; + gpios = <&gpioi 4>; + default-state = "off"; + }; + led5 { + label = "LED5"; + gpios = <&gpioi 5>; + default-state = "off"; + }; + led6 { + label = "LED6"; + gpios = <&gpioi 6>; + default-state = "off"; + }; + led7 { + label = "LED7"; + gpios = <&gpioi 7>; + default-state = "off"; + }; + led8 { + label = "LED8"; + gpios = <&gpioi 8>; + default-state = "off"; + }; + led9 { + label = "LED9"; + gpios = <&gpioi 9>; + default-state = "off"; + }; + led10 { + label = "LED10"; + gpios = <&gpioi 10>; + default-state = "off"; + }; + led11 { + label = "LED11"; + gpios = <&gpioi 11>; + default-state = "off"; + }; + }; + }; +}; diff --git a/trunk/arch/arc/boot/dts/abilis_tb101.dtsi b/trunk/arch/arc/boot/dts/abilis_tb101.dtsi new file mode 100644 index 000000000000..fd25c212049f --- /dev/null +++ b/trunk/arch/arc/boot/dts/abilis_tb101.dtsi @@ -0,0 +1,349 @@ +/* + * Abilis Systems TB101 SOC device tree + * + * Copyright (C) Abilis Systems 2013 + * + * Author: Christian Ruppert + * + * 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. + * + * 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/ "abilis_tb10x.dtsi" + +/* interrupt specifiers + * -------------------- + * 0: rising, 1: low, 2: high, 3: falling, + */ + +/ { + clock-frequency = <500000000>; /* 500 MHZ */ + + soc100 { + bus-frequency = <166666666>; + + pll0: oscillator { + clock-frequency = <1000000000>; + }; + cpu_clk: clkdiv_cpu { + clock-mult = <1>; + clock-div = <2>; + }; + ahb_clk: clkdiv_ahb { + clock-mult = <1>; + clock-div = <6>; + }; + + iomux: iomux@FF10601c { + /* Port 1 */ + pctl_tsin_s0: pctl-tsin-s0 { /* Serial TS-in 0 */ + pingrp = "mis0_pins"; + }; + pctl_tsin_s1: pctl-tsin-s1 { /* Serial TS-in 1 */ + pingrp = "mis1_pins"; + }; + pctl_gpio_a: pctl-gpio-a { /* GPIO bank A */ + pingrp = "gpioa_pins"; + }; + pctl_tsin_p1: pctl-tsin-p1 { /* Parallel TS-in 1 */ + pingrp = "mip1_pins"; + }; + /* Port 2 */ + pctl_tsin_s2: pctl-tsin-s2 { /* Serial TS-in 2 */ + pingrp = "mis2_pins"; + }; + pctl_tsin_s3: pctl-tsin-s3 { /* Serial TS-in 3 */ + pingrp = "mis3_pins"; + }; + pctl_gpio_c: pctl-gpio-c { /* GPIO bank C */ + pingrp = "gpioc_pins"; + }; + pctl_tsin_p3: pctl-tsin-p3 { /* Parallel TS-in 3 */ + pingrp = "mip3_pins"; + }; + /* Port 3 */ + pctl_tsin_s4: pctl-tsin-s4 { /* Serial TS-in 4 */ + pingrp = "mis4_pins"; + }; + pctl_tsin_s5: pctl-tsin-s5 { /* Serial TS-in 5 */ + pingrp = "mis5_pins"; + }; + pctl_gpio_e: pctl-gpio-e { /* GPIO bank E */ + pingrp = "gpioe_pins"; + }; + pctl_tsin_p5: pctl-tsin-p5 { /* Parallel TS-in 5 */ + pingrp = "mip5_pins"; + }; + /* Port 4 */ + pctl_tsin_s6: pctl-tsin-s6 { /* Serial TS-in 6 */ + pingrp = "mis6_pins"; + }; + pctl_tsin_s7: pctl-tsin-s7 { /* Serial TS-in 7 */ + pingrp = "mis7_pins"; + }; + pctl_gpio_g: pctl-gpio-g { /* GPIO bank G */ + pingrp = "gpiog_pins"; + }; + pctl_tsin_p7: pctl-tsin-p7 { /* Parallel TS-in 7 */ + pingrp = "mip7_pins"; + }; + /* Port 5 */ + pctl_gpio_j: pctl-gpio-j { /* GPIO bank J */ + pingrp = "gpioj_pins"; + }; + pctl_gpio_k: pctl-gpio-k { /* GPIO bank K */ + pingrp = "gpiok_pins"; + }; + pctl_ciplus: pctl-ciplus { /* CI+ interface */ + pingrp = "ciplus_pins"; + }; + pctl_mcard: pctl-mcard { /* M-Card interface */ + pingrp = "mcard_pins"; + }; + pctl_stc0: pctl-stc0 { /* Smart card I/F 0 */ + pingrp = "stc0_pins"; + }; + pctl_stc1: pctl-stc1 { /* Smart card I/F 1 */ + pingrp = "stc1_pins"; + }; + /* Port 6 */ + pctl_tsout_p: pctl-tsout-p { /* Parallel TS-out */ + pingrp = "mop_pins"; + }; + pctl_tsout_s0: pctl-tsout-s0 { /* Serial TS-out 0 */ + pingrp = "mos0_pins"; + }; + pctl_tsout_s1: pctl-tsout-s1 { /* Serial TS-out 1 */ + pingrp = "mos1_pins"; + }; + pctl_tsout_s2: pctl-tsout-s2 { /* Serial TS-out 2 */ + pingrp = "mos2_pins"; + }; + pctl_tsout_s3: pctl-tsout-s3 { /* Serial TS-out 3 */ + pingrp = "mos3_pins"; + }; + /* Port 7 */ + pctl_uart0: pctl-uart0 { /* UART 0 */ + pingrp = "uart0_pins"; + }; + pctl_uart1: pctl-uart1 { /* UART 1 */ + pingrp = "uart1_pins"; + }; + pctl_gpio_l: pctl-gpio-l { /* GPIO bank L */ + pingrp = "gpiol_pins"; + }; + pctl_gpio_m: pctl-gpio-m { /* GPIO bank M */ + pingrp = "gpiom_pins"; + }; + /* Port 8 */ + pctl_spi3: pctl-spi3 { + pingrp = "spi3_pins"; + }; + pctl_jtag: pctl-jtag { + pingrp = "jtag_pins"; + }; + /* Port 9 */ + pctl_spi1: pctl-spi1 { + pingrp = "spi1_pins"; + }; + pctl_gpio_n: pctl-gpio-n { + pingrp = "gpion_pins"; + }; + /* Unmuxed GPIOs */ + pctl_gpio_b: pctl-gpio-b { + pingrp = "gpiob_pins"; + }; + pctl_gpio_d: pctl-gpio-d { + pingrp = "gpiod_pins"; + }; + pctl_gpio_f: pctl-gpio-f { + pingrp = "gpiof_pins"; + }; + pctl_gpio_h: pctl-gpio-h { + pingrp = "gpioh_pins"; + }; + pctl_gpio_i: pctl-gpio-i { + pingrp = "gpioi_pins"; + }; + }; + + gpioa: gpio@FF140000 { + compatible = "abilis,tb10x-gpio"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <27 1>; + reg = <0xFF140000 0x1000>; + gpio-controller; + #gpio-cells = <1>; + gpio-base = <0>; + gpio-pins = <&pctl_gpio_a>; + }; + gpiob: gpio@FF141000 { + compatible = "abilis,tb10x-gpio"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <27 1>; + reg = <0xFF141000 0x1000>; + gpio-controller; + #gpio-cells = <1>; + gpio-base = <3>; + gpio-pins = <&pctl_gpio_b>; + }; + gpioc: gpio@FF142000 { + compatible = "abilis,tb10x-gpio"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <27 1>; + reg = <0xFF142000 0x1000>; + gpio-controller; + #gpio-cells = <1>; + gpio-base = <5>; + gpio-pins = <&pctl_gpio_c>; + }; + gpiod: gpio@FF143000 { + compatible = "abilis,tb10x-gpio"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <27 1>; + reg = <0xFF143000 0x1000>; + gpio-controller; + #gpio-cells = <1>; + gpio-base = <8>; + gpio-pins = <&pctl_gpio_d>; + }; + gpioe: gpio@FF144000 { + compatible = "abilis,tb10x-gpio"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <27 1>; + reg = <0xFF144000 0x1000>; + gpio-controller; + #gpio-cells = <1>; + gpio-base = <10>; + gpio-pins = <&pctl_gpio_e>; + }; + gpiof: gpio@FF145000 { + compatible = "abilis,tb10x-gpio"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <27 1>; + reg = <0xFF145000 0x1000>; + gpio-controller; + #gpio-cells = <1>; + gpio-base = <13>; + gpio-pins = <&pctl_gpio_f>; + }; + gpiog: gpio@FF146000 { + compatible = "abilis,tb10x-gpio"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <27 1>; + reg = <0xFF146000 0x1000>; + gpio-controller; + #gpio-cells = <1>; + gpio-base = <15>; + gpio-pins = <&pctl_gpio_g>; + }; + gpioh: gpio@FF147000 { + compatible = "abilis,tb10x-gpio"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <27 1>; + reg = <0xFF147000 0x1000>; + gpio-controller; + #gpio-cells = <1>; + gpio-base = <18>; + gpio-pins = <&pctl_gpio_h>; + }; + gpioi: gpio@FF148000 { + compatible = "abilis,tb10x-gpio"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <27 1>; + reg = <0xFF148000 0x1000>; + gpio-controller; + #gpio-cells = <1>; + gpio-base = <20>; + gpio-pins = <&pctl_gpio_i>; + }; + gpioj: gpio@FF149000 { + compatible = "abilis,tb10x-gpio"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <27 1>; + reg = <0xFF149000 0x1000>; + gpio-controller; + #gpio-cells = <1>; + gpio-base = <32>; + gpio-pins = <&pctl_gpio_j>; + }; + gpiok: gpio@FF14a000 { + compatible = "abilis,tb10x-gpio"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <27 1>; + reg = <0xFF14A000 0x1000>; + gpio-controller; + #gpio-cells = <1>; + gpio-base = <64>; + gpio-pins = <&pctl_gpio_k>; + }; + gpiol: gpio@FF14b000 { + compatible = "abilis,tb10x-gpio"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <27 1>; + reg = <0xFF14B000 0x1000>; + gpio-controller; + #gpio-cells = <1>; + gpio-base = <86>; + gpio-pins = <&pctl_gpio_l>; + }; + gpiom: gpio@FF14c000 { + compatible = "abilis,tb10x-gpio"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <27 1>; + reg = <0xFF14C000 0x1000>; + gpio-controller; + #gpio-cells = <1>; + gpio-base = <90>; + gpio-pins = <&pctl_gpio_m>; + }; + gpion: gpio@FF14d000 { + compatible = "abilis,tb10x-gpio"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <27 1>; + reg = <0xFF14D000 0x1000>; + gpio-controller; + #gpio-cells = <1>; + gpio-base = <94>; + gpio-pins = <&pctl_gpio_n>; + }; + }; +}; diff --git a/trunk/arch/arc/boot/dts/abilis_tb101_dvk.dts b/trunk/arch/arc/boot/dts/abilis_tb101_dvk.dts new file mode 100644 index 000000000000..6f8c381f6268 --- /dev/null +++ b/trunk/arch/arc/boot/dts/abilis_tb101_dvk.dts @@ -0,0 +1,127 @@ +/* + * Abilis Systems TB101 Development Kit PCB device tree + * + * Copyright (C) Abilis Systems 2013 + * + * Author: Christian Ruppert + * + * 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. + * + * 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 + */ + +/dts-v1/; + +/include/ "abilis_tb101.dtsi" + +/ { + chosen { + bootargs = "earlycon=uart8250,mmio32,0xff100000,9600n8 console=ttyS0,9600n8"; + }; + + aliases { }; + + memory { + device_type = "memory"; + reg = <0x80000000 0x08000000>; /* 128M */ + }; + + soc100 { + uart@FF100000 { + pinctrl-names = "abilis,simple-default"; + pinctrl-0 = <&pctl_uart0>; + }; + ethernet@FE100000 { + phy-mode = "rgmii"; + }; + + i2c0: i2c@FF120000 { + sda-hold-time = <432>; + }; + i2c1: i2c@FF121000 { + sda-hold-time = <432>; + }; + i2c2: i2c@FF122000 { + sda-hold-time = <432>; + }; + i2c3: i2c@FF123000 { + sda-hold-time = <432>; + }; + i2c4: i2c@FF124000 { + sda-hold-time = <432>; + }; + + leds { + compatible = "gpio-leds"; + power { + label = "Power"; + gpios = <&gpioi 0>; + linux,default-trigger = "default-on"; + }; + heartbeat { + label = "Heartbeat"; + gpios = <&gpioi 1>; + linux,default-trigger = "heartbeat"; + }; + led2 { + label = "LED2"; + gpios = <&gpioi 2>; + default-state = "off"; + }; + led3 { + label = "LED3"; + gpios = <&gpioi 3>; + default-state = "off"; + }; + led4 { + label = "LED4"; + gpios = <&gpioi 4>; + default-state = "off"; + }; + led5 { + label = "LED5"; + gpios = <&gpioi 5>; + default-state = "off"; + }; + led6 { + label = "LED6"; + gpios = <&gpioi 6>; + default-state = "off"; + }; + led7 { + label = "LED7"; + gpios = <&gpioi 7>; + default-state = "off"; + }; + led8 { + label = "LED8"; + gpios = <&gpioi 8>; + default-state = "off"; + }; + led9 { + label = "LED9"; + gpios = <&gpioi 9>; + default-state = "off"; + }; + led10 { + label = "LED10"; + gpios = <&gpioi 10>; + default-state = "off"; + }; + led11 { + label = "LED11"; + gpios = <&gpioi 11>; + default-state = "off"; + }; + }; + }; +}; diff --git a/trunk/arch/arc/boot/dts/abilis_tb10x.dtsi b/trunk/arch/arc/boot/dts/abilis_tb10x.dtsi new file mode 100644 index 000000000000..a6139fc5aaa3 --- /dev/null +++ b/trunk/arch/arc/boot/dts/abilis_tb10x.dtsi @@ -0,0 +1,247 @@ +/* + * Abilis Systems TB10X SOC device tree + * + * Copyright (C) Abilis Systems 2013 + * + * Author: Christian Ruppert + * + * 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. + * + * 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 + */ + +/* interrupt specifiers + * -------------------- + * 0: rising, 1: low, 2: high, 3: falling, + */ + +/ { + compatible = "abilis,arc-tb10x"; + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + cpu@0 { + device_type = "cpu"; + compatible = "snps,arc770d"; + reg = <0>; + }; + }; + + soc100 { + #address-cells = <1>; + #size-cells = <1>; + device_type = "soc"; + ranges = <0xfe000000 0xfe000000 0x02000000 + 0x000F0000 0x000F0000 0x00010000>; + compatible = "abilis,tb10x", "simple-bus"; + + pll0: oscillator { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-output-names = "pll0"; + }; + cpu_clk: clkdiv_cpu { + compatible = "fixed-factor-clock"; + #clock-cells = <0>; + clocks = <&pll0>; + clock-output-names = "cpu_clk"; + }; + ahb_clk: clkdiv_ahb { + compatible = "fixed-factor-clock"; + #clock-cells = <0>; + clocks = <&pll0>; + clock-output-names = "ahb_clk"; + }; + + iomux: iomux@FF10601c { + #address-cells = <1>; + #size-cells = <1>; + compatible = "abilis,tb10x-iomux"; + reg = <0xFF10601c 0x4>; + }; + + intc: interrupt-controller { + compatible = "snps,arc700-intc"; + interrupt-controller; + #interrupt-cells = <1>; + }; + tb10x_ictl: pic@fe002000 { + compatible = "abilis,tb10x_ictl"; + reg = <0xFE002000 0x20>; + interrupt-controller; + #interrupt-cells = <2>; + interrupt-parent = <&intc>; + interrupts = <5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 + 20 21 22 23 24 25 26 27 28 29 30 31>; + }; + + uart@FF100000 { + compatible = "snps,dw-apb-uart", + "abilis,simple-pinctrl"; + reg = <0xFF100000 0x100>; + clock-frequency = <166666666>; + interrupts = <25 1>; + reg-shift = <2>; + reg-io-width = <4>; + interrupt-parent = <&tb10x_ictl>; + }; + ethernet@FE100000 { + compatible = "snps,dwmac-3.70a","snps,dwmac"; + reg = <0xFE100000 0x1058>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <6 1>; + interrupt-names = "macirq"; + clocks = <&ahb_clk>; + clock-names = "stmmaceth"; + }; + dma@FE000000 { + compatible = "snps,dma-spear1340"; + reg = <0xFE000000 0x400>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <14 1>; + dma-channels = <6>; + dma-requests = <0>; + dma-masters = <1>; + #dma-cells = <3>; + chan_allocation_order = <0>; + chan_priority = <1>; + block_size = <0x7ff>; + data_width = <2 0 0 0>; + clocks = <&ahb_clk>; + clock-names = "hclk"; + }; + + i2c0: i2c@FF120000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,designware-i2c"; + reg = <0xFF120000 0x1000>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <12 1>; + clocks = <&ahb_clk>; + }; + i2c1: i2c@FF121000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,designware-i2c"; + reg = <0xFF121000 0x1000>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <12 1>; + clocks = <&ahb_clk>; + }; + i2c2: i2c@FF122000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,designware-i2c"; + reg = <0xFF122000 0x1000>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <12 1>; + clocks = <&ahb_clk>; + }; + i2c3: i2c@FF123000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,designware-i2c"; + reg = <0xFF123000 0x1000>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <12 1>; + clocks = <&ahb_clk>; + }; + i2c4: i2c@FF124000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,designware-i2c"; + reg = <0xFF124000 0x1000>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <12 1>; + clocks = <&ahb_clk>; + }; + + spi0: spi@0xFE010000 { + #address-cells = <1>; + #size-cells = <0>; + cell-index = <0>; + compatible = "abilis,tb100-spi"; + num-cs = <1>; + reg = <0xFE010000 0x20>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <26 1>; + clocks = <&ahb_clk>; + }; + spi1: spi@0xFE011000 { + #address-cells = <1>; + #size-cells = <0>; + cell-index = <1>; + compatible = "abilis,tb100-spi", + "abilis,simple-pinctrl"; + num-cs = <2>; + reg = <0xFE011000 0x20>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <10 1>; + clocks = <&ahb_clk>; + }; + + tb10x_tsm: tb10x-tsm@ff316000 { + compatible = "abilis,tb100-tsm"; + reg = <0xff316000 0x400>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <17 1>; + output-clkdiv = <4>; + global-packet-delay = <0x21>; + port-packet-delay = <0>; + }; + tb10x_stream_proc: tb10x-stream-proc { + compatible = "abilis,tb100-streamproc"; + reg = <0xfff00000 0x200>, + <0x000f0000 0x10000>, + <0xfff00200 0x105>, + <0xff10600c 0x1>, + <0xfe001018 0x1>; + reg-names = "mbox", + "sp_iccm", + "mbox_irq", + "cpuctrl", + "a6it_int_force"; + interrupt-parent = <&tb10x_ictl>; + interrupts = <20 1>, <19 1>; + interrupt-names = "cmd_irq", "event_irq"; + }; + tb10x_mdsc0: tb10x-mdscr@FF300000 { + compatible = "abilis,tb100-mdscr"; + reg = <0xFF300000 0x7000>; + tb100-mdscr-manage-tsin; + }; + tb10x_mscr0: tb10x-mdscr@FF307000 { + compatible = "abilis,tb100-mdscr"; + reg = <0xFF307000 0x7000>; + }; + tb10x_scr0: tb10x-mdscr@ff30e000 { + compatible = "abilis,tb100-mdscr"; + reg = <0xFF30e000 0x4000>; + tb100-mdscr-manage-tsin; + }; + tb10x_scr1: tb10x-mdscr@ff312000 { + compatible = "abilis,tb100-mdscr"; + reg = <0xFF312000 0x4000>; + tb100-mdscr-manage-tsin; + }; + tb10x_wfb: tb10x-wfb@ff319000 { + compatible = "abilis,tb100-wfb"; + reg = <0xff319000 0x1000>; + interrupt-parent = <&tb10x_ictl>; + interrupts = <16 1>; + }; + }; +}; diff --git a/trunk/arch/arc/boot/dts/nsimosci.dts b/trunk/arch/arc/boot/dts/nsimosci.dts new file mode 100644 index 000000000000..ea16d782af58 --- /dev/null +++ b/trunk/arch/arc/boot/dts/nsimosci.dts @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2013 Synopsys, Inc. (www.synopsys.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +/dts-v1/; + +/include/ "skeleton.dtsi" + +/ { + compatible = "snps,nsimosci"; + clock-frequency = <80000000>; /* 80 MHZ */ + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&intc>; + + chosen { + bootargs = "console=tty0 consoleblank=0"; + }; + + aliases { + serial0 = &uart0; + }; + + memory { + device_type = "memory"; + reg = <0x80000000 0x10000000>; /* 256M */ + }; + + fpga { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + + /* child and parent address space 1:1 mapped */ + ranges; + + intc: interrupt-controller { + compatible = "snps,arc700-intc"; + interrupt-controller; + #interrupt-cells = <1>; + }; + + uart0: serial@c0000000 { + compatible = "snps,dw-apb-uart"; + reg = <0xc0000000 0x2000>; + interrupts = <11>; + #clock-frequency = <80000000>; + clock-frequency = <3686400>; + baud = <115200>; + reg-shift = <2>; + reg-io-width = <4>; + status = "okay"; + }; + + pgu0: pgu@c9000000 { + compatible = "snps,arcpgufb"; + reg = <0xc9000000 0x400>; + }; + + ps2: ps2@c9001000 { + compatible = "snps,arc_ps2"; + reg = <0xc9000400 0x14>; + interrupts = <13>; + interrupt-names = "arc_ps2_irq"; + }; + + eth0: ethernet@c0003000 { + compatible = "snps,oscilan"; + reg = <0xc0003000 0x44>; + interrupts = <7>, <8>; + interrupt-names = "rx", "tx"; + }; + }; +}; diff --git a/trunk/arch/arc/configs/fpga_defconfig b/trunk/arch/arc/configs/fpga_defconfig index b8698067ebbe..95350be6ef6f 100644 --- a/trunk/arch/arc/configs/fpga_defconfig +++ b/trunk/arch/arc/configs/fpga_defconfig @@ -9,7 +9,7 @@ CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set # CONFIG_PID_NS is not set CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="../arc_initramfs" +CONFIG_INITRAMFS_SOURCE="../arc_initramfs/" CONFIG_KALLSYMS_ALL=y CONFIG_EMBEDDED=y # CONFIG_SLUB_DEBUG is not set @@ -24,6 +24,7 @@ CONFIG_ARC_PLAT_FPGA_LEGACY=y CONFIG_ARC_BOARD_ML509=y # CONFIG_ARC_HAS_RTSC is not set CONFIG_ARC_BUILTIN_DTB_NAME="angel4" +CONFIG_PREEMPT=y # CONFIG_COMPACTION is not set # CONFIG_CROSS_MEMORY_ATTACH is not set CONFIG_NET=y diff --git a/trunk/arch/arc/configs/nsimosci_defconfig b/trunk/arch/arc/configs/nsimosci_defconfig new file mode 100644 index 000000000000..446c96c24eff --- /dev/null +++ b/trunk/arch/arc/configs/nsimosci_defconfig @@ -0,0 +1,75 @@ +CONFIG_CROSS_COMPILE="arc-elf32-" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_DEFAULT_HOSTNAME="ARCLinux" +# CONFIG_SWAP is not set +CONFIG_HIGH_RES_TIMERS=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_PID_NS is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="../arc_initramfs" +CONFIG_KALLSYMS_ALL=y +CONFIG_EMBEDDED=y +# CONFIG_SLUB_DEBUG is not set +# CONFIG_COMPAT_BRK is not set +CONFIG_KPROBES=y +CONFIG_MODULES=y +# CONFIG_LBDAF is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +CONFIG_ARC_PLAT_FPGA_LEGACY=y +CONFIG_ARC_BOARD_ML509=y +# CONFIG_ARC_IDE is not set +# CONFIG_ARCTANGENT_EMAC is not set +# CONFIG_ARC_HAS_RTSC is not set +CONFIG_ARC_BUILTIN_DTB_NAME="nsimosci" +# CONFIG_COMPACTION is not set +# CONFIG_CROSS_MEMORY_ATTACH is not set +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_UNIX_DIAG=y +CONFIG_NET_KEY=y +CONFIG_INET=y +# CONFIG_IPV6 is not set +# CONFIG_STANDALONE is not set +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +# CONFIG_FIRMWARE_IN_KERNEL is not set +# CONFIG_BLK_DEV is not set +CONFIG_NETDEVICES=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +# CONFIG_MOUSE_PS2_ALPS is not set +# CONFIG_MOUSE_PS2_LOGIPS2PP is not set +# CONFIG_MOUSE_PS2_SYNAPTICS is not set +# CONFIG_MOUSE_PS2_TRACKPOINT is not set +CONFIG_MOUSE_PS2_TOUCHKIT=y +# CONFIG_SERIO_I8042 is not set +# CONFIG_SERIO_SERPORT is not set +CONFIG_SERIO_ARC_PS2=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVKMEM is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_DW=y +CONFIG_SERIAL_ARC=y +CONFIG_SERIAL_ARC_CONSOLE=y +# CONFIG_HW_RANDOM is not set +# CONFIG_HWMON is not set +CONFIG_FB=y +# CONFIG_VGA_CONSOLE is not set +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_LOGO=y +# CONFIG_HID is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_TMPFS=y +# CONFIG_MISC_FILESYSTEMS is not set +CONFIG_NFS_FS=y +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_XZ_DEC=y diff --git a/trunk/arch/arc/configs/tb10x_defconfig b/trunk/arch/arc/configs/tb10x_defconfig new file mode 100644 index 000000000000..4fa5cd9f2202 --- /dev/null +++ b/trunk/arch/arc/configs/tb10x_defconfig @@ -0,0 +1,117 @@ +CONFIG_CROSS_COMPILE="arc-elf32-" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_DEFAULT_HOSTNAME="tb10x" +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=16 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="../tb10x-rootfs.cpio" +CONFIG_INITRAMFS_ROOT_UID=2100 +CONFIG_INITRAMFS_ROOT_GID=501 +# CONFIG_RD_GZIP is not set +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_AIO is not set +CONFIG_EMBEDDED=y +# CONFIG_COMPAT_BRK is not set +CONFIG_SLAB=y +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_BLOCK is not set +CONFIG_ARC_PLAT_TB10X=y +CONFIG_ARC_CACHE_LINE_SHIFT=5 +# CONFIG_ARC_HAS_RTSC is not set +CONFIG_ARC_STACK_NONEXEC=y +CONFIG_HZ=250 +CONFIG_ARC_BUILTIN_DTB_NAME="abilis_tb100_dvk" +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_COMPACTION is not set +# CONFIG_CROSS_MEMORY_ATTACH is not set +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_IPV6 is not set +# CONFIG_WIRELESS is not set +# CONFIG_FIRMWARE_IN_KERNEL is not set +CONFIG_PROC_DEVICETREE=y +CONFIG_NETDEVICES=y +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_SEEQ is not set +CONFIG_STMMAC_ETH=y +CONFIG_STMMAC_DEBUG_FS=y +CONFIG_STMMAC_DA=y +CONFIG_STMMAC_CHAINED=y +# CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_WLAN is not set +# CONFIG_INPUT is not set +# CONFIG_SERIO is not set +# CONFIG_VT is not set +CONFIG_DEVPTS_MULTIPLE_INSTANCES=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVKMEM is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=1 +CONFIG_SERIAL_8250_RUNTIME_UARTS=1 +CONFIG_SERIAL_8250_DW=y +# CONFIG_HW_RANDOM is not set +CONFIG_I2C=y +# CONFIG_I2C_COMPAT is not set +CONFIG_I2C_DESIGNWARE_PLATFORM=y +CONFIG_GPIO_SYSFS=y +# CONFIG_HWMON is not set +# CONFIG_USB_SUPPORT is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_ONESHOT=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_LEDS_TRIGGER_GPIO=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y +CONFIG_LEDS_TRIGGER_TRANSIENT=y +CONFIG_DMADEVICES=y +CONFIG_DW_DMAC=y +CONFIG_NET_DMA=y +CONFIG_ASYNC_TX_DMA=y +# CONFIG_IOMMU_SUPPORT is not set +# CONFIG_DNOTIFY is not set +CONFIG_PROC_KCORE=y +CONFIG_TMPFS=y +CONFIG_CONFIGFS_FS=y +# CONFIG_MISC_FILESYSTEMS is not set +# CONFIG_NETWORK_FILESYSTEMS is not set +# CONFIG_ENABLE_WARN_DEPRECATED is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_STRIP_ASM_SYMS=y +CONFIG_DEBUG_FS=y +CONFIG_HEADERS_CHECK=y +CONFIG_DEBUG_SECTION_MISMATCH=y +CONFIG_DETECT_HUNG_TASK=y +CONFIG_SCHEDSTATS=y +CONFIG_TIMER_STATS=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_MEMORY_INIT=y +CONFIG_DEBUG_STACKOVERFLOW=y +# CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_HW is not set diff --git a/trunk/arch/arc/include/asm/Kbuild b/trunk/arch/arc/include/asm/Kbuild index 48af742f8b5a..d8dd660898b9 100644 --- a/trunk/arch/arc/include/asm/Kbuild +++ b/trunk/arch/arc/include/asm/Kbuild @@ -32,7 +32,6 @@ generic-y += resource.h generic-y += scatterlist.h generic-y += sembuf.h generic-y += shmbuf.h -generic-y += shmparam.h generic-y += siginfo.h generic-y += socket.h generic-y += sockios.h diff --git a/trunk/arch/arc/include/asm/cache.h b/trunk/arch/arc/include/asm/cache.h index 6632273861fd..d5555fe4742a 100644 --- a/trunk/arch/arc/include/asm/cache.h +++ b/trunk/arch/arc/include/asm/cache.h @@ -55,9 +55,6 @@ : "r"(data), "r"(ptr)); \ }) -/* used to give SHMLBA a value to avoid Cache Aliasing */ -extern unsigned int ARC_shmlba; - #define ARCH_DMA_MINALIGN L1_CACHE_BYTES /* diff --git a/trunk/arch/arc/include/asm/cacheflush.h b/trunk/arch/arc/include/asm/cacheflush.h index 97ee96f26505..9f841af41092 100644 --- a/trunk/arch/arc/include/asm/cacheflush.h +++ b/trunk/arch/arc/include/asm/cacheflush.h @@ -19,13 +19,24 @@ #define _ASM_CACHEFLUSH_H #include +#include + +/* + * Semantically we need this because icache doesn't snoop dcache/dma. + * However ARC Cache flush requires paddr as well as vaddr, latter not available + * in the flush_icache_page() API. So we no-op it but do the equivalent work + * in update_mmu_cache() + */ +#define flush_icache_page(vma, page) void flush_cache_all(void); void flush_icache_range(unsigned long start, unsigned long end); -void flush_icache_page(struct vm_area_struct *vma, struct page *page); -void flush_icache_range_vaddr(unsigned long paddr, unsigned long u_vaddr, - int len); +void __sync_icache_dcache(unsigned long paddr, unsigned long vaddr, int len); +void __inv_icache_page(unsigned long paddr, unsigned long vaddr); +void ___flush_dcache_page(unsigned long paddr, unsigned long vaddr); +#define __flush_dcache_page(p, v) \ + ___flush_dcache_page((unsigned long)p, (unsigned long)v) #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 @@ -42,23 +53,60 @@ void dma_cache_wback(unsigned long start, unsigned long sz); #define flush_cache_vmap(start, end) flush_cache_all() #define flush_cache_vunmap(start, end) flush_cache_all() -/* - * VM callbacks when entire/range of user-space V-P mappings are - * torn-down/get-invalidated - * - * Currently we don't support D$ aliasing configs for our VIPT caches - * NOPS for VIPT Cache with non-aliasing D$ configurations only - */ -#define flush_cache_dup_mm(mm) /* called on fork */ +#define flush_cache_dup_mm(mm) /* called on fork (VIVT only) */ + +#ifndef CONFIG_ARC_CACHE_VIPT_ALIASING + #define flush_cache_mm(mm) /* called on munmap/exit */ #define flush_cache_range(mm, u_vstart, u_vend) #define flush_cache_page(vma, u_vaddr, pfn) /* PF handling/COW-break */ +#else /* VIPT aliasing dcache */ + +/* To clear out stale userspace mappings */ +void flush_cache_mm(struct mm_struct *mm); +void flush_cache_range(struct vm_area_struct *vma, + unsigned long start,unsigned long end); +void flush_cache_page(struct vm_area_struct *vma, + unsigned long user_addr, unsigned long page); + +/* + * To make sure that userspace mapping is flushed to memory before + * get_user_pages() uses a kernel mapping to access the page + */ +#define ARCH_HAS_FLUSH_ANON_PAGE +void flush_anon_page(struct vm_area_struct *vma, + struct page *page, unsigned long u_vaddr); + +#endif /* CONFIG_ARC_CACHE_VIPT_ALIASING */ + +/* + * Simple wrapper over config option + * Bootup code ensures that hardware matches kernel configuration + */ +static inline int cache_is_vipt_aliasing(void) +{ +#ifdef CONFIG_ARC_CACHE_VIPT_ALIASING + return 1; +#else + return 0; +#endif +} + +#define CACHE_COLOR(addr) (((unsigned long)(addr) >> (PAGE_SHIFT)) & 3) + +/* + * checks if two addresses (after page aligning) index into same cache set + */ +#define addr_not_cache_congruent(addr1, addr2) \ + cache_is_vipt_aliasing() ? \ + (CACHE_COLOR(addr1) != CACHE_COLOR(addr2)) : 0 \ + #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ do { \ memcpy(dst, src, len); \ if (vma->vm_flags & VM_EXEC) \ - flush_icache_range_vaddr((unsigned long)(dst), vaddr, len);\ + __sync_icache_dcache((unsigned long)(dst), vaddr, len); \ } while (0) #define copy_from_user_page(vma, page, vaddr, dst, src, len) \ diff --git a/trunk/arch/arc/include/asm/irq.h b/trunk/arch/arc/include/asm/irq.h index 4c588f9820cf..57898a17eb82 100644 --- a/trunk/arch/arc/include/asm/irq.h +++ b/trunk/arch/arc/include/asm/irq.h @@ -9,7 +9,8 @@ #ifndef __ASM_ARC_IRQ_H #define __ASM_ARC_IRQ_H -#define NR_IRQS 32 +#define NR_CPU_IRQS 32 /* number of interrupt lines of ARC770 CPU */ +#define NR_IRQS 128 /* allow some CPU external IRQ handling */ /* Platform Independent IRQs */ #define TIMER0_IRQ 3 diff --git a/trunk/arch/arc/include/asm/page.h b/trunk/arch/arc/include/asm/page.h index bdf546104551..374a35514116 100644 --- a/trunk/arch/arc/include/asm/page.h +++ b/trunk/arch/arc/include/asm/page.h @@ -16,13 +16,27 @@ #define get_user_page(vaddr) __get_free_page(GFP_KERNEL) #define free_user_page(page, addr) free_page(addr) -/* TBD: for now don't worry about VIPT D$ aliasing */ #define clear_page(paddr) memset((paddr), 0, PAGE_SIZE) #define copy_page(to, from) memcpy((to), (from), PAGE_SIZE) +#ifndef CONFIG_ARC_CACHE_VIPT_ALIASING + #define clear_user_page(addr, vaddr, pg) clear_page(addr) #define copy_user_page(vto, vfrom, vaddr, pg) copy_page(vto, vfrom) +#else /* VIPT aliasing dcache */ + +struct vm_area_struct; +struct page; + +#define __HAVE_ARCH_COPY_USER_HIGHPAGE + +void copy_user_highpage(struct page *to, struct page *from, + unsigned long u_vaddr, struct vm_area_struct *vma); +void clear_user_page(void *to, unsigned long u_vaddr, struct page *page); + +#endif /* CONFIG_ARC_CACHE_VIPT_ALIASING */ + #undef STRICT_MM_TYPECHECKS #ifdef STRICT_MM_TYPECHECKS diff --git a/trunk/arch/arc/include/asm/pgtable.h b/trunk/arch/arc/include/asm/pgtable.h index b7e36684c091..1cc4720faccb 100644 --- a/trunk/arch/arc/include/asm/pgtable.h +++ b/trunk/arch/arc/include/asm/pgtable.h @@ -395,6 +395,9 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, #include +/* to cope with aliasing VIPT cache */ +#define HAVE_ARCH_UNMAPPED_AREA + /* * No page table caches to initialise */ diff --git a/trunk/arch/arc/include/asm/serial.h b/trunk/arch/arc/include/asm/serial.h index 4dff5a1e4128..602b0970a764 100644 --- a/trunk/arch/arc/include/asm/serial.h +++ b/trunk/arch/arc/include/asm/serial.h @@ -22,4 +22,14 @@ #define BASE_BAUD (arc_get_core_freq() / 16) +/* + * This is definitely going to break early 8250 consoles on multi-platform + * images but hey, it won't add any code complexity for a debug feature of + * one broken driver. + */ +#ifdef CONFIG_ARC_PLAT_TB10X +#undef BASE_BAUD +#define BASE_BAUD (arc_get_core_freq() / 16 / 3) +#endif + #endif /* _ASM_ARC_SERIAL_H */ diff --git a/trunk/arch/arc/include/asm/shmparam.h b/trunk/arch/arc/include/asm/shmparam.h new file mode 100644 index 000000000000..fffeecc04270 --- /dev/null +++ b/trunk/arch/arc/include/asm/shmparam.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2013 Synopsys, Inc. (www.synopsys.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ARC_ASM_SHMPARAM_H +#define __ARC_ASM_SHMPARAM_H + +/* Handle upto 2 cache bins */ +#define SHMLBA (2 * PAGE_SIZE) + +/* Enforce SHMLBA in shmat */ +#define __ARCH_FORCE_SHMLBA + +#endif diff --git a/trunk/arch/arc/include/asm/tlb.h b/trunk/arch/arc/include/asm/tlb.h index 3eb2ce0bdfa3..85b6df839bd7 100644 --- a/trunk/arch/arc/include/asm/tlb.h +++ b/trunk/arch/arc/include/asm/tlb.h @@ -21,20 +21,35 @@ #ifndef __ASSEMBLY__ -#define tlb_flush(tlb) local_flush_tlb_mm((tlb)->mm) +#define tlb_flush(tlb) \ +do { \ + if (tlb->fullmm) \ + flush_tlb_mm((tlb)->mm); \ +} while (0) /* * This pair is called at time of munmap/exit to flush cache and TLB entries * for mappings being torn down. - * 1) cache-flush part -implemented via tlb_start_vma( ) can be NOP (for now) - * as we don't support aliasing configs in our VIPT D$. - * 2) tlb-flush part - implemted via tlb_end_vma( ) can be NOP as well- - * albiet for difft reasons - its better handled by moving to new ASID + * 1) cache-flush part -implemented via tlb_start_vma( ) for VIPT aliasing D$ + * 2) tlb-flush part - implemted via tlb_end_vma( ) flushes the TLB range * * Note, read http://lkml.org/lkml/2004/1/15/6 */ +#ifndef CONFIG_ARC_CACHE_VIPT_ALIASING #define tlb_start_vma(tlb, vma) -#define tlb_end_vma(tlb, vma) +#else +#define tlb_start_vma(tlb, vma) \ +do { \ + if (!tlb->fullmm) \ + flush_cache_range(vma, vma->vm_start, vma->vm_end); \ +} while(0) +#endif + +#define tlb_end_vma(tlb, vma) \ +do { \ + if (!tlb->fullmm) \ + flush_tlb_range(vma, vma->vm_start, vma->vm_end); \ +} while (0) #define __tlb_remove_tlb_entry(tlb, ptep, address) diff --git a/trunk/arch/arc/kernel/asm-offsets.c b/trunk/arch/arc/kernel/asm-offsets.c index 0dc148ebce74..7dcda7025241 100644 --- a/trunk/arch/arc/kernel/asm-offsets.c +++ b/trunk/arch/arc/kernel/asm-offsets.c @@ -11,9 +11,9 @@ #include #include #include +#include #include #include -#include int main(void) { diff --git a/trunk/arch/arc/kernel/clk.c b/trunk/arch/arc/kernel/clk.c index 66ce0dc917fb..10c7b0b5a079 100644 --- a/trunk/arch/arc/kernel/clk.c +++ b/trunk/arch/arc/kernel/clk.c @@ -8,7 +8,7 @@ #include -unsigned long core_freq = 800000000; +unsigned long core_freq = 80000000; /* * As of now we default to device-tree provided clock diff --git a/trunk/arch/arc/kernel/disasm.c b/trunk/arch/arc/kernel/disasm.c index d14764ae2c60..b8a549c4f540 100644 --- a/trunk/arch/arc/kernel/disasm.c +++ b/trunk/arch/arc/kernel/disasm.c @@ -12,8 +12,8 @@ #include #include #include +#include #include -#include #if defined(CONFIG_KGDB) || defined(CONFIG_ARC_MISALIGN_ACCESS) || \ defined(CONFIG_KPROBES) diff --git a/trunk/arch/arc/kernel/entry.S b/trunk/arch/arc/kernel/entry.S index 91eeab81f52d..0c6d664d4a83 100644 --- a/trunk/arch/arc/kernel/entry.S +++ b/trunk/arch/arc/kernel/entry.S @@ -393,12 +393,14 @@ ARC_ENTRY EV_TLBProtV #ifdef CONFIG_ARC_MISALIGN_ACCESS SAVE_CALLEE_SAVED_USER mov r3, sp ; callee_regs -#endif bl do_misaligned_access -#ifdef CONFIG_ARC_MISALIGN_ACCESS - DISCARD_CALLEE_SAVED_USER + ; TBD: optimize - do this only if a callee reg was involved + ; either a dst of emulated LD/ST or src with address-writeback + RESTORE_CALLEE_SAVED_USER +#else + bl do_misaligned_error #endif b ret_from_exception diff --git a/trunk/arch/arc/kernel/irq.c b/trunk/arch/arc/kernel/irq.c index 551c10dff481..8115fa531575 100644 --- a/trunk/arch/arc/kernel/irq.c +++ b/trunk/arch/arc/kernel/irq.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include "../../drivers/irqchip/irqchip.h" #include #include #include @@ -26,7 +28,7 @@ * -Disable all IRQs (on CPU side) * -Optionally, setup the High priority Interrupts as Level 2 IRQs */ -void __init arc_init_IRQ(void) +void __cpuinit arc_init_IRQ(void) { int level_mask = 0; @@ -97,15 +99,13 @@ static const struct irq_domain_ops arc_intc_domain_ops = { static struct irq_domain *root_domain; -void __init init_onchip_IRQ(void) +static int __init +init_onchip_IRQ(struct device_node *intc, struct device_node *parent) { - struct device_node *intc = NULL; + if (parent) + panic("DeviceTree incore intc not a root irq controller\n"); - intc = of_find_compatible_node(NULL, NULL, "snps,arc700-intc"); - if(!intc) - panic("DeviceTree Missing incore intc\n"); - - root_domain = irq_domain_add_legacy(intc, NR_IRQS, 0, 0, + root_domain = irq_domain_add_legacy(intc, NR_CPU_IRQS, 0, 0, &arc_intc_domain_ops, NULL); if (!root_domain) @@ -113,8 +113,12 @@ void __init init_onchip_IRQ(void) /* with this we don't need to export root_domain */ irq_set_default_host(root_domain); + + return 0; } +IRQCHIP_DECLARE(arc_intc, "snps,arc700-intc", init_onchip_IRQ); + /* * Late Interrupt system init called from start_kernel for Boot CPU only * @@ -123,12 +127,13 @@ void __init init_onchip_IRQ(void) */ void __init init_IRQ(void) { - init_onchip_IRQ(); - /* Any external intc can be setup here */ if (machine_desc->init_irq) machine_desc->init_irq(); + /* process the entire interrupt tree in one go */ + irqchip_init(); + #ifdef CONFIG_SMP /* Master CPU can initialize it's side of IPI */ if (machine_desc->init_smp) diff --git a/trunk/arch/arc/kernel/kprobes.c b/trunk/arch/arc/kernel/kprobes.c index 3bfeacb674de..5a7b80e2d883 100644 --- a/trunk/arch/arc/kernel/kprobes.c +++ b/trunk/arch/arc/kernel/kprobes.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/arc/kernel/module.c b/trunk/arch/arc/kernel/module.c index cdd359352c0a..376e04622962 100644 --- a/trunk/arch/arc/kernel/module.c +++ b/trunk/arch/arc/kernel/module.c @@ -47,7 +47,7 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, } } #endif - return 0; + return 0; } void module_arch_cleanup(struct module *mod) @@ -141,5 +141,5 @@ int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, mod->arch.unw_info = unw; } #endif - return 0; + return 0; } diff --git a/trunk/arch/arc/kernel/setup.c b/trunk/arch/arc/kernel/setup.c index 2d95ac07df7b..b2b3731dd1e9 100644 --- a/trunk/arch/arc/kernel/setup.c +++ b/trunk/arch/arc/kernel/setup.c @@ -14,14 +14,13 @@ #include #include #include +#include #include #include #include -#include #include #include #include -#include #include #include #include @@ -32,14 +31,14 @@ int running_on_hw = 1; /* vs. on ISS */ char __initdata command_line[COMMAND_LINE_SIZE]; -struct machine_desc *machine_desc __initdata; +struct machine_desc *machine_desc __cpuinitdata; struct task_struct *_current_task[NR_CPUS]; /* For stack switching */ struct cpuinfo_arc cpuinfo_arc700[NR_CPUS]; -void __init read_arc_build_cfg_regs(void) +void __cpuinit read_arc_build_cfg_regs(void) { struct bcr_perip uncached_space; struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; @@ -238,7 +237,7 @@ char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len) return buf; } -void __init arc_chk_ccms(void) +void __cpuinit arc_chk_ccms(void) { #if defined(CONFIG_ARC_HAS_DCCM) || defined(CONFIG_ARC_HAS_ICCM) struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; @@ -273,7 +272,7 @@ void __init arc_chk_ccms(void) * hardware has dedicated regs which need to be saved/restored on ctx-sw * (Single Precision uses core regs), thus kernel is kind of oblivious to it */ -void __init arc_chk_fpu(void) +void __cpuinit arc_chk_fpu(void) { struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; @@ -294,7 +293,7 @@ void __init arc_chk_fpu(void) * such as only for boot CPU etc */ -void __init setup_processor(void) +void __cpuinit setup_processor(void) { char str[512]; int cpu_id = smp_processor_id(); @@ -319,23 +318,20 @@ void __init setup_processor(void) void __init setup_arch(char **cmdline_p) { + /* This also populates @boot_command_line from /bootargs */ + machine_desc = setup_machine_fdt(__dtb_start); + if (!machine_desc) + panic("Embedded DT invalid\n"); + + /* Append any u-boot provided cmdline */ #ifdef CONFIG_CMDLINE_UBOOT - /* Make sure that a whitespace is inserted before */ - strlcat(command_line, " ", sizeof(command_line)); + /* Add a whitespace seperator between the 2 cmdlines */ + strlcat(boot_command_line, " ", COMMAND_LINE_SIZE); + strlcat(boot_command_line, command_line, COMMAND_LINE_SIZE); #endif - /* - * Append .config cmdline to base command line, which might already - * contain u-boot "bootargs" (handled by head.S, if so configured) - */ - strlcat(command_line, CONFIG_CMDLINE, sizeof(command_line)); /* Save unparsed command line copy for /proc/cmdline */ - strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); - *cmdline_p = command_line; - - machine_desc = setup_machine_fdt(__dtb_start); - if (!machine_desc) - panic("Embedded DT invalid\n"); + *cmdline_p = boot_command_line; /* To force early parsing of things like mem=xxx */ parse_early_param(); diff --git a/trunk/arch/arc/kernel/time.c b/trunk/arch/arc/kernel/time.c index f13f72807aa5..09f4309aa2c0 100644 --- a/trunk/arch/arc/kernel/time.c +++ b/trunk/arch/arc/kernel/time.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/arc/kernel/traps.c b/trunk/arch/arc/kernel/traps.c index 7496995371e8..0471d9c9dd54 100644 --- a/trunk/arch/arc/kernel/traps.c +++ b/trunk/arch/arc/kernel/traps.c @@ -16,11 +16,12 @@ #include #include #include -#include +#include +#include +#include #include -#include #include -#include +#include void __init trap_init(void) { @@ -83,6 +84,7 @@ DO_ERROR_INFO(SIGILL, "Invalid Extn Insn", do_extension_fault, ILL_ILLOPC) DO_ERROR_INFO(SIGILL, "Illegal Insn (or Seq)", insterror_is_error, ILL_ILLOPC) DO_ERROR_INFO(SIGBUS, "Invalid Mem Access", do_memory_error, BUS_ADRERR) DO_ERROR_INFO(SIGTRAP, "Breakpoint Set", trap_is_brkpt, TRAP_BRKPT) +DO_ERROR_INFO(SIGBUS, "Misaligned Access", do_misaligned_error, BUS_ADRALN) #ifdef CONFIG_ARC_MISALIGN_ACCESS /* @@ -91,21 +93,11 @@ DO_ERROR_INFO(SIGTRAP, "Breakpoint Set", trap_is_brkpt, TRAP_BRKPT) int do_misaligned_access(unsigned long cause, unsigned long address, struct pt_regs *regs, struct callee_regs *cregs) { - if (misaligned_fixup(address, regs, cause, cregs) != 0) { - siginfo_t info; - - info.si_signo = SIGBUS; - info.si_errno = 0; - info.si_code = BUS_ADRALN; - info.si_addr = (void __user *)address; - return handle_exception(cause, "Misaligned Access", regs, - &info); - } + if (misaligned_fixup(address, regs, cause, cregs) != 0) + return do_misaligned_error(cause, address, regs); + return 0; } - -#else -DO_ERROR_INFO(SIGSEGV, "Misaligned Access", do_misaligned_access, SEGV_ACCERR) #endif /* diff --git a/trunk/arch/arc/kernel/troubleshoot.c b/trunk/arch/arc/kernel/troubleshoot.c index 0aec01985bf9..11c301b81c92 100644 --- a/trunk/arch/arc/kernel/troubleshoot.c +++ b/trunk/arch/arc/kernel/troubleshoot.c @@ -26,7 +26,6 @@ static noinline void print_reg_file(long *reg_rev, int start_num) char buf[512]; int n = 0, len = sizeof(buf); - /* weird loop because pt_regs regs rev r12..r0, r25..r13 */ for (i = start_num; i < start_num + 13; i++) { n += scnprintf(buf + n, len - n, "r%02u: 0x%08lx\t", i, (unsigned long)*reg_rev); @@ -34,13 +33,18 @@ static noinline void print_reg_file(long *reg_rev, int start_num) if (((i + 1) % 3) == 0) n += scnprintf(buf + n, len - n, "\n"); + /* because pt_regs has regs reversed: r12..r0, r25..r13 */ reg_rev--; } if (start_num != 0) n += scnprintf(buf + n, len - n, "\n\n"); - pr_info("%s", buf); + /* To continue printing callee regs on same line as scratch regs */ + if (start_num == 0) + pr_info("%s", buf); + else + pr_cont("%s\n", buf); } static void show_callee_regs(struct callee_regs *cregs) @@ -83,6 +87,10 @@ static void show_faulting_vma(unsigned long address, char *buf) dev_t dev = 0; char *nm = buf; + /* can't use print_vma_addr() yet as it doesn't check for + * non-inclusive vma + */ + vma = find_vma(current->active_mm, address); /* check against the find_vma( ) behaviour which returns the next VMA @@ -98,10 +106,13 @@ static void show_faulting_vma(unsigned long address, char *buf) ino = inode->i_ino; } pr_info(" @off 0x%lx in [%s]\n" - " VMA: 0x%08lx to 0x%08lx\n\n", - address - vma->vm_start, nm, vma->vm_start, vma->vm_end); - } else + " VMA: 0x%08lx to 0x%08lx\n", + vma->vm_start < TASK_UNMAPPED_BASE ? + address : address - vma->vm_start, + nm, vma->vm_start, vma->vm_end); + } else { pr_info(" @No matching VMA found\n"); + } } static void show_ecr_verbose(struct pt_regs *regs) @@ -110,7 +121,7 @@ static void show_ecr_verbose(struct pt_regs *regs) unsigned long address; cause_reg = current->thread.cause_code; - pr_info("\n[ECR]: 0x%08x => ", cause_reg); + pr_info("\n[ECR ]: 0x%08x => ", cause_reg); /* For Data fault, this is data address not instruction addr */ address = current->thread.fault_address; @@ -120,7 +131,7 @@ static void show_ecr_verbose(struct pt_regs *regs) /* For DTLB Miss or ProtV, display the memory involved too */ if (vec == ECR_V_DTLB_MISS) { - pr_cont("Invalid (%s) @ 0x%08lx by insn @ 0x%08lx\n", + pr_cont("Invalid %s 0x%08lx by insn @ 0x%08lx\n", (cause_code == 0x01) ? "Read From" : ((cause_code == 0x02) ? "Write to" : "EX"), address, regs->ret); @@ -168,20 +179,23 @@ void show_regs(struct pt_regs *regs) if (current->thread.cause_code) show_ecr_verbose(regs); - pr_info("[EFA]: 0x%08lx\n", current->thread.fault_address); - pr_info("[ERET]: 0x%08lx (PC of Faulting Instr)\n", regs->ret); + pr_info("[EFA ]: 0x%08lx\n[BLINK ]: %pS\n[ERET ]: %pS\n", + current->thread.fault_address, + (void *)regs->blink, (void *)regs->ret); - show_faulting_vma(regs->ret, buf); /* faulting code, not data */ + if (user_mode(regs)) + show_faulting_vma(regs->ret, buf); /* faulting code, not data */ - /* can't use print_vma_addr() yet as it doesn't check for - * non-inclusive vma - */ + pr_info("[STAT32]: 0x%08lx", regs->status32); + +#define STS_BIT(r, bit) r->status32 & STATUS_##bit##_MASK ? #bit : "" + if (!user_mode(regs)) + pr_cont(" : %2s %2s %2s %2s %2s\n", + STS_BIT(regs, AE), STS_BIT(regs, A2), STS_BIT(regs, A1), + STS_BIT(regs, E2), STS_BIT(regs, E1)); - /* print special regs */ - pr_info("status32: 0x%08lx\n", regs->status32); - pr_info(" SP: 0x%08lx\tFP: 0x%08lx\n", regs->sp, regs->fp); - pr_info("BTA: 0x%08lx\tBLINK: 0x%08lx\n", - regs->bta, regs->blink); + pr_info("BTA: 0x%08lx\t SP: 0x%08lx\t FP: 0x%08lx\n", + regs->bta, regs->sp, regs->fp); pr_info("LPS: 0x%08lx\tLPE: 0x%08lx\tLPC: 0x%08lx\n", regs->lp_start, regs->lp_end, regs->lp_count); diff --git a/trunk/arch/arc/mm/Makefile b/trunk/arch/arc/mm/Makefile index 168dc146a8f6..ac95cc239c1e 100644 --- a/trunk/arch/arc/mm/Makefile +++ b/trunk/arch/arc/mm/Makefile @@ -7,4 +7,4 @@ # obj-y := extable.o ioremap.o dma.o fault.o init.o -obj-y += tlb.o tlbex.o cache_arc700.o +obj-y += tlb.o tlbex.o cache_arc700.o mmap.o diff --git a/trunk/arch/arc/mm/cache_arc700.c b/trunk/arch/arc/mm/cache_arc700.c index 88d617d84234..2f12bca8aef3 100644 --- a/trunk/arch/arc/mm/cache_arc700.c +++ b/trunk/arch/arc/mm/cache_arc700.c @@ -68,20 +68,11 @@ #include #include #include +#include #include #include #include - -#ifdef CONFIG_ARC_HAS_ICACHE -static void __ic_line_inv_no_alias(unsigned long, int); -static void __ic_line_inv_2_alias(unsigned long, int); -static void __ic_line_inv_4_alias(unsigned long, int); - -/* Holds the ptr to flush routine, dependign on size due to aliasing issues */ -static void (*___flush_icache_rtn) (unsigned long, int); -#endif - char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len) { int n = 0; @@ -109,7 +100,7 @@ char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len) * the cpuinfo structure for later use. * No Validation done here, simply read/convert the BCRs */ -void __init read_decode_cache_bcr(void) +void __cpuinit read_decode_cache_bcr(void) { struct bcr_cache ibcr, dbcr; struct cpuinfo_arc_cache *p_ic, *p_dc; @@ -141,13 +132,14 @@ void __init read_decode_cache_bcr(void) * 3. Enable the Caches, setup default flush mode for D-Cache * 3. Calculate the SHMLBA used by user space */ -void __init arc_cache_init(void) +void __cpuinit arc_cache_init(void) { unsigned int temp; unsigned int cpu = smp_processor_id(); struct cpuinfo_arc_cache *ic = &cpuinfo_arc700[cpu].icache; struct cpuinfo_arc_cache *dc = &cpuinfo_arc700[cpu].dcache; int way_pg_ratio = way_pg_ratio; + int dcache_does_alias; char str[256]; printk(arc_cache_mumbojumbo(0, str, sizeof(str))); @@ -171,30 +163,6 @@ void __init arc_cache_init(void) } #endif - - /* - * if Cache way size is <= page size then no aliasing exhibited - * otherwise ratio determines num of aliases. - * e.g. 32K I$, 2 way set assoc, 8k pg size - * way-sz = 32k/2 = 16k - * way-pg-ratio = 16k/8k = 2, so 2 aliases possible - * (meaning 1 line could be in 2 possible locations). - */ - way_pg_ratio = ic->sz / ARC_ICACHE_WAYS / PAGE_SIZE; - switch (way_pg_ratio) { - case 0: - case 1: - ___flush_icache_rtn = __ic_line_inv_no_alias; - break; - case 2: - ___flush_icache_rtn = __ic_line_inv_2_alias; - break; - case 4: - ___flush_icache_rtn = __ic_line_inv_4_alias; - break; - default: - panic("Unsupported I-Cache Sz\n"); - } #endif /* Enable/disable I-Cache */ @@ -218,9 +186,13 @@ void __init arc_cache_init(void) panic("Cache H/W doesn't match kernel Config"); } + dcache_does_alias = (dc->sz / ARC_DCACHE_WAYS) > PAGE_SIZE; + /* check for D-Cache aliasing */ - if ((dc->sz / ARC_DCACHE_WAYS) > PAGE_SIZE) - panic("D$ aliasing not handled right now\n"); + if (dcache_does_alias && !cache_is_vipt_aliasing()) + panic("Enable CONFIG_ARC_CACHE_VIPT_ALIASING\n"); + else if (!dcache_does_alias && cache_is_vipt_aliasing()) + panic("Don't need CONFIG_ARC_CACHE_VIPT_ALIASING\n"); #endif /* Set the default Invalidate Mode to "simpy discard dirty lines" @@ -303,47 +275,57 @@ static inline void __dc_entire_op(const int cacheop) * Per Line Operation on D-Cache * Doesn't deal with type-of-op/IRQ-disabling/waiting-for-flush-to-complete * It's sole purpose is to help gcc generate ZOL + * (aliasing VIPT dcache flushing needs both vaddr and paddr) */ -static inline void __dc_line_loop(unsigned long start, unsigned long sz, - int aux_reg) +static inline void __dc_line_loop(unsigned long paddr, unsigned long vaddr, + unsigned long sz, const int aux_reg) { - int num_lines, slack; + int num_lines; /* Ensure we properly floor/ceil the non-line aligned/sized requests - * and have @start - aligned to cache line and integral @num_lines. + * and have @paddr - aligned to cache line and integral @num_lines. * This however can be avoided for page sized since: - * -@start will be cache-line aligned already (being page aligned) + * -@paddr will be cache-line aligned already (being page aligned) * -@sz will be integral multiple of line size (being page sized). */ if (!(__builtin_constant_p(sz) && sz == PAGE_SIZE)) { - slack = start & ~DCACHE_LINE_MASK; - sz += slack; - start -= slack; + sz += paddr & ~DCACHE_LINE_MASK; + paddr &= DCACHE_LINE_MASK; + vaddr &= DCACHE_LINE_MASK; } num_lines = DIV_ROUND_UP(sz, ARC_DCACHE_LINE_LEN); +#if (CONFIG_ARC_MMU_VER <= 2) + paddr |= (vaddr >> PAGE_SHIFT) & 0x1F; +#endif + while (num_lines-- > 0) { #if (CONFIG_ARC_MMU_VER > 2) /* * Just as for I$, in MMU v3, D$ ops also require * "tag" bits in DC_PTAG, "index" bits in FLDL,IVDL ops - * But we pass phy addr for both. This works since Linux - * doesn't support aliasing configs for D$, yet. - * Thus paddr is enough to provide both tag and index. */ - write_aux_reg(ARC_REG_DC_PTAG, start); + write_aux_reg(ARC_REG_DC_PTAG, paddr); + + write_aux_reg(aux_reg, vaddr); + vaddr += ARC_DCACHE_LINE_LEN; +#else + /* paddr contains stuffed vaddrs bits */ + write_aux_reg(aux_reg, paddr); #endif - write_aux_reg(aux_reg, start); - start += ARC_DCACHE_LINE_LEN; + paddr += ARC_DCACHE_LINE_LEN; } } +/* For kernel mappings cache operation: index is same as paddr */ +#define __dc_line_op_k(p, sz, op) __dc_line_op(p, p, sz, op) + /* * D-Cache : Per Line INV (discard or wback+discard) or FLUSH (wback) */ -static inline void __dc_line_op(unsigned long start, unsigned long sz, - const int cacheop) +static inline void __dc_line_op(unsigned long paddr, unsigned long vaddr, + unsigned long sz, const int cacheop) { unsigned long flags, tmp = tmp; int aux; @@ -366,7 +348,7 @@ static inline void __dc_line_op(unsigned long start, unsigned long sz, else aux = ARC_REG_DC_FLDL; - __dc_line_loop(start, sz, aux); + __dc_line_loop(paddr, vaddr, sz, aux); if (cacheop & OP_FLUSH) /* flush / flush-n-inv both wait */ wait_for_flush(); @@ -381,7 +363,8 @@ static inline void __dc_line_op(unsigned long start, unsigned long sz, #else #define __dc_entire_op(cacheop) -#define __dc_line_op(start, sz, cacheop) +#define __dc_line_op(paddr, vaddr, sz, cacheop) +#define __dc_line_op_k(paddr, sz, cacheop) #endif /* CONFIG_ARC_HAS_DCACHE */ @@ -391,75 +374,38 @@ static inline void __dc_line_op(unsigned long start, unsigned long sz, /* * I-Cache Aliasing in ARC700 VIPT caches * - * For fetching code from I$, ARC700 uses vaddr (embedded in program code) - * to "index" into SET of cache-line and paddr from MMU to match the TAG - * in the WAYS of SET. - * - * However the CDU iterface (to flush/inv) lines from software, only takes - * paddr (to have simpler hardware interface). For simpler cases, using paddr - * alone suffices. - * e.g. 2-way-set-assoc, 16K I$ (8k MMU pg sz, 32b cache line size): - * way_sz = cache_sz / num_ways = 16k/2 = 8k - * num_sets = way_sz / line_sz = 8k/32 = 256 => 8 bits - * Ignoring the bottom 5 bits corresp to the off within a 32b cacheline, - * bits req for calc set-index = bits 12:5 (0 based). Since this range fits - * inside the bottom 13 bits of paddr, which are same for vaddr and paddr - * (with 8k pg sz), paddr alone can be safely used by CDU to unambigously - * locate a cache-line. + * ARC VIPT I-cache uses vaddr to index into cache and paddr to match the tag. + * The orig Cache Management Module "CDU" only required paddr to invalidate a + * certain line since it sufficed as index in Non-Aliasing VIPT cache-geometry. + * Infact for distinct V1,V2,P: all of {V1-P},{V2-P},{P-P} would end up fetching + * the exact same line. * - * However for a difft sized cache, say 32k I$, above math yields need - * for 14 bits of vaddr to locate a cache line, which can't be provided by - * paddr, since the bit 13 (0 based) might differ between the two. - * - * This lack of extra bits needed for correct line addressing, defines the - * classical problem of Cache aliasing with VIPT architectures - * num_aliases = 1 << extra_bits - * e.g. 2-way-set-assoc, 32K I$ with 8k MMU pg sz => 2 aliases - * 2-way-set-assoc, 64K I$ with 8k MMU pg sz => 4 aliases - * 2-way-set-assoc, 16K I$ with 8k MMU pg sz => NO aliases + * However for larger Caches (way-size > page-size) - i.e. in Aliasing config, + * paddr alone could not be used to correctly index the cache. * * ------------------ * MMU v1/v2 (Fixed Page Size 8k) * ------------------ * The solution was to provide CDU with these additonal vaddr bits. These - * would be bits [x:13], x would depend on cache-geom. + * would be bits [x:13], x would depend on cache-geometry, 13 comes from + * standard page size of 8k. * H/w folks chose [17:13] to be a future safe range, and moreso these 5 bits * of vaddr could easily be "stuffed" in the paddr as bits [4:0] since the * orig 5 bits of paddr were anyways ignored by CDU line ops, as they * represent the offset within cache-line. The adv of using this "clumsy" - * interface for additional info was no new reg was needed in CDU. + * interface for additional info was no new reg was needed in CDU programming + * model. * * 17:13 represented the max num of bits passable, actual bits needed were * fewer, based on the num-of-aliases possible. * -for 2 alias possibility, only bit 13 needed (32K cache) * -for 4 alias possibility, bits 14:13 needed (64K cache) * - * Since vaddr was not available for all instances of I$ flush req by core - * kernel, the only safe way (non-optimal though) was to kill all possible - * lines which could represent an alias (even if they didnt represent one - * in execution). - * e.g. for 64K I$, 4 aliases possible, so we did - * flush start - * flush start | 0x01 - * flush start | 0x2 - * flush start | 0x3 - * - * The penalty was invoking the operation itself, since tag match is anyways - * paddr based, a line which didn't represent an alias would not match the - * paddr, hence wont be killed - * - * Note that aliasing concerns are independent of line-sz for a given cache - * geometry (size + set_assoc) because the extra bits required by line-sz are - * reduced from the set calc. - * e.g. 2-way-set-assoc, 32K I$ with 8k MMU pg sz and using math above - * 32b line-sz: 9 bits set-index-calc, 5 bits offset-in-line => 1 extra bit - * 64b line-sz: 8 bits set-index-calc, 6 bits offset-in-line => 1 extra bit - * * ------------------ * MMU v3 * ------------------ - * This ver of MMU supports var page sizes (1k-16k) - Linux will support - * 8k (default), 16k and 4k. + * This ver of MMU supports variable page sizes (1k-16k): although Linux will + * only support 8k (default), 16k and 4k. * However from hardware perspective, smaller page sizes aggrevate aliasing * meaning more vaddr bits needed to disambiguate the cache-line-op ; * the existing scheme of piggybacking won't work for certain configurations. @@ -468,144 +414,53 @@ static inline void __dc_line_op(unsigned long start, unsigned long sz, */ /*********************************************************** - * Machine specific helpers for per line I-Cache invalidate. - * 3 routines to accpunt for 1, 2, 4 aliases possible + * Machine specific helper for per line I-Cache invalidate. */ - -static void __ic_line_inv_no_alias(unsigned long start, int num_lines) -{ - while (num_lines-- > 0) { -#if (CONFIG_ARC_MMU_VER > 2) - write_aux_reg(ARC_REG_IC_PTAG, start); -#endif - write_aux_reg(ARC_REG_IC_IVIL, start); - start += ARC_ICACHE_LINE_LEN; - } -} - -static void __ic_line_inv_2_alias(unsigned long start, int num_lines) -{ - while (num_lines-- > 0) { - -#if (CONFIG_ARC_MMU_VER > 2) - /* - * MMU v3, CDU prog model (for line ops) now uses a new IC_PTAG - * reg to pass the "tag" bits and existing IVIL reg only looks - * at bits relevant for "index" (details above) - * Programming Notes: - * -when writing tag to PTAG reg, bit chopping can be avoided, - * CDU ignores non-tag bits. - * -Ideally "index" must be computed from vaddr, but it is not - * avail in these rtns. So to be safe, we kill the lines in all - * possible indexes corresp to num of aliases possible for - * given cache config. - */ - write_aux_reg(ARC_REG_IC_PTAG, start); - write_aux_reg(ARC_REG_IC_IVIL, - start & ~(0x1 << PAGE_SHIFT)); - write_aux_reg(ARC_REG_IC_IVIL, start | (0x1 << PAGE_SHIFT)); -#else - write_aux_reg(ARC_REG_IC_IVIL, start); - write_aux_reg(ARC_REG_IC_IVIL, start | 0x01); -#endif - start += ARC_ICACHE_LINE_LEN; - } -} - -static void __ic_line_inv_4_alias(unsigned long start, int num_lines) -{ - while (num_lines-- > 0) { - -#if (CONFIG_ARC_MMU_VER > 2) - write_aux_reg(ARC_REG_IC_PTAG, start); - - write_aux_reg(ARC_REG_IC_IVIL, - start & ~(0x3 << PAGE_SHIFT)); - write_aux_reg(ARC_REG_IC_IVIL, - start & ~(0x2 << PAGE_SHIFT)); - write_aux_reg(ARC_REG_IC_IVIL, - start & ~(0x1 << PAGE_SHIFT)); - write_aux_reg(ARC_REG_IC_IVIL, start | (0x3 << PAGE_SHIFT)); -#else - write_aux_reg(ARC_REG_IC_IVIL, start); - write_aux_reg(ARC_REG_IC_IVIL, start | 0x01); - write_aux_reg(ARC_REG_IC_IVIL, start | 0x02); - write_aux_reg(ARC_REG_IC_IVIL, start | 0x03); -#endif - start += ARC_ICACHE_LINE_LEN; - } -} - -static void __ic_line_inv(unsigned long start, unsigned long sz) +static void __ic_line_inv_vaddr(unsigned long paddr, unsigned long vaddr, + unsigned long sz) { unsigned long flags; - int num_lines, slack; + int num_lines; /* - * Ensure we properly floor/ceil the non-line aligned/sized requests - * and have @start - aligned to cache line, and integral @num_lines + * Ensure we properly floor/ceil the non-line aligned/sized requests: * However page sized flushes can be compile time optimised. - * -@start will be cache-line aligned already (being page aligned) + * -@paddr will be cache-line aligned already (being page aligned) * -@sz will be integral multiple of line size (being page sized). */ if (!(__builtin_constant_p(sz) && sz == PAGE_SIZE)) { - slack = start & ~ICACHE_LINE_MASK; - sz += slack; - start -= slack; + sz += paddr & ~ICACHE_LINE_MASK; + paddr &= ICACHE_LINE_MASK; + vaddr &= ICACHE_LINE_MASK; } num_lines = DIV_ROUND_UP(sz, ARC_ICACHE_LINE_LEN); - local_irq_save(flags); - (*___flush_icache_rtn) (start, num_lines); - local_irq_restore(flags); -} - -/* Unlike routines above, having vaddr for flush op (along with paddr), - * prevents the need to speculatively kill the lines in multiple sets - * based on ratio of way_sz : pg_sz - */ -static void __ic_line_inv_vaddr(unsigned long phy_start, - unsigned long vaddr, unsigned long sz) -{ - unsigned long flags; - int num_lines, slack; - unsigned int addr; - - slack = phy_start & ~ICACHE_LINE_MASK; - sz += slack; - phy_start -= slack; - num_lines = DIV_ROUND_UP(sz, ARC_ICACHE_LINE_LEN); - -#if (CONFIG_ARC_MMU_VER > 2) - vaddr &= ~ICACHE_LINE_MASK; - addr = phy_start; -#else +#if (CONFIG_ARC_MMU_VER <= 2) /* bits 17:13 of vaddr go as bits 4:0 of paddr */ - addr = phy_start | ((vaddr >> 13) & 0x1F); + paddr |= (vaddr >> PAGE_SHIFT) & 0x1F; #endif local_irq_save(flags); while (num_lines-- > 0) { #if (CONFIG_ARC_MMU_VER > 2) /* tag comes from phy addr */ - write_aux_reg(ARC_REG_IC_PTAG, addr); + write_aux_reg(ARC_REG_IC_PTAG, paddr); /* index bits come from vaddr */ write_aux_reg(ARC_REG_IC_IVIL, vaddr); vaddr += ARC_ICACHE_LINE_LEN; #else - /* this paddr contains vaddrs bits as needed */ - write_aux_reg(ARC_REG_IC_IVIL, addr); + /* paddr contains stuffed vaddrs bits */ + write_aux_reg(ARC_REG_IC_IVIL, paddr); #endif - addr += ARC_ICACHE_LINE_LEN; + paddr += ARC_ICACHE_LINE_LEN; } local_irq_restore(flags); } #else -#define __ic_line_inv(start, sz) #define __ic_line_inv_vaddr(pstart, vstart, sz) #endif /* CONFIG_ARC_HAS_ICACHE */ @@ -615,35 +470,72 @@ static void __ic_line_inv_vaddr(unsigned long phy_start, * Exported APIs */ -/* TBD: use pg_arch_1 to optimize this */ +/* + * Handle cache congruency of kernel and userspace mappings of page when kernel + * writes-to/reads-from + * + * The idea is to defer flushing of kernel mapping after a WRITE, possible if: + * -dcache is NOT aliasing, hence any U/K-mappings of page are congruent + * -U-mapping doesn't exist yet for page (finalised in update_mmu_cache) + * -In SMP, if hardware caches are coherent + * + * There's a corollary case, where kernel READs from a userspace mapped page. + * If the U-mapping is not congruent to to K-mapping, former needs flushing. + */ void flush_dcache_page(struct page *page) { - __dc_line_op((unsigned long)page_address(page), PAGE_SIZE, OP_FLUSH); + struct address_space *mapping; + + if (!cache_is_vipt_aliasing()) { + set_bit(PG_arch_1, &page->flags); + return; + } + + /* don't handle anon pages here */ + mapping = page_mapping(page); + if (!mapping) + return; + + /* + * pagecache page, file not yet mapped to userspace + * Make a note that K-mapping is dirty + */ + if (!mapping_mapped(mapping)) { + set_bit(PG_arch_1, &page->flags); + } else if (page_mapped(page)) { + + /* kernel reading from page with U-mapping */ + void *paddr = page_address(page); + unsigned long vaddr = page->index << PAGE_CACHE_SHIFT; + + if (addr_not_cache_congruent(paddr, vaddr)) + __flush_dcache_page(paddr, vaddr); + } } EXPORT_SYMBOL(flush_dcache_page); void dma_cache_wback_inv(unsigned long start, unsigned long sz) { - __dc_line_op(start, sz, OP_FLUSH_N_INV); + __dc_line_op_k(start, sz, OP_FLUSH_N_INV); } EXPORT_SYMBOL(dma_cache_wback_inv); void dma_cache_inv(unsigned long start, unsigned long sz) { - __dc_line_op(start, sz, OP_INV); + __dc_line_op_k(start, sz, OP_INV); } EXPORT_SYMBOL(dma_cache_inv); void dma_cache_wback(unsigned long start, unsigned long sz) { - __dc_line_op(start, sz, OP_FLUSH); + __dc_line_op_k(start, sz, OP_FLUSH); } EXPORT_SYMBOL(dma_cache_wback); /* - * This is API for making I/D Caches consistent when modifying code - * (loadable modules, kprobes, etc) + * This is API for making I/D Caches consistent when modifying + * kernel code (loadable modules, kprobes, kgdb...) * This is called on insmod, with kernel virtual address for CODE of * the module. ARC cache maintenance ops require PHY address thus we * need to convert vmalloc addr to PHY addr @@ -652,7 +544,6 @@ void flush_icache_range(unsigned long kstart, unsigned long kend) { unsigned int tot_sz, off, sz; unsigned long phy, pfn; - unsigned long flags; /* printk("Kernel Cache Cohenercy: %lx to %lx\n",kstart, kend); */ @@ -673,8 +564,13 @@ void flush_icache_range(unsigned long kstart, unsigned long kend) /* Case: Kernel Phy addr (0x8000_0000 onwards) */ if (likely(kstart > PAGE_OFFSET)) { - __ic_line_inv(kstart, kend - kstart); - __dc_line_op(kstart, kend - kstart, OP_FLUSH); + /* + * The 2nd arg despite being paddr will be used to index icache + * This is OK since no alternate virtual mappings will exist + * given the callers for this case: kprobe/kgdb in built-in + * kernel code only. + */ + __sync_icache_dcache(kstart, kstart, kend - kstart); return; } @@ -692,42 +588,45 @@ void flush_icache_range(unsigned long kstart, unsigned long kend) pfn = vmalloc_to_pfn((void *)kstart); phy = (pfn << PAGE_SHIFT) + off; sz = min_t(unsigned int, tot_sz, PAGE_SIZE - off); - local_irq_save(flags); - __dc_line_op(phy, sz, OP_FLUSH); - __ic_line_inv(phy, sz); - local_irq_restore(flags); + __sync_icache_dcache(phy, kstart, sz); kstart += sz; tot_sz -= sz; } } /* - * Optimised ver of flush_icache_range() with spec callers: ptrace/signals - * where vaddr is also available. This allows passing both vaddr and paddr - * bits to CDU for cache flush, short-circuting the current pessimistic algo - * which kills all possible aliases. - * An added adv of knowing that vaddr is user-vaddr avoids various checks - * and handling for k-vaddr, k-paddr as done in orig ver above + * General purpose helper to make I and D cache lines consistent. + * @paddr is phy addr of region + * @vaddr is typically user or kernel vaddr (vmalloc) + * Howver in one instance, flush_icache_range() by kprobe (for a breakpt in + * builtin kernel code) @vaddr will be paddr only, meaning CDU operation will + * use a paddr to index the cache (despite VIPT). This is fine since since a + * built-in kernel page will not have any virtual mappings (not even kernel) + * kprobe on loadable module is different as it will have kvaddr. */ -void flush_icache_range_vaddr(unsigned long paddr, unsigned long u_vaddr, - int len) +void __sync_icache_dcache(unsigned long paddr, unsigned long vaddr, int len) { - __ic_line_inv_vaddr(paddr, u_vaddr, len); - __dc_line_op(paddr, len, OP_FLUSH); + unsigned long flags; + + local_irq_save(flags); + __ic_line_inv_vaddr(paddr, vaddr, len); + __dc_line_op(paddr, vaddr, len, OP_FLUSH); + local_irq_restore(flags); +} + +/* wrapper to compile time eliminate alignment checks in flush loop */ +void __inv_icache_page(unsigned long paddr, unsigned long vaddr) +{ + __ic_line_inv_vaddr(paddr, vaddr, PAGE_SIZE); } /* - * XXX: This also needs to be optim using pg_arch_1 - * This is called when a page-cache page is about to be mapped into a - * user process' address space. It offers an opportunity for a - * port to ensure d-cache/i-cache coherency if necessary. + * wrapper to clearout kernel or userspace mappings of a page + * For kernel mappings @vaddr == @paddr */ -void flush_icache_page(struct vm_area_struct *vma, struct page *page) +void ___flush_dcache_page(unsigned long paddr, unsigned long vaddr) { - if (!(vma->vm_flags & VM_EXEC)) - return; - - __ic_line_inv((unsigned long)page_address(page), PAGE_SIZE); + __dc_line_op(paddr, vaddr & PAGE_MASK, PAGE_SIZE, OP_FLUSH_N_INV); } void flush_icache_all(void) @@ -756,6 +655,87 @@ noinline void flush_cache_all(void) } +#ifdef CONFIG_ARC_CACHE_VIPT_ALIASING + +void flush_cache_mm(struct mm_struct *mm) +{ + flush_cache_all(); +} + +void flush_cache_page(struct vm_area_struct *vma, unsigned long u_vaddr, + unsigned long pfn) +{ + unsigned int paddr = pfn << PAGE_SHIFT; + + __sync_icache_dcache(paddr, u_vaddr, PAGE_SIZE); +} + +void flush_cache_range(struct vm_area_struct *vma, unsigned long start, + unsigned long end) +{ + flush_cache_all(); +} + +void copy_user_highpage(struct page *to, struct page *from, + unsigned long u_vaddr, struct vm_area_struct *vma) +{ + void *kfrom = page_address(from); + void *kto = page_address(to); + int clean_src_k_mappings = 0; + + /* + * If SRC page was already mapped in userspace AND it's U-mapping is + * not congruent with K-mapping, sync former to physical page so that + * K-mapping in memcpy below, sees the right data + * + * Note that while @u_vaddr refers to DST page's userspace vaddr, it is + * equally valid for SRC page as well + */ + if (page_mapped(from) && addr_not_cache_congruent(kfrom, u_vaddr)) { + __flush_dcache_page(kfrom, u_vaddr); + clean_src_k_mappings = 1; + } + + copy_page(kto, kfrom); + + /* + * Mark DST page K-mapping as dirty for a later finalization by + * update_mmu_cache(). Although the finalization could have been done + * here as well (given that both vaddr/paddr are available). + * But update_mmu_cache() already has code to do that for other + * non copied user pages (e.g. read faults which wire in pagecache page + * directly). + */ + set_bit(PG_arch_1, &to->flags); + + /* + * if SRC was already usermapped and non-congruent to kernel mapping + * sync the kernel mapping back to physical page + */ + if (clean_src_k_mappings) { + __flush_dcache_page(kfrom, kfrom); + } else { + set_bit(PG_arch_1, &from->flags); + } +} + +void clear_user_page(void *to, unsigned long u_vaddr, struct page *page) +{ + clear_page(to); + set_bit(PG_arch_1, &page->flags); +} + +void flush_anon_page(struct vm_area_struct *vma, struct page *page, + unsigned long u_vaddr) +{ + /* TBD: do we really need to clear the kernel mapping */ + __flush_dcache_page(page_address(page), u_vaddr); + __flush_dcache_page(page_address(page), page_address(page)); + +} + +#endif + /********************************************************************** * Explicit Cache flush request from user space via syscall * Needed for JITs which generate code on the fly diff --git a/trunk/arch/arc/mm/extable.c b/trunk/arch/arc/mm/extable.c index 014172ba8432..aa652e281324 100644 --- a/trunk/arch/arc/mm/extable.c +++ b/trunk/arch/arc/mm/extable.c @@ -27,7 +27,7 @@ int fixup_exception(struct pt_regs *regs) #ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE -long arc_copy_from_user_noinline(void *to, const void __user * from, +long arc_copy_from_user_noinline(void *to, const void __user *from, unsigned long n) { return __arc_copy_from_user(to, from, n); @@ -48,7 +48,7 @@ unsigned long arc_clear_user_noinline(void __user *to, } EXPORT_SYMBOL(arc_clear_user_noinline); -long arc_strncpy_from_user_noinline (char *dst, const char __user *src, +long arc_strncpy_from_user_noinline(char *dst, const char __user *src, long count) { return __arc_strncpy_from_user(dst, src, count); diff --git a/trunk/arch/arc/mm/fault.c b/trunk/arch/arc/mm/fault.c index af55aab803d2..689ffd86d5e9 100644 --- a/trunk/arch/arc/mm/fault.c +++ b/trunk/arch/arc/mm/fault.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/arc/mm/init.c b/trunk/arch/arc/mm/init.c index 727d4794ea0f..4a177365b2c4 100644 --- a/trunk/arch/arc/mm/init.c +++ b/trunk/arch/arc/mm/init.c @@ -10,9 +10,6 @@ #include #include #include -#ifdef CONFIG_BLOCK_DEV_RAM -#include -#endif #include #include #include diff --git a/trunk/arch/arc/mm/ioremap.c b/trunk/arch/arc/mm/ioremap.c index 3e5c92c79936..739e65f355de 100644 --- a/trunk/arch/arc/mm/ioremap.c +++ b/trunk/arch/arc/mm/ioremap.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include void __iomem *ioremap(unsigned long paddr, unsigned long size) { diff --git a/trunk/arch/arc/mm/mmap.c b/trunk/arch/arc/mm/mmap.c new file mode 100644 index 000000000000..2e06d56e987b --- /dev/null +++ b/trunk/arch/arc/mm/mmap.c @@ -0,0 +1,78 @@ +/* + * ARC700 mmap + * + * (started from arm version - for VIPT alias handling) + * + * Copyright (C) 2013 Synopsys, Inc. (www.synopsys.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include + +#define COLOUR_ALIGN(addr, pgoff) \ + ((((addr) + SHMLBA - 1) & ~(SHMLBA - 1)) + \ + (((pgoff) << PAGE_SHIFT) & (SHMLBA - 1))) + +/* + * Ensure that shared mappings are correctly aligned to + * avoid aliasing issues with VIPT caches. + * We need to ensure that + * a specific page of an object is always mapped at a multiple of + * SHMLBA bytes. + */ +unsigned long +arch_get_unmapped_area(struct file *filp, unsigned long addr, + unsigned long len, unsigned long pgoff, unsigned long flags) +{ + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; + int do_align = 0; + int aliasing = cache_is_vipt_aliasing(); + struct vm_unmapped_area_info info; + + /* + * We only need to do colour alignment if D cache aliases. + */ + if (aliasing) + do_align = filp || (flags & MAP_SHARED); + + /* + * We enforce the MAP_FIXED case. + */ + if (flags & MAP_FIXED) { + if (aliasing && flags & MAP_SHARED && + (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)) + return -EINVAL; + return addr; + } + + if (len > TASK_SIZE) + return -ENOMEM; + + if (addr) { + if (do_align) + addr = COLOUR_ALIGN(addr, pgoff); + else + addr = PAGE_ALIGN(addr); + + vma = find_vma(mm, addr); + if (TASK_SIZE - len >= addr && + (!vma || addr + len <= vma->vm_start)) + return addr; + } + + info.flags = 0; + info.length = len; + info.low_limit = mm->mmap_base; + info.high_limit = TASK_SIZE; + info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0; + info.align_offset = pgoff << PAGE_SHIFT; + return vm_unmapped_area(&info); +} diff --git a/trunk/arch/arc/mm/tlb.c b/trunk/arch/arc/mm/tlb.c index 9b9ce23f4ec3..066145b5f348 100644 --- a/trunk/arch/arc/mm/tlb.c +++ b/trunk/arch/arc/mm/tlb.c @@ -418,23 +418,52 @@ void create_tlb(struct vm_area_struct *vma, unsigned long address, pte_t *ptep) local_irq_restore(flags); } -/* arch hook called by core VM at the end of handle_mm_fault( ), - * when a new PTE is entered in Page Tables or an existing one - * is modified. We aggresively pre-install a TLB entry +/* + * Called at the end of pagefault, for a userspace mapped page + * -pre-install the corresponding TLB entry into MMU + * -Finalize the delayed D-cache flush of kernel mapping of page due to + * flush_dcache_page(), copy_user_page() + * + * Note that flush (when done) involves both WBACK - so physical page is + * in sync as well as INV - so any non-congruent aliases don't remain */ - -void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddress, +void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr_unaligned, pte_t *ptep) { + unsigned long vaddr = vaddr_unaligned & PAGE_MASK; + unsigned long paddr = pte_val(*ptep) & PAGE_MASK; + + create_tlb(vma, vaddr, ptep); + + /* + * Exec page : Independent of aliasing/page-color considerations, + * since icache doesn't snoop dcache on ARC, any dirty + * K-mapping of a code page needs to be wback+inv so that + * icache fetch by userspace sees code correctly. + * !EXEC page: If K-mapping is NOT congruent to U-mapping, flush it + * so userspace sees the right data. + * (Avoids the flush for Non-exec + congruent mapping case) + */ + if (vma->vm_flags & VM_EXEC || addr_not_cache_congruent(paddr, vaddr)) { + struct page *page = pfn_to_page(pte_pfn(*ptep)); + + int dirty = test_and_clear_bit(PG_arch_1, &page->flags); + if (dirty) { + /* wback + inv dcache lines */ + __flush_dcache_page(paddr, paddr); - create_tlb(vma, vaddress, ptep); + /* invalidate any existing icache lines */ + if (vma->vm_flags & VM_EXEC) + __inv_icache_page(paddr, vaddr); + } + } } /* Read the Cache Build Confuration Registers, Decode them and save into * the cpuinfo structure for later use. * No Validation is done here, simply read/convert the BCRs */ -void __init read_decode_mmu_bcr(void) +void __cpuinit read_decode_mmu_bcr(void) { unsigned int tmp; struct bcr_mmu_1_2 *mmu2; /* encoded MMU2 attr */ @@ -466,7 +495,7 @@ void __init read_decode_mmu_bcr(void) char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len) { int n = 0; - struct cpuinfo_arc_mmu *p_mmu = &cpuinfo_arc700[smp_processor_id()].mmu; + struct cpuinfo_arc_mmu *p_mmu = &cpuinfo_arc700[cpu_id].mmu; n += scnprintf(buf + n, len - n, "ARC700 MMU [v%x]\t: %dk PAGE, ", p_mmu->ver, TO_KB(p_mmu->pg_sz)); @@ -480,7 +509,7 @@ char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len) return buf; } -void __init arc_mmu_init(void) +void __cpuinit arc_mmu_init(void) { char str[256]; struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu; diff --git a/trunk/arch/arc/plat-arcfpga/platform.c b/trunk/arch/arc/plat-arcfpga/platform.c index 4e20a1a5104d..b3700c064c06 100644 --- a/trunk/arch/arc/plat-arcfpga/platform.c +++ b/trunk/arch/arc/plat-arcfpga/platform.c @@ -224,3 +224,15 @@ MACHINE_START(ML509, "ml509") .init_smp = iss_model_init_smp, #endif MACHINE_END + +static const char *nsimosci_compat[] __initdata = { + "snps,nsimosci", + NULL, +}; + +MACHINE_START(NSIMOSCI, "nsimosci") + .dt_compat = nsimosci_compat, + .init_early = NULL, + .init_machine = plat_fpga_populate_dev, + .init_irq = NULL, +MACHINE_END diff --git a/trunk/arch/arc/plat-tb10x/Kconfig b/trunk/arch/arc/plat-tb10x/Kconfig new file mode 100644 index 000000000000..1d3452100f1f --- /dev/null +++ b/trunk/arch/arc/plat-tb10x/Kconfig @@ -0,0 +1,29 @@ +# Abilis Systems TB10x platform kernel configuration file +# +# Author: Christian Ruppert +# +# 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. +# +# 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 + + +menuconfig ARC_PLAT_TB10X + bool "Abilis TB10x" + select COMMON_CLK + select PINCTRL + select PINMUX + select ARCH_REQUIRE_GPIOLIB + help + Support for platforms based on the TB10x home media gateway SOC by + Abilis Systems. TB10x is based on the ARC700 CPU architecture. + Say Y if you are building a kernel for one of the SOCs in this + series (e.g. TB100 or TB101). If in doubt say N. diff --git a/trunk/arch/arc/plat-tb10x/Makefile b/trunk/arch/arc/plat-tb10x/Makefile new file mode 100644 index 000000000000..89611d25ef35 --- /dev/null +++ b/trunk/arch/arc/plat-tb10x/Makefile @@ -0,0 +1,21 @@ +# Abilis Systems TB10x platform Makefile +# +# Author: Christian Ruppert +# +# 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. +# +# 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 + + +KBUILD_CFLAGS += -Iarch/arc/plat-tb10x/include + +obj-y += tb10x.o diff --git a/trunk/arch/arc/plat-tb10x/tb10x.c b/trunk/arch/arc/plat-tb10x/tb10x.c new file mode 100644 index 000000000000..d3567691c7e1 --- /dev/null +++ b/trunk/arch/arc/plat-tb10x/tb10x.c @@ -0,0 +1,71 @@ +/* + * Abilis Systems TB10x platform initialisation + * + * Copyright (C) Abilis Systems 2012 + * + * Author: Christian Ruppert + * + * 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. + * + * 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 +#include +#include +#include + +#include + + +static void __init tb10x_platform_init(void) +{ + of_clk_init(NULL); + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); +} + +static void __init tb10x_platform_late_init(void) +{ + struct device_node *dn; + + /* + * Pinctrl documentation recommends setting up the iomux here for + * all modules which don't require control over the pins themselves. + * Modules which need this kind of assistance are compatible with + * "abilis,simple-pinctrl", i.e. we can easily iterate over them. + * TODO: Does this recommended method work cleanly with pins required + * by modules? + */ + for_each_compatible_node(dn, NULL, "abilis,simple-pinctrl") { + struct platform_device *pd = of_find_device_by_node(dn); + struct pinctrl *pctl; + + pctl = pinctrl_get_select(&pd->dev, "abilis,simple-default"); + if (IS_ERR(pctl)) { + int ret = PTR_ERR(pctl); + dev_err(&pd->dev, "Could not set up pinctrl: %d\n", + ret); + } + } +} + +static const char *tb10x_compat[] __initdata = { + "abilis,arc-tb10x", + NULL, +}; + +MACHINE_START(TB10x, "tb10x") + .dt_compat = tb10x_compat, + .init_machine = tb10x_platform_init, + .init_late = tb10x_platform_late_init, +MACHINE_END diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index 4ed24b4aa714..49d993cee512 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -38,6 +38,7 @@ config ARM select HAVE_GENERIC_HARDIRQS select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7)) select HAVE_IDE if PCI || ISA || PCMCIA + select HAVE_IRQ_TIME_ACCOUNTING select HAVE_KERNEL_GZIP select HAVE_KERNEL_LZMA select HAVE_KERNEL_LZO @@ -59,6 +60,7 @@ config ARM select CLONE_BACKWARDS select OLD_SIGSUSPEND3 select OLD_SIGACTION + select HAVE_CONTEXT_TRACKING help The ARM series is a line of low-power-consumption RISC chip designs licensed by ARM Ltd and targeted at embedded applications and @@ -108,9 +110,6 @@ config MIGHT_HAVE_PCI config SYS_SUPPORTS_APM_EMULATION bool -config GENERIC_GPIO - bool - config HAVE_TCM bool select GENERIC_ALLOCATOR @@ -490,13 +489,14 @@ config ARCH_IXP4XX config ARCH_DOVE bool "Marvell Dove" select ARCH_REQUIRE_GPIOLIB - select CPU_V7 + select CPU_PJ4 select GENERIC_CLOCKEVENTS select MIGHT_HAVE_PCI select PINCTRL select PINCTRL_DOVE select PLAT_ORION_LEGACY select USB_ARCH_HAS_EHCI + select MVEBU_MBUS help Support for the Marvell Dove SoC 88AP510 @@ -510,6 +510,7 @@ config ARCH_KIRKWOOD select PINCTRL select PINCTRL_KIRKWOOD select PLAT_ORION_LEGACY + select MVEBU_MBUS help Support for the following Marvell Kirkwood series SoCs: 88F6180, 88F6192 and 88F6281. @@ -521,6 +522,7 @@ config ARCH_MV78XX0 select GENERIC_CLOCKEVENTS select PCI select PLAT_ORION_LEGACY + select MVEBU_MBUS help Support for the following Marvell MV78xx0 series SoCs: MV781x0, MV782x0. @@ -533,6 +535,7 @@ config ARCH_ORION5X select GENERIC_CLOCKEVENTS select PCI select PLAT_ORION_LEGACY + select MVEBU_MBUS help Support for the following Marvell Orion 5x series SoCs: Orion-1 (5181), Orion-VoIP (5181L), Orion-NAS (5182), @@ -642,7 +645,7 @@ config ARCH_SHMOBILE select MULTI_IRQ_HANDLER select NEED_MACH_MEMORY_H select NO_IOPORT - select PINCTRL + select PINCTRL if ARCH_WANT_OPTIONAL_GPIOLIB select PM_GENERIC_DOMAINS if PM select SPARSE_IRQ help @@ -688,12 +691,15 @@ config ARCH_SA1100 config ARCH_S3C24XX bool "Samsung S3C24XX SoCs" select ARCH_HAS_CPUFREQ - select ARCH_USES_GETTIMEOFFSET + select ARCH_REQUIRE_GPIOLIB select CLKDEV_LOOKUP + select CLKSRC_MMIO + select GENERIC_CLOCKEVENTS select HAVE_CLK select HAVE_S3C2410_I2C if I2C select HAVE_S3C2410_WATCHDOG if WATCHDOG select HAVE_S3C_RTC if RTC_CLASS + select MULTI_IRQ_HANDLER select NEED_MACH_GPIO_H select NEED_MACH_IO_H help @@ -706,10 +712,11 @@ config ARCH_S3C64XX bool "Samsung S3C64XX" select ARCH_HAS_CPUFREQ select ARCH_REQUIRE_GPIOLIB - select ARCH_USES_GETTIMEOFFSET select ARM_VIC select CLKDEV_LOOKUP + select CLKSRC_MMIO select CPU_V6 + select GENERIC_CLOCKEVENTS select HAVE_CLK select HAVE_S3C2410_I2C if I2C select HAVE_S3C2410_WATCHDOG if WATCHDOG @@ -743,9 +750,11 @@ config ARCH_S5P64X0 config ARCH_S5PC100 bool "Samsung S5PC100" - select ARCH_USES_GETTIMEOFFSET + select ARCH_REQUIRE_GPIOLIB select CLKDEV_LOOKUP + select CLKSRC_MMIO select CPU_V7 + select GENERIC_CLOCKEVENTS select HAVE_CLK select HAVE_S3C2410_I2C if I2C select HAVE_S3C2410_WATCHDOG if WATCHDOG @@ -778,6 +787,7 @@ config ARCH_EXYNOS select ARCH_HAS_HOLES_MEMORYMODEL select ARCH_SPARSEMEM_ENABLE select CLKDEV_LOOKUP + select COMMON_CLK select CPU_V7 select GENERIC_CLOCKEVENTS select HAVE_CLK @@ -888,7 +898,6 @@ config ARCH_MULTI_V7 bool "ARMv7 based platforms (Cortex-A, PJ4, Scorpion, Krait)" default y select ARCH_MULTI_V6_V7 - select ARCH_VEXPRESS select CPU_V7 config ARCH_MULTI_V6_V7 @@ -1047,6 +1056,7 @@ config PLAT_VERSATILE config ARM_TIMER_SP804 bool select CLKSRC_MMIO + select CLKSRC_OF if OF source arch/arm/mm/Kconfig @@ -1479,6 +1489,14 @@ config HAVE_ARM_TWD help This options enables support for the ARM timer and watchdog unit +config MCPM + bool "Multi-Cluster Power Management" + depends on CPU_V7 && SMP + help + This option provides the common power management infrastructure + for (multi-)cluster based systems, such as big.LITTLE based + systems. + choice prompt "Memory split" default VMSPLIT_3G @@ -1543,7 +1561,8 @@ config ARCH_NR_GPIO default 1024 if ARCH_SHMOBILE || ARCH_TEGRA default 512 if SOC_OMAP5 default 392 if ARCH_U8500 - default 288 if ARCH_VT8500 || ARCH_SUNXI + default 352 if ARCH_VT8500 + default 288 if ARCH_SUNXI default 264 if MACH_H4700 default 0 help @@ -1565,8 +1584,9 @@ config SCHED_HRTICK def_bool HIGH_RES_TIMERS config THUMB2_KERNEL - bool "Compile the kernel in Thumb-2 mode" + bool "Compile the kernel in Thumb-2 mode" if !CPU_THUMBONLY depends on CPU_V7 && !CPU_V6 && !CPU_V6K + default y if CPU_THUMBONLY select AEABI select ARM_ASM_UNIFIED select ARM_UNWIND @@ -1771,6 +1791,7 @@ config XEN depends on ARM && AEABI && OF depends on CPU_V7 && !CPU_V6 depends on !GENERIC_ATOMIC64 + select ARM_PSCI help Say Y if you want to run Linux in a Virtual Machine on Xen on ARM. diff --git a/trunk/arch/arm/Kconfig.debug b/trunk/arch/arm/Kconfig.debug index 54d6fdc03e04..1d41908d5cda 100644 --- a/trunk/arch/arm/Kconfig.debug +++ b/trunk/arch/arm/Kconfig.debug @@ -245,11 +245,11 @@ choice on i.MX53. config DEBUG_IMX6Q_UART - bool "i.MX6Q Debug UART" + bool "i.MX6Q/DL Debug UART" depends on SOC_IMX6Q help Say Y here if you want kernel low-level debugging support - on i.MX6Q. + on i.MX6Q/DL. config DEBUG_MMP_UART2 bool "Kernel low-level debugging message via MMP UART2" @@ -330,6 +330,13 @@ choice Say Y here if you want kernel low-level debugging support on PicoXcell based platforms. + config DEBUG_PXA_UART1 + depends on ARCH_PXA + bool "Use PXA UART1 for low-level debug" + help + Say Y here if you want kernel low-level debugging support + on PXA UART1. + config DEBUG_REALVIEW_STD_PORT bool "RealView Default UART" depends on ARCH_REALVIEW @@ -615,6 +622,7 @@ config DEBUG_LL_INCLUDE default "debug/bcm2835.S" if DEBUG_BCM2835 default "debug/cns3xxx.S" if DEBUG_CNS3XXX default "debug/exynos.S" if DEBUG_EXYNOS_UART + default "debug/highbank.S" if DEBUG_HIGHBANK_UART default "debug/icedcc.S" if DEBUG_ICEDCC default "debug/imx.S" if DEBUG_IMX1_UART || \ DEBUG_IMX25_UART || \ @@ -624,23 +632,35 @@ config DEBUG_LL_INCLUDE DEBUG_IMX51_UART || \ DEBUG_IMX53_UART ||\ DEBUG_IMX6Q_UART - default "debug/highbank.S" if DEBUG_HIGHBANK_UART default "debug/mvebu.S" if DEBUG_MVEBU_UART default "debug/mxs.S" if DEBUG_IMX23_UART || DEBUG_IMX28_UART default "debug/nomadik.S" if DEBUG_NOMADIK_UART default "debug/omap2plus.S" if DEBUG_OMAP2PLUS_UART default "debug/picoxcell.S" if DEBUG_PICOXCELL_UART + default "debug/pxa.S" if DEBUG_PXA_UART1 || DEBUG_MMP_UART2 || \ + DEBUG_MMP_UART3 default "debug/sirf.S" if DEBUG_SIRFPRIMA2_UART1 || DEBUG_SIRFMARCO_UART1 default "debug/socfpga.S" if DEBUG_SOCFPGA_UART default "debug/sunxi.S" if DEBUG_SUNXI_UART0 || DEBUG_SUNXI_UART1 + default "debug/tegra.S" if DEBUG_TEGRA_UART + default "debug/ux500.S" if DEBUG_UX500_UART default "debug/vexpress.S" if DEBUG_VEXPRESS_UART0_DETECT || \ DEBUG_VEXPRESS_UART0_CA9 || DEBUG_VEXPRESS_UART0_RS1 default "debug/vt8500.S" if DEBUG_VT8500_UART0 - default "debug/tegra.S" if DEBUG_TEGRA_UART - default "debug/ux500.S" if DEBUG_UX500_UART default "debug/zynq.S" if DEBUG_ZYNQ_UART0 || DEBUG_ZYNQ_UART1 default "mach/debug-macro.S" +config DEBUG_UNCOMPRESS + bool + default y if ARCH_MULTIPLATFORM && DEBUG_LL && \ + !DEBUG_OMAP2PLUS_UART && \ + !DEBUG_TEGRA_UART + +config UNCOMPRESS_INCLUDE + string + default "debug/uncompress.h" if ARCH_MULTIPLATFORM + default "mach/uncompress.h" + config EARLY_PRINTK bool "Early printk" depends on DEBUG_LL diff --git a/trunk/arch/arm/Makefile b/trunk/arch/arm/Makefile index 47374085befd..1ba358ba16b8 100644 --- a/trunk/arch/arm/Makefile +++ b/trunk/arch/arm/Makefile @@ -309,7 +309,7 @@ define archhelp echo ' Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)' echo '* xipImage - XIP kernel image, if configured (arch/$(ARCH)/boot/xipImage)' echo ' uImage - U-Boot wrapped zImage' - echo ' bootpImage - Combined zImage and initial RAM disk' + echo ' bootpImage - Combined zImage and initial RAM disk' echo ' (supply initrd image via make variable INITRD=)' echo '* dtbs - Build device tree blobs for enabled boards' echo ' install - Install uncompressed kernel' diff --git a/trunk/arch/arm/boot/compressed/Makefile b/trunk/arch/arm/boot/compressed/Makefile index afed28e37ea5..3580d57ea218 100644 --- a/trunk/arch/arm/boot/compressed/Makefile +++ b/trunk/arch/arm/boot/compressed/Makefile @@ -24,6 +24,9 @@ endif AFLAGS_head.o += -DTEXT_OFFSET=$(TEXT_OFFSET) HEAD = head.o OBJS += misc.o decompress.o +ifeq ($(CONFIG_DEBUG_UNCOMPRESS),y) +OBJS += debug.o +endif FONTC = $(srctree)/drivers/video/console/font_acorn_8x8.c # string library code (-Os is enforced to keep it much smaller) diff --git a/trunk/arch/arm/boot/compressed/debug.S b/trunk/arch/arm/boot/compressed/debug.S new file mode 100644 index 000000000000..6e8382d5b7a4 --- /dev/null +++ b/trunk/arch/arm/boot/compressed/debug.S @@ -0,0 +1,12 @@ +#include +#include + +#include CONFIG_DEBUG_LL_INCLUDE + +ENTRY(putc) + addruart r1, r2, r3 + waituart r3, r1 + senduart r0, r1 + busyuart r3, r1 + mov pc, lr +ENDPROC(putc) diff --git a/trunk/arch/arm/boot/compressed/misc.c b/trunk/arch/arm/boot/compressed/misc.c index df899834d84e..31bd43b82095 100644 --- a/trunk/arch/arm/boot/compressed/misc.c +++ b/trunk/arch/arm/boot/compressed/misc.c @@ -25,13 +25,7 @@ unsigned int __machine_arch_type; static void putstr(const char *ptr); extern void error(char *x); -#ifdef CONFIG_ARCH_MULTIPLATFORM -static inline void putc(int c) {} -static inline void flush(void) {} -static inline void arch_decomp_setup(void) {} -#else -#include -#endif +#include CONFIG_UNCOMPRESS_INCLUDE #ifdef CONFIG_DEBUG_ICEDCC diff --git a/trunk/arch/arm/boot/dts/Makefile b/trunk/arch/arm/boot/dts/Makefile index 20358fb43450..b9f7121e6ecf 100644 --- a/trunk/arch/arm/boot/dts/Makefile +++ b/trunk/arch/arm/boot/dts/Makefile @@ -49,7 +49,12 @@ dtb-$(CONFIG_ARCH_DOVE) += dove-cm-a510.dtb \ dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \ exynos4210-smdkv310.dtb \ exynos4210-trats.dtb \ + exynos4210-universal_c210.dtb \ + exynos4412-odroidx.dtb \ exynos4412-smdk4412.dtb \ + exynos4412-origen.dtb \ + exynos5250-arndale.dtb \ + exynos5440-sd5v1.dtb \ exynos5250-smdk5250.dtb \ exynos5250-snow.dtb \ exynos5440-ssdk5440.dtb @@ -58,7 +63,8 @@ dtb-$(CONFIG_ARCH_HIGHBANK) += highbank.dtb \ dtb-$(CONFIG_ARCH_INTEGRATOR) += integratorap.dtb \ integratorcp.dtb dtb-$(CONFIG_ARCH_LPC32XX) += ea3250.dtb phy3250.dtb -dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-dns320.dtb \ +dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-cloudbox.dtb \ + kirkwood-dns320.dtb \ kirkwood-dns325.dtb \ kirkwood-dockstar.dtb \ kirkwood-dreamplug.dtb \ @@ -72,6 +78,7 @@ dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-dns320.dtb \ kirkwood-lschlv2.dtb \ kirkwood-lsxhl.dtb \ kirkwood-mplcec4.dtb \ + kirkwood-netgear_readynas_duo_v2.dtb \ kirkwood-ns2.dtb \ kirkwood-ns2lite.dtb \ kirkwood-ns2max.dtb \ @@ -129,10 +136,14 @@ dtb-$(CONFIG_ARCH_MXS) += imx23-evk.dtb \ imx28-tx28.dtb dtb-$(CONFIG_ARCH_NOMADIK) += ste-nomadik-s8815.dtb dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \ + omap3430-sdp.dtb \ omap3-beagle.dtb \ + omap3-devkit8000.dtb \ omap3-beagle-xm.dtb \ omap3-evm.dtb \ omap3-tobi.dtb \ + omap3-igep0020.dtb \ + omap3-igep0030.dtb \ omap4-panda.dtb \ omap4-panda-a4.dtb \ omap4-panda-es.dtb \ @@ -150,7 +161,12 @@ dtb-$(CONFIG_ARCH_U8500) += snowball.dtb \ ccu9540.dtb dtb-$(CONFIG_ARCH_SHMOBILE) += emev2-kzm9d.dtb \ r8a7740-armadillo800eva.dtb \ + r8a7778-bockw.dtb \ + r8a7779-marzen-reference.dtb \ + r8a7790-lager.dtb \ sh73a0-kzm9g.dtb \ + sh73a0-kzm9g-reference.dtb \ + r8a73a4-ape6evm.dtb \ sh7372-mackerel.dtb dtb-$(CONFIG_ARCH_SOCFPGA) += socfpga_cyclone5.dtb \ socfpga_vt.dtb @@ -179,11 +195,13 @@ dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \ tegra30-cardhu-a04.dtb \ tegra114-dalmore.dtb \ tegra114-pluto.dtb +dtb-$(CONFIG_ARCH_VERSATILE) += versatile-ab.dtb \ + versatile-pb.dtb dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2p-ca5s.dtb \ vexpress-v2p-ca9.dtb \ vexpress-v2p-ca15-tc1.dtb \ - vexpress-v2p-ca15_a7.dtb \ - xenvm-4.2.dtb + vexpress-v2p-ca15_a7.dtb +dtb-$(CONFIG_ARCH_VIRT) += xenvm-4.2.dtb dtb-$(CONFIG_ARCH_VT8500) += vt8500-bv07.dtb \ wm8505-ref.dtb \ wm8650-mid.dtb \ diff --git a/trunk/arch/arm/boot/dts/am335x-bone.dts b/trunk/arch/arm/boot/dts/am335x-bone.dts index 11b240c5d323..5302f79c05b7 100644 --- a/trunk/arch/arm/boot/dts/am335x-bone.dts +++ b/trunk/arch/arm/boot/dts/am335x-bone.dts @@ -43,7 +43,7 @@ status = "okay"; }; - i2c1: i2c@44e0b000 { + i2c0: i2c@44e0b000 { status = "okay"; clock-frequency = <400000>; @@ -59,27 +59,27 @@ led@2 { label = "beaglebone:green:heartbeat"; - gpios = <&gpio2 21 0>; + gpios = <&gpio1 21 0>; linux,default-trigger = "heartbeat"; default-state = "off"; }; led@3 { label = "beaglebone:green:mmc0"; - gpios = <&gpio2 22 0>; + gpios = <&gpio1 22 0>; linux,default-trigger = "mmc0"; default-state = "off"; }; led@4 { label = "beaglebone:green:usr2"; - gpios = <&gpio2 23 0>; + gpios = <&gpio1 23 0>; default-state = "off"; }; led@5 { label = "beaglebone:green:usr3"; - gpios = <&gpio2 24 0>; + gpios = <&gpio1 24 0>; default-state = "off"; }; }; diff --git a/trunk/arch/arm/boot/dts/am335x-evm.dts b/trunk/arch/arm/boot/dts/am335x-evm.dts index d6496440fcea..0423298a26fe 100644 --- a/trunk/arch/arm/boot/dts/am335x-evm.dts +++ b/trunk/arch/arm/boot/dts/am335x-evm.dts @@ -51,7 +51,7 @@ status = "okay"; }; - i2c1: i2c@44e0b000 { + i2c0: i2c@44e0b000 { status = "okay"; clock-frequency = <400000>; @@ -60,7 +60,7 @@ }; }; - i2c2: i2c@4802a000 { + i2c1: i2c@4802a000 { status = "okay"; clock-frequency = <100000>; @@ -123,12 +123,12 @@ debounce-delay-ms = <5>; col-scan-delay-us = <2>; - row-gpios = <&gpio2 25 0 /* Bank1, pin25 */ - &gpio2 26 0 /* Bank1, pin26 */ - &gpio2 27 0>; /* Bank1, pin27 */ + row-gpios = <&gpio1 25 0 /* Bank1, pin25 */ + &gpio1 26 0 /* Bank1, pin26 */ + &gpio1 27 0>; /* Bank1, pin27 */ - col-gpios = <&gpio2 21 0 /* Bank1, pin21 */ - &gpio2 22 0>; /* Bank1, pin22 */ + col-gpios = <&gpio1 21 0 /* Bank1, pin21 */ + &gpio1 22 0>; /* Bank1, pin22 */ linux,keymap = <0x0000008b /* MENU */ 0x0100009e /* BACK */ @@ -147,14 +147,14 @@ switch@9 { label = "volume-up"; linux,code = <115>; - gpios = <&gpio1 2 1>; + gpios = <&gpio0 2 1>; gpio-key,wakeup; }; switch@10 { label = "volume-down"; linux,code = <114>; - gpios = <&gpio1 3 1>; + gpios = <&gpio0 3 1>; gpio-key,wakeup; }; }; diff --git a/trunk/arch/arm/boot/dts/am335x-evmsk.dts b/trunk/arch/arm/boot/dts/am335x-evmsk.dts index f5a6162a4ff2..f67c360844f4 100644 --- a/trunk/arch/arm/boot/dts/am335x-evmsk.dts +++ b/trunk/arch/arm/boot/dts/am335x-evmsk.dts @@ -58,7 +58,7 @@ status = "okay"; }; - i2c1: i2c@44e0b000 { + i2c0: i2c@44e0b000 { status = "okay"; clock-frequency = <400000>; @@ -115,26 +115,26 @@ led@1 { label = "evmsk:green:usr0"; - gpios = <&gpio2 4 0>; + gpios = <&gpio1 4 0>; default-state = "off"; }; led@2 { label = "evmsk:green:usr1"; - gpios = <&gpio2 5 0>; + gpios = <&gpio1 5 0>; default-state = "off"; }; led@3 { label = "evmsk:green:mmc0"; - gpios = <&gpio2 6 0>; + gpios = <&gpio1 6 0>; linux,default-trigger = "mmc0"; default-state = "off"; }; led@4 { label = "evmsk:green:heartbeat"; - gpios = <&gpio2 7 0>; + gpios = <&gpio1 7 0>; linux,default-trigger = "heartbeat"; default-state = "off"; }; @@ -148,26 +148,26 @@ switch@1 { label = "button0"; linux,code = <0x100>; - gpios = <&gpio3 3 0>; + gpios = <&gpio2 3 0>; }; switch@2 { label = "button1"; linux,code = <0x101>; - gpios = <&gpio3 2 0>; + gpios = <&gpio2 2 0>; }; switch@3 { label = "button2"; linux,code = <0x102>; - gpios = <&gpio1 30 0>; + gpios = <&gpio0 30 0>; gpio-key,wakeup; }; switch@4 { label = "button3"; linux,code = <0x103>; - gpios = <&gpio3 5 0>; + gpios = <&gpio2 5 0>; }; }; }; diff --git a/trunk/arch/arm/boot/dts/am33xx.dtsi b/trunk/arch/arm/boot/dts/am33xx.dtsi index 91fe4f148f80..1460d9b88adf 100644 --- a/trunk/arch/arm/boot/dts/am33xx.dtsi +++ b/trunk/arch/arm/boot/dts/am33xx.dtsi @@ -21,6 +21,8 @@ serial3 = &uart4; serial4 = &uart5; serial5 = &uart6; + d_can0 = &dcan0; + d_can1 = &dcan1; }; cpus { @@ -87,7 +89,7 @@ reg = <0x48200000 0x1000>; }; - gpio1: gpio@44e07000 { + gpio0: gpio@44e07000 { compatible = "ti,omap4-gpio"; ti,hwmods = "gpio1"; gpio-controller; @@ -98,7 +100,7 @@ interrupts = <96>; }; - gpio2: gpio@4804c000 { + gpio1: gpio@4804c000 { compatible = "ti,omap4-gpio"; ti,hwmods = "gpio2"; gpio-controller; @@ -109,7 +111,7 @@ interrupts = <98>; }; - gpio3: gpio@481ac000 { + gpio2: gpio@481ac000 { compatible = "ti,omap4-gpio"; ti,hwmods = "gpio3"; gpio-controller; @@ -120,7 +122,7 @@ interrupts = <32>; }; - gpio4: gpio@481ae000 { + gpio3: gpio@481ae000 { compatible = "ti,omap4-gpio"; ti,hwmods = "gpio4"; gpio-controller; @@ -185,7 +187,7 @@ status = "disabled"; }; - i2c1: i2c@44e0b000 { + i2c0: i2c@44e0b000 { compatible = "ti,omap4-i2c"; #address-cells = <1>; #size-cells = <0>; @@ -195,7 +197,7 @@ status = "disabled"; }; - i2c2: i2c@4802a000 { + i2c1: i2c@4802a000 { compatible = "ti,omap4-i2c"; #address-cells = <1>; #size-cells = <0>; @@ -205,7 +207,7 @@ status = "disabled"; }; - i2c3: i2c@4819c000 { + i2c2: i2c@4819c000 { compatible = "ti,omap4-i2c"; #address-cells = <1>; #size-cells = <0>; @@ -225,7 +227,8 @@ dcan0: d_can@481cc000 { compatible = "bosch,d_can"; ti,hwmods = "d_can0"; - reg = <0x481cc000 0x2000>; + reg = <0x481cc000 0x2000 + 0x44e10644 0x4>; interrupts = <52>; status = "disabled"; }; @@ -233,13 +236,14 @@ dcan1: d_can@481d0000 { compatible = "bosch,d_can"; ti,hwmods = "d_can1"; - reg = <0x481d0000 0x2000>; + reg = <0x481d0000 0x2000 + 0x44e10644 0x4>; interrupts = <55>; status = "disabled"; }; timer1: timer@44e31000 { - compatible = "ti,omap2-timer"; + compatible = "ti,am335x-timer-1ms"; reg = <0x44e31000 0x400>; interrupts = <67>; ti,hwmods = "timer1"; @@ -247,21 +251,21 @@ }; timer2: timer@48040000 { - compatible = "ti,omap2-timer"; + compatible = "ti,am335x-timer"; reg = <0x48040000 0x400>; interrupts = <68>; ti,hwmods = "timer2"; }; timer3: timer@48042000 { - compatible = "ti,omap2-timer"; + compatible = "ti,am335x-timer"; reg = <0x48042000 0x400>; interrupts = <69>; ti,hwmods = "timer3"; }; timer4: timer@48044000 { - compatible = "ti,omap2-timer"; + compatible = "ti,am335x-timer"; reg = <0x48044000 0x400>; interrupts = <92>; ti,hwmods = "timer4"; @@ -269,7 +273,7 @@ }; timer5: timer@48046000 { - compatible = "ti,omap2-timer"; + compatible = "ti,am335x-timer"; reg = <0x48046000 0x400>; interrupts = <93>; ti,hwmods = "timer5"; @@ -277,7 +281,7 @@ }; timer6: timer@48048000 { - compatible = "ti,omap2-timer"; + compatible = "ti,am335x-timer"; reg = <0x48048000 0x400>; interrupts = <94>; ti,hwmods = "timer6"; @@ -285,7 +289,7 @@ }; timer7: timer@4804a000 { - compatible = "ti,omap2-timer"; + compatible = "ti,am335x-timer"; reg = <0x4804a000 0x400>; interrupts = <95>; ti,hwmods = "timer7"; @@ -305,7 +309,7 @@ #address-cells = <1>; #size-cells = <0>; reg = <0x48030000 0x400>; - interrupt = <65>; + interrupts = <65>; ti,spi-num-cs = <2>; ti,hwmods = "spi0"; status = "disabled"; @@ -316,7 +320,7 @@ #address-cells = <1>; #size-cells = <0>; reg = <0x481a0000 0x400>; - interrupt = <125>; + interrupts = <125>; ti,spi-num-cs = <2>; ti,hwmods = "spi1"; status = "disabled"; @@ -399,5 +403,17 @@ 0x44d80000 0x2000>; /* M3 DMEM */ ti,hwmods = "wkup_m3"; }; + + gpmc: gpmc@50000000 { + compatible = "ti,am3352-gpmc"; + ti,hwmods = "gpmc"; + reg = <0x50000000 0x2000>; + interrupts = <100>; + num-cs = <7>; + num-waitpins = <2>; + #address-cells = <2>; + #size-cells = <1>; + status = "disabled"; + }; }; }; diff --git a/trunk/arch/arm/boot/dts/am3517-evm.dts b/trunk/arch/arm/boot/dts/am3517-evm.dts index 474f760ecadf..e9b5bdae4908 100644 --- a/trunk/arch/arm/boot/dts/am3517-evm.dts +++ b/trunk/arch/arm/boot/dts/am3517-evm.dts @@ -7,7 +7,7 @@ */ /dts-v1/; -/include/ "omap3.dtsi" +/include/ "omap34xx.dtsi" / { model = "TI AM3517 EVM (AM3517/05)"; diff --git a/trunk/arch/arm/boot/dts/am3517_mt_ventoux.dts b/trunk/arch/arm/boot/dts/am3517_mt_ventoux.dts index 5eb26d7d9b4e..556868388a23 100644 --- a/trunk/arch/arm/boot/dts/am3517_mt_ventoux.dts +++ b/trunk/arch/arm/boot/dts/am3517_mt_ventoux.dts @@ -7,7 +7,7 @@ */ /dts-v1/; -/include/ "omap3.dtsi" +/include/ "omap34xx.dtsi" / { model = "TeeJet Mt.Ventoux"; diff --git a/trunk/arch/arm/boot/dts/armada-370-db.dts b/trunk/arch/arm/boot/dts/armada-370-db.dts index 6403acdbb75f..2353b1f13704 100644 --- a/trunk/arch/arm/boot/dts/armada-370-db.dts +++ b/trunk/arch/arm/boot/dts/armada-370-db.dts @@ -30,85 +30,87 @@ }; soc { - serial@d0012000 { - clock-frequency = <200000000>; - status = "okay"; - }; - sata@d00a0000 { - nr-ports = <2>; - status = "okay"; - }; - - mdio { - phy0: ethernet-phy@0 { - reg = <0>; + internal-regs { + serial@12000 { + clock-frequency = <200000000>; + status = "okay"; }; - - phy1: ethernet-phy@1 { - reg = <1>; + sata@a0000 { + nr-ports = <2>; + status = "okay"; }; - }; - ethernet@d0070000 { - status = "okay"; - phy = <&phy0>; - phy-mode = "rgmii-id"; - }; - ethernet@d0074000 { - status = "okay"; - phy = <&phy1>; - phy-mode = "rgmii-id"; - }; + mdio { + phy0: ethernet-phy@0 { + reg = <0>; + }; - mvsdio@d00d4000 { - pinctrl-0 = <&sdio_pins1>; - pinctrl-names = "default"; - /* - * This device is disabled by default, because - * using the SD card connector requires - * changing the default CON40 connector - * "DB-88F6710_MPP_2xRGMII_DEVICE_Jumper" to a - * different connector - * "DB-88F6710_MPP_RGMII_SD_Jumper". - */ - status = "disabled"; - /* No CD or WP GPIOs */ - }; + phy1: ethernet-phy@1 { + reg = <1>; + }; + }; - usb@d0050000 { - status = "okay"; - }; + ethernet@70000 { + status = "okay"; + phy = <&phy0>; + phy-mode = "rgmii-id"; + }; + ethernet@74000 { + status = "okay"; + phy = <&phy1>; + phy-mode = "rgmii-id"; + }; - usb@d0051000 { - status = "okay"; - }; + mvsdio@d4000 { + pinctrl-0 = <&sdio_pins1>; + pinctrl-names = "default"; + /* + * This device is disabled by default, because + * using the SD card connector requires + * changing the default CON40 connector + * "DB-88F6710_MPP_2xRGMII_DEVICE_Jumper" to a + * different connector + * "DB-88F6710_MPP_RGMII_SD_Jumper". + */ + status = "disabled"; + /* No CD or WP GPIOs */ + }; - spi0: spi@d0010600 { - status = "okay"; + usb@50000 { + status = "okay"; + }; - spi-flash@0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "mx25l25635e"; - reg = <0>; /* Chip select 0 */ - spi-max-frequency = <50000000>; + usb@51000 { + status = "okay"; }; - }; - pcie-controller { - status = "okay"; - /* - * The two PCIe units are accessible through - * both standard PCIe slots and mini-PCIe - * slots on the board. - */ - pcie@1,0 { - /* Port 0, Lane 0 */ + spi0: spi@10600 { status = "okay"; + + spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "mx25l25635e"; + reg = <0>; /* Chip select 0 */ + spi-max-frequency = <50000000>; + }; }; - pcie@2,0 { - /* Port 1, Lane 0 */ + + pcie-controller { status = "okay"; + /* + * The two PCIe units are accessible through + * both standard PCIe slots and mini-PCIe + * slots on the board. + */ + pcie@1,0 { + /* Port 0, Lane 0 */ + status = "okay"; + }; + pcie@2,0 { + /* Port 1, Lane 0 */ + status = "okay"; + }; }; }; }; diff --git a/trunk/arch/arm/boot/dts/armada-370-mirabox.dts b/trunk/arch/arm/boot/dts/armada-370-mirabox.dts index 58ee79372206..14e36e19d515 100644 --- a/trunk/arch/arm/boot/dts/armada-370-mirabox.dts +++ b/trunk/arch/arm/boot/dts/armada-370-mirabox.dts @@ -25,113 +25,115 @@ }; soc { - serial@d0012000 { - clock-frequency = <200000000>; - status = "okay"; - }; - timer@d0020300 { - clock-frequency = <600000000>; - status = "okay"; - }; - - pinctrl { - pwr_led_pin: pwr-led-pin { - marvell,pins = "mpp63"; - marvell,function = "gpo"; + internal-regs { + serial@12000 { + clock-frequency = <200000000>; + status = "okay"; }; - - stat_led_pins: stat-led-pins { - marvell,pins = "mpp64", "mpp65"; - marvell,function = "gpio"; + timer@20300 { + clock-frequency = <600000000>; + status = "okay"; }; - }; - gpio_leds { - compatible = "gpio-leds"; - pinctrl-names = "default"; - pinctrl-0 = <&pwr_led_pin &stat_led_pins>; + pinctrl { + pwr_led_pin: pwr-led-pin { + marvell,pins = "mpp63"; + marvell,function = "gpo"; + }; - green_pwr_led { - label = "mirabox:green:pwr"; - gpios = <&gpio1 31 1>; - linux,default-trigger = "heartbeat"; + stat_led_pins: stat-led-pins { + marvell,pins = "mpp64", "mpp65"; + marvell,function = "gpio"; + }; }; - blue_stat_led { - label = "mirabox:blue:stat"; - gpios = <&gpio2 0 1>; - linux,default-trigger = "cpu0"; + gpio_leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&pwr_led_pin &stat_led_pins>; + + green_pwr_led { + label = "mirabox:green:pwr"; + gpios = <&gpio1 31 1>; + linux,default-trigger = "heartbeat"; + }; + + blue_stat_led { + label = "mirabox:blue:stat"; + gpios = <&gpio2 0 1>; + linux,default-trigger = "cpu0"; + }; + + green_stat_led { + label = "mirabox:green:stat"; + gpios = <&gpio2 1 1>; + default-state = "off"; + }; }; - green_stat_led { - label = "mirabox:green:stat"; - gpios = <&gpio2 1 1>; - default-state = "off"; - }; - }; + mdio { + phy0: ethernet-phy@0 { + reg = <0>; + }; - mdio { - phy0: ethernet-phy@0 { - reg = <0>; + phy1: ethernet-phy@1 { + reg = <1>; + }; }; - - phy1: ethernet-phy@1 { - reg = <1>; + ethernet@70000 { + status = "okay"; + phy = <&phy0>; + phy-mode = "rgmii-id"; + }; + ethernet@74000 { + status = "okay"; + phy = <&phy1>; + phy-mode = "rgmii-id"; }; - }; - ethernet@d0070000 { - status = "okay"; - phy = <&phy0>; - phy-mode = "rgmii-id"; - }; - ethernet@d0074000 { - status = "okay"; - phy = <&phy1>; - phy-mode = "rgmii-id"; - }; - - mvsdio@d00d4000 { - pinctrl-0 = <&sdio_pins3>; - pinctrl-names = "default"; - status = "okay"; - /* - * No CD or WP GPIOs: SDIO interface used for - * Wifi/Bluetooth chip - */ - }; - - usb@d0050000 { - status = "okay"; - }; - usb@d0051000 { - status = "okay"; - }; + mvsdio@d4000 { + pinctrl-0 = <&sdio_pins3>; + pinctrl-names = "default"; + status = "okay"; + /* + * No CD or WP GPIOs: SDIO interface used for + * Wifi/Bluetooth chip + */ + }; - i2c@d0011000 { - status = "okay"; - clock-frequency = <100000>; - pca9505: pca9505@25 { - compatible = "nxp,pca9505"; - gpio-controller; - #gpio-cells = <2>; - reg = <0x25>; + usb@50000 { + status = "okay"; }; - }; - pcie-controller { - status = "okay"; + usb@51000 { + status = "okay"; + }; - /* Internal mini-PCIe connector */ - pcie@1,0 { - /* Port 0, Lane 0 */ + i2c@11000 { status = "okay"; + clock-frequency = <100000>; + pca9505: pca9505@25 { + compatible = "nxp,pca9505"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x25>; + }; }; - /* Connected on the PCB to a USB 3.0 XHCI controller */ - pcie@2,0 { - /* Port 1, Lane 0 */ + pcie-controller { status = "okay"; + + /* Internal mini-PCIe connector */ + pcie@1,0 { + /* Port 0, Lane 0 */ + status = "okay"; + }; + + /* Connected on the PCB to a USB 3.0 XHCI controller */ + pcie@2,0 { + /* Port 1, Lane 0 */ + status = "okay"; + }; }; }; }; diff --git a/trunk/arch/arm/boot/dts/armada-370-rd.dts b/trunk/arch/arm/boot/dts/armada-370-rd.dts index 516dec31b469..130f8390a7e4 100644 --- a/trunk/arch/arm/boot/dts/armada-370-rd.dts +++ b/trunk/arch/arm/boot/dts/armada-370-rd.dts @@ -28,60 +28,62 @@ }; soc { - serial@d0012000 { - clock-frequency = <200000000>; - status = "okay"; - }; - sata@d00a0000 { - nr-ports = <2>; - status = "okay"; - }; - - mdio { - phy0: ethernet-phy@0 { - reg = <0>; + internal-regs { + serial@12000 { + clock-frequency = <200000000>; + status = "okay"; }; + sata@a0000 { + nr-ports = <2>; + status = "okay"; + }; + + mdio { + phy0: ethernet-phy@0 { + reg = <0>; + }; - phy1: ethernet-phy@1 { - reg = <1>; + phy1: ethernet-phy@1 { + reg = <1>; + }; }; - }; - ethernet@d0070000 { - status = "okay"; - phy = <&phy0>; - phy-mode = "sgmii"; - }; - ethernet@d0074000 { - status = "okay"; - phy = <&phy1>; - phy-mode = "rgmii-id"; - }; + ethernet@70000 { + status = "okay"; + phy = <&phy0>; + phy-mode = "sgmii"; + }; + ethernet@74000 { + status = "okay"; + phy = <&phy1>; + phy-mode = "rgmii-id"; + }; - mvsdio@d00d4000 { - pinctrl-0 = <&sdio_pins1>; - pinctrl-names = "default"; - status = "okay"; - /* No CD or WP GPIOs */ - }; + mvsdio@d4000 { + pinctrl-0 = <&sdio_pins1>; + pinctrl-names = "default"; + status = "okay"; + /* No CD or WP GPIOs */ + }; - usb@d0050000 { - status = "okay"; - }; + usb@50000 { + status = "okay"; + }; - usb@d0051000 { - status = "okay"; - }; - }; + usb@51000 { + status = "okay"; + }; - gpio-keys { - compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; - button@1 { - label = "Software Button"; - linux,code = <116>; - gpios = <&gpio0 6 1>; + gpio-keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + button@1 { + label = "Software Button"; + linux,code = <116>; + gpios = <&gpio0 6 1>; + }; + }; }; }; -}; + }; diff --git a/trunk/arch/arm/boot/dts/armada-370-xp.dtsi b/trunk/arch/arm/boot/dts/armada-370-xp.dtsi index 758c4ea90344..272bbc65fab0 100644 --- a/trunk/arch/arm/boot/dts/armada-370-xp.dtsi +++ b/trunk/arch/arm/boot/dts/armada-370-xp.dtsi @@ -16,7 +16,7 @@ * 370 and Armada XP SoC. */ -/include/ "skeleton.dtsi" +/include/ "skeleton64.dtsi" / { model = "Marvell Armada 370 and XP SoC"; @@ -28,204 +28,203 @@ }; }; - mpic: interrupt-controller@d0020000 { - compatible = "marvell,mpic"; - #interrupt-cells = <1>; - #size-cells = <1>; - interrupt-controller; - }; - - coherency-fabric@d0020200 { - compatible = "marvell,coherency-fabric"; - reg = <0xd0020200 0xb0>, - <0xd0021810 0x1c>; - }; - soc { #address-cells = <1>; #size-cells = <1>; compatible = "simple-bus"; interrupt-parent = <&mpic>; - ranges; + ranges = <0 0 0xd0000000 0x100000>; + + internal-regs { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + mpic: interrupt-controller@20000 { + compatible = "marvell,mpic"; + #interrupt-cells = <1>; + #size-cells = <1>; + interrupt-controller; + }; + + coherency-fabric@20200 { + compatible = "marvell,coherency-fabric"; + reg = <0x20200 0xb0>, <0x21810 0x1c>; + }; - serial@d0012000 { + serial@12000 { compatible = "snps,dw-apb-uart"; - reg = <0xd0012000 0x100>; + reg = <0x12000 0x100>; reg-shift = <2>; interrupts = <41>; reg-io-width = <1>; status = "disabled"; - }; - serial@d0012100 { + }; + serial@12100 { compatible = "snps,dw-apb-uart"; - reg = <0xd0012100 0x100>; + reg = <0x12100 0x100>; reg-shift = <2>; interrupts = <42>; reg-io-width = <1>; status = "disabled"; - }; - - timer@d0020300 { - compatible = "marvell,armada-370-xp-timer"; - reg = <0xd0020300 0x30>, - <0xd0021040 0x30>; - interrupts = <37>, <38>, <39>, <40>, <5>, <6>; - clocks = <&coreclk 2>; - }; - - addr-decoding@d0020000 { - compatible = "marvell,armada-addr-decoding-controller"; - reg = <0xd0020000 0x258>; - }; - - sata@d00a0000 { - compatible = "marvell,orion-sata"; - reg = <0xd00a0000 0x2400>; - interrupts = <55>; - clocks = <&gateclk 15>, <&gateclk 30>; - clock-names = "0", "1"; - status = "disabled"; - }; + }; + + timer@20300 { + compatible = "marvell,armada-370-xp-timer"; + reg = <0x20300 0x30>, <0x21040 0x30>; + interrupts = <37>, <38>, <39>, <40>, <5>, <6>; + clocks = <&coreclk 2>; + }; + + sata@a0000 { + compatible = "marvell,orion-sata"; + reg = <0xa0000 0x2400>; + interrupts = <55>; + clocks = <&gateclk 15>, <&gateclk 30>; + clock-names = "0", "1"; + status = "disabled"; + }; - mdio { - #address-cells = <1>; - #size-cells = <0>; - compatible = "marvell,orion-mdio"; - reg = <0xd0072004 0x4>; - }; + mdio { + #address-cells = <1>; + #size-cells = <0>; + compatible = "marvell,orion-mdio"; + reg = <0x72004 0x4>; + }; - ethernet@d0070000 { + ethernet@70000 { compatible = "marvell,armada-370-neta"; - reg = <0xd0070000 0x2500>; + reg = <0x70000 0x2500>; interrupts = <8>; clocks = <&gateclk 4>; status = "disabled"; - }; + }; - ethernet@d0074000 { + ethernet@74000 { compatible = "marvell,armada-370-neta"; - reg = <0xd0074000 0x2500>; + reg = <0x74000 0x2500>; interrupts = <10>; clocks = <&gateclk 3>; status = "disabled"; - }; - - i2c0: i2c@d0011000 { - compatible = "marvell,mv64xxx-i2c"; - reg = <0xd0011000 0x20>; - #address-cells = <1>; - #size-cells = <0>; - interrupts = <31>; - timeout-ms = <1000>; - clocks = <&coreclk 0>; - status = "disabled"; - }; - - i2c1: i2c@d0011100 { - compatible = "marvell,mv64xxx-i2c"; - reg = <0xd0011100 0x20>; - #address-cells = <1>; - #size-cells = <0>; - interrupts = <32>; - timeout-ms = <1000>; - clocks = <&coreclk 0>; - status = "disabled"; - }; - - rtc@10300 { - compatible = "marvell,orion-rtc"; - reg = <0xd0010300 0x20>; - interrupts = <50>; - }; - - mvsdio@d00d4000 { - compatible = "marvell,orion-sdio"; - reg = <0xd00d4000 0x200>; - interrupts = <54>; - clocks = <&gateclk 17>; - status = "disabled"; - }; - - usb@d0050000 { - compatible = "marvell,orion-ehci"; - reg = <0xd0050000 0x500>; - interrupts = <45>; - status = "disabled"; - }; - - usb@d0051000 { - compatible = "marvell,orion-ehci"; - reg = <0xd0051000 0x500>; - interrupts = <46>; - status = "disabled"; - }; - - spi0: spi@d0010600 { - compatible = "marvell,orion-spi"; - reg = <0xd0010600 0x28>; - #address-cells = <1>; - #size-cells = <0>; - cell-index = <0>; - interrupts = <30>; - clocks = <&coreclk 0>; - status = "disabled"; - }; - - spi1: spi@d0010680 { - compatible = "marvell,orion-spi"; - reg = <0xd0010680 0x28>; - #address-cells = <1>; - #size-cells = <0>; - cell-index = <1>; - interrupts = <92>; - clocks = <&coreclk 0>; - status = "disabled"; - }; - - devbus-bootcs@d0010400 { - compatible = "marvell,mvebu-devbus"; - reg = <0xd0010400 0x8>; - #address-cells = <1>; - #size-cells = <1>; - clocks = <&coreclk 0>; - status = "disabled"; - }; - - devbus-cs0@d0010408 { - compatible = "marvell,mvebu-devbus"; - reg = <0xd0010408 0x8>; - #address-cells = <1>; - #size-cells = <1>; - clocks = <&coreclk 0>; - status = "disabled"; - }; - - devbus-cs1@d0010410 { - compatible = "marvell,mvebu-devbus"; - reg = <0xd0010410 0x8>; - #address-cells = <1>; - #size-cells = <1>; - clocks = <&coreclk 0>; - status = "disabled"; - }; + }; + + i2c0: i2c@11000 { + compatible = "marvell,mv64xxx-i2c"; + reg = <0x11000 0x20>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <31>; + timeout-ms = <1000>; + clocks = <&coreclk 0>; + status = "disabled"; + }; + + i2c1: i2c@11100 { + compatible = "marvell,mv64xxx-i2c"; + reg = <0x11100 0x20>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <32>; + timeout-ms = <1000>; + clocks = <&coreclk 0>; + status = "disabled"; + }; + + rtc@10300 { + compatible = "marvell,orion-rtc"; + reg = <0x10300 0x20>; + interrupts = <50>; + }; + + mvsdio@d4000 { + compatible = "marvell,orion-sdio"; + reg = <0xd4000 0x200>; + interrupts = <54>; + clocks = <&gateclk 17>; + status = "disabled"; + }; - devbus-cs2@d0010418 { - compatible = "marvell,mvebu-devbus"; - reg = <0xd0010418 0x8>; - #address-cells = <1>; - #size-cells = <1>; - clocks = <&coreclk 0>; - status = "disabled"; - }; + usb@50000 { + compatible = "marvell,orion-ehci"; + reg = <0x50000 0x500>; + interrupts = <45>; + status = "disabled"; + }; - devbus-cs3@d0010420 { - compatible = "marvell,mvebu-devbus"; - reg = <0xd0010420 0x8>; - #address-cells = <1>; - #size-cells = <1>; - clocks = <&coreclk 0>; - status = "disabled"; + usb@51000 { + compatible = "marvell,orion-ehci"; + reg = <0x51000 0x500>; + interrupts = <46>; + status = "disabled"; + }; + + spi0: spi@10600 { + compatible = "marvell,orion-spi"; + reg = <0x10600 0x28>; + #address-cells = <1>; + #size-cells = <0>; + cell-index = <0>; + interrupts = <30>; + clocks = <&coreclk 0>; + status = "disabled"; + }; + + spi1: spi@10680 { + compatible = "marvell,orion-spi"; + reg = <0x10680 0x28>; + #address-cells = <1>; + #size-cells = <0>; + cell-index = <1>; + interrupts = <92>; + clocks = <&coreclk 0>; + status = "disabled"; + }; + + devbus-bootcs@10400 { + compatible = "marvell,mvebu-devbus"; + reg = <0x10400 0x8>; + #address-cells = <1>; + #size-cells = <1>; + clocks = <&coreclk 0>; + status = "disabled"; + }; + + devbus-cs0@10408 { + compatible = "marvell,mvebu-devbus"; + reg = <0x10408 0x8>; + #address-cells = <1>; + #size-cells = <1>; + clocks = <&coreclk 0>; + status = "disabled"; + }; + + devbus-cs1@10410 { + compatible = "marvell,mvebu-devbus"; + reg = <0x10410 0x8>; + #address-cells = <1>; + #size-cells = <1>; + clocks = <&coreclk 0>; + status = "disabled"; + }; + + devbus-cs2@10418 { + compatible = "marvell,mvebu-devbus"; + reg = <0x10418 0x8>; + #address-cells = <1>; + #size-cells = <1>; + clocks = <&coreclk 0>; + status = "disabled"; + }; + + devbus-cs3@10420 { + compatible = "marvell,mvebu-devbus"; + reg = <0x10420 0x8>; + #address-cells = <1>; + #size-cells = <1>; + clocks = <&coreclk 0>; + status = "disabled"; + }; }; }; -}; - + }; diff --git a/trunk/arch/arm/boot/dts/armada-370.dtsi b/trunk/arch/arm/boot/dts/armada-370.dtsi index 18f6eb47cc50..b2c1b5af9749 100644 --- a/trunk/arch/arm/boot/dts/armada-370.dtsi +++ b/trunk/arch/arm/boot/dts/armada-370.dtsi @@ -16,16 +16,11 @@ */ /include/ "armada-370-xp.dtsi" +/include/ "skeleton.dtsi" / { model = "Marvell Armada 370 family SoC"; compatible = "marvell,armada370", "marvell,armada-370-xp"; - L2: l2-cache { - compatible = "marvell,aurora-outer-cache"; - reg = <0xd0008000 0x1000>; - cache-id-part = <0x100>; - wt-override; - }; aliases { gpio0 = &gpio0; @@ -33,188 +28,197 @@ gpio2 = &gpio2; }; - mpic: interrupt-controller@d0020000 { - reg = <0xd0020a00 0x1d0>, - <0xd0021870 0x58>; - }; - soc { - system-controller@d0018200 { + ranges = <0 0xd0000000 0x100000>; + internal-regs { + system-controller@18200 { compatible = "marvell,armada-370-xp-system-controller"; - reg = <0xd0018200 0x100>; - }; - - pinctrl { - compatible = "marvell,mv88f6710-pinctrl"; - reg = <0xd0018000 0x38>; - - sdio_pins1: sdio-pins1 { - marvell,pins = "mpp9", "mpp11", "mpp12", - "mpp13", "mpp14", "mpp15"; - marvell,function = "sd0"; + reg = <0x18200 0x100>; }; - sdio_pins2: sdio-pins2 { - marvell,pins = "mpp47", "mpp48", "mpp49", - "mpp50", "mpp51", "mpp52"; - marvell,function = "sd0"; + L2: l2-cache { + compatible = "marvell,aurora-outer-cache"; + reg = <0xd0008000 0x1000>; + cache-id-part = <0x100>; + wt-override; }; - sdio_pins3: sdio-pins3 { - marvell,pins = "mpp48", "mpp49", "mpp50", - "mpp51", "mpp52", "mpp53"; - marvell,function = "sd0"; + mpic: interrupt-controller@20000 { + reg = <0x20a00 0x1d0>, <0x21870 0x58>; }; - }; - - gpio0: gpio@d0018100 { - compatible = "marvell,orion-gpio"; - reg = <0xd0018100 0x40>; - ngpios = <32>; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupts-cells = <2>; - interrupts = <82>, <83>, <84>, <85>; - }; - - gpio1: gpio@d0018140 { - compatible = "marvell,orion-gpio"; - reg = <0xd0018140 0x40>; - ngpios = <32>; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupts-cells = <2>; - interrupts = <87>, <88>, <89>, <90>; - }; - - gpio2: gpio@d0018180 { - compatible = "marvell,orion-gpio"; - reg = <0xd0018180 0x40>; - ngpios = <2>; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupts-cells = <2>; - interrupts = <91>; - }; - coreclk: mvebu-sar@d0018230 { - compatible = "marvell,armada-370-core-clock"; - reg = <0xd0018230 0x08>; - #clock-cells = <1>; - }; - - gateclk: clock-gating-control@d0018220 { - compatible = "marvell,armada-370-gating-clock"; - reg = <0xd0018220 0x4>; - clocks = <&coreclk 0>; - #clock-cells = <1>; - }; - - xor@d0060800 { - compatible = "marvell,orion-xor"; - reg = <0xd0060800 0x100 - 0xd0060A00 0x100>; - status = "okay"; - - xor00 { - interrupts = <51>; - dmacap,memcpy; - dmacap,xor; + pinctrl { + compatible = "marvell,mv88f6710-pinctrl"; + reg = <0x18000 0x38>; + + sdio_pins1: sdio-pins1 { + marvell,pins = "mpp9", "mpp11", "mpp12", + "mpp13", "mpp14", "mpp15"; + marvell,function = "sd0"; + }; + + sdio_pins2: sdio-pins2 { + marvell,pins = "mpp47", "mpp48", "mpp49", + "mpp50", "mpp51", "mpp52"; + marvell,function = "sd0"; + }; + + sdio_pins3: sdio-pins3 { + marvell,pins = "mpp48", "mpp49", "mpp50", + "mpp51", "mpp52", "mpp53"; + marvell,function = "sd0"; + }; }; - xor01 { - interrupts = <52>; - dmacap,memcpy; - dmacap,xor; - dmacap,memset; - }; - }; - - xor@d0060900 { - compatible = "marvell,orion-xor"; - reg = <0xd0060900 0x100 - 0xd0060b00 0x100>; - status = "okay"; - xor10 { - interrupts = <94>; - dmacap,memcpy; - dmacap,xor; + gpio0: gpio@18100 { + compatible = "marvell,orion-gpio"; + reg = <0x18100 0x40>; + ngpios = <32>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupts-cells = <2>; + interrupts = <82>, <83>, <84>, <85>; }; - xor11 { - interrupts = <95>; - dmacap,memcpy; - dmacap,xor; - dmacap,memset; - }; - }; - usb@d0050000 { - clocks = <&coreclk 0>; - }; - - usb@d0051000 { - clocks = <&coreclk 0>; - }; + gpio1: gpio@18140 { + compatible = "marvell,orion-gpio"; + reg = <0x18140 0x40>; + ngpios = <32>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupts-cells = <2>; + interrupts = <87>, <88>, <89>, <90>; + }; - thermal@d0018300 { - compatible = "marvell,armada370-thermal"; - reg = <0xd0018300 0x4 - 0xd0018304 0x4>; - status = "okay"; - }; + gpio2: gpio@18180 { + compatible = "marvell,orion-gpio"; + reg = <0x18180 0x40>; + ngpios = <2>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupts-cells = <2>; + interrupts = <91>; + }; - pcie-controller { - compatible = "marvell,armada-370-pcie"; - status = "disabled"; - device_type = "pci"; + coreclk: mvebu-sar@18230 { + compatible = "marvell,armada-370-core-clock"; + reg = <0x18230 0x08>; + #clock-cells = <1>; + }; - #address-cells = <3>; - #size-cells = <2>; + gateclk: clock-gating-control@18220 { + compatible = "marvell,armada-370-gating-clock"; + reg = <0x18220 0x4>; + clocks = <&coreclk 0>; + #clock-cells = <1>; + }; - bus-range = <0x00 0xff>; + xor@60800 { + compatible = "marvell,orion-xor"; + reg = <0x60800 0x100 + 0x60A00 0x100>; + status = "okay"; + + xor00 { + interrupts = <51>; + dmacap,memcpy; + dmacap,xor; + }; + xor01 { + interrupts = <52>; + dmacap,memcpy; + dmacap,xor; + dmacap,memset; + }; + }; - reg = <0xd0040000 0x2000>, <0xd0080000 0x2000>; + xor@60900 { + compatible = "marvell,orion-xor"; + reg = <0x60900 0x100 + 0x60b00 0x100>; + status = "okay"; + + xor10 { + interrupts = <94>; + dmacap,memcpy; + dmacap,xor; + }; + xor11 { + interrupts = <95>; + dmacap,memcpy; + dmacap,xor; + dmacap,memset; + }; + }; - reg-names = "pcie0.0", "pcie1.0"; + usb@50000 { + clocks = <&coreclk 0>; + }; - ranges = <0x82000000 0 0xd0040000 0xd0040000 0 0x00002000 /* Port 0.0 registers */ - 0x82000000 0 0xd0080000 0xd0080000 0 0x00002000 /* Port 1.0 registers */ - 0x82000000 0 0xe0000000 0xe0000000 0 0x08000000 /* non-prefetchable memory */ - 0x81000000 0 0 0xe8000000 0 0x00100000>; /* downstream I/O */ + usb@51000 { + clocks = <&coreclk 0>; + }; - pcie@1,0 { - device_type = "pci"; - assigned-addresses = <0x82000800 0 0xd0040000 0 0x2000>; - reg = <0x0800 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - ranges; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &mpic 58>; - marvell,pcie-port = <0>; - marvell,pcie-lane = <0>; - clocks = <&gateclk 5>; - status = "disabled"; + thermal@18300 { + compatible = "marvell,armada370-thermal"; + reg = <0x18300 0x4 + 0x18304 0x4>; + status = "okay"; }; - pcie@2,0 { + pcie-controller { + compatible = "marvell,armada-370-pcie"; + status = "disabled"; device_type = "pci"; - assigned-addresses = <0x82002800 0 0xd0080000 0 0x2000>; - reg = <0x1000 0 0 0 0>; + #address-cells = <3>; #size-cells = <2>; - #interrupt-cells = <1>; - ranges; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &mpic 62>; - marvell,pcie-port = <1>; - marvell,pcie-lane = <0>; - clocks = <&gateclk 9>; - status = "disabled"; + + bus-range = <0x00 0xff>; + + reg = <0x40000 0x2000>, <0x80000 0x2000>; + + reg-names = "pcie0.0", "pcie1.0"; + + ranges = <0x82000000 0 0x40000 0x40000 0 0x00002000 /* Port 0.0 registers */ + 0x82000000 0 0x80000 0x80000 0 0x00002000 /* Port 1.0 registers */ + 0x82000000 0 0xe0000000 0xe0000000 0 0x08000000 /* non-prefetchable memory */ + 0x81000000 0 0 0xe8000000 0 0x00100000>; /* downstream I/O */ + + pcie@1,0 { + device_type = "pci"; + assigned-addresses = <0x82000800 0 0x40000 0 0x2000>; + reg = <0x0800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &mpic 58>; + marvell,pcie-port = <0>; + marvell,pcie-lane = <0>; + clocks = <&gateclk 5>; + status = "disabled"; + }; + + pcie@2,0 { + device_type = "pci"; + assigned-addresses = <0x82002800 0 0x80000 0 0x2000>; + reg = <0x1000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &mpic 62>; + marvell,pcie-port = <1>; + marvell,pcie-lane = <0>; + clocks = <&gateclk 9>; + status = "disabled"; + }; }; }; }; diff --git a/trunk/arch/arm/boot/dts/armada-xp-db.dts b/trunk/arch/arm/boot/dts/armada-xp-db.dts index 54cc5bb705fb..d6cc8bf8272e 100644 --- a/trunk/arch/arm/boot/dts/armada-xp-db.dts +++ b/trunk/arch/arm/boot/dts/armada-xp-db.dts @@ -26,132 +26,134 @@ memory { device_type = "memory"; - reg = <0x00000000 0x80000000>; /* 2 GB */ + reg = <0 0x00000000 0 0x80000000>; /* 2 GB */ }; soc { - serial@d0012000 { - clock-frequency = <250000000>; - status = "okay"; - }; - serial@d0012100 { - clock-frequency = <250000000>; - status = "okay"; - }; - serial@d0012200 { - clock-frequency = <250000000>; - status = "okay"; - }; - serial@d0012300 { - clock-frequency = <250000000>; - status = "okay"; - }; - - sata@d00a0000 { - nr-ports = <2>; - status = "okay"; - }; - - mdio { - phy0: ethernet-phy@0 { - reg = <0>; + internal-regs { + serial@12000 { + clock-frequency = <250000000>; + status = "okay"; }; - - phy1: ethernet-phy@1 { - reg = <1>; + serial@12100 { + clock-frequency = <250000000>; + status = "okay"; }; - - phy2: ethernet-phy@2 { - reg = <25>; + serial@12200 { + clock-frequency = <250000000>; + status = "okay"; }; - - phy3: ethernet-phy@3 { - reg = <27>; + serial@12300 { + clock-frequency = <250000000>; + status = "okay"; }; - }; - - ethernet@d0070000 { - status = "okay"; - phy = <&phy0>; - phy-mode = "rgmii-id"; - }; - ethernet@d0074000 { - status = "okay"; - phy = <&phy1>; - phy-mode = "rgmii-id"; - }; - ethernet@d0030000 { - status = "okay"; - phy = <&phy2>; - phy-mode = "sgmii"; - }; - ethernet@d0034000 { - status = "okay"; - phy = <&phy3>; - phy-mode = "sgmii"; - }; - - mvsdio@d00d4000 { - pinctrl-0 = <&sdio_pins>; - pinctrl-names = "default"; - status = "okay"; - /* No CD or WP GPIOs */ - }; - usb@d0050000 { - status = "okay"; - }; + sata@a0000 { + nr-ports = <2>; + status = "okay"; + }; - usb@d0051000 { - status = "okay"; - }; + mdio { + phy0: ethernet-phy@0 { + reg = <0>; + }; - usb@d0052000 { - status = "okay"; - }; + phy1: ethernet-phy@1 { + reg = <1>; + }; - spi0: spi@d0010600 { - status = "okay"; + phy2: ethernet-phy@2 { + reg = <25>; + }; - spi-flash@0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "m25p64"; - reg = <0>; /* Chip select 0 */ - spi-max-frequency = <20000000>; + phy3: ethernet-phy@3 { + reg = <27>; + }; }; - }; - pcie-controller { - status = "okay"; + ethernet@70000 { + status = "okay"; + phy = <&phy0>; + phy-mode = "rgmii-id"; + }; + ethernet@74000 { + status = "okay"; + phy = <&phy1>; + phy-mode = "rgmii-id"; + }; + ethernet@30000 { + status = "okay"; + phy = <&phy2>; + phy-mode = "sgmii"; + }; + ethernet@34000 { + status = "okay"; + phy = <&phy3>; + phy-mode = "sgmii"; + }; - /* - * All 6 slots are physically present as - * standard PCIe slots on the board. - */ - pcie@1,0 { - /* Port 0, Lane 0 */ + mvsdio@d4000 { + pinctrl-0 = <&sdio_pins>; + pinctrl-names = "default"; status = "okay"; + /* No CD or WP GPIOs */ }; - pcie@2,0 { - /* Port 0, Lane 1 */ + + usb@50000 { status = "okay"; }; - pcie@3,0 { - /* Port 0, Lane 2 */ + + usb@51000 { status = "okay"; }; - pcie@4,0 { - /* Port 0, Lane 3 */ + + usb@52000 { status = "okay"; }; - pcie@9,0 { - /* Port 2, Lane 0 */ + + spi0: spi@10600 { status = "okay"; + + spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "m25p64"; + reg = <0>; /* Chip select 0 */ + spi-max-frequency = <20000000>; + }; }; - pcie@10,0 { - /* Port 3, Lane 0 */ + + pcie-controller { status = "okay"; + + /* + * All 6 slots are physically present as + * standard PCIe slots on the board. + */ + pcie@1,0 { + /* Port 0, Lane 0 */ + status = "okay"; + }; + pcie@2,0 { + /* Port 0, Lane 1 */ + status = "okay"; + }; + pcie@3,0 { + /* Port 0, Lane 2 */ + status = "okay"; + }; + pcie@4,0 { + /* Port 0, Lane 3 */ + status = "okay"; + }; + pcie@9,0 { + /* Port 2, Lane 0 */ + status = "okay"; + }; + pcie@10,0 { + /* Port 3, Lane 0 */ + status = "okay"; + }; }; }; }; diff --git a/trunk/arch/arm/boot/dts/armada-xp-gp.dts b/trunk/arch/arm/boot/dts/armada-xp-gp.dts index 04f28a712b98..26ad06fc147e 100644 --- a/trunk/arch/arm/boot/dts/armada-xp-gp.dts +++ b/trunk/arch/arm/boot/dts/armada-xp-gp.dts @@ -26,137 +26,141 @@ memory { device_type = "memory"; - /* - * 4 GB of plug-in RAM modules by default but only 3GB - * are visible, the amount of memory available can be - * changed by the bootloader according the size of the - * module actually plugged + * 8 GB of plug-in RAM modules by default.The amount + * of memory available can be changed by the + * bootloader according the size of the module + * actually plugged. Only 7GB are usable because + * addresses from 0xC0000000 to 0xffffffff are used by + * the internal registers of the SoC. */ - reg = <0x00000000 0xC0000000>; + reg = <0x00000000 0x00000000 0x00000000 0xC0000000>, + <0x00000001 0x00000000 0x00000001 0x00000000>; }; soc { - serial@d0012000 { - clock-frequency = <250000000>; - status = "okay"; - }; - serial@d0012100 { - clock-frequency = <250000000>; - status = "okay"; - }; - serial@d0012200 { - clock-frequency = <250000000>; - status = "okay"; - }; - serial@d0012300 { - clock-frequency = <250000000>; - status = "okay"; - }; - - sata@d00a0000 { - nr-ports = <2>; - status = "okay"; - }; - - mdio { - phy0: ethernet-phy@0 { - reg = <16>; + internal-regs { + serial@12000 { + clock-frequency = <250000000>; + status = "okay"; }; - - phy1: ethernet-phy@1 { - reg = <17>; + serial@12100 { + clock-frequency = <250000000>; + status = "okay"; }; - - phy2: ethernet-phy@2 { - reg = <18>; + serial@12200 { + clock-frequency = <250000000>; + status = "okay"; + }; + serial@12300 { + clock-frequency = <250000000>; + status = "okay"; }; - phy3: ethernet-phy@3 { - reg = <19>; + sata@a0000 { + nr-ports = <2>; + status = "okay"; }; - }; - ethernet@d0070000 { - status = "okay"; - phy = <&phy0>; - phy-mode = "rgmii-id"; - }; - ethernet@d0074000 { - status = "okay"; - phy = <&phy1>; - phy-mode = "rgmii-id"; - }; - ethernet@d0030000 { - status = "okay"; - phy = <&phy2>; - phy-mode = "rgmii-id"; - }; - ethernet@d0034000 { - status = "okay"; - phy = <&phy3>; - phy-mode = "rgmii-id"; - }; + mdio { + phy0: ethernet-phy@0 { + reg = <16>; + }; - spi0: spi@d0010600 { - status = "okay"; + phy1: ethernet-phy@1 { + reg = <17>; + }; - spi-flash@0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "n25q128a13"; - reg = <0>; /* Chip select 0 */ - spi-max-frequency = <108000000>; - }; - }; + phy2: ethernet-phy@2 { + reg = <18>; + }; - devbus-bootcs@d0010400 { - status = "okay"; - ranges = <0 0xf0000000 0x1000000>; /* @addr 0xf000000, size 0x1000000 */ - - /* Device Bus parameters are required */ - - /* Read parameters */ - devbus,bus-width = <8>; - devbus,turn-off-ps = <60000>; - devbus,badr-skew-ps = <0>; - devbus,acc-first-ps = <124000>; - devbus,acc-next-ps = <248000>; - devbus,rd-setup-ps = <0>; - devbus,rd-hold-ps = <0>; - - /* Write parameters */ - devbus,sync-enable = <0>; - devbus,wr-high-ps = <60000>; - devbus,wr-low-ps = <60000>; - devbus,ale-wr-ps = <60000>; - - /* NOR 16 MiB */ - nor@0 { - compatible = "cfi-flash"; - reg = <0 0x1000000>; - bank-width = <2>; + phy3: ethernet-phy@3 { + reg = <19>; + }; }; - }; - pcie-controller { - status = "okay"; + ethernet@70000 { + status = "okay"; + phy = <&phy0>; + phy-mode = "rgmii-id"; + }; + ethernet@74000 { + status = "okay"; + phy = <&phy1>; + phy-mode = "rgmii-id"; + }; + ethernet@30000 { + status = "okay"; + phy = <&phy2>; + phy-mode = "rgmii-id"; + }; + ethernet@34000 { + status = "okay"; + phy = <&phy3>; + phy-mode = "rgmii-id"; + }; - /* - * The 3 slots are physically present as - * standard PCIe slots on the board. - */ - pcie@1,0 { - /* Port 0, Lane 0 */ + spi0: spi@10600 { status = "okay"; + + spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "n25q128a13"; + reg = <0>; /* Chip select 0 */ + spi-max-frequency = <108000000>; + }; }; - pcie@9,0 { - /* Port 2, Lane 0 */ + + devbus-bootcs@10400 { status = "okay"; + ranges = <0 0xf0000000 0x1000000>; /* @addr 0xf000000, size 0x1000000 */ + + /* Device Bus parameters are required */ + + /* Read parameters */ + devbus,bus-width = <8>; + devbus,turn-off-ps = <60000>; + devbus,badr-skew-ps = <0>; + devbus,acc-first-ps = <124000>; + devbus,acc-next-ps = <248000>; + devbus,rd-setup-ps = <0>; + devbus,rd-hold-ps = <0>; + + /* Write parameters */ + devbus,sync-enable = <0>; + devbus,wr-high-ps = <60000>; + devbus,wr-low-ps = <60000>; + devbus,ale-wr-ps = <60000>; + + /* NOR 16 MiB */ + nor@0 { + compatible = "cfi-flash"; + reg = <0 0x1000000>; + bank-width = <2>; + }; }; - pcie@10,0 { - /* Port 3, Lane 0 */ + + pcie-controller { status = "okay"; + + /* + * The 3 slots are physically present as + * standard PCIe slots on the board. + */ + pcie@1,0 { + /* Port 0, Lane 0 */ + status = "okay"; + }; + pcie@9,0 { + /* Port 2, Lane 0 */ + status = "okay"; + }; + pcie@10,0 { + /* Port 3, Lane 0 */ + status = "okay"; + }; }; }; }; diff --git a/trunk/arch/arm/boot/dts/armada-xp-mv78230.dtsi b/trunk/arch/arm/boot/dts/armada-xp-mv78230.dtsi index c2c78459a4d4..f8eaa383e07f 100644 --- a/trunk/arch/arm/boot/dts/armada-xp-mv78230.dtsi +++ b/trunk/arch/arm/boot/dts/armada-xp-mv78230.dtsi @@ -25,159 +25,161 @@ }; cpus { - #address-cells = <1>; - #size-cells = <0>; - - cpu@0 { - device_type = "cpu"; - compatible = "marvell,sheeva-v7"; - reg = <0>; - clocks = <&cpuclk 0>; - }; - - cpu@1 { - device_type = "cpu"; - compatible = "marvell,sheeva-v7"; - reg = <1>; - clocks = <&cpuclk 1>; - }; - }; - - soc { - pinctrl { - compatible = "marvell,mv78230-pinctrl"; - reg = <0xd0018000 0x38>; - - sdio_pins: sdio-pins { - marvell,pins = "mpp30", "mpp31", "mpp32", - "mpp33", "mpp34", "mpp35"; - marvell,function = "sd0"; - }; - }; - - gpio0: gpio@d0018100 { - compatible = "marvell,orion-gpio"; - reg = <0xd0018100 0x40>; - ngpios = <32>; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupts-cells = <2>; - interrupts = <82>, <83>, <84>, <85>; + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "marvell,sheeva-v7"; + reg = <0>; + clocks = <&cpuclk 0>; }; - gpio1: gpio@d0018140 { - compatible = "marvell,orion-gpio"; - reg = <0xd0018140 0x40>; - ngpios = <17>; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupts-cells = <2>; - interrupts = <87>, <88>, <89>; + cpu@1 { + device_type = "cpu"; + compatible = "marvell,sheeva-v7"; + reg = <1>; + clocks = <&cpuclk 1>; }; + }; - /* - * MV78230 has 2 PCIe units Gen2.0: One unit can be - * configured as x4 or quad x1 lanes. One unit is - * x4/x1. - */ - pcie-controller { - compatible = "marvell,armada-xp-pcie"; - status = "disabled"; - device_type = "pci"; - - #address-cells = <3>; - #size-cells = <2>; - - bus-range = <0x00 0xff>; - - ranges = <0x82000000 0 0xd0040000 0xd0040000 0 0x00002000 /* Port 0.0 registers */ - 0x82000000 0 0xd0042000 0xd0042000 0 0x00002000 /* Port 2.0 registers */ - 0x82000000 0 0xd0044000 0xd0044000 0 0x00002000 /* Port 0.1 registers */ - 0x82000000 0 0xd0048000 0xd0048000 0 0x00002000 /* Port 0.2 registers */ - 0x82000000 0 0xd004c000 0xd004c000 0 0x00002000 /* Port 0.3 registers */ - 0x82000000 0 0xe0000000 0xe0000000 0 0x08000000 /* non-prefetchable memory */ - 0x81000000 0 0 0xe8000000 0 0x00100000>; /* downstream I/O */ - - pcie@1,0 { - device_type = "pci"; - assigned-addresses = <0x82000800 0 0xd0040000 0 0x2000>; - reg = <0x0800 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - ranges; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &mpic 58>; - marvell,pcie-port = <0>; - marvell,pcie-lane = <0>; - clocks = <&gateclk 5>; - status = "disabled"; + soc { + internal-regs { + pinctrl { + compatible = "marvell,mv78230-pinctrl"; + reg = <0x18000 0x38>; + + sdio_pins: sdio-pins { + marvell,pins = "mpp30", "mpp31", "mpp32", + "mpp33", "mpp34", "mpp35"; + marvell,function = "sd0"; + }; }; - pcie@2,0 { - device_type = "pci"; - assigned-addresses = <0x82000800 0 0xd0044000 0 0x2000>; - reg = <0x1000 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - ranges; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &mpic 59>; - marvell,pcie-port = <0>; - marvell,pcie-lane = <1>; - clocks = <&gateclk 6>; - status = "disabled"; + gpio0: gpio@18100 { + compatible = "marvell,orion-gpio"; + reg = <0x18100 0x40>; + ngpios = <32>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupts-cells = <2>; + interrupts = <82>, <83>, <84>, <85>; }; - pcie@3,0 { - device_type = "pci"; - assigned-addresses = <0x82000800 0 0xd0048000 0 0x2000>; - reg = <0x1800 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - ranges; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &mpic 60>; - marvell,pcie-port = <0>; - marvell,pcie-lane = <2>; - clocks = <&gateclk 7>; - status = "disabled"; + gpio1: gpio@18140 { + compatible = "marvell,orion-gpio"; + reg = <0x18140 0x40>; + ngpios = <17>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupts-cells = <2>; + interrupts = <87>, <88>, <89>; }; - pcie@4,0 { - device_type = "pci"; - assigned-addresses = <0x82000800 0 0xd004c000 0 0x2000>; - reg = <0x2000 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - ranges; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &mpic 61>; - marvell,pcie-port = <0>; - marvell,pcie-lane = <3>; - clocks = <&gateclk 8>; + /* + * MV78230 has 2 PCIe units Gen2.0: One unit can be + * configured as x4 or quad x1 lanes. One unit is + * x4/x1. + */ + pcie-controller { + compatible = "marvell,armada-xp-pcie"; status = "disabled"; - }; - - pcie@9,0 { device_type = "pci"; - assigned-addresses = <0x82000800 0 0xd0042000 0 0x2000>; - reg = <0x4800 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - ranges; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &mpic 99>; - marvell,pcie-port = <2>; - marvell,pcie-lane = <0>; - clocks = <&gateclk 26>; - status = "disabled"; + +#address-cells = <3>; +#size-cells = <2>; + + bus-range = <0x00 0xff>; + + ranges = <0x82000000 0 0x40000 0x40000 0 0x00002000 /* Port 0.0 registers */ + 0x82000000 0 0x42000 0x42000 0 0x00002000 /* Port 2.0 registers */ + 0x82000000 0 0x44000 0x44000 0 0x00002000 /* Port 0.1 registers */ + 0x82000000 0 0x48000 0x48000 0 0x00002000 /* Port 0.2 registers */ + 0x82000000 0 0x4c000 0x4c000 0 0x00002000 /* Port 0.3 registers */ + 0x82000000 0 0xe0000000 0xe0000000 0 0x08000000 /* non-prefetchable memory */ + 0x81000000 0 0 0xe8000000 0 0x00100000>; /* downstream I/O */ + + pcie@1,0 { + device_type = "pci"; + assigned-addresses = <0x82000800 0 0x40000 0 0x2000>; + reg = <0x0800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &mpic 58>; + marvell,pcie-port = <0>; + marvell,pcie-lane = <0>; + clocks = <&gateclk 5>; + status = "disabled"; + }; + + pcie@2,0 { + device_type = "pci"; + assigned-addresses = <0x82000800 0 0x44000 0 0x2000>; + reg = <0x1000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &mpic 59>; + marvell,pcie-port = <0>; + marvell,pcie-lane = <1>; + clocks = <&gateclk 6>; + status = "disabled"; + }; + + pcie@3,0 { + device_type = "pci"; + assigned-addresses = <0x82000800 0 0x48000 0 0x2000>; + reg = <0x1800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &mpic 60>; + marvell,pcie-port = <0>; + marvell,pcie-lane = <2>; + clocks = <&gateclk 7>; + status = "disabled"; + }; + + pcie@4,0 { + device_type = "pci"; + assigned-addresses = <0x82000800 0 0x4c000 0 0x2000>; + reg = <0x2000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &mpic 61>; + marvell,pcie-port = <0>; + marvell,pcie-lane = <3>; + clocks = <&gateclk 8>; + status = "disabled"; + }; + + pcie@9,0 { + device_type = "pci"; + assigned-addresses = <0x82000800 0 0x42000 0 0x2000>; + reg = <0x4800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &mpic 99>; + marvell,pcie-port = <2>; + marvell,pcie-lane = <0>; + clocks = <&gateclk 26>; + status = "disabled"; + }; }; }; }; diff --git a/trunk/arch/arm/boot/dts/armada-xp-mv78260.dtsi b/trunk/arch/arm/boot/dts/armada-xp-mv78260.dtsi index 885bf229eef7..f4029f015aff 100644 --- a/trunk/arch/arm/boot/dts/armada-xp-mv78260.dtsi +++ b/trunk/arch/arm/boot/dts/armada-xp-mv78260.dtsi @@ -26,196 +26,198 @@ }; cpus { - #address-cells = <1>; - #size-cells = <0>; - - cpu@0 { - device_type = "cpu"; - compatible = "marvell,sheeva-v7"; - reg = <0>; - clocks = <&cpuclk 0>; - }; - - cpu@1 { - device_type = "cpu"; - compatible = "marvell,sheeva-v7"; - reg = <1>; - clocks = <&cpuclk 1>; - }; + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "marvell,sheeva-v7"; + reg = <0>; + clocks = <&cpuclk 0>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "marvell,sheeva-v7"; + reg = <1>; + clocks = <&cpuclk 1>; + }; }; soc { - pinctrl { - compatible = "marvell,mv78260-pinctrl"; - reg = <0xd0018000 0x38>; - - sdio_pins: sdio-pins { - marvell,pins = "mpp30", "mpp31", "mpp32", - "mpp33", "mpp34", "mpp35"; - marvell,function = "sd0"; + internal-regs { + pinctrl { + compatible = "marvell,mv78260-pinctrl"; + reg = <0x18000 0x38>; + + sdio_pins: sdio-pins { + marvell,pins = "mpp30", "mpp31", "mpp32", + "mpp33", "mpp34", "mpp35"; + marvell,function = "sd0"; + }; }; - }; - gpio0: gpio@d0018100 { - compatible = "marvell,orion-gpio"; - reg = <0xd0018100 0x40>; - ngpios = <32>; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupts-cells = <2>; - interrupts = <82>, <83>, <84>, <85>; - }; + gpio0: gpio@18100 { + compatible = "marvell,orion-gpio"; + reg = <0x18100 0x40>; + ngpios = <32>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupts-cells = <2>; + interrupts = <82>, <83>, <84>, <85>; + }; - gpio1: gpio@d0018140 { - compatible = "marvell,orion-gpio"; - reg = <0xd0018140 0x40>; - ngpios = <32>; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupts-cells = <2>; - interrupts = <87>, <88>, <89>, <90>; - }; + gpio1: gpio@18140 { + compatible = "marvell,orion-gpio"; + reg = <0x18140 0x40>; + ngpios = <32>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupts-cells = <2>; + interrupts = <87>, <88>, <89>, <90>; + }; - gpio2: gpio@d0018180 { - compatible = "marvell,orion-gpio"; - reg = <0xd0018180 0x40>; - ngpios = <3>; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupts-cells = <2>; - interrupts = <91>; - }; + gpio2: gpio@18180 { + compatible = "marvell,orion-gpio"; + reg = <0x18180 0x40>; + ngpios = <3>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupts-cells = <2>; + interrupts = <91>; + }; - ethernet@d0034000 { + ethernet@34000 { compatible = "marvell,armada-370-neta"; - reg = <0xd0034000 0x2500>; + reg = <0x34000 0x2500>; interrupts = <14>; clocks = <&gateclk 1>; status = "disabled"; - }; - - /* - * MV78260 has 3 PCIe units Gen2.0: Two units can be - * configured as x4 or quad x1 lanes. One unit is - * x4/x1. - */ - pcie-controller { - compatible = "marvell,armada-xp-pcie"; - status = "disabled"; - device_type = "pci"; - - #address-cells = <3>; - #size-cells = <2>; - - bus-range = <0x00 0xff>; - - ranges = <0x82000000 0 0xd0040000 0xd0040000 0 0x00002000 /* Port 0.0 registers */ - 0x82000000 0 0xd0042000 0xd0042000 0 0x00002000 /* Port 2.0 registers */ - 0x82000000 0 0xd0044000 0xd0044000 0 0x00002000 /* Port 0.1 registers */ - 0x82000000 0 0xd0048000 0xd0048000 0 0x00002000 /* Port 0.2 registers */ - 0x82000000 0 0xd004c000 0xd004c000 0 0x00002000 /* Port 0.3 registers */ - 0x82000000 0 0xd0080000 0xd0080000 0 0x00002000 /* Port 1.0 registers */ - 0x82000000 0 0xd0082000 0xd0082000 0 0x00002000 /* Port 3.0 registers */ - 0x82000000 0 0xe0000000 0xe0000000 0 0x08000000 /* non-prefetchable memory */ - 0x81000000 0 0 0xe8000000 0 0x00100000>; /* downstream I/O */ - - pcie@1,0 { - device_type = "pci"; - assigned-addresses = <0x82000800 0 0xd0040000 0 0x2000>; - reg = <0x0800 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - ranges; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &mpic 58>; - marvell,pcie-port = <0>; - marvell,pcie-lane = <0>; - clocks = <&gateclk 5>; - status = "disabled"; - }; - - pcie@2,0 { - device_type = "pci"; - assigned-addresses = <0x82000800 0 0xd0044000 0 0x2000>; - reg = <0x1000 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - ranges; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &mpic 59>; - marvell,pcie-port = <0>; - marvell,pcie-lane = <1>; - clocks = <&gateclk 6>; - status = "disabled"; }; - pcie@3,0 { - device_type = "pci"; - assigned-addresses = <0x82000800 0 0xd0048000 0 0x2000>; - reg = <0x1800 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - ranges; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &mpic 60>; - marvell,pcie-port = <0>; - marvell,pcie-lane = <2>; - clocks = <&gateclk 7>; + /* + * MV78260 has 3 PCIe units Gen2.0: Two units can be + * configured as x4 or quad x1 lanes. One unit is + * x4/x1. + */ + pcie-controller { + compatible = "marvell,armada-xp-pcie"; status = "disabled"; - }; - - pcie@4,0 { device_type = "pci"; - assigned-addresses = <0x82000800 0 0xd004c000 0 0x2000>; - reg = <0x2000 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - ranges; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &mpic 61>; - marvell,pcie-port = <0>; - marvell,pcie-lane = <3>; - clocks = <&gateclk 8>; - status = "disabled"; - }; - pcie@9,0 { - device_type = "pci"; - assigned-addresses = <0x82000800 0 0xd0042000 0 0x2000>; - reg = <0x4800 0 0 0 0>; #address-cells = <3>; #size-cells = <2>; - #interrupt-cells = <1>; - ranges; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &mpic 99>; - marvell,pcie-port = <2>; - marvell,pcie-lane = <0>; - clocks = <&gateclk 26>; - status = "disabled"; - }; - pcie@10,0 { - device_type = "pci"; - assigned-addresses = <0x82000800 0 0xd0082000 0 0x2000>; - reg = <0x5000 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - ranges; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &mpic 103>; - marvell,pcie-port = <3>; - marvell,pcie-lane = <0>; - clocks = <&gateclk 27>; - status = "disabled"; + bus-range = <0x00 0xff>; + + ranges = <0x82000000 0 0x40000 0x40000 0 0x00002000 /* Port 0.0 registers */ + 0x82000000 0 0x42000 0x42000 0 0x00002000 /* Port 2.0 registers */ + 0x82000000 0 0x44000 0x44000 0 0x00002000 /* Port 0.1 registers */ + 0x82000000 0 0x48000 0x48000 0 0x00002000 /* Port 0.2 registers */ + 0x82000000 0 0x4c000 0x4c000 0 0x00002000 /* Port 0.3 registers */ + 0x82000000 0 0x80000 0x80000 0 0x00002000 /* Port 1.0 registers */ + 0x82000000 0 0x82000 0x82000 0 0x00002000 /* Port 3.0 registers */ + 0x82000000 0 0xe0000000 0xe0000000 0 0x08000000 /* non-prefetchable memory */ + 0x81000000 0 0 0xe8000000 0 0x00100000>; /* downstream I/O */ + + pcie@1,0 { + device_type = "pci"; + assigned-addresses = <0x82000800 0 0x40000 0 0x2000>; + reg = <0x0800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &mpic 58>; + marvell,pcie-port = <0>; + marvell,pcie-lane = <0>; + clocks = <&gateclk 5>; + status = "disabled"; + }; + + pcie@2,0 { + device_type = "pci"; + assigned-addresses = <0x82000800 0 0x44000 0 0x2000>; + reg = <0x1000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &mpic 59>; + marvell,pcie-port = <0>; + marvell,pcie-lane = <1>; + clocks = <&gateclk 6>; + status = "disabled"; + }; + + pcie@3,0 { + device_type = "pci"; + assigned-addresses = <0x82000800 0 0x48000 0 0x2000>; + reg = <0x1800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &mpic 60>; + marvell,pcie-port = <0>; + marvell,pcie-lane = <2>; + clocks = <&gateclk 7>; + status = "disabled"; + }; + + pcie@4,0 { + device_type = "pci"; + assigned-addresses = <0x82000800 0 0x4c000 0 0x2000>; + reg = <0x2000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &mpic 61>; + marvell,pcie-port = <0>; + marvell,pcie-lane = <3>; + clocks = <&gateclk 8>; + status = "disabled"; + }; + + pcie@9,0 { + device_type = "pci"; + assigned-addresses = <0x82000800 0 0x42000 0 0x2000>; + reg = <0x4800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &mpic 99>; + marvell,pcie-port = <2>; + marvell,pcie-lane = <0>; + clocks = <&gateclk 26>; + status = "disabled"; + }; + + pcie@10,0 { + device_type = "pci"; + assigned-addresses = <0x82000800 0 0x82000 0 0x2000>; + reg = <0x5000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &mpic 103>; + marvell,pcie-port = <3>; + marvell,pcie-lane = <0>; + clocks = <&gateclk 27>; + status = "disabled"; + }; }; }; }; diff --git a/trunk/arch/arm/boot/dts/armada-xp-mv78460.dtsi b/trunk/arch/arm/boot/dts/armada-xp-mv78460.dtsi index 23a5ac4490a8..6ab56bd35de9 100644 --- a/trunk/arch/arm/boot/dts/armada-xp-mv78460.dtsi +++ b/trunk/arch/arm/boot/dts/armada-xp-mv78460.dtsi @@ -27,277 +27,279 @@ cpus { - #address-cells = <1>; - #size-cells = <0>; + #address-cells = <1>; + #size-cells = <0>; - cpu@0 { - device_type = "cpu"; - compatible = "marvell,sheeva-v7"; - reg = <0>; - clocks = <&cpuclk 0>; - }; + cpu@0 { + device_type = "cpu"; + compatible = "marvell,sheeva-v7"; + reg = <0>; + clocks = <&cpuclk 0>; + }; - cpu@1 { - device_type = "cpu"; - compatible = "marvell,sheeva-v7"; - reg = <1>; - clocks = <&cpuclk 1>; - }; + cpu@1 { + device_type = "cpu"; + compatible = "marvell,sheeva-v7"; + reg = <1>; + clocks = <&cpuclk 1>; + }; - cpu@2 { - device_type = "cpu"; - compatible = "marvell,sheeva-v7"; - reg = <2>; - clocks = <&cpuclk 2>; - }; + cpu@2 { + device_type = "cpu"; + compatible = "marvell,sheeva-v7"; + reg = <2>; + clocks = <&cpuclk 2>; + }; - cpu@3 { - device_type = "cpu"; - compatible = "marvell,sheeva-v7"; - reg = <3>; - clocks = <&cpuclk 3>; - }; + cpu@3 { + device_type = "cpu"; + compatible = "marvell,sheeva-v7"; + reg = <3>; + clocks = <&cpuclk 3>; + }; }; soc { - pinctrl { - compatible = "marvell,mv78460-pinctrl"; - reg = <0xd0018000 0x38>; + internal-regs { + pinctrl { + compatible = "marvell,mv78460-pinctrl"; + reg = <0x18000 0x38>; - sdio_pins: sdio-pins { - marvell,pins = "mpp30", "mpp31", "mpp32", - "mpp33", "mpp34", "mpp35"; - marvell,function = "sd0"; + sdio_pins: sdio-pins { + marvell,pins = "mpp30", "mpp31", "mpp32", + "mpp33", "mpp34", "mpp35"; + marvell,function = "sd0"; + }; }; - }; - gpio0: gpio@d0018100 { - compatible = "marvell,orion-gpio"; - reg = <0xd0018100 0x40>; - ngpios = <32>; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupts-cells = <2>; - interrupts = <82>, <83>, <84>, <85>; - }; + gpio0: gpio@18100 { + compatible = "marvell,orion-gpio"; + reg = <0x18100 0x40>; + ngpios = <32>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupts-cells = <2>; + interrupts = <82>, <83>, <84>, <85>; + }; - gpio1: gpio@d0018140 { - compatible = "marvell,orion-gpio"; - reg = <0xd0018140 0x40>; - ngpios = <32>; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupts-cells = <2>; - interrupts = <87>, <88>, <89>, <90>; - }; + gpio1: gpio@18140 { + compatible = "marvell,orion-gpio"; + reg = <0x18140 0x40>; + ngpios = <32>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupts-cells = <2>; + interrupts = <87>, <88>, <89>, <90>; + }; - gpio2: gpio@d0018180 { - compatible = "marvell,orion-gpio"; - reg = <0xd0018180 0x40>; - ngpios = <3>; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupts-cells = <2>; - interrupts = <91>; - }; + gpio2: gpio@18180 { + compatible = "marvell,orion-gpio"; + reg = <0x18180 0x40>; + ngpios = <3>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupts-cells = <2>; + interrupts = <91>; + }; - ethernet@d0034000 { + ethernet@34000 { compatible = "marvell,armada-370-neta"; - reg = <0xd0034000 0x2500>; + reg = <0x34000 0x2500>; interrupts = <14>; clocks = <&gateclk 1>; status = "disabled"; - }; + }; - /* - * MV78460 has 4 PCIe units Gen2.0: Two units can be - * configured as x4 or quad x1 lanes. Two units are - * x4/x1. - */ - pcie-controller { - compatible = "marvell,armada-xp-pcie"; - status = "disabled"; - device_type = "pci"; + /* + * MV78460 has 4 PCIe units Gen2.0: Two units can be + * configured as x4 or quad x1 lanes. Two units are + * x4/x1. + */ + pcie-controller { + compatible = "marvell,armada-xp-pcie"; + status = "disabled"; + device_type = "pci"; - #address-cells = <3>; - #size-cells = <2>; + #address-cells = <3>; + #size-cells = <2>; - bus-range = <0x00 0xff>; + bus-range = <0x00 0xff>; - ranges = <0x82000000 0 0xd0040000 0xd0040000 0 0x00002000 /* Port 0.0 registers */ - 0x82000000 0 0xd0042000 0xd0042000 0 0x00002000 /* Port 2.0 registers */ - 0x82000000 0 0xd0044000 0xd0044000 0 0x00002000 /* Port 0.1 registers */ - 0x82000000 0 0xd0048000 0xd0048000 0 0x00002000 /* Port 0.2 registers */ - 0x82000000 0 0xd004c000 0xd004c000 0 0x00002000 /* Port 0.3 registers */ - 0x82000000 0 0xd0080000 0xd0080000 0 0x00002000 /* Port 1.0 registers */ - 0x82000000 0 0xd0082000 0xd0082000 0 0x00002000 /* Port 3.0 registers */ - 0x82000000 0 0xd0084000 0xd0084000 0 0x00002000 /* Port 1.1 registers */ - 0x82000000 0 0xd0088000 0xd0088000 0 0x00002000 /* Port 1.2 registers */ - 0x82000000 0 0xd008c000 0xd008c000 0 0x00002000 /* Port 1.3 registers */ - 0x82000000 0 0xe0000000 0xe0000000 0 0x08000000 /* non-prefetchable memory */ - 0x81000000 0 0 0xe8000000 0 0x00100000>; /* downstream I/O */ + ranges = <0x82000000 0 0x40000 0x40000 0 0x00002000 /* Port 0.0 registers */ + 0x82000000 0 0x42000 0x42000 0 0x00002000 /* Port 2.0 registers */ + 0x82000000 0 0x44000 0x44000 0 0x00002000 /* Port 0.1 registers */ + 0x82000000 0 0x48000 0x48000 0 0x00002000 /* Port 0.2 registers */ + 0x82000000 0 0x4c000 0x4c000 0 0x00002000 /* Port 0.3 registers */ + 0x82000000 0 0x80000 0x80000 0 0x00002000 /* Port 1.0 registers */ + 0x82000000 0 0x82000 0x82000 0 0x00002000 /* Port 3.0 registers */ + 0x82000000 0 0x84000 0x84000 0 0x00002000 /* Port 1.1 registers */ + 0x82000000 0 0x88000 0x88000 0 0x00002000 /* Port 1.2 registers */ + 0x82000000 0 0x8c000 0x8c000 0 0x00002000 /* Port 1.3 registers */ + 0x82000000 0 0xe0000000 0xe0000000 0 0x08000000 /* non-prefetchable memory */ + 0x81000000 0 0 0xe8000000 0 0x00100000>; /* downstream I/O */ - pcie@1,0 { - device_type = "pci"; - assigned-addresses = <0x82000800 0 0xd0040000 0 0x2000>; - reg = <0x0800 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - ranges; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &mpic 58>; - marvell,pcie-port = <0>; - marvell,pcie-lane = <0>; - clocks = <&gateclk 5>; - status = "disabled"; - }; + pcie@1,0 { + device_type = "pci"; + assigned-addresses = <0x82000800 0 0x40000 0 0x2000>; + reg = <0x0800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &mpic 58>; + marvell,pcie-port = <0>; + marvell,pcie-lane = <0>; + clocks = <&gateclk 5>; + status = "disabled"; + }; - pcie@2,0 { - device_type = "pci"; - assigned-addresses = <0x82001000 0 0xd0044000 0 0x2000>; - reg = <0x1000 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - ranges; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &mpic 59>; - marvell,pcie-port = <0>; - marvell,pcie-lane = <1>; - clocks = <&gateclk 6>; - status = "disabled"; - }; + pcie@2,0 { + device_type = "pci"; + assigned-addresses = <0x82001000 0 0x44000 0 0x2000>; + reg = <0x1000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &mpic 59>; + marvell,pcie-port = <0>; + marvell,pcie-lane = <1>; + clocks = <&gateclk 6>; + status = "disabled"; + }; - pcie@3,0 { - device_type = "pci"; - assigned-addresses = <0x82001800 0 0xd0048000 0 0x2000>; - reg = <0x1800 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - ranges; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &mpic 60>; - marvell,pcie-port = <0>; - marvell,pcie-lane = <2>; - clocks = <&gateclk 7>; - status = "disabled"; - }; + pcie@3,0 { + device_type = "pci"; + assigned-addresses = <0x82001800 0 0x48000 0 0x2000>; + reg = <0x1800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &mpic 60>; + marvell,pcie-port = <0>; + marvell,pcie-lane = <2>; + clocks = <&gateclk 7>; + status = "disabled"; + }; - pcie@4,0 { - device_type = "pci"; - assigned-addresses = <0x82002000 0 0xd004c000 0 0x2000>; - reg = <0x2000 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - ranges; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &mpic 61>; - marvell,pcie-port = <0>; - marvell,pcie-lane = <3>; - clocks = <&gateclk 8>; - status = "disabled"; - }; + pcie@4,0 { + device_type = "pci"; + assigned-addresses = <0x82002000 0 0x4c000 0 0x2000>; + reg = <0x2000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &mpic 61>; + marvell,pcie-port = <0>; + marvell,pcie-lane = <3>; + clocks = <&gateclk 8>; + status = "disabled"; + }; - pcie@5,0 { - device_type = "pci"; - assigned-addresses = <0x82002800 0 0xd0080000 0 0x2000>; - reg = <0x2800 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - ranges; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &mpic 62>; - marvell,pcie-port = <1>; - marvell,pcie-lane = <0>; - clocks = <&gateclk 9>; - status = "disabled"; - }; + pcie@5,0 { + device_type = "pci"; + assigned-addresses = <0x82002800 0 0x80000 0 0x2000>; + reg = <0x2800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &mpic 62>; + marvell,pcie-port = <1>; + marvell,pcie-lane = <0>; + clocks = <&gateclk 9>; + status = "disabled"; + }; - pcie@6,0 { - device_type = "pci"; - assigned-addresses = <0x82003000 0 0xd0084000 0 0x2000>; - reg = <0x3000 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - ranges; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &mpic 63>; - marvell,pcie-port = <1>; - marvell,pcie-lane = <1>; - clocks = <&gateclk 10>; - status = "disabled"; - }; + pcie@6,0 { + device_type = "pci"; + assigned-addresses = <0x82003000 0 0x84000 0 0x2000>; + reg = <0x3000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &mpic 63>; + marvell,pcie-port = <1>; + marvell,pcie-lane = <1>; + clocks = <&gateclk 10>; + status = "disabled"; + }; - pcie@7,0 { - device_type = "pci"; - assigned-addresses = <0x82003800 0 0xd0088000 0 0x2000>; - reg = <0x3800 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - ranges; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &mpic 64>; - marvell,pcie-port = <1>; - marvell,pcie-lane = <2>; - clocks = <&gateclk 11>; - status = "disabled"; - }; + pcie@7,0 { + device_type = "pci"; + assigned-addresses = <0x82003800 0 0x88000 0 0x2000>; + reg = <0x3800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &mpic 64>; + marvell,pcie-port = <1>; + marvell,pcie-lane = <2>; + clocks = <&gateclk 11>; + status = "disabled"; + }; - pcie@8,0 { - device_type = "pci"; - assigned-addresses = <0x82004000 0 0xd008c000 0 0x2000>; - reg = <0x4000 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - ranges; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &mpic 65>; - marvell,pcie-port = <1>; - marvell,pcie-lane = <3>; - clocks = <&gateclk 12>; - status = "disabled"; - }; - pcie@9,0 { - device_type = "pci"; - assigned-addresses = <0x82004800 0 0xd0042000 0 0x2000>; - reg = <0x4800 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - ranges; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &mpic 99>; - marvell,pcie-port = <2>; - marvell,pcie-lane = <0>; - clocks = <&gateclk 26>; - status = "disabled"; - }; + pcie@8,0 { + device_type = "pci"; + assigned-addresses = <0x82004000 0 0x8c000 0 0x2000>; + reg = <0x4000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &mpic 65>; + marvell,pcie-port = <1>; + marvell,pcie-lane = <3>; + clocks = <&gateclk 12>; + status = "disabled"; + }; + pcie@9,0 { + device_type = "pci"; + assigned-addresses = <0x82004800 0 0x42000 0 0x2000>; + reg = <0x4800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &mpic 99>; + marvell,pcie-port = <2>; + marvell,pcie-lane = <0>; + clocks = <&gateclk 26>; + status = "disabled"; + }; - pcie@10,0 { - device_type = "pci"; - assigned-addresses = <0x82005000 0 0xd0082000 0 0x2000>; - reg = <0x5000 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - ranges; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &mpic 103>; - marvell,pcie-port = <3>; - marvell,pcie-lane = <0>; - clocks = <&gateclk 27>; - status = "disabled"; + pcie@10,0 { + device_type = "pci"; + assigned-addresses = <0x82005000 0 0x82000 0 0x2000>; + reg = <0x5000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &mpic 103>; + marvell,pcie-port = <3>; + marvell,pcie-lane = <0>; + clocks = <&gateclk 27>; + status = "disabled"; + }; }; }; }; - }; +}; diff --git a/trunk/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts b/trunk/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts index 9d04f04d4e39..f14d36c46159 100644 --- a/trunk/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts +++ b/trunk/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts @@ -23,158 +23,160 @@ memory { device_type = "memory"; - reg = <0x00000000 0xC0000000>; /* 3 GB */ + reg = <0 0x00000000 0 0xC0000000>; /* 3 GB */ }; soc { - serial@d0012000 { - clock-frequency = <250000000>; - status = "okay"; - }; - serial@d0012100 { - clock-frequency = <250000000>; - status = "okay"; - }; - pinctrl { - led_pins: led-pins-0 { - marvell,pins = "mpp49", "mpp51", "mpp53"; - marvell,function = "gpio"; + internal-regs { + serial@12000 { + clock-frequency = <250000000>; + status = "okay"; }; - }; - leds { - compatible = "gpio-leds"; - pinctrl-names = "default"; - pinctrl-0 = <&led_pins>; - - red_led { - label = "red_led"; - gpios = <&gpio1 17 1>; - default-state = "off"; + serial@12100 { + clock-frequency = <250000000>; + status = "okay"; }; - - yellow_led { - label = "yellow_led"; - gpios = <&gpio1 19 1>; - default-state = "off"; + pinctrl { + led_pins: led-pins-0 { + marvell,pins = "mpp49", "mpp51", "mpp53"; + marvell,function = "gpio"; + }; }; - - green_led { - label = "green_led"; - gpios = <&gpio1 21 1>; - default-state = "off"; - linux,default-trigger = "heartbeat"; + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&led_pins>; + + red_led { + label = "red_led"; + gpios = <&gpio1 17 1>; + default-state = "off"; + }; + + yellow_led { + label = "yellow_led"; + gpios = <&gpio1 19 1>; + default-state = "off"; + }; + + green_led { + label = "green_led"; + gpios = <&gpio1 21 1>; + default-state = "off"; + linux,default-trigger = "heartbeat"; + }; }; - }; - gpio_keys { - compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; - button@1 { - label = "Init Button"; - linux,code = <116>; - gpios = <&gpio1 28 0>; + button@1 { + label = "Init Button"; + linux,code = <116>; + gpios = <&gpio1 28 0>; + }; }; - }; - mdio { - phy0: ethernet-phy@0 { - reg = <0>; - }; + mdio { + phy0: ethernet-phy@0 { + reg = <0>; + }; - phy1: ethernet-phy@1 { - reg = <1>; - }; + phy1: ethernet-phy@1 { + reg = <1>; + }; - phy2: ethernet-phy@2 { - reg = <2>; - }; + phy2: ethernet-phy@2 { + reg = <2>; + }; - phy3: ethernet-phy@3 { - reg = <3>; + phy3: ethernet-phy@3 { + reg = <3>; + }; }; - }; - ethernet@d0070000 { - status = "okay"; - phy = <&phy0>; - phy-mode = "sgmii"; - }; - ethernet@d0074000 { - status = "okay"; - phy = <&phy1>; - phy-mode = "sgmii"; - }; - ethernet@d0030000 { - status = "okay"; - phy = <&phy2>; - phy-mode = "sgmii"; - }; - ethernet@d0034000 { - status = "okay"; - phy = <&phy3>; - phy-mode = "sgmii"; - }; - i2c@d0011000 { - status = "okay"; - clock-frequency = <400000>; - }; - i2c@d0011100 { - status = "okay"; - clock-frequency = <400000>; + ethernet@70000 { + status = "okay"; + phy = <&phy0>; + phy-mode = "sgmii"; + }; + ethernet@74000 { + status = "okay"; + phy = <&phy1>; + phy-mode = "sgmii"; + }; + ethernet@30000 { + status = "okay"; + phy = <&phy2>; + phy-mode = "sgmii"; + }; + ethernet@34000 { + status = "okay"; + phy = <&phy3>; + phy-mode = "sgmii"; + }; + i2c@11000 { + status = "okay"; + clock-frequency = <400000>; + }; + i2c@11100 { + status = "okay"; + clock-frequency = <400000>; - s35390a: s35390a@30 { - compatible = "s35390a"; - reg = <0x30>; + s35390a: s35390a@30 { + compatible = "s35390a"; + reg = <0x30>; + }; + }; + sata@a0000 { + nr-ports = <2>; + status = "okay"; + }; + usb@50000 { + status = "okay"; + }; + usb@51000 { + status = "okay"; }; - }; - sata@d00a0000 { - nr-ports = <2>; - status = "okay"; - }; - usb@d0050000 { - status = "okay"; - }; - usb@d0051000 { - status = "okay"; - }; - devbus-bootcs@d0010400 { - status = "okay"; - ranges = <0 0xf0000000 0x8000000>; /* @addr 0xf000000, size 0x8000000 */ - - /* Device Bus parameters are required */ - - /* Read parameters */ - devbus,bus-width = <8>; - devbus,turn-off-ps = <60000>; - devbus,badr-skew-ps = <0>; - devbus,acc-first-ps = <124000>; - devbus,acc-next-ps = <248000>; - devbus,rd-setup-ps = <0>; - devbus,rd-hold-ps = <0>; - - /* Write parameters */ - devbus,sync-enable = <0>; - devbus,wr-high-ps = <60000>; - devbus,wr-low-ps = <60000>; - devbus,ale-wr-ps = <60000>; - - /* NOR 128 MiB */ - nor@0 { - compatible = "cfi-flash"; - reg = <0 0x8000000>; - bank-width = <2>; + devbus-bootcs@10400 { + status = "okay"; + ranges = <0 0xf0000000 0x8000000>; /* @addr 0xf000000, size 0x8000000 */ + + /* Device Bus parameters are required */ + + /* Read parameters */ + devbus,bus-width = <8>; + devbus,turn-off-ps = <60000>; + devbus,badr-skew-ps = <0>; + devbus,acc-first-ps = <124000>; + devbus,acc-next-ps = <248000>; + devbus,rd-setup-ps = <0>; + devbus,rd-hold-ps = <0>; + + /* Write parameters */ + devbus,sync-enable = <0>; + devbus,wr-high-ps = <60000>; + devbus,wr-low-ps = <60000>; + devbus,ale-wr-ps = <60000>; + + /* NOR 128 MiB */ + nor@0 { + compatible = "cfi-flash"; + reg = <0 0x8000000>; + bank-width = <2>; + }; }; - }; - pcie-controller { - status = "okay"; - /* Internal mini-PCIe connector */ - pcie@1,0 { - /* Port 0, Lane 0 */ + pcie-controller { status = "okay"; + /* Internal mini-PCIe connector */ + pcie@1,0 { + /* Port 0, Lane 0 */ + status = "okay"; + }; }; }; }; diff --git a/trunk/arch/arm/boot/dts/armada-xp.dtsi b/trunk/arch/arm/boot/dts/armada-xp.dtsi index 29dfeb6d4a26..bacab11c10dc 100644 --- a/trunk/arch/arm/boot/dts/armada-xp.dtsi +++ b/trunk/arch/arm/boot/dts/armada-xp.dtsi @@ -22,140 +22,140 @@ model = "Marvell Armada XP family SoC"; compatible = "marvell,armadaxp", "marvell,armada-370-xp"; - L2: l2-cache { - compatible = "marvell,aurora-system-cache"; - reg = <0xd0008000 0x1000>; - cache-id-part = <0x100>; - wt-override; - }; + soc { + internal-regs { + L2: l2-cache { + compatible = "marvell,aurora-system-cache"; + reg = <0x08000 0x1000>; + cache-id-part = <0x100>; + wt-override; + }; - mpic: interrupt-controller@d0020000 { - reg = <0xd0020a00 0x2d0>, - <0xd0021070 0x58>; - }; + mpic: interrupt-controller@20000 { + reg = <0x20a00 0x2d0>, <0x21070 0x58>; + }; - armada-370-xp-pmsu@d0022000 { - compatible = "marvell,armada-370-xp-pmsu"; - reg = <0xd0022100 0x430>, - <0xd0020800 0x20>; - }; + armada-370-xp-pmsu@22000 { + compatible = "marvell,armada-370-xp-pmsu"; + reg = <0x22100 0x430>, <0x20800 0x20>; + }; - soc { - serial@d0012200 { + serial@12200 { compatible = "snps,dw-apb-uart"; - reg = <0xd0012200 0x100>; + reg = <0x12200 0x100>; reg-shift = <2>; interrupts = <43>; reg-io-width = <1>; status = "disabled"; - }; - serial@d0012300 { + }; + serial@12300 { compatible = "snps,dw-apb-uart"; - reg = <0xd0012300 0x100>; + reg = <0x12300 0x100>; reg-shift = <2>; interrupts = <44>; reg-io-width = <1>; status = "disabled"; - }; + }; - timer@d0020300 { + timer@20300 { marvell,timer-25Mhz; - }; + }; - coreclk: mvebu-sar@d0018230 { - compatible = "marvell,armada-xp-core-clock"; - reg = <0xd0018230 0x08>; - #clock-cells = <1>; - }; + coreclk: mvebu-sar@18230 { + compatible = "marvell,armada-xp-core-clock"; + reg = <0x18230 0x08>; + #clock-cells = <1>; + }; - cpuclk: clock-complex@d0018700 { - #clock-cells = <1>; - compatible = "marvell,armada-xp-cpu-clock"; - reg = <0xd0018700 0xA0>; - clocks = <&coreclk 1>; - }; + cpuclk: clock-complex@18700 { + #clock-cells = <1>; + compatible = "marvell,armada-xp-cpu-clock"; + reg = <0x18700 0xA0>; + clocks = <&coreclk 1>; + }; - gateclk: clock-gating-control@d0018220 { - compatible = "marvell,armada-xp-gating-clock"; - reg = <0xd0018220 0x4>; - clocks = <&coreclk 0>; - #clock-cells = <1>; - }; + gateclk: clock-gating-control@18220 { + compatible = "marvell,armada-xp-gating-clock"; + reg = <0x18220 0x4>; + clocks = <&coreclk 0>; + #clock-cells = <1>; + }; - system-controller@d0018200 { + system-controller@18200 { compatible = "marvell,armada-370-xp-system-controller"; - reg = <0xd0018200 0x500>; - }; + reg = <0x18200 0x500>; + }; - ethernet@d0030000 { + ethernet@30000 { compatible = "marvell,armada-370-neta"; - reg = <0xd0030000 0x2500>; + reg = <0x30000 0x2500>; interrupts = <12>; clocks = <&gateclk 2>; status = "disabled"; - }; - - xor@d0060900 { - compatible = "marvell,orion-xor"; - reg = <0xd0060900 0x100 - 0xd0060b00 0x100>; - clocks = <&gateclk 22>; - status = "okay"; - - xor10 { - interrupts = <51>; - dmacap,memcpy; - dmacap,xor; - }; - xor11 { - interrupts = <52>; - dmacap,memcpy; - dmacap,xor; - dmacap,memset; }; - }; - xor@d00f0900 { - compatible = "marvell,orion-xor"; - reg = <0xd00F0900 0x100 - 0xd00F0B00 0x100>; - clocks = <&gateclk 28>; - status = "okay"; - - xor00 { - interrupts = <94>; - dmacap,memcpy; - dmacap,xor; + xor@60900 { + compatible = "marvell,orion-xor"; + reg = <0x60900 0x100 + 0x60b00 0x100>; + clocks = <&gateclk 22>; + status = "okay"; + + xor10 { + interrupts = <51>; + dmacap,memcpy; + dmacap,xor; + }; + xor11 { + interrupts = <52>; + dmacap,memcpy; + dmacap,xor; + dmacap,memset; + }; }; - xor01 { - interrupts = <95>; - dmacap,memcpy; - dmacap,xor; - dmacap,memset; + + xor@f0900 { + compatible = "marvell,orion-xor"; + reg = <0xF0900 0x100 + 0xF0B00 0x100>; + clocks = <&gateclk 28>; + status = "okay"; + + xor00 { + interrupts = <94>; + dmacap,memcpy; + dmacap,xor; + }; + xor01 { + interrupts = <95>; + dmacap,memcpy; + dmacap,xor; + dmacap,memset; + }; }; - }; - usb@d0050000 { - clocks = <&gateclk 18>; - }; + usb@50000 { + clocks = <&gateclk 18>; + }; - usb@d0051000 { - clocks = <&gateclk 19>; - }; + usb@51000 { + clocks = <&gateclk 19>; + }; - usb@d0052000 { - compatible = "marvell,orion-ehci"; - reg = <0xd0052000 0x500>; - interrupts = <47>; - clocks = <&gateclk 20>; - status = "disabled"; - }; + usb@52000 { + compatible = "marvell,orion-ehci"; + reg = <0x52000 0x500>; + interrupts = <47>; + clocks = <&gateclk 20>; + status = "disabled"; + }; - thermal@d00182b0 { - compatible = "marvell,armadaxp-thermal"; - reg = <0xd00182b0 0x4 - 0xd00184d0 0x4>; - status = "okay"; + thermal@182b0 { + compatible = "marvell,armadaxp-thermal"; + reg = <0x182b0 0x4 + 0x184d0 0x4>; + status = "okay"; + }; }; }; }; diff --git a/trunk/arch/arm/boot/dts/at91sam9g45.dtsi b/trunk/arch/arm/boot/dts/at91sam9g45.dtsi index f8f7370e8669..bf18a735c37d 100644 --- a/trunk/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/trunk/arch/arm/boot/dts/at91sam9g45.dtsi @@ -108,6 +108,7 @@ compatible = "atmel,at91sam9g45-dma"; reg = <0xffffec00 0x200>; interrupts = <21 4 0>; + #dma-cells = <2>; }; pinctrl@fffff200 { @@ -533,6 +534,8 @@ compatible = "atmel,hsmci"; reg = <0xfff80000 0x600>; interrupts = <11 4 0>; + dmas = <&dma 1 0>; + dma-names = "rxtx"; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -542,6 +545,8 @@ compatible = "atmel,hsmci"; reg = <0xfffd0000 0x600>; interrupts = <29 4 0>; + dmas = <&dma 1 13>; + dma-names = "rxtx"; #address-cells = <1>; #size-cells = <0>; status = "disabled"; diff --git a/trunk/arch/arm/boot/dts/at91sam9n12.dtsi b/trunk/arch/arm/boot/dts/at91sam9n12.dtsi index b2961f1ea51b..3de8e6dfbcb1 100644 --- a/trunk/arch/arm/boot/dts/at91sam9n12.dtsi +++ b/trunk/arch/arm/boot/dts/at91sam9n12.dtsi @@ -89,6 +89,8 @@ compatible = "atmel,hsmci"; reg = <0xf0008000 0x600>; interrupts = <12 4 0>; + dmas = <&dma 1 0>; + dma-names = "rxtx"; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -110,6 +112,7 @@ compatible = "atmel,at91sam9g45-dma"; reg = <0xffffec00 0x200>; interrupts = <20 4 0>; + #dma-cells = <2>; }; pinctrl@fffff400 { @@ -378,6 +381,9 @@ compatible = "atmel,at91sam9x5-i2c"; reg = <0xf8010000 0x100>; interrupts = <9 4 6>; + dmas = <&dma 1 13>, + <&dma 1 14>; + dma-names = "tx", "rx"; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -387,6 +393,9 @@ compatible = "atmel,at91sam9x5-i2c"; reg = <0xf8014000 0x100>; interrupts = <10 4 6>; + dmas = <&dma 1 15>, + <&dma 1 16>; + dma-names = "tx", "rx"; #address-cells = <1>; #size-cells = <0>; status = "disabled"; diff --git a/trunk/arch/arm/boot/dts/at91sam9x5.dtsi b/trunk/arch/arm/boot/dts/at91sam9x5.dtsi index 640b3bbbb706..1145ac330fb7 100644 --- a/trunk/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/trunk/arch/arm/boot/dts/at91sam9x5.dtsi @@ -104,12 +104,14 @@ compatible = "atmel,at91sam9g45-dma"; reg = <0xffffec00 0x200>; interrupts = <20 4 0>; + #dma-cells = <2>; }; dma1: dma-controller@ffffee00 { compatible = "atmel,at91sam9g45-dma"; reg = <0xffffee00 0x200>; interrupts = <21 4 0>; + #dma-cells = <2>; }; pinctrl@fffff400 { @@ -465,6 +467,8 @@ compatible = "atmel,hsmci"; reg = <0xf0008000 0x600>; interrupts = <12 4 0>; + dmas = <&dma0 1 0>; + dma-names = "rxtx"; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -474,6 +478,8 @@ compatible = "atmel,hsmci"; reg = <0xf000c000 0x600>; interrupts = <26 4 0>; + dmas = <&dma1 1 0>; + dma-names = "rxtx"; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -535,6 +541,9 @@ compatible = "atmel,at91sam9x5-i2c"; reg = <0xf8010000 0x100>; interrupts = <9 4 6>; + dmas = <&dma0 1 7>, + <&dma0 1 8>; + dma-names = "tx", "rx"; #address-cells = <1>; #size-cells = <0>; pinctrl-names = "default"; @@ -546,6 +555,9 @@ compatible = "atmel,at91sam9x5-i2c"; reg = <0xf8014000 0x100>; interrupts = <10 4 6>; + dmas = <&dma1 1 5>, + <&dma1 1 6>; + dma-names = "tx", "rx"; #address-cells = <1>; #size-cells = <0>; pinctrl-names = "default"; @@ -557,6 +569,9 @@ compatible = "atmel,at91sam9x5-i2c"; reg = <0xf8018000 0x100>; interrupts = <11 4 6>; + dmas = <&dma0 1 9>, + <&dma0 1 10>; + dma-names = "tx", "rx"; #address-cells = <1>; #size-cells = <0>; pinctrl-names = "default"; diff --git a/trunk/arch/arm/boot/dts/bcm11351.dtsi b/trunk/arch/arm/boot/dts/bcm11351.dtsi index 8f71f40722b9..41b2c6c33f09 100644 --- a/trunk/arch/arm/boot/dts/bcm11351.dtsi +++ b/trunk/arch/arm/boot/dts/bcm11351.dtsi @@ -31,6 +31,11 @@ <0x3ff00100 0x100>; }; + smc@0x3404c000 { + compatible = "bcm,bcm11351-smc", "bcm,kona-smc"; + reg = <0x3404c000 0x400>; //1 KiB in SRAM + }; + uart@3e000000 { compatible = "bcm,bcm11351-dw-apb-uart", "snps,dw-apb-uart"; status = "disabled"; diff --git a/trunk/arch/arm/boot/dts/cros5250-common.dtsi b/trunk/arch/arm/boot/dts/cros5250-common.dtsi index 46c098017036..3f0239ec1bc5 100644 --- a/trunk/arch/arm/boot/dts/cros5250-common.dtsi +++ b/trunk/arch/arm/boot/dts/cros5250-common.dtsi @@ -19,31 +19,176 @@ chosen { }; + pinctrl@11400000 { + /* + * Disabled pullups since external part has its own pullups and + * double-pulling gets us out of spec in some cases. + */ + i2c2_bus: i2c2-bus { + samsung,pin-pud = <0>; + }; + }; + i2c@12C60000 { samsung,i2c-sda-delay = <100>; samsung,i2c-max-bus-freq = <378000>; - gpios = <&gpb3 0 2 3 0>, - <&gpb3 1 2 3 0>; + + max77686@09 { + compatible = "maxim,max77686"; + reg = <0x09>; + + voltage-regulators { + ldo1_reg: LDO1 { + regulator-name = "P1.0V_LDO_OUT1"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + }; + + ldo2_reg: LDO2 { + regulator-name = "P1.8V_LDO_OUT2"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + ldo3_reg: LDO3 { + regulator-name = "P1.8V_LDO_OUT3"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + ldo7_reg: LDO7 { + regulator-name = "P1.1V_LDO_OUT7"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-always-on; + }; + + ldo8_reg: LDO8 { + regulator-name = "P1.0V_LDO_OUT8"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + }; + + ldo10_reg: LDO10 { + regulator-name = "P1.8V_LDO_OUT10"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + ldo12_reg: LDO12 { + regulator-name = "P3.0V_LDO_OUT12"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + }; + + ldo14_reg: LDO14 { + regulator-name = "P1.8V_LDO_OUT14"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + ldo15_reg: LDO15 { + regulator-name = "P1.0V_LDO_OUT15"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + }; + + ldo16_reg: LDO16 { + regulator-name = "P1.8V_LDO_OUT16"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + buck1_reg: BUCK1 { + regulator-name = "vdd_mif"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1300000>; + regulator-always-on; + regulator-boot-on; + }; + + buck2_reg: BUCK2 { + regulator-name = "vdd_arm"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; + regulator-boot-on; + }; + + buck3_reg: BUCK3 { + regulator-name = "vdd_int"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + regulator-boot-on; + }; + + buck4_reg: BUCK4 { + regulator-name = "vdd_g3d"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1300000>; + regulator-always-on; + regulator-boot-on; + }; + + buck5_reg: BUCK5 { + regulator-name = "P1.8V_BUCK_OUT5"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + }; + + buck6_reg: BUCK6 { + regulator-name = "P1.35V_BUCK_OUT6"; + regulator-min-microvolt = <1350000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; + }; + + buck7_reg: BUCK7 { + regulator-name = "P2.0V_BUCK_OUT7"; + regulator-min-microvolt = <2000000>; + regulator-max-microvolt = <2000000>; + regulator-always-on; + }; + + buck8_reg: BUCK8 { + regulator-name = "P2.85V_BUCK_OUT8"; + regulator-min-microvolt = <2850000>; + regulator-max-microvolt = <2850000>; + regulator-always-on; + }; + }; + }; }; i2c@12C70000 { samsung,i2c-sda-delay = <100>; samsung,i2c-max-bus-freq = <378000>; - gpios = <&gpb3 2 2 3 0>, - <&gpb3 3 2 3 0>; + + trackpad { + reg = <0x67>; + compatible = "cypress,cyapa"; + interrupts = <2 0>; + interrupt-parent = <&gpx1>; + wakeup-source; + }; }; i2c@12C80000 { samsung,i2c-sda-delay = <100>; samsung,i2c-max-bus-freq = <66000>; - /* - * Disabled pullups since external part has its own pullups and - * double-pulling gets us out of spec in some cases. - */ - gpios = <&gpa0 6 3 0 0>, - <&gpa0 7 3 0 0>; - hdmiddc@50 { compatible = "samsung,exynos5-hdmiddc"; reg = <0x50>; @@ -53,19 +198,16 @@ i2c@12C90000 { samsung,i2c-sda-delay = <100>; samsung,i2c-max-bus-freq = <66000>; - gpios = <&gpa1 2 3 3 0>, - <&gpa1 3 3 3 0>; }; i2c@12CA0000 { - status = "disabled"; + samsung,i2c-sda-delay = <100>; + samsung,i2c-max-bus-freq = <66000>; }; i2c@12CB0000 { samsung,i2c-sda-delay = <100>; samsung,i2c-max-bus-freq = <66000>; - gpios = <&gpa2 2 3 3 0>, - <&gpa2 3 3 3 0>; }; i2c@12CC0000 { @@ -75,8 +217,6 @@ i2c@12CD0000 { samsung,i2c-sda-delay = <100>; samsung,i2c-max-bus-freq = <66000>; - gpios = <&gpb2 2 3 3 0>, - <&gpb2 3 3 3 0>; }; i2c@12CE0000 { @@ -98,15 +238,12 @@ samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; samsung,dw-mshc-ddr-timing = <1 2>; + pinctrl-names = "default"; + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_cd &sd0_bus4 &sd0_bus8>; slot@0 { reg = <0>; bus-width = <8>; - gpios = <&gpc0 0 2 0 3>, <&gpc0 1 2 0 3>, - <&gpc1 0 2 3 3>, <&gpc1 1 2 3 3>, - <&gpc1 2 2 3 3>, <&gpc1 3 2 3 3>, - <&gpc0 3 2 3 3>, <&gpc0 4 2 3 3>, - <&gpc0 5 2 3 3>, <&gpc0 6 2 3 3>; }; }; @@ -122,15 +259,13 @@ samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; samsung,dw-mshc-ddr-timing = <1 2>; + pinctrl-names = "default"; + pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>; slot@0 { reg = <0>; bus-width = <4>; - samsung,cd-pinmux-gpio = <&gpc3 2 2 3 3>; - wp-gpios = <&gpc2 1 0 0 3>; - gpios = <&gpc3 0 2 0 3>, <&gpc3 1 2 0 3>, - <&gpc3 3 2 3 3>, <&gpc3 4 2 3 3>, - <&gpc3 5 2 3 3>, <&gpc3 6 2 3 3>; + wp-gpios = <&gpc2 1 0>; }; }; @@ -143,11 +278,11 @@ samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; samsung,dw-mshc-ddr-timing = <1 2>; + /* See board-specific dts files for pin setup */ slot@0 { reg = <0>; bus-width = <4>; - /* See board-specific dts files for GPIOs */ }; }; @@ -156,9 +291,6 @@ }; spi_1: spi@12d30000 { - gpios = <&gpa2 4 2 3 0>, - <&gpa2 6 2 3 0>, - <&gpa2 7 2 3 0>; samsung,spi-src-clk = <0>; num-cs = <1>; }; @@ -168,7 +300,7 @@ }; hdmi { - hpd-gpio = <&gpx3 7 0xf 1 3>; + hpd-gpio = <&gpx3 7 0>; }; gpio-keys { @@ -176,7 +308,7 @@ power { label = "Power"; - gpios = <&gpx1 3 0 0x10000 0>; + gpios = <&gpx1 3 1>; linux,code = <116>; /* KEY_POWER */ gpio-key,wakeup; }; diff --git a/trunk/arch/arm/boot/dts/da850-evm.dts b/trunk/arch/arm/boot/dts/da850-evm.dts index c5834a6c5bf4..c914357c0d89 100644 --- a/trunk/arch/arm/boot/dts/da850-evm.dts +++ b/trunk/arch/arm/boot/dts/da850-evm.dts @@ -50,6 +50,46 @@ pinctrl-names = "default"; pinctrl-0 = <&mmc0_pins>; }; + spi1: spi@1f0e000 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&spi1_pins &spi1_cs0_pin>; + flash: m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "m25p64"; + spi-max-frequency = <30000000>; + reg = <0>; + partition@0 { + label = "U-Boot-SPL"; + reg = <0x00000000 0x00010000>; + read-only; + }; + partition@1 { + label = "U-Boot"; + reg = <0x00010000 0x00080000>; + read-only; + }; + partition@2 { + label = "U-Boot-Env"; + reg = <0x00090000 0x00010000>; + read-only; + }; + partition@3 { + label = "Kernel"; + reg = <0x000a0000 0x00280000>; + }; + partition@4 { + label = "Filesystem"; + reg = <0x00320000 0x00400000>; + }; + partition@5 { + label = "MAC-Address"; + reg = <0x007f0000 0x00010000>; + read-only; + }; + }; + }; }; nand_cs3@62000000 { status = "okay"; diff --git a/trunk/arch/arm/boot/dts/da850.dtsi b/trunk/arch/arm/boot/dts/da850.dtsi index 3ade343f13cc..2c88313d2c7a 100644 --- a/trunk/arch/arm/boot/dts/da850.dtsi +++ b/trunk/arch/arm/boot/dts/da850.dtsi @@ -71,6 +71,60 @@ 0x28 0x00222222 0x00ffffff >; }; + ehrpwm0a_pins: pinmux_ehrpwm0a_pins { + pinctrl-single,bits = < + /* EPWM0A */ + 0xc 0x00000002 0x0000000f + >; + }; + ehrpwm0b_pins: pinmux_ehrpwm0b_pins { + pinctrl-single,bits = < + /* EPWM0B */ + 0xc 0x00000020 0x000000f0 + >; + }; + ehrpwm1a_pins: pinmux_ehrpwm1a_pins { + pinctrl-single,bits = < + /* EPWM1A */ + 0x14 0x00000002 0x0000000f + >; + }; + ehrpwm1b_pins: pinmux_ehrpwm1b_pins { + pinctrl-single,bits = < + /* EPWM1B */ + 0x14 0x00000020 0x000000f0 + >; + }; + ecap0_pins: pinmux_ecap0_pins { + pinctrl-single,bits = < + /* ECAP0_APWM0 */ + 0x8 0x20000000 0xf0000000 + >; + }; + ecap1_pins: pinmux_ecap1_pins { + pinctrl-single,bits = < + /* ECAP1_APWM1 */ + 0x4 0x40000000 0xf0000000 + >; + }; + ecap2_pins: pinmux_ecap2_pins { + pinctrl-single,bits = < + /* ECAP2_APWM2 */ + 0x4 0x00000004 0x0000000f + >; + }; + spi1_pins: pinmux_spi_pins { + pinctrl-single,bits = < + /* SIMO, SOMI, CLK */ + 0x14 0x00110100 0x00ff0f00 + >; + }; + spi1_cs0_pin: pinmux_spi1_cs0 { + pinctrl-single,bits = < + /* CS0 */ + 0x14 0x00000010 0x000000f0 + >; + }; }; serial0: serial@1c42000 { compatible = "ns16550a"; @@ -122,6 +176,46 @@ interrupts = <16>; status = "disabled"; }; + ehrpwm0: ehrpwm@01f00000 { + compatible = "ti,da850-ehrpwm", "ti,am33xx-ehrpwm"; + #pwm-cells = <3>; + reg = <0x300000 0x2000>; + status = "disabled"; + }; + ehrpwm1: ehrpwm@01f02000 { + compatible = "ti,da850-ehrpwm", "ti,am33xx-ehrpwm"; + #pwm-cells = <3>; + reg = <0x302000 0x2000>; + status = "disabled"; + }; + ecap0: ecap@01f06000 { + compatible = "ti,da850-ecap", "ti,am33xx-ecap"; + #pwm-cells = <3>; + reg = <0x306000 0x80>; + status = "disabled"; + }; + ecap1: ecap@01f07000 { + compatible = "ti,da850-ecap", "ti,am33xx-ecap"; + #pwm-cells = <3>; + reg = <0x307000 0x80>; + status = "disabled"; + }; + ecap2: ecap@01f08000 { + compatible = "ti,da850-ecap", "ti,am33xx-ecap"; + #pwm-cells = <3>; + reg = <0x308000 0x80>; + status = "disabled"; + }; + spi1: spi@1f0e000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "ti,da830-spi"; + reg = <0x30e000 0x1000>; + num-cs = <4>; + ti,davinci-spi-intr-line = <1>; + interrupts = <56>; + status = "disabled"; + }; }; nand_cs3@62000000 { compatible = "ti,davinci-nand"; diff --git a/trunk/arch/arm/boot/dts/exynos4.dtsi b/trunk/arch/arm/boot/dts/exynos4.dtsi index 1a62bcf18aa3..359694c78918 100644 --- a/trunk/arch/arm/boot/dts/exynos4.dtsi +++ b/trunk/arch/arm/boot/dts/exynos4.dtsi @@ -38,6 +38,11 @@ i2c7 = &i2c_7; }; + chipid@10000000 { + compatible = "samsung,exynos4210-chipid"; + reg = <0x10000000 0x100>; + }; + pd_mfc: mfc-power-domain@10023C40 { compatible = "samsung,exynos4210-pd"; reg = <0x10023C40 0x20>; @@ -82,10 +87,17 @@ reg = <0x10440000 0x1000>; }; + sys_reg: sysreg { + compatible = "samsung,exynos4-sysreg", "syscon"; + reg = <0x10010000 0x400>; + }; + watchdog@10060000 { compatible = "samsung,s3c2410-wdt"; reg = <0x10060000 0x100>; interrupts = <0 43 0>; + clocks = <&clock 345>; + clock-names = "watchdog"; status = "disabled"; }; @@ -93,6 +105,8 @@ compatible = "samsung,s3c6410-rtc"; reg = <0x10070000 0x100>; interrupts = <0 44 0>, <0 45 0>; + clocks = <&clock 346>; + clock-names = "rtc"; status = "disabled"; }; @@ -100,6 +114,8 @@ compatible = "samsung,s5pv210-keypad"; reg = <0x100A0000 0x100>; interrupts = <0 109 0>; + clocks = <&clock 347>; + clock-names = "keypad"; status = "disabled"; }; @@ -107,6 +123,8 @@ compatible = "samsung,exynos4210-sdhci"; reg = <0x12510000 0x100>; interrupts = <0 73 0>; + clocks = <&clock 297>, <&clock 145>; + clock-names = "hsmmc", "mmc_busclk.2"; status = "disabled"; }; @@ -114,6 +132,8 @@ compatible = "samsung,exynos4210-sdhci"; reg = <0x12520000 0x100>; interrupts = <0 74 0>; + clocks = <&clock 298>, <&clock 146>; + clock-names = "hsmmc", "mmc_busclk.2"; status = "disabled"; }; @@ -121,6 +141,8 @@ compatible = "samsung,exynos4210-sdhci"; reg = <0x12530000 0x100>; interrupts = <0 75 0>; + clocks = <&clock 299>, <&clock 147>; + clock-names = "hsmmc", "mmc_busclk.2"; status = "disabled"; }; @@ -128,6 +150,16 @@ compatible = "samsung,exynos4210-sdhci"; reg = <0x12540000 0x100>; interrupts = <0 76 0>; + clocks = <&clock 300>, <&clock 148>; + clock-names = "hsmmc", "mmc_busclk.2"; + status = "disabled"; + }; + + mfc: codec@13400000 { + compatible = "samsung,mfc-v5"; + reg = <0x13400000 0x10000>; + interrupts = <0 94 0>; + samsung,power-domain = <&pd_mfc>; status = "disabled"; }; @@ -135,6 +167,8 @@ compatible = "samsung,exynos4210-uart"; reg = <0x13800000 0x100>; interrupts = <0 52 0>; + clocks = <&clock 312>, <&clock 151>; + clock-names = "uart", "clk_uart_baud0"; status = "disabled"; }; @@ -142,6 +176,8 @@ compatible = "samsung,exynos4210-uart"; reg = <0x13810000 0x100>; interrupts = <0 53 0>; + clocks = <&clock 313>, <&clock 152>; + clock-names = "uart", "clk_uart_baud0"; status = "disabled"; }; @@ -149,6 +185,8 @@ compatible = "samsung,exynos4210-uart"; reg = <0x13820000 0x100>; interrupts = <0 54 0>; + clocks = <&clock 314>, <&clock 153>; + clock-names = "uart", "clk_uart_baud0"; status = "disabled"; }; @@ -156,6 +194,8 @@ compatible = "samsung,exynos4210-uart"; reg = <0x13830000 0x100>; interrupts = <0 55 0>; + clocks = <&clock 315>, <&clock 154>; + clock-names = "uart", "clk_uart_baud0"; status = "disabled"; }; @@ -165,6 +205,10 @@ compatible = "samsung,s3c2440-i2c"; reg = <0x13860000 0x100>; interrupts = <0 58 0>; + clocks = <&clock 317>; + clock-names = "i2c"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_bus>; status = "disabled"; }; @@ -174,6 +218,10 @@ compatible = "samsung,s3c2440-i2c"; reg = <0x13870000 0x100>; interrupts = <0 59 0>; + clocks = <&clock 318>; + clock-names = "i2c"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_bus>; status = "disabled"; }; @@ -183,6 +231,8 @@ compatible = "samsung,s3c2440-i2c"; reg = <0x13880000 0x100>; interrupts = <0 60 0>; + clocks = <&clock 319>; + clock-names = "i2c"; status = "disabled"; }; @@ -192,6 +242,8 @@ compatible = "samsung,s3c2440-i2c"; reg = <0x13890000 0x100>; interrupts = <0 61 0>; + clocks = <&clock 320>; + clock-names = "i2c"; status = "disabled"; }; @@ -201,6 +253,8 @@ compatible = "samsung,s3c2440-i2c"; reg = <0x138A0000 0x100>; interrupts = <0 62 0>; + clocks = <&clock 321>; + clock-names = "i2c"; status = "disabled"; }; @@ -210,6 +264,8 @@ compatible = "samsung,s3c2440-i2c"; reg = <0x138B0000 0x100>; interrupts = <0 63 0>; + clocks = <&clock 322>; + clock-names = "i2c"; status = "disabled"; }; @@ -219,6 +275,8 @@ compatible = "samsung,s3c2440-i2c"; reg = <0x138C0000 0x100>; interrupts = <0 64 0>; + clocks = <&clock 323>; + clock-names = "i2c"; status = "disabled"; }; @@ -228,6 +286,8 @@ compatible = "samsung,s3c2440-i2c"; reg = <0x138D0000 0x100>; interrupts = <0 65 0>; + clocks = <&clock 324>; + clock-names = "i2c"; status = "disabled"; }; @@ -239,6 +299,10 @@ rx-dma-channel = <&pdma0 6>; /* preliminary */ #address-cells = <1>; #size-cells = <0>; + clocks = <&clock 327>, <&clock 159>; + clock-names = "spi", "spi_busclk0"; + pinctrl-names = "default"; + pinctrl-0 = <&spi0_bus>; status = "disabled"; }; @@ -250,6 +314,10 @@ rx-dma-channel = <&pdma1 6>; /* preliminary */ #address-cells = <1>; #size-cells = <0>; + clocks = <&clock 328>, <&clock 160>; + clock-names = "spi", "spi_busclk0"; + pinctrl-names = "default"; + pinctrl-0 = <&spi1_bus>; status = "disabled"; }; @@ -261,6 +329,18 @@ rx-dma-channel = <&pdma0 8>; /* preliminary */ #address-cells = <1>; #size-cells = <0>; + clocks = <&clock 329>, <&clock 161>; + clock-names = "spi", "spi_busclk0"; + pinctrl-names = "default"; + pinctrl-0 = <&spi2_bus>; + status = "disabled"; + }; + + pwm@139D0000 { + compatible = "samsung,exynos4210-pwm"; + reg = <0x139D0000 0x1000>; + interrupts = <0 37 0>, <0 38 0>, <0 39 0>, <0 40 0>, <0 41 0>; + #pwm-cells = <2>; status = "disabled"; }; @@ -275,6 +355,8 @@ compatible = "arm,pl330", "arm,primecell"; reg = <0x12680000 0x1000>; interrupts = <0 35 0>; + clocks = <&clock 292>; + clock-names = "apb_pclk"; #dma-cells = <1>; #dma-channels = <8>; #dma-requests = <32>; @@ -284,6 +366,8 @@ compatible = "arm,pl330", "arm,primecell"; reg = <0x12690000 0x1000>; interrupts = <0 36 0>; + clocks = <&clock 293>; + clock-names = "apb_pclk"; #dma-cells = <1>; #dma-channels = <8>; #dma-requests = <32>; @@ -293,9 +377,23 @@ compatible = "arm,pl330", "arm,primecell"; reg = <0x12850000 0x1000>; interrupts = <0 34 0>; + clocks = <&clock 279>; + clock-names = "apb_pclk"; #dma-cells = <1>; #dma-channels = <8>; #dma-requests = <1>; }; }; + + fimd: fimd@11c00000 { + compatible = "samsung,exynos4210-fimd"; + interrupt-parent = <&combiner>; + reg = <0x11c00000 0x20000>; + interrupt-names = "fifo", "vsync", "lcd_sys"; + interrupts = <11 0>, <11 1>, <11 2>; + clocks = <&clock 140>, <&clock 283>; + clock-names = "sclk_fimd", "fimd"; + samsung,power-domain = <&pd_lcd0>; + status = "disabled"; + }; }; diff --git a/trunk/arch/arm/boot/dts/exynos4210-origen.dts b/trunk/arch/arm/boot/dts/exynos4210-origen.dts index f2710018e84e..524b90846df5 100644 --- a/trunk/arch/arm/boot/dts/exynos4210-origen.dts +++ b/trunk/arch/arm/boot/dts/exynos4210-origen.dts @@ -57,6 +57,16 @@ status = "okay"; }; + g2d@12800000 { + status = "okay"; + }; + + codec@13400000 { + samsung,mfc-r = <0x43000000 0x800000>; + samsung,mfc-l = <0x51000000 0x800000>; + status = "okay"; + }; + serial@13800000 { status = "okay"; }; @@ -121,4 +131,16 @@ linux,default-trigger = "heartbeat"; }; }; + + fixed-rate-clocks { + xxti { + compatible = "samsung,clock-xxti"; + clock-frequency = <0>; + }; + + xusbxti { + compatible = "samsung,clock-xusbxti"; + clock-frequency = <24000000>; + }; + }; }; diff --git a/trunk/arch/arm/boot/dts/exynos4210-smdkv310.dts b/trunk/arch/arm/boot/dts/exynos4210-smdkv310.dts index f63490707f3a..91332b72acf5 100644 --- a/trunk/arch/arm/boot/dts/exynos4210-smdkv310.dts +++ b/trunk/arch/arm/boot/dts/exynos4210-smdkv310.dts @@ -30,16 +30,19 @@ }; sdhci@12530000 { - samsung,sdhci-bus-width = <4>; - linux,mmc_cap_4_bit_data; - samsung,sdhci-cd-internal; - gpio-cd = <&gpk2 2 2 3 3>; - gpios = <&gpk2 0 2 0 3>, - <&gpk2 1 2 0 3>, - <&gpk2 3 2 3 3>, - <&gpk2 4 2 3 3>, - <&gpk2 5 2 3 3>, - <&gpk2 6 2 3 3>; + bus-width = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>; + status = "okay"; + }; + + g2d@12800000 { + status = "okay"; + }; + + codec@13400000 { + samsung,mfc-r = <0x43000000 0x800000>; + samsung,mfc-l = <0x51000000 0x800000>; status = "okay"; }; @@ -59,25 +62,32 @@ status = "okay"; }; + pinctrl@11000000 { + keypad_rows: keypad-rows { + samsung,pins = "gpx2-0", "gpx2-1"; + samsung,pin-function = <3>; + samsung,pin-pud = <3>; + samsung,pin-drv = <0>; + }; + + keypad_cols: keypad-cols { + samsung,pins = "gpx1-0", "gpx1-1", "gpx1-2", "gpx1-3", + "gpx1-4", "gpx1-5", "gpx1-6", "gpx1-7"; + samsung,pin-function = <3>; + samsung,pin-pud = <0>; + samsung,pin-drv = <0>; + }; + }; + keypad@100A0000 { samsung,keypad-num-rows = <2>; samsung,keypad-num-columns = <8>; linux,keypad-no-autorepeat; linux,keypad-wakeup; + pinctrl-names = "default"; + pinctrl-0 = <&keypad_rows &keypad_cols>; status = "okay"; - row-gpios = <&gpx2 0 3 3 0>, - <&gpx2 1 3 3 0>; - - col-gpios = <&gpx1 0 3 0 0>, - <&gpx1 1 3 0 0>, - <&gpx1 2 3 0 0>, - <&gpx1 3 3 0 0>, - <&gpx1 4 3 0 0>, - <&gpx1 5 3 0 0>, - <&gpx1 6 3 0 0>, - <&gpx1 7 3 0 0>; - key_1 { keypad,row = <0>; keypad,column = <3>; @@ -143,9 +153,7 @@ #address-cells = <1>; #size-cells = <0>; samsung,i2c-sda-delay = <100>; - samsung,i2c-max-bus-freq = <20000>; - gpios = <&gpd1 0 2 3 0>, - <&gpd1 1 2 3 0>; + samsung,i2c-max-bus-freq = <100000>; status = "okay"; eeprom@50 { @@ -160,9 +168,6 @@ }; spi_2: spi@13940000 { - gpios = <&gpc1 1 5 3 0>, - <&gpc1 3 5 3 0>, - <&gpc1 4 5 3 0>; status = "okay"; w25x80@0 { @@ -173,7 +178,7 @@ spi-max-frequency = <1000000>; controller-data { - cs-gpio = <&gpc1 2 1 0 3>; + cs-gpio = <&gpc1 2 0>; samsung,spi-feedback-delay = <0>; }; @@ -189,4 +194,16 @@ }; }; }; + + fixed-rate-clocks { + xxti { + compatible = "samsung,clock-xxti"; + clock-frequency = <12000000>; + }; + + xusbxti { + compatible = "samsung,clock-xusbxti"; + clock-frequency = <24000000>; + }; + }; }; diff --git a/trunk/arch/arm/boot/dts/exynos4210-trats.dts b/trunk/arch/arm/boot/dts/exynos4210-trats.dts index c346b64dff55..9a14484c7bb1 100644 --- a/trunk/arch/arm/boot/dts/exynos4210-trats.dts +++ b/trunk/arch/arm/boot/dts/exynos4210-trats.dts @@ -289,4 +289,16 @@ }; }; }; + + fixed-rate-clocks { + xxti { + compatible = "samsung,clock-xxti"; + clock-frequency = <0>; + }; + + xusbxti { + compatible = "samsung,clock-xusbxti"; + clock-frequency = <24000000>; + }; + }; }; diff --git a/trunk/arch/arm/boot/dts/exynos4210-universal_c210.dts b/trunk/arch/arm/boot/dts/exynos4210-universal_c210.dts new file mode 100644 index 000000000000..345cdb51dcb7 --- /dev/null +++ b/trunk/arch/arm/boot/dts/exynos4210-universal_c210.dts @@ -0,0 +1,352 @@ +/* + * Samsung's Exynos4210 based Universal C210 board device tree source + * + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Device tree source file for Samsung's Universal C210 board which is based on + * Samsung's Exynos4210 rev0 SoC. + * + * 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. +*/ + +/dts-v1/; +/include/ "exynos4210.dtsi" + +/ { + model = "Samsung Universal C210 based on Exynos4210 rev0"; + compatible = "samsung,universal_c210", "samsung,exynos4210"; + + memory { + reg = <0x40000000 0x10000000 + 0x50000000 0x10000000>; + }; + + chosen { + bootargs = "console=ttySAC2,115200N8 root=/dev/mmcblk0p5 rw rootwait earlyprintk panic=5 maxcpus=1"; + }; + + mct@10050000 { + compatible = "none"; + }; + + fixed-rate-clocks { + xxti { + compatible = "samsung,clock-xxti"; + clock-frequency = <0>; + }; + + xusbxti { + compatible = "samsung,clock-xusbxti"; + clock-frequency = <24000000>; + }; + }; + + vemmc_reg: voltage-regulator { + compatible = "regulator-fixed"; + regulator-name = "VMEM_VDD_2_8V"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + gpio = <&gpe1 3 0>; + enable-active-high; + }; + + sdhci_emmc: sdhci@12510000 { + bus-width = <8>; + non-removable; + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus8>; + pinctrl-names = "default"; + vmmc-supply = <&vemmc_reg>; + status = "okay"; + }; + + serial@13800000 { + status = "okay"; + }; + + serial@13810000 { + status = "okay"; + }; + + serial@13820000 { + status = "okay"; + }; + + serial@13830000 { + status = "okay"; + }; + + gpio-keys { + compatible = "gpio-keys"; + + vol-up-key { + gpios = <&gpx2 0 1>; + linux,code = <115>; + label = "volume up"; + debounce-interval = <1>; + }; + + vol-down-key { + gpios = <&gpx2 1 1>; + linux,code = <114>; + label = "volume down"; + debounce-interval = <1>; + }; + + config-key { + gpios = <&gpx2 2 1>; + linux,code = <171>; + label = "config"; + debounce-interval = <1>; + gpio-key,wakeup; + }; + + camera-key { + gpios = <&gpx2 3 1>; + linux,code = <212>; + label = "camera"; + debounce-interval = <1>; + }; + + power-key { + gpios = <&gpx2 7 1>; + linux,code = <116>; + label = "power"; + debounce-interval = <1>; + gpio-key,wakeup; + }; + + ok-key { + gpios = <&gpx3 5 1>; + linux,code = <352>; + label = "ok"; + debounce-interval = <1>; + }; + }; + + tsp_reg: voltage-regulator { + compatible = "regulator-fixed"; + regulator-name = "TSP_2_8V"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + gpio = <&gpe2 3 0>; + enable-active-high; + }; + + i2c@13890000 { + samsung,i2c-sda-delay = <100>; + samsung,i2c-slave-addr = <0x10>; + samsung,i2c-max-bus-freq = <100000>; + pinctrl-0 = <&i2c3_bus>; + pinctrl-names = "default"; + status = "okay"; + + tsp@4a { + /* TBD: Atmel maXtouch touchscreen */ + reg = <0x4a>; + }; + }; + + i2c@138B0000 { + samsung,i2c-sda-delay = <100>; + samsung,i2c-slave-addr = <0x10>; + samsung,i2c-max-bus-freq = <100000>; + pinctrl-0 = <&i2c5_bus>; + pinctrl-names = "default"; + status = "okay"; + + vdd_arm_reg: pmic@60 { + compatible = "maxim,max8952"; + reg = <0x60>; + + max8952,vid-gpios = <&gpx0 3 0>, <&gpx0 4 0>; + max8952,default-mode = <0>; + max8952,dvs-mode-microvolt = <1250000>, <1200000>, + <1050000>, <950000>; + max8952,sync-freq = <0>; + max8952,ramp-speed = <0>; + + regulator-name = "vdd_arm"; + regulator-min-microvolt = <770000>; + regulator-max-microvolt = <1400000>; + regulator-always-on; + regulator-boot-on; + }; + + pmic@66 { + compatible = "national,lp3974"; + reg = <0x66>; + + max8998,pmic-buck1-default-dvs-idx = <0>; + max8998,pmic-buck1-dvs-gpios = <&gpx0 5 0>, + <&gpx0 6 0>; + max8998,pmic-buck1-dvs-voltage = <1100000>, <1000000>, + <1100000>, <1000000>; + + max8998,pmic-buck2-default-dvs-idx = <0>; + max8998,pmic-buck2-dvs-gpio = <&gpe2 0 0>; + max8998,pmic-buck2-dvs-voltage = <1200000>, <1100000>; + + regulators { + ldo2_reg: LDO2 { + regulator-name = "VALIVE_1.2V"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + }; + + ldo3_reg: LDO3 { + regulator-name = "VUSB+MIPI_1.1V"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + }; + + ldo4_reg: LDO4 { + regulator-name = "VADC_3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + ldo5_reg: LDO5 { + regulator-name = "VTF_2.8V"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + }; + + ldo6_reg: LDO6 { + regulator-name = "LDO6"; + regulator-min-microvolt = <2000000>; + regulator-max-microvolt = <2000000>; + }; + + ldo7_reg: LDO7 { + regulator-name = "VLCD+VMIPI_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + ldo8_reg: LDO8 { + regulator-name = "VUSB+VDAC_3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + ldo9_reg: LDO9 { + regulator-name = "VCC_2.8V"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-always-on; + }; + + ldo10_reg: LDO10 { + regulator-name = "VPLL_1.1V"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo11_reg: LDO11 { + regulator-name = "CAM_AF_3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + ldo12_reg: LDO12 { + regulator-name = "PS_2.8V"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + }; + + ldo13_reg: LDO13 { + regulator-name = "VHIC_1.2V"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + + ldo14_reg: LDO14 { + regulator-name = "CAM_I_HOST_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + ldo15_reg: LDO15 { + regulator-name = "CAM_S_DIG+FM33_CORE_1.2V"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + + ldo16_reg: LDO16 { + regulator-name = "CAM_S_ANA_2.8V"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + }; + + ldo17_reg: LDO17 { + regulator-name = "VCC_3.0V_LCD"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + }; + + buck1_reg: BUCK1 { + regulator-name = "VINT_1.1V"; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1500000>; + regulator-boot-on; + regulator-always-on; + }; + + buck2_reg: BUCK2 { + regulator-name = "VG3D_1.1V"; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1500000>; + regulator-boot-on; + }; + + buck3_reg: BUCK3 { + regulator-name = "VCC_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + buck4_reg: BUCK4 { + regulator-name = "VMEM_1.2V"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + }; + + ap32khz_reg: EN32KHz-AP { + regulator-name = "32KHz AP"; + regulator-always-on; + }; + + cp32khz_reg: EN32KHz-CP { + regulator-name = "32KHz CP"; + }; + + vichg_reg: ENVICHG { + regulator-name = "VICHG"; + }; + + safeout1_reg: ESAFEOUT1 { + regulator-name = "SAFEOUT1"; + regulator-always-on; + }; + + safeout2_reg: ESAFEOUT2 { + regulator-name = "SAFEOUT2"; + regulator-boot-on; + }; + }; + }; + }; + + pwm@139D0000 { + compatible = "samsung,s5p6440-pwm"; + status = "okay"; + }; +}; diff --git a/trunk/arch/arm/boot/dts/exynos4210.dtsi b/trunk/arch/arm/boot/dts/exynos4210.dtsi index 2feffc70814c..54710de82908 100644 --- a/trunk/arch/arm/boot/dts/exynos4210.dtsi +++ b/trunk/arch/arm/boot/dts/exynos4210.dtsi @@ -41,12 +41,49 @@ }; combiner:interrupt-controller@10440000 { + samsung,combiner-nr = <16>; interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>, <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>, <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>, <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>; }; + mct@10050000 { + compatible = "samsung,exynos4210-mct"; + reg = <0x10050000 0x800>; + interrupt-controller; + #interrups-cells = <2>; + interrupt-parent = <&mct_map>; + interrupts = <0 0>, <1 0>, <2 0>, <3 0>, + <4 0>, <5 0>; + clocks = <&clock 3>, <&clock 344>; + clock-names = "fin_pll", "mct"; + + mct_map: mct-map { + #interrupt-cells = <2>; + #address-cells = <0>; + #size-cells = <0>; + interrupt-map = <0x0 0 &gic 0 57 0>, + <0x1 0 &gic 0 69 0>, + <0x2 0 &combiner 12 6>, + <0x3 0 &combiner 12 7>, + <0x4 0 &gic 0 42 0>, + <0x5 0 &gic 0 48 0>; + }; + }; + + clock: clock-controller@0x10030000 { + compatible = "samsung,exynos4210-clock"; + reg = <0x10030000 0x20000>; + #clock-cells = <1>; + }; + + pmu { + compatible = "arm,cortex-a9-pmu"; + interrupt-parent = <&combiner>; + interrupts = <2 2>, <3 2>; + }; + pinctrl_0: pinctrl@11400000 { compatible = "samsung,exynos4210-pinctrl"; reg = <0x11400000 0x1000>; @@ -76,4 +113,11 @@ reg = <0x100C0000 0x100>; interrupts = <2 4>; }; + + g2d@12800000 { + compatible = "samsung,s5pv210-g2d"; + reg = <0x12800000 0x1000>; + interrupts = <0 89 0>; + status = "disabled"; + }; }; diff --git a/trunk/arch/arm/boot/dts/exynos4212.dtsi b/trunk/arch/arm/boot/dts/exynos4212.dtsi index c6ae2005961f..c0f60f49cea6 100644 --- a/trunk/arch/arm/boot/dts/exynos4212.dtsi +++ b/trunk/arch/arm/boot/dts/exynos4212.dtsi @@ -25,4 +25,35 @@ gic:interrupt-controller@10490000 { cpu-offset = <0x8000>; }; + + interrupt-controller@10440000 { + samsung,combiner-nr = <18>; + interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>, + <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>, + <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>, + <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>, + <0 107 0>, <0 108 0>; + }; + + mct@10050000 { + compatible = "samsung,exynos4412-mct"; + reg = <0x10050000 0x800>; + interrupt-controller; + #interrups-cells = <2>; + interrupt-parent = <&mct_map>; + interrupts = <0 0>, <1 0>, <2 0>, <3 0>, + <4 0>, <5 0>; + + mct_map: mct-map { + #interrupt-cells = <2>; + #address-cells = <0>; + #size-cells = <0>; + interrupt-map = <0x0 0 &gic 0 57 0>, + <0x1 0 &combiner 12 5>, + <0x2 0 &combiner 12 6>, + <0x3 0 &combiner 12 7>, + <0x4 0 &gic 1 12 0>, + <0x5 0 &gic 1 12 0>; + }; + }; }; diff --git a/trunk/arch/arm/boot/dts/exynos4412-odroidx.dts b/trunk/arch/arm/boot/dts/exynos4412-odroidx.dts new file mode 100644 index 000000000000..53bc8bf77984 --- /dev/null +++ b/trunk/arch/arm/boot/dts/exynos4412-odroidx.dts @@ -0,0 +1,111 @@ +/* + * Hardkernel's Exynos4412 based ODROID-X board device tree source + * + * Copyright (c) 2012 Dongjin Kim + * + * Device tree source file for Hardkernel's ODROID-X board which is based on + * Samsung's Exynos4412 SoC. + * + * 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. +*/ + +/dts-v1/; +/include/ "exynos4412.dtsi" + +/ { + model = "Hardkernel ODROID-X board based on Exynos4412"; + compatible = "hardkernel,odroid-x", "samsung,exynos4412"; + + memory { + reg = <0x40000000 0x40000000>; + }; + + leds { + compatible = "gpio-leds"; + led1 { + label = "led1:heart"; + gpios = <&gpc1 0 1>; + default-state = "on"; + linux,default-trigger = "heartbeat"; + }; + led2 { + label = "led2:mmc0"; + gpios = <&gpc1 2 1>; + default-state = "on"; + linux,default-trigger = "mmc0"; + }; + }; + + mshc@12550000 { + #address-cells = <1>; + #size-cells = <0>; + pinctrl-0 = <&sd4_clk &sd4_cmd &sd4_bus4 &sd4_bus8>; + pinctrl-names = "default"; + status = "okay"; + + num-slots = <1>; + supports-highspeed; + broken-cd; + fifo-depth = <0x80>; + card-detect-delay = <200>; + samsung,dw-mshc-ciu-div = <3>; + samsung,dw-mshc-sdr-timing = <2 3>; + samsung,dw-mshc-ddr-timing = <1 2>; + + slot@0 { + reg = <0>; + bus-width = <8>; + }; + }; + + regulator_p3v3 { + compatible = "regulator-fixed"; + regulator-name = "p3v3_en"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpa1 1 1>; + enable-active-high; + regulator-boot-on; + }; + + rtc@10070000 { + status = "okay"; + }; + + sdhci@12530000 { + bus-width = <4>; + pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>; + pinctrl-names = "default"; + status = "okay"; + }; + + serial@13800000 { + status = "okay"; + }; + + serial@13810000 { + status = "okay"; + }; + + serial@13820000 { + status = "okay"; + }; + + serial@13830000 { + status = "okay"; + }; + + fixed-rate-clocks { + xxti { + compatible = "samsung,clock-xxti"; + clock-frequency = <0>; + }; + + xusbxti { + compatible = "samsung,clock-xusbxti"; + clock-frequency = <24000000>; + }; + }; +}; diff --git a/trunk/arch/arm/boot/dts/exynos4412-origen.dts b/trunk/arch/arm/boot/dts/exynos4412-origen.dts new file mode 100644 index 000000000000..1c21bad32ca9 --- /dev/null +++ b/trunk/arch/arm/boot/dts/exynos4412-origen.dts @@ -0,0 +1,453 @@ +/* + * Insignal's Exynos4412 based Origen board device tree source + * + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Device tree source file for Insignal's Origen board which is based on + * Samsung's Exynos4412 SoC. + * + * 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. +*/ + +/dts-v1/; +/include/ "exynos4412.dtsi" + +/ { + model = "Insignal Origen evaluation board based on Exynos4412"; + compatible = "insignal,origen4412", "samsung,exynos4412"; + + memory { + reg = <0x40000000 0x40000000>; + }; + + chosen { + bootargs ="console=ttySAC2,115200"; + }; + + mmc_reg: voltage-regulator { + compatible = "regulator-fixed"; + regulator-name = "VMEM_VDD_2.8V"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + gpio = <&gpx1 1 0>; + enable-active-high; + }; + + sdhci@12530000 { + bus-width = <4>; + pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4 &sd2_cd>; + pinctrl-names = "default"; + vmmc-supply = <&mmc_reg>; + status = "okay"; + }; + + mshc@12550000 { + #address-cells = <1>; + #size-cells = <0>; + pinctrl-0 = <&sd4_clk &sd4_cmd &sd4_bus4 &sd4_bus8>; + pinctrl-names = "default"; + status = "okay"; + + num-slots = <1>; + supports-highspeed; + broken-cd; + fifo-depth = <0x80>; + card-detect-delay = <200>; + samsung,dw-mshc-ciu-div = <3>; + samsung,dw-mshc-sdr-timing = <2 3>; + samsung,dw-mshc-ddr-timing = <1 2>; + + slot@0 { + reg = <0>; + bus-width = <8>; + }; + }; + + codec@13400000 { + samsung,mfc-r = <0x43000000 0x800000>; + samsung,mfc-l = <0x51000000 0x800000>; + status = "okay"; + }; + + fimd@11c00000 { + pinctrl-0 = <&lcd_clk &lcd_data24 &pwm1_out>; + pinctrl-names = "default"; + status = "okay"; + }; + + display-timings { + native-mode = <&timing0>; + timing0: timing { + clock-frequency = <50000>; + hactive = <1024>; + vactive = <600>; + hfront-porch = <64>; + hback-porch = <16>; + hsync-len = <48>; + vback-porch = <64>; + vfront-porch = <16>; + vsync-len = <3>; + }; + }; + + serial@13800000 { + status = "okay"; + }; + + serial@13810000 { + status = "okay"; + }; + + serial@13820000 { + status = "okay"; + }; + + serial@13830000 { + status = "okay"; + }; + + i2c@13860000 { + #address-cells = <1>; + #size-cells = <0>; + samsung,i2c-sda-delay = <100>; + samsung,i2c-max-bus-freq = <20000>; + pinctrl-0 = <&i2c0_bus>; + pinctrl-names = "default"; + status = "okay"; + + s5m8767_pmic@66 { + compatible = "samsung,s5m8767-pmic"; + reg = <0x66>; + + s5m8767,pmic-buck-default-dvs-idx = <3>; + + s5m8767,pmic-buck-dvs-gpios = <&gpx2 3 0>, + <&gpx2 4 0>, + <&gpx2 5 0>; + + s5m8767,pmic-buck-ds-gpios = <&gpm3 5 0>, + <&gpm3 6 0>, + <&gpm3 7 0>; + + s5m8767,pmic-buck2-dvs-voltage = <1250000>, <1200000>, + <1200000>, <1200000>, + <1200000>, <1200000>, + <1200000>, <1200000>; + + s5m8767,pmic-buck3-dvs-voltage = <1100000>, <1100000>, + <1100000>, <1100000>, + <1100000>, <1100000>, + <1100000>, <1100000>; + + s5m8767,pmic-buck4-dvs-voltage = <1200000>, <1200000>, + <1200000>, <1200000>, + <1200000>, <1200000>, + <1200000>, <1200000>; + + regulators { + ldo1_reg: LDO1 { + regulator-name = "VDD_ALIVE"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; /* Normal Mode */ + }; + + ldo2_reg: LDO2 { + regulator-name = "VDDQ_M12"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + op_mode = <1>; /* Normal Mode */ + }; + + ldo3_reg: LDO3 { + regulator-name = "VDDIOAP_18"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + op_mode = <1>; /* Normal Mode */ + }; + + ldo4_reg: LDO4 { + regulator-name = "VDDQ_PRE"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + op_mode = <1>; /* Normal Mode */ + }; + + ldo5_reg: LDO5 { + regulator-name = "VDD18_2M"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + op_mode = <1>; /* Normal Mode */ + }; + + ldo6_reg: LDO6 { + regulator-name = "VDD10_MPLL"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + op_mode = <1>; /* Normal Mode */ + }; + + ldo7_reg: LDO7 { + regulator-name = "VDD10_XPLL"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + op_mode = <1>; /* Normal Mode */ + }; + + ldo8_reg: LDO8 { + regulator-name = "VDD10_MIPI"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + op_mode = <1>; /* Normal Mode */ + }; + + ldo9_reg: LDO9 { + regulator-name = "VDD33_LCD"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + op_mode = <1>; /* Normal Mode */ + }; + + ldo10_reg: LDO10 { + regulator-name = "VDD18_MIPI"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + op_mode = <1>; /* Normal Mode */ + }; + + ldo11_reg: LDO11 { + regulator-name = "VDD18_ABB1"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + op_mode = <1>; /* Normal Mode */ + }; + + ldo12_reg: LDO12 { + regulator-name = "VDD33_UOTG"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + op_mode = <1>; /* Normal Mode */ + }; + + ldo13_reg: LDO13 { + regulator-name = "VDDIOPERI_18"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + op_mode = <1>; /* Normal Mode */ + }; + + ldo14_reg: LDO14 { + regulator-name = "VDD18_ABB02"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + op_mode = <1>; /* Normal Mode */ + }; + + ldo15_reg: LDO15 { + regulator-name = "VDD10_USH"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + op_mode = <1>; /* Normal Mode */ + }; + + ldo16_reg: LDO16 { + regulator-name = "VDD18_HSIC"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + op_mode = <1>; /* Normal Mode */ + }; + + ldo17_reg: LDO17 { + regulator-name = "VDDIOAP_MMC012_28"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-always-on; + op_mode = <1>; /* Normal Mode */ + }; + + ldo18_reg: LDO18 { + regulator-name = "VDDIOPERI_28"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-always-on; + op_mode = <1>; /* Normal Mode */ + }; + + ldo19_reg: LDO19 { + regulator-name = "DVDD25"; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + regulator-always-on; + op_mode = <1>; /* Normal Mode */ + }; + + ldo20_reg: LDO20 { + regulator-name = "VDD28_CAM"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-always-on; + op_mode = <1>; /* Normal Mode */ + }; + + ldo21_reg: LDO21 { + regulator-name = "VDD28_AF"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-always-on; + op_mode = <1>; /* Normal Mode */ + }; + + ldo22_reg: LDO22 { + regulator-name = "VDDA28_2M"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-always-on; + op_mode = <1>; /* Normal Mode */ + }; + + ldo23_reg: LDO23 { + regulator-name = "VDD28_TF"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-always-on; + op_mode = <1>; /* Normal Mode */ + }; + + ldo24_reg: LDO24 { + regulator-name = "VDD33_A31"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + op_mode = <1>; /* Normal Mode */ + }; + + ldo25_reg: LDO25 { + regulator-name = "VDD18_CAM"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + op_mode = <1>; /* Normal Mode */ + }; + + ldo26_reg: LDO26 { + regulator-name = "VDD18_A31"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + op_mode = <1>; /* Normal Mode */ + }; + + ldo27_reg: LDO27 { + regulator-name = "GPS_1V8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + op_mode = <1>; /* Normal Mode */ + }; + + ldo28_reg: LDO28 { + regulator-name = "DVDD12"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + op_mode = <1>; /* Normal Mode */ + }; + + buck1_reg: BUCK1 { + regulator-name = "vdd_mif"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1100000>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; /* Normal Mode */ + }; + + buck2_reg: BUCK2 { + regulator-name = "vdd_arm"; + regulator-min-microvolt = <925000>; + regulator-max-microvolt = <1300000>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; /* Normal Mode */ + }; + + buck3_reg: BUCK3 { + regulator-name = "vdd_int"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; /* Normal Mode */ + }; + + buck4_reg: BUCK4 { + regulator-name = "vdd_g3d"; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1500000>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; /* Normal Mode */ + }; + + buck5_reg: BUCK5 { + regulator-name = "vdd_m12"; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1500000>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; /* Normal Mode */ + }; + + buck6_reg: BUCK6 { + regulator-name = "vdd12_5m"; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1500000>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; /* Normal Mode */ + }; + + buck9_reg: BUCK9 { + regulator-name = "vddf28_emmc"; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; /* Normal Mode */ + }; + }; + }; + }; + + fixed-rate-clocks { + xxti { + compatible = "samsung,clock-xxti"; + clock-frequency = <0>; + }; + + xusbxti { + compatible = "samsung,clock-xusbxti"; + clock-frequency = <24000000>; + }; + }; +}; diff --git a/trunk/arch/arm/boot/dts/exynos4412-smdk4412.dts b/trunk/arch/arm/boot/dts/exynos4412-smdk4412.dts index f05bf575cc45..dd564310d4a5 100644 --- a/trunk/arch/arm/boot/dts/exynos4412-smdk4412.dts +++ b/trunk/arch/arm/boot/dts/exynos4412-smdk4412.dts @@ -27,6 +27,27 @@ bootargs ="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc"; }; + g2d@10800000 { + status = "okay"; + }; + + g2d@10800000 { + status = "okay"; + }; + + sdhci@12530000 { + bus-width = <4>; + pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4 &sd2_cd>; + pinctrl-names = "default"; + status = "okay"; + }; + + codec@13400000 { + samsung,mfc-r = <0x43000000 0x800000>; + samsung,mfc-l = <0x51000000 0x800000>; + status = "okay"; + }; + serial@13800000 { status = "okay"; }; @@ -42,4 +63,16 @@ serial@13830000 { status = "okay"; }; + + fixed-rate-clocks { + xxti { + compatible = "samsung,clock-xxti"; + clock-frequency = <0>; + }; + + xusbxti { + compatible = "samsung,clock-xusbxti"; + clock-frequency = <24000000>; + }; + }; }; diff --git a/trunk/arch/arm/boot/dts/exynos4412.dtsi b/trunk/arch/arm/boot/dts/exynos4412.dtsi index d7dfe312772a..270b389e0a1b 100644 --- a/trunk/arch/arm/boot/dts/exynos4412.dtsi +++ b/trunk/arch/arm/boot/dts/exynos4412.dtsi @@ -25,4 +25,47 @@ gic:interrupt-controller@10490000 { cpu-offset = <0x4000>; }; + + interrupt-controller@10440000 { + samsung,combiner-nr = <20>; + interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>, + <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>, + <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>, + <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>, + <0 107 0>, <0 108 0>, <0 48 0>, <0 42 0>; + }; + + mct@10050000 { + compatible = "samsung,exynos4412-mct"; + reg = <0x10050000 0x800>; + interrupt-controller; + #interrups-cells = <2>; + interrupt-parent = <&mct_map>; + interrupts = <0 0>, <1 0>, <2 0>, <3 0>, + <4 0>, <5 0>, <6 0>, <7 0>; + clocks = <&clock 3>, <&clock 344>; + clock-names = "fin_pll", "mct"; + + mct_map: mct-map { + #interrupt-cells = <2>; + #address-cells = <0>; + #size-cells = <0>; + interrupt-map = <0x0 0 &gic 0 57 0>, + <0x1 0 &combiner 12 5>, + <0x2 0 &combiner 12 6>, + <0x3 0 &combiner 12 7>, + <0x4 0 &gic 1 12 0>, + <0x5 0 &gic 1 12 0>, + <0x6 0 &gic 1 12 0>, + <0x7 0 &gic 1 12 0>; + }; + }; + + mshc@12550000 { + compatible = "samsung,exynos4412-dw-mshc"; + reg = <0x12550000 0x1000>; + interrupts = <0 77 0>; + #address-cells = <1>; + #size-cells = <0>; + }; }; diff --git a/trunk/arch/arm/boot/dts/exynos4x12.dtsi b/trunk/arch/arm/boot/dts/exynos4x12.dtsi index 9a8780694909..e3380a7a285c 100644 --- a/trunk/arch/arm/boot/dts/exynos4x12.dtsi +++ b/trunk/arch/arm/boot/dts/exynos4x12.dtsi @@ -36,6 +36,12 @@ <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>; }; + clock: clock-controller@0x10030000 { + compatible = "samsung,exynos4412-clock"; + reg = <0x10030000 0x20000>; + #clock-cells = <1>; + }; + pinctrl_0: pinctrl@11400000 { compatible = "samsung,exynos4x12-pinctrl"; reg = <0x11400000 0x1000>; @@ -66,4 +72,11 @@ reg = <0x106E0000 0x1000>; interrupts = <0 72 0>; }; + + g2d@10800000 { + compatible = "samsung,exynos4212-g2d"; + reg = <0x10800000 0x1000>; + interrupts = <0 89 0>; + status = "disabled"; + }; }; diff --git a/trunk/arch/arm/boot/dts/exynos5250-arndale.dts b/trunk/arch/arm/boot/dts/exynos5250-arndale.dts new file mode 100644 index 000000000000..02cfc76d002f --- /dev/null +++ b/trunk/arch/arm/boot/dts/exynos5250-arndale.dts @@ -0,0 +1,452 @@ +/* + * Samsung's Exynos5250 based Arndale board device tree source + * + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +/dts-v1/; +/include/ "exynos5250.dtsi" + +/ { + model = "Insignal Arndale evaluation board based on EXYNOS5250"; + compatible = "insignal,arndale", "samsung,exynos5250"; + + memory { + reg = <0x40000000 0x80000000>; + }; + + chosen { + bootargs = "console=ttySAC2,115200"; + }; + + codec@11000000 { + samsung,mfc-r = <0x43000000 0x800000>; + samsung,mfc-l = <0x51000000 0x800000>; + }; + + i2c@12C60000 { + samsung,i2c-sda-delay = <100>; + samsung,i2c-max-bus-freq = <20000>; + samsung,i2c-slave-addr = <0x66>; + + s5m8767_pmic@66 { + compatible = "samsung,s5m8767-pmic"; + reg = <0x66>; + + s5m8767,pmic-buck2-dvs-voltage = <1300000>; + s5m8767,pmic-buck3-dvs-voltage = <1100000>; + s5m8767,pmic-buck4-dvs-voltage = <1200000>; + s5m8767,pmic-buck-dvs-gpios = <&gpd1 0 0>, + <&gpd1 1 0>, + <&gpd1 2 0>; + s5m8767,pmic-buck-ds-gpios = <&gpx2 3 0>, + <&gpx2 4 0>, + <&gpx2 5 0>; + regulators { + ldo1_reg: LDO1 { + regulator-name = "VDD_ALIVE_1.0V"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; + }; + + ldo2_reg: LDO2 { + regulator-name = "VDD_28IO_DP_1.35V"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; + }; + + ldo3_reg: LDO3 { + regulator-name = "VDD_COMMON1_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; + }; + + ldo4_reg: LDO4 { + regulator-name = "VDD_IOPERI_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + op_mode = <1>; + }; + + ldo5_reg: LDO5 { + regulator-name = "VDD_EXT_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; + }; + + ldo6_reg: LDO6 { + regulator-name = "VDD_MPLL_1.1V"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; + }; + + ldo7_reg: LDO7 { + regulator-name = "VDD_XPLL_1.1V"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; + }; + + ldo8_reg: LDO8 { + regulator-name = "VDD_COMMON2_1.0V"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; + }; + + ldo9_reg: LDO9 { + regulator-name = "VDD_33ON_3.0V"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + op_mode = <1>; + }; + + ldo10_reg: LDO10 { + regulator-name = "VDD_COMMON3_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; + }; + + ldo11_reg: LDO11 { + regulator-name = "VDD_ABB2_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; + }; + + ldo12_reg: LDO12 { + regulator-name = "VDD_USB_3.0V"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; + }; + + ldo13_reg: LDO13 { + regulator-name = "VDDQ_C2C_W_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; + }; + + ldo14_reg: LDO14 { + regulator-name = "VDD18_ABB0_3_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; + }; + + ldo15_reg: LDO15 { + regulator-name = "VDD10_COMMON4_1.0V"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; + }; + + ldo16_reg: LDO16 { + regulator-name = "VDD18_HSIC_1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; + }; + + ldo17_reg: LDO17 { + regulator-name = "VDDQ_MMC2_3_2.8V"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; + }; + + ldo18_reg: LDO18 { + regulator-name = "VDD_33ON_2.8V"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + op_mode = <1>; + }; + + ldo22_reg: LDO22 { + regulator-name = "EXT_33_OFF"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + op_mode = <1>; + }; + + ldo23_reg: LDO23 { + regulator-name = "EXT_28_OFF"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + op_mode = <1>; + }; + + ldo25_reg: LDO25 { + regulator-name = "PVDD_LDO25"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + op_mode = <1>; + }; + + ldo26_reg: LDO26 { + regulator-name = "EXT_18_OFF"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + op_mode = <1>; + }; + + buck1_reg: BUCK1 { + regulator-name = "vdd_mif"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; + }; + + buck2_reg: BUCK2 { + regulator-name = "vdd_arm"; + regulator-min-microvolt = <925000>; + regulator-max-microvolt = <1300000>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; + }; + + buck3_reg: BUCK3 { + regulator-name = "vdd_int"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; + }; + + buck4_reg: BUCK4 { + regulator-name = "vdd_g3d"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-boot-on; + op_mode = <1>; + }; + + buck5_reg: BUCK5 { + regulator-name = "VDD_MEM_1.35V"; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1355000>; + regulator-always-on; + regulator-boot-on; + op_mode = <1>; + }; + + buck9_reg: BUCK9 { + regulator-name = "VDD_33_OFF_EXT1"; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <3000000>; + op_mode = <1>; + }; + }; + }; + }; + + i2c@12C70000 { + status = "disabled"; + }; + + i2c@12C80000 { + status = "disabled"; + }; + + i2c@12C90000 { + status = "disabled"; + }; + + i2c@12CA0000 { + status = "disabled"; + }; + + i2c@12CB0000 { + status = "disabled"; + }; + + i2c@12CC0000 { + status = "disabled"; + }; + + i2c@12CD0000 { + status = "disabled"; + }; + + i2c@121D0000 { + status = "disabled"; + }; + + dwmmc_0: dwmmc0@12200000 { + num-slots = <1>; + supports-highspeed; + broken-cd; + fifo-depth = <0x80>; + card-detect-delay = <200>; + samsung,dw-mshc-ciu-div = <3>; + samsung,dw-mshc-sdr-timing = <2 3>; + samsung,dw-mshc-ddr-timing = <1 2>; + vmmc-supply = <&mmc_reg>; + pinctrl-names = "default"; + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; + + slot@0 { + reg = <0>; + bus-width = <8>; + }; + }; + + dwmmc_1: dwmmc1@12210000 { + status = "disabled"; + }; + + dwmmc_2: dwmmc2@12220000 { + num-slots = <1>; + supports-highspeed; + fifo-depth = <0x80>; + card-detect-delay = <200>; + samsung,dw-mshc-ciu-div = <3>; + samsung,dw-mshc-sdr-timing = <2 3>; + samsung,dw-mshc-ddr-timing = <1 2>; + vmmc-supply = <&mmc_reg>; + pinctrl-names = "default"; + pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>; + + slot@0 { + reg = <0>; + bus-width = <4>; + disable-wp; + }; + }; + + dwmmc_3: dwmmc3@12230000 { + status = "disabled"; + }; + + spi_0: spi@12d20000 { + status = "disabled"; + }; + + spi_1: spi@12d30000 { + status = "disabled"; + }; + + spi_2: spi@12d40000 { + status = "disabled"; + }; + + gpio_keys { + compatible = "gpio-keys"; + + menu { + label = "SW-TACT2"; + gpios = <&gpx1 4 1>; + linux,code = <139>; + gpio-key,wakeup; + }; + + home { + label = "SW-TACT3"; + gpios = <&gpx1 5 1>; + linux,code = <102>; + gpio-key,wakeup; + }; + + up { + label = "SW-TACT4"; + gpios = <&gpx1 6 1>; + linux,code = <103>; + gpio-key,wakeup; + }; + + down { + label = "SW-TACT5"; + gpios = <&gpx1 7 1>; + linux,code = <108>; + gpio-key,wakeup; + }; + + back { + label = "SW-TACT6"; + gpios = <&gpx2 0 1>; + linux,code = <158>; + gpio-key,wakeup; + }; + + wakeup { + label = "SW-TACT7"; + gpios = <&gpx2 1 1>; + linux,code = <143>; + gpio-key,wakeup; + }; + }; + + hdmi { + hpd-gpio = <&gpx3 7 2>; + vdd_osc-supply = <&ldo10_reg>; + vdd_pll-supply = <&ldo8_reg>; + vdd-supply = <&ldo8_reg>; + }; + + mmc_reg: voltage-regulator { + compatible = "regulator-fixed"; + regulator-name = "VDD_33ON_2.8V"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + gpio = <&gpx1 1 1>; + enable-active-high; + }; + + reg_hdmi_en: fixedregulator@0 { + compatible = "regulator-fixed"; + regulator-name = "hdmi-en"; + }; + + fixed-rate-clocks { + xxti { + compatible = "samsung,clock-xxti"; + clock-frequency = <24000000>; + }; + }; +}; diff --git a/trunk/arch/arm/boot/dts/exynos5250-pinctrl.dtsi b/trunk/arch/arm/boot/dts/exynos5250-pinctrl.dtsi new file mode 100644 index 000000000000..d1650fb34c0a --- /dev/null +++ b/trunk/arch/arm/boot/dts/exynos5250-pinctrl.dtsi @@ -0,0 +1,783 @@ +/* + * Samsung's Exynos5250 SoC pin-mux and pin-config device tree source + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Samsung's Exynos5250 SoC pin-mux and pin-config optiosn are listed as device + * tree nodes are listed in this file. + * + * 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. +*/ + +/ { + pinctrl@11400000 { + gpa0: gpa0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpa1: gpa1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpa2: gpa2 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpb0: gpb0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpb1: gpb1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpb2: gpb2 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpb3: gpb3 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpc0: gpc0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpc1: gpc1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpc2: gpc2 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpc3: gpc3 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpd0: gpd0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpd1: gpd1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpy0: gpy0 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpy1: gpy1 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpy2: gpy2 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpy3: gpy3 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpy4: gpy4 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpy5: gpy5 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpy6: gpy6 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpc4: gpc4 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpx0: gpx0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + interrupt-parent = <&combiner>; + #interrupt-cells = <2>; + interrupts = <23 0>, <24 0>, <25 0>, <25 1>, + <26 0>, <26 1>, <27 0>, <27 1>; + }; + + gpx1: gpx1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + interrupt-parent = <&combiner>; + #interrupt-cells = <2>; + interrupts = <28 0>, <28 1>, <29 0>, <29 1>, + <30 0>, <30 1>, <31 0>, <31 1>; + }; + + gpx2: gpx2 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpx3: gpx3 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + uart0_data: uart0-data { + samsung,pins = "gpa0-0", "gpa0-1"; + samsung,pin-function = <2>; + samsung,pin-pud = <0>; + samsung,pin-drv = <0>; + }; + + uart0_fctl: uart0-fctl { + samsung,pins = "gpa0-2", "gpa0-3"; + samsung,pin-function = <2>; + samsung,pin-pud = <0>; + samaung,pin-drv = <0>; + }; + + i2c2_bus: i2c2-bus { + samsung,pins = "gpa0-6", "gpa0-7"; + samsung,pin-function = <3>; + samsung,pin-pud = <3>; + samaung,pin-drv = <0>; + }; + + i2c2_hs_bus: i2c2-hs-bus { + samsung,pins = "gpa0-6", "gpa0-7"; + samsung,pin-function = <4>; + samsung,pin-pud = <3>; + samaung,pin-drv = <0>; + }; + + uart2_data: uart2-data { + samsung,pins = "gpa1-0", "gpa1-1"; + samsung,pin-function = <2>; + samsung,pin-pud = <0>; + samsung,pin-drv = <0>; + }; + + uart2_fctl: uart2-fctl { + samsung,pins = "gpa1-2", "gpa1-3"; + samsung,pin-function = <2>; + samsung,pin-pud = <0>; + samaung,pin-drv = <0>; + }; + + i2c3_bus: i2c3-bus { + samsung,pins = "gpa1-2", "gpa1-3"; + samsung,pin-function = <3>; + samsung,pin-pud = <3>; + samaung,pin-drv = <0>; + }; + + i2c3_hs_bus: i2c3-hs-bus { + samsung,pins = "gpa1-2", "gpa1-3"; + samsung,pin-function = <4>; + samsung,pin-pud = <3>; + samaung,pin-drv = <0>; + }; + + uart3_data: uart3-data { + samsung,pins = "gpa1-4", "gpa1-4"; + samsung,pin-function = <2>; + samsung,pin-pud = <0>; + samsung,pin-drv = <0>; + }; + + spi0_bus: spi0-bus { + samsung,pins = "gpa2-0", "gpa2-2", "gpa2-3"; + samsung,pin-function = <2>; + samsung,pin-pud = <3>; + samsung,pin-drv = <0>; + }; + + i2c4_bus: i2c4-bus { + samsung,pins = "gpa2-0", "gpa2-1"; + samsung,pin-function = <3>; + samsung,pin-pud = <3>; + samaung,pin-drv = <0>; + }; + + i2c5_bus: i2c5-bus { + samsung,pins = "gpa2-2", "gpa2-3"; + samsung,pin-function = <3>; + samsung,pin-pud = <3>; + samaung,pin-drv = <0>; + }; + + spi1_bus: spi1-bus { + samsung,pins = "gpa2-4", "gpa2-6", "gpa2-7"; + samsung,pin-function = <2>; + samsung,pin-pud = <3>; + samsung,pin-drv = <0>; + }; + + i2s1_bus: i2s1-bus { + samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3", + "gpb0-4"; + samsung,pin-function = <2>; + samsung,pin-pud = <0>; + samsung,pin-drv = <0>; + }; + + pcm1_bus: pcm1-bus { + samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3", + "gpb0-4"; + samsung,pin-function = <3>; + samsung,pin-pud = <0>; + samsung,pin-drv = <0>; + }; + + ac97_bus: ac97-bus { + samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3", + "gpb0-4"; + samsung,pin-function = <4>; + samsung,pin-pud = <0>; + samsung,pin-drv = <0>; + }; + + i2s2_bus: i2s2-bus { + samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3", + "gpb1-4"; + samsung,pin-function = <2>; + samsung,pin-pud = <0>; + samsung,pin-drv = <0>; + }; + + pcm2_bus: pcm2-bus { + samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3", + "gpb1-4"; + samsung,pin-function = <3>; + samsung,pin-pud = <0>; + samsung,pin-drv = <0>; + }; + + spdif_bus: spdif-bus { + samsung,pins = "gpb1-0", "gpb1-1"; + samsung,pin-function = <4>; + samsung,pin-pud = <0>; + samsung,pin-drv = <0>; + }; + + spi2_bus: spi2-bus { + samsung,pins = "gpb1-1", "gpb1-3", "gpb1-4"; + samsung,pin-function = <5>; + samsung,pin-pud = <3>; + samsung,pin-drv = <0>; + }; + + i2c6_bus: i2c6-bus { + samsung,pins = "gpb1-3", "gpb1-4"; + samsung,pin-function = <4>; + samsung,pin-pud = <3>; + samsung,pin-drv = <0>; + }; + + i2c7_bus: i2c7-bus { + samsung,pins = "gpb2-2", "gpb2-3"; + samsung,pin-function = <3>; + samsung,pin-pud = <3>; + samsung,pin-drv = <0>; + }; + + i2c0_bus: i2c0-bus { + samsung,pins = "gpb3-0", "gpb3-1"; + samsung,pin-function = <2>; + samsung,pin-pud = <3>; + samsung,pin-drv = <0>; + }; + + i2c1_bus: i2c1-bus { + samsung,pins = "gpb3-2", "gpb3-3"; + samsung,pin-function = <2>; + samsung,pin-pud = <3>; + samsung,pin-drv = <0>; + }; + + i2c0_hs_bus: i2c0-hs-bus { + samsung,pins = "gpb3-0", "gpb3-1"; + samsung,pin-function = <4>; + samsung,pin-pud = <3>; + samaung,pin-drv = <0>; + }; + + i2c1_hs_bus: i2c1-hs-bus { + samsung,pins = "gpb3-2", "gpb3-3"; + samsung,pin-function = <4>; + samsung,pin-pud = <3>; + samaung,pin-drv = <0>; + }; + + sd0_clk: sd0-clk { + samsung,pins = "gpc0-0"; + samsung,pin-function = <2>; + samsung,pin-pud = <0>; + samsung,pin-drv = <3>; + }; + + sd0_cmd: sd0-cmd { + samsung,pins = "gpc0-1"; + samsung,pin-function = <2>; + samsung,pin-pud = <0>; + samsung,pin-drv = <3>; + }; + + sd0_cd: sd0-cd { + samsung,pins = "gpc0-2"; + samsung,pin-function = <2>; + samsung,pin-pud = <3>; + samsung,pin-drv = <3>; + }; + + sd0_bus1: sd0-bus-width1 { + samsung,pins = "gpc0-3"; + samsung,pin-function = <2>; + samsung,pin-pud = <3>; + samsung,pin-drv = <3>; + }; + + sd0_bus4: sd0-bus-width4 { + samsung,pins = "gpc0-3", "gpc0-4", "gpc0-5", "gpc0-6"; + samsung,pin-function = <2>; + samsung,pin-pud = <3>; + samsung,pin-drv = <3>; + }; + + sd0_bus8: sd0-bus-width8 { + samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3"; + samsung,pin-function = <2>; + samsung,pin-pud = <3>; + samsung,pin-drv = <3>; + }; + + sd1_clk: sd1-clk { + samsung,pins = "gpc2-0"; + samsung,pin-function = <2>; + samsung,pin-pud = <0>; + samsung,pin-drv = <3>; + }; + + sd1_cmd: sd1-cmd { + samsung,pins = "gpc2-1"; + samsung,pin-function = <2>; + samsung,pin-pud = <0>; + samsung,pin-drv = <3>; + }; + + sd1_cd: sd1-cd { + samsung,pins = "gpc2-2"; + samsung,pin-function = <2>; + samsung,pin-pud = <3>; + samsung,pin-drv = <3>; + }; + + sd1_bus1: sd1-bus-width1 { + samsung,pins = "gpc2-3"; + samsung,pin-function = <2>; + samsung,pin-pud = <3>; + samsung,pin-drv = <3>; + }; + + sd1_bus4: sd1-bus-width4 { + samsung,pins = "gpc2-3", "gpc2-4", "gpc2-5", "gpc2-6"; + samsung,pin-function = <2>; + samsung,pin-pud = <3>; + samsung,pin-drv = <3>; + }; + + sd2_clk: sd2-clk { + samsung,pins = "gpc3-0"; + samsung,pin-function = <2>; + samsung,pin-pud = <0>; + samsung,pin-drv = <3>; + }; + + sd2_cmd: sd2-cmd { + samsung,pins = "gpc3-1"; + samsung,pin-function = <2>; + samsung,pin-pud = <0>; + samsung,pin-drv = <3>; + }; + + sd2_cd: sd2-cd { + samsung,pins = "gpc3-2"; + samsung,pin-function = <2>; + samsung,pin-pud = <3>; + samsung,pin-drv = <3>; + }; + + sd2_bus1: sd2-bus-width1 { + samsung,pins = "gpc3-3"; + samsung,pin-function = <2>; + samsung,pin-pud = <3>; + samsung,pin-drv = <3>; + }; + + sd2_bus4: sd2-bus-width4 { + samsung,pins = "gpc3-3", "gpc3-4", "gpc3-5", "gpc3-6"; + samsung,pin-function = <2>; + samsung,pin-pud = <3>; + samsung,pin-drv = <3>; + }; + + sd2_bus8: sd2-bus-width8 { + samsung,pins = "gpc4-3", "gpc4-4", "gpc4-5", "gpc4-6"; + samsung,pin-function = <3>; + samsung,pin-pud = <3>; + samsung,pin-drv = <3>; + }; + + sd3_clk: sd3-clk { + samsung,pins = "gpc4-0"; + samsung,pin-function = <2>; + samsung,pin-pud = <0>; + samsung,pin-drv = <3>; + }; + + sd3_cmd: sd3-cmd { + samsung,pins = "gpc4-1"; + samsung,pin-function = <2>; + samsung,pin-pud = <0>; + samsung,pin-drv = <3>; + }; + + sd3_cd: sd3-cd { + samsung,pins = "gpc4-2"; + samsung,pin-function = <2>; + samsung,pin-pud = <3>; + samsung,pin-drv = <3>; + }; + + sd3_bus1: sd3-bus-width1 { + samsung,pins = "gpc4-3"; + samsung,pin-function = <2>; + samsung,pin-pud = <3>; + samsung,pin-drv = <3>; + }; + + sd3_bus4: sd3-bus-width4 { + samsung,pins = "gpc4-3", "gpc4-4", "gpc4-5", "gpc4-6"; + samsung,pin-function = <2>; + samsung,pin-pud = <3>; + samsung,pin-drv = <3>; + }; + + uart1_data: uart1-data { + samsung,pins = "gpd0-0", "gpd0-1"; + samsung,pin-function = <2>; + samsung,pin-pud = <0>; + samsung,pin-drv = <0>; + }; + + uart1_fctl: uart1-fctl { + samsung,pins = "gpd0-2", "gpd0-3"; + samsung,pin-function = <2>; + samsung,pin-pud = <0>; + samaung,pin-drv = <0>; + }; + }; + + pinctrl@13400000 { + gpe0: gpe0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpe1: gpe1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpf0: gpf0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpf1: gpf1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpg0: gpg0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpg1: gpg1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpg2: gpg2 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gph0: gph0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gph1: gph1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + cam_gpio_a: cam-gpio-a { + samsung,pins = "gpe0-0", "gpe0-1", "gpe0-2", "gpe0-3", + "gpe0-4", "gpe0-5", "gpe0-6", "gpe0-7", + "gpe1-0", "gpe1-1"; + samsung,pin-function = <2>; + samsung,pin-pud = <0>; + samsung,pin-drv = <0>; + }; + + cam_gpio_b: cam-gpio-b { + samsung,pins = "gpf0-0", "gpf0-1", "gpf0-2", "gpf0-3", + "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3"; + samsung,pin-function = <3>; + samsung,pin-pud = <0>; + samaung,pin-drv = <0>; + }; + + cam_i2c2_bus: cam-i2c2-bus { + samsung,pins = "gpe0-6", "gpe1-0"; + samsung,pin-function = <4>; + samsung,pin-pud = <3>; + samaung,pin-drv = <0>; + }; + + cam_spi1_bus: cam-spi1-bus { + samsung,pins = "gpe0-4", "gpe0-5", "gpf0-2", "gpf0-3"; + samsung,pin-function = <4>; + samsung,pin-pud = <0>; + samaung,pin-drv = <0>; + }; + + cam_i2c1_bus: cam-i2c1-bus { + samsung,pins = "gpf0-2", "gpf0-3"; + samsung,pin-function = <2>; + samsung,pin-pud = <3>; + samaung,pin-drv = <0>; + }; + + cam_i2c0_bus: cam-i2c0-bus { + samsung,pins = "gpf0-0", "gpf0-1"; + samsung,pin-function = <2>; + samsung,pin-pud = <3>; + samaung,pin-drv = <0>; + }; + + cam_spi0_bus: cam-spi0-bus { + samsung,pins = "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3"; + samsung,pin-function = <2>; + samsung,pin-pud = <0>; + samaung,pin-drv = <0>; + }; + + cam_bayrgb_bus: cam-bayrgb-bus { + samsung,pins = "gpg0-0", "gpg0-1", "gpg0-2", "gpg0-3", + "gpg0-4", "gpg0-5", "gpg0-6", "gpg0-7", + "gpg1-0", "gpg1-1", "gpg1-2", "gpg1-3", + "gpg1-4", "gpg1-5", "gpg1-6", "gpg1-7", + "gpg2-0", "gpg2-1"; + samsung,pin-function = <2>; + samsung,pin-pud = <0>; + samaung,pin-drv = <0>; + }; + + cam_port_a: cam-port-a { + samsung,pins = "gph0-0", "gph0-1", "gph0-2", "gph0-3", + "gph1-0", "gph1-1", "gph1-2", "gph1-3", + "gph1-4", "gph1-5", "gph1-6", "gph1-7"; + samsung,pin-function = <2>; + samsung,pin-pud = <0>; + samaung,pin-drv = <0>; + }; + }; + + pinctrl@10d10000 { + gpv0: gpv0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpv1: gpv1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpv2: gpv2 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpv3: gpv3 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpv4: gpv4 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + c2c_rxd: c2c-rxd { + samsung,pins = "gpv0-0", "gpv0-1", "gpv0-2", "gpv0-3", + "gpv0-4", "gpv0-5", "gpv0-6", "gpv0-7", + "gpv1-0", "gpv1-1", "gpv1-2", "gpv1-3", + "gpv1-4", "gpv1-5", "gpv1-6", "gpv1-7"; + samsung,pin-function = <2>; + samsung,pin-pud = <0>; + samaung,pin-drv = <0>; + }; + + c2c_txd: c2c-txd { + samsung,pins = "gpv2-0", "gpv2-1", "gpv2-2", "gpv2-3", + "gpv2-4", "gpv2-5", "gpv2-6", "gpv2-7", + "gpv3-0", "gpv3-1", "gpv3-2", "gpv3-3", + "gpv3-4", "gpv3-5", "gpv3-6", "gpv3-7"; + samsung,pin-function = <2>; + samsung,pin-pud = <0>; + samaung,pin-drv = <0>; + }; + }; + + pinctrl@03680000 { + gpz: gpz { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + i2s0_bus: i2s0-bus { + samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3", + "gpz-4", "gpz-5", "gpz-6"; + samsung,pin-function = <2>; + samsung,pin-pud = <0>; + samsung,pin-drv = <0>; + }; + }; +}; diff --git a/trunk/arch/arm/boot/dts/exynos5250-smdk5250.dts b/trunk/arch/arm/boot/dts/exynos5250-smdk5250.dts index 1b8d4106d338..3e0c792e2767 100644 --- a/trunk/arch/arm/boot/dts/exynos5250-smdk5250.dts +++ b/trunk/arch/arm/boot/dts/exynos5250-smdk5250.dts @@ -30,8 +30,6 @@ i2c@12C60000 { samsung,i2c-sda-delay = <100>; samsung,i2c-max-bus-freq = <20000>; - gpios = <&gpb3 0 2 3 0>, - <&gpb3 1 2 3 0>; eeprom@50 { compatible = "samsung,s524ad0xd1"; @@ -42,8 +40,6 @@ i2c@12C70000 { samsung,i2c-sda-delay = <100>; samsung,i2c-max-bus-freq = <20000>; - gpios = <&gpb3 2 2 3 0>, - <&gpb3 3 2 3 0>; eeprom@51 { compatible = "samsung,s524ad0xd1"; @@ -74,8 +70,6 @@ i2c@12C80000 { samsung,i2c-sda-delay = <100>; samsung,i2c-max-bus-freq = <66000>; - gpios = <&gpa0 6 3 3 0>, - <&gpa0 7 3 3 0>; hdmiddc@50 { compatible = "samsung,exynos5-hdmiddc"; @@ -122,15 +116,12 @@ samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; samsung,dw-mshc-ddr-timing = <1 2>; + pinctrl-names = "default"; + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; slot@0 { reg = <0>; bus-width = <8>; - gpios = <&gpc0 0 2 0 3>, <&gpc0 1 2 0 3>, - <&gpc1 0 2 3 3>, <&gpc1 1 2 3 3>, - <&gpc1 2 2 3 3>, <&gpc1 3 2 3 3>, - <&gpc0 3 2 3 3>, <&gpc0 4 2 3 3>, - <&gpc0 5 2 3 3>, <&gpc0 6 2 3 3>; }; }; @@ -146,17 +137,13 @@ samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; samsung,dw-mshc-ddr-timing = <1 2>; + pinctrl-names = "default"; + pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>; slot@0 { reg = <0>; bus-width = <4>; - samsung,cd-pinmux-gpio = <&gpc3 2 2 3 3>; disable-wp; - gpios = <&gpc3 0 2 0 3>, <&gpc3 1 2 0 3>, - <&gpc3 3 2 3 3>, <&gpc3 4 2 3 3>, - <&gpc3 5 2 3 3>, <&gpc3 6 2 3 3>, - <&gpc4 3 3 3 3>, <&gpc4 3 3 3 3>, - <&gpc4 5 3 3 3>, <&gpc4 6 3 3 3>; }; }; @@ -169,10 +156,6 @@ }; spi_1: spi@12d30000 { - gpios = <&gpa2 4 2 3 0>, - <&gpa2 6 2 3 0>, - <&gpa2 7 2 3 0>; - w25q80bw@0 { #address-cells = <1>; #size-cells = <1>; @@ -181,7 +164,7 @@ spi-max-frequency = <1000000>; controller-data { - cs-gpio = <&gpa2 5 1 0 3>; + cs-gpio = <&gpa2 5 0>; samsung,spi-feedback-delay = <0>; }; @@ -203,7 +186,7 @@ }; hdmi { - hpd-gpio = <&gpx3 7 0xf 1 3>; + hpd-gpio = <&gpx3 7 0>; }; codec@11000000 { @@ -212,9 +195,7 @@ }; i2s0: i2s@03830000 { - gpios = <&gpz 0 2 0 0>, <&gpz 1 2 0 0>, <&gpz 2 2 0 0>, - <&gpz 3 2 0 0>, <&gpz 4 2 0 0>, <&gpz 5 2 0 0>, - <&gpz 6 2 0 0>; + status = "okay"; }; i2s1: i2s@12D60000 { @@ -231,4 +212,40 @@ samsung,i2s-controller = <&i2s0>; samsung,audio-codec = <&wm8994>; }; + + usb@12110000 { + samsung,vbus-gpio = <&gpx2 6 0>; + }; + + dp-controller { + samsung,color-space = <0>; + samsung,dynamic-range = <0>; + samsung,ycbcr-coeff = <0>; + samsung,color-depth = <1>; + samsung,link-rate = <0x0a>; + samsung,lane-count = <4>; + }; + + display-timings { + native-mode = <&timing0>; + timing0: timing@0 { + /* 1280x800 */ + clock-frequency = <50000>; + hactive = <1280>; + vactive = <800>; + hfront-porch = <4>; + hback-porch = <4>; + hsync-len = <4>; + vback-porch = <4>; + vfront-porch = <4>; + vsync-len = <4>; + }; + }; + + fixed-rate-clocks { + xxti { + compatible = "samsung,clock-xxti"; + clock-frequency = <24000000>; + }; + }; }; diff --git a/trunk/arch/arm/boot/dts/exynos5250-snow.dts b/trunk/arch/arm/boot/dts/exynos5250-snow.dts index 17dd951c1cd2..d449feb7e143 100644 --- a/trunk/arch/arm/boot/dts/exynos5250-snow.dts +++ b/trunk/arch/arm/boot/dts/exynos5250-snow.dts @@ -16,12 +16,31 @@ model = "Google Snow"; compatible = "google,snow", "samsung,exynos5250"; + aliases { + i2c104 = &i2c_104; + }; + + pinctrl@11400000 { + sd3_clk: sd3-clk { + samsung,pin-drv = <0>; + }; + + sd3_cmd: sd3-cmd { + samsung,pin-pud = <3>; + samsung,pin-drv = <0>; + }; + + sd3_bus4: sd3-bus-width4 { + samsung,pin-drv = <0>; + }; + }; + gpio-keys { compatible = "gpio-keys"; lid-switch { label = "Lid"; - gpios = <&gpx3 5 0 0x10000 0>; + gpios = <&gpx3 5 1>; linux,input-type = <5>; /* EV_SW */ linux,code = <0>; /* SW_LID */ debounce-interval = <1>; @@ -29,15 +48,148 @@ }; }; + i2c-arbitrator { + compatible = "i2c-arb-gpio-challenge"; + #address-cells = <1>; + #size-cells = <0>; + + i2c-parent = <&{/i2c@12CA0000}>; + + our-claim-gpio = <&gpf0 3 1>; + their-claim-gpios = <&gpe0 4 1>; + slew-delay-us = <10>; + wait-retry-us = <3000>; + wait-free-us = <50000>; + + /* Use ID 104 as a hint that we're on physical bus 4 */ + i2c_104: i2c@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + battery: sbs-battery@b { + compatible = "sbs,sbs-battery"; + reg = <0xb>; + sbs,poll-retry-count = <1>; + }; + + ec: embedded-controller { + compatible = "google,cros-ec-i2c"; + reg = <0x1e>; + interrupts = <6 0>; + interrupt-parent = <&gpx1>; + wakeup-source; + + keyboard-controller { + compatible = "google,cros-ec-keyb"; + keypad,num-rows = <8>; + keypad,num-columns = <13>; + google,needs-ghost-filter; + linux,keymap = <0x0001003a /* CAPSLK */ + 0x0002003b /* F1 */ + 0x00030030 /* B */ + 0x00040044 /* F10 */ + 0x00060031 /* N */ + 0x0008000d /* = */ + 0x000a0064 /* R_ALT */ + + 0x01010001 /* ESC */ + 0x0102003e /* F4 */ + 0x01030022 /* G */ + 0x01040041 /* F7 */ + 0x01060023 /* H */ + 0x01080028 /* ' */ + 0x01090043 /* F9 */ + 0x010b000e /* BKSPACE */ + + 0x0200001d /* L_CTRL */ + 0x0201000f /* TAB */ + 0x0202003d /* F3 */ + 0x02030014 /* T */ + 0x02040040 /* F6 */ + 0x0205001b /* ] */ + 0x02060015 /* Y */ + 0x02070056 /* 102ND */ + 0x0208001a /* [ */ + 0x02090042 /* F8 */ + + 0x03010029 /* GRAVE */ + 0x0302003c /* F2 */ + 0x03030006 /* 5 */ + 0x0304003f /* F5 */ + 0x03060007 /* 6 */ + 0x0308000c /* - */ + 0x030b002b /* \ */ + + 0x04000061 /* R_CTRL */ + 0x0401001e /* A */ + 0x04020020 /* D */ + 0x04030021 /* F */ + 0x0404001f /* S */ + 0x04050025 /* K */ + 0x04060024 /* J */ + 0x04080027 /* ; */ + 0x04090026 /* L */ + 0x040b001c /* ENTER */ + + 0x0501002c /* Z */ + 0x0502002e /* C */ + 0x0503002f /* V */ + 0x0504002d /* X */ + 0x05050033 /* , */ + 0x05060032 /* M */ + 0x0507002a /* L_SHIFT */ + 0x05080035 /* / */ + 0x05090034 /* . */ + 0x050B0039 /* SPACE */ + + 0x06010002 /* 1 */ + 0x06020004 /* 3 */ + 0x06030005 /* 4 */ + 0x06040003 /* 2 */ + 0x06050009 /* 8 */ + 0x06060008 /* 7 */ + 0x0608000b /* 0 */ + 0x0609000a /* 9 */ + 0x060a0038 /* L_ALT */ + 0x060b006c /* DOWN */ + 0x060c006a /* RIGHT */ + + 0x07010010 /* Q */ + 0x07020012 /* E */ + 0x07030013 /* R */ + 0x07040011 /* W */ + 0x07050017 /* I */ + 0x07060016 /* U */ + 0x07070036 /* R_SHIFT */ + 0x07080019 /* P */ + 0x07090018 /* O */ + 0x070b0067 /* UP */ + 0x070c0069>; /* LEFT */ + }; + }; + }; + }; + /* * On Snow we've got SIP WiFi and so can keep drive strengths low to * reduce EMI. */ dwmmc3@12230000 { slot@0 { - gpios = <&gpc4 0 2 0 0>, <&gpc4 1 2 3 0>, - <&gpc4 3 2 3 0>, <&gpc4 4 2 3 0>, - <&gpc4 5 2 3 0>, <&gpc4 6 2 3 0>; + pinctrl-names = "default"; + pinctrl-0 = <&sd3_clk &sd3_cmd &sd3_bus4>; + }; + }; + + usb@12110000 { + samsung,vbus-gpio = <&gpx1 1 0>; + }; + + fixed-rate-clocks { + xxti { + compatible = "samsung,clock-xxti"; + clock-frequency = <24000000>; }; }; }; diff --git a/trunk/arch/arm/boot/dts/exynos5250.dtsi b/trunk/arch/arm/boot/dts/exynos5250.dtsi index b1ac73e21c80..98dfc3ea5c0b 100644 --- a/trunk/arch/arm/boot/dts/exynos5250.dtsi +++ b/trunk/arch/arm/boot/dts/exynos5250.dtsi @@ -18,6 +18,7 @@ */ /include/ "skeleton.dtsi" +/include/ "exynos5250-pinctrl.dtsi" / { compatible = "samsung,exynos5250"; @@ -44,13 +45,50 @@ i2c6 = &i2c_6; i2c7 = &i2c_7; i2c8 = &i2c_8; + pinctrl0 = &pinctrl_0; + pinctrl1 = &pinctrl_1; + pinctrl2 = &pinctrl_2; + pinctrl3 = &pinctrl_3; + }; + + chipid@10000000 { + compatible = "samsung,exynos4210-chipid"; + reg = <0x10000000 0x100>; + }; + + pd_gsc: gsc-power-domain@0x10044000 { + compatible = "samsung,exynos4210-pd"; + reg = <0x10044000 0x20>; + }; + + pd_mfc: mfc-power-domain@0x10044040 { + compatible = "samsung,exynos4210-pd"; + reg = <0x10044040 0x20>; + }; + + clock: clock-controller@0x10010000 { + compatible = "samsung,exynos5250-clock"; + reg = <0x10010000 0x30000>; + #clock-cells = <1>; }; gic:interrupt-controller@10481000 { - compatible = "arm,cortex-a9-gic"; + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic"; #interrupt-cells = <3>; interrupt-controller; - reg = <0x10481000 0x1000>, <0x10482000 0x2000>; + reg = <0x10481000 0x1000>, + <0x10482000 0x1000>, + <0x10484000 0x2000>, + <0x10486000 0x2000>; + interrupts = <1 9 0xf04>; + }; + + timer { + compatible = "arm,armv7-timer"; + interrupts = <1 13 0xf08>, + <1 14 0xf08>, + <1 11 0xf08>, + <1 10 0xf08>; }; combiner:interrupt-controller@10440000 { @@ -69,58 +107,136 @@ <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>; }; + mct@101C0000 { + compatible = "samsung,exynos4210-mct"; + reg = <0x101C0000 0x800>; + interrupt-controller; + #interrups-cells = <2>; + interrupt-parent = <&mct_map>; + interrupts = <0 0>, <1 0>, <2 0>, <3 0>, + <4 0>, <5 0>; + clocks = <&clock 1>, <&clock 335>; + clock-names = "fin_pll", "mct"; + + mct_map: mct-map { + #interrupt-cells = <2>; + #address-cells = <0>; + #size-cells = <0>; + interrupt-map = <0x0 0 &combiner 23 3>, + <0x1 0 &combiner 23 4>, + <0x2 0 &combiner 25 2>, + <0x3 0 &combiner 25 3>, + <0x4 0 &gic 0 120 0>, + <0x5 0 &gic 0 121 0>; + }; + }; + + pmu { + compatible = "arm,cortex-a15-pmu"; + interrupt-parent = <&combiner>; + interrupts = <1 2>, <22 4>; + }; + + pinctrl_0: pinctrl@11400000 { + compatible = "samsung,exynos5250-pinctrl"; + reg = <0x11400000 0x1000>; + interrupts = <0 46 0>; + + wakup_eint: wakeup-interrupt-controller { + compatible = "samsung,exynos4210-wakeup-eint"; + interrupt-parent = <&gic>; + interrupts = <0 32 0>; + }; + }; + + pinctrl_1: pinctrl@13400000 { + compatible = "samsung,exynos5250-pinctrl"; + reg = <0x13400000 0x1000>; + interrupts = <0 45 0>; + }; + + pinctrl_2: pinctrl@10d10000 { + compatible = "samsung,exynos5250-pinctrl"; + reg = <0x10d10000 0x1000>; + interrupts = <0 50 0>; + }; + + pinctrl_3: pinctrl@03680000 { + compatible = "samsung,exynos5250-pinctrl"; + reg = <0x0368000 0x1000>; + interrupts = <0 47 0>; + }; + watchdog { compatible = "samsung,s3c2410-wdt"; reg = <0x101D0000 0x100>; interrupts = <0 42 0>; + clocks = <&clock 336>; + clock-names = "watchdog"; }; codec@11000000 { compatible = "samsung,mfc-v6"; reg = <0x11000000 0x10000>; interrupts = <0 96 0>; + samsung,power-domain = <&pd_mfc>; }; rtc { compatible = "samsung,s3c6410-rtc"; reg = <0x101E0000 0x100>; interrupts = <0 43 0>, <0 44 0>; + clocks = <&clock 337>; + clock-names = "rtc"; + status = "disabled"; }; tmu@10060000 { compatible = "samsung,exynos5250-tmu"; reg = <0x10060000 0x100>; interrupts = <0 65 0>; + clocks = <&clock 338>; + clock-names = "tmu_apbif"; }; serial@12C00000 { compatible = "samsung,exynos4210-uart"; reg = <0x12C00000 0x100>; interrupts = <0 51 0>; + clocks = <&clock 289>, <&clock 146>; + clock-names = "uart", "clk_uart_baud0"; }; serial@12C10000 { compatible = "samsung,exynos4210-uart"; reg = <0x12C10000 0x100>; interrupts = <0 52 0>; + clocks = <&clock 290>, <&clock 147>; + clock-names = "uart", "clk_uart_baud0"; }; serial@12C20000 { compatible = "samsung,exynos4210-uart"; reg = <0x12C20000 0x100>; interrupts = <0 53 0>; + clocks = <&clock 291>, <&clock 148>; + clock-names = "uart", "clk_uart_baud0"; }; serial@12C30000 { compatible = "samsung,exynos4210-uart"; reg = <0x12C30000 0x100>; interrupts = <0 54 0>; + clocks = <&clock 292>, <&clock 149>; + clock-names = "uart", "clk_uart_baud0"; }; sata@122F0000 { compatible = "samsung,exynos5-sata-ahci"; reg = <0x122F0000 0x1ff>; interrupts = <0 115 0>; + clocks = <&clock 277>, <&clock 143>; + clock-names = "sata", "sclk_sata"; }; sata-phy@12170000 { @@ -134,6 +250,10 @@ interrupts = <0 56 0>; #address-cells = <1>; #size-cells = <0>; + clocks = <&clock 294>; + clock-names = "i2c"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_bus>; }; i2c_1: i2c@12C70000 { @@ -142,6 +262,10 @@ interrupts = <0 57 0>; #address-cells = <1>; #size-cells = <0>; + clocks = <&clock 295>; + clock-names = "i2c"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_bus>; }; i2c_2: i2c@12C80000 { @@ -150,6 +274,10 @@ interrupts = <0 58 0>; #address-cells = <1>; #size-cells = <0>; + clocks = <&clock 296>; + clock-names = "i2c"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_bus>; }; i2c_3: i2c@12C90000 { @@ -158,6 +286,10 @@ interrupts = <0 59 0>; #address-cells = <1>; #size-cells = <0>; + clocks = <&clock 297>; + clock-names = "i2c"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c3_bus>; }; i2c_4: i2c@12CA0000 { @@ -166,6 +298,10 @@ interrupts = <0 60 0>; #address-cells = <1>; #size-cells = <0>; + clocks = <&clock 298>; + clock-names = "i2c"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c4_bus>; }; i2c_5: i2c@12CB0000 { @@ -174,6 +310,10 @@ interrupts = <0 61 0>; #address-cells = <1>; #size-cells = <0>; + clocks = <&clock 299>; + clock-names = "i2c"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c5_bus>; }; i2c_6: i2c@12CC0000 { @@ -182,6 +322,10 @@ interrupts = <0 62 0>; #address-cells = <1>; #size-cells = <0>; + clocks = <&clock 300>; + clock-names = "i2c"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c6_bus>; }; i2c_7: i2c@12CD0000 { @@ -190,6 +334,10 @@ interrupts = <0 63 0>; #address-cells = <1>; #size-cells = <0>; + clocks = <&clock 301>; + clock-names = "i2c"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c7_bus>; }; i2c_8: i2c@12CE0000 { @@ -198,6 +346,8 @@ interrupts = <0 64 0>; #address-cells = <1>; #size-cells = <0>; + clocks = <&clock 302>; + clock-names = "i2c"; }; i2c@121D0000 { @@ -205,6 +355,8 @@ reg = <0x121D0000 0x100>; #address-cells = <1>; #size-cells = <0>; + clocks = <&clock 288>; + clock-names = "i2c"; }; spi_0: spi@12d20000 { @@ -216,6 +368,10 @@ dma-names = "tx", "rx"; #address-cells = <1>; #size-cells = <0>; + clocks = <&clock 304>, <&clock 154>; + clock-names = "spi", "spi_busclk0"; + pinctrl-names = "default"; + pinctrl-0 = <&spi0_bus>; }; spi_1: spi@12d30000 { @@ -227,6 +383,10 @@ dma-names = "tx", "rx"; #address-cells = <1>; #size-cells = <0>; + clocks = <&clock 305>, <&clock 155>; + clock-names = "spi", "spi_busclk0"; + pinctrl-names = "default"; + pinctrl-0 = <&spi1_bus>; }; spi_2: spi@12d40000 { @@ -238,6 +398,10 @@ dma-names = "tx", "rx"; #address-cells = <1>; #size-cells = <0>; + clocks = <&clock 306>, <&clock 156>; + clock-names = "spi", "spi_busclk0"; + pinctrl-names = "default"; + pinctrl-0 = <&spi2_bus>; }; dwmmc_0: dwmmc0@12200000 { @@ -246,6 +410,8 @@ interrupts = <0 75 0>; #address-cells = <1>; #size-cells = <0>; + clocks = <&clock 280>, <&clock 139>; + clock-names = "biu", "ciu"; }; dwmmc_1: dwmmc1@12210000 { @@ -254,6 +420,8 @@ interrupts = <0 76 0>; #address-cells = <1>; #size-cells = <0>; + clocks = <&clock 281>, <&clock 140>; + clock-names = "biu", "ciu"; }; dwmmc_2: dwmmc2@12220000 { @@ -262,6 +430,8 @@ interrupts = <0 77 0>; #address-cells = <1>; #size-cells = <0>; + clocks = <&clock 282>, <&clock 141>; + clock-names = "biu", "ciu"; }; dwmmc_3: dwmmc3@12230000 { @@ -270,6 +440,8 @@ interrupts = <0 78 0>; #address-cells = <1>; #size-cells = <0>; + clocks = <&clock 283>, <&clock 142>; + clock-names = "biu", "ciu"; }; i2s0: i2s@03830000 { @@ -283,6 +455,8 @@ samsung,supports-rstclr; samsung,supports-secdai; samsung,idma-addr = <0x03000000>; + pinctrl-names = "default"; + pinctrl-0 = <&i2s0_bus>; }; i2s1: i2s@12D60000 { @@ -291,6 +465,8 @@ dmas = <&pdma1 12 &pdma1 11>; dma-names = "tx", "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&i2s1_bus>; }; i2s2: i2s@12D70000 { @@ -299,6 +475,26 @@ dmas = <&pdma0 12 &pdma0 11>; dma-names = "tx", "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&i2s2_bus>; + }; + + usb@12110000 { + compatible = "samsung,exynos4210-ehci"; + reg = <0x12110000 0x100>; + interrupts = <0 71 0>; + + clocks = <&clock 285>; + clock-names = "usbhost"; + }; + + usb@12120000 { + compatible = "samsung,exynos4210-ohci"; + reg = <0x12120000 0x100>; + interrupts = <0 71 0>; + + clocks = <&clock 285>; + clock-names = "usbhost"; }; amba { @@ -312,6 +508,8 @@ compatible = "arm,pl330", "arm,primecell"; reg = <0x121A0000 0x1000>; interrupts = <0 34 0>; + clocks = <&clock 275>; + clock-names = "apb_pclk"; #dma-cells = <1>; #dma-channels = <8>; #dma-requests = <32>; @@ -321,6 +519,8 @@ compatible = "arm,pl330", "arm,primecell"; reg = <0x121B0000 0x1000>; interrupts = <0 35 0>; + clocks = <&clock 276>; + clock-names = "apb_pclk"; #dma-cells = <1>; #dma-channels = <8>; #dma-requests = <32>; @@ -330,6 +530,8 @@ compatible = "arm,pl330", "arm,primecell"; reg = <0x10800000 0x1000>; interrupts = <0 33 0>; + clocks = <&clock 271>; + clock-names = "apb_pclk"; #dma-cells = <1>; #dma-channels = <8>; #dma-requests = <1>; @@ -339,287 +541,58 @@ compatible = "arm,pl330", "arm,primecell"; reg = <0x11C10000 0x1000>; interrupts = <0 124 0>; + clocks = <&clock 271>; + clock-names = "apb_pclk"; #dma-cells = <1>; #dma-channels = <8>; #dma-requests = <1>; }; }; - gpio-controllers { - #address-cells = <1>; - #size-cells = <1>; - gpio-controller; - ranges; - - gpa0: gpio-controller@11400000 { - compatible = "samsung,exynos4-gpio"; - reg = <0x11400000 0x20>; - #gpio-cells = <4>; - }; - - gpa1: gpio-controller@11400020 { - compatible = "samsung,exynos4-gpio"; - reg = <0x11400020 0x20>; - #gpio-cells = <4>; - }; - - gpa2: gpio-controller@11400040 { - compatible = "samsung,exynos4-gpio"; - reg = <0x11400040 0x20>; - #gpio-cells = <4>; - }; - - gpb0: gpio-controller@11400060 { - compatible = "samsung,exynos4-gpio"; - reg = <0x11400060 0x20>; - #gpio-cells = <4>; - }; - - gpb1: gpio-controller@11400080 { - compatible = "samsung,exynos4-gpio"; - reg = <0x11400080 0x20>; - #gpio-cells = <4>; - }; - - gpb2: gpio-controller@114000A0 { - compatible = "samsung,exynos4-gpio"; - reg = <0x114000A0 0x20>; - #gpio-cells = <4>; - }; - - gpb3: gpio-controller@114000C0 { - compatible = "samsung,exynos4-gpio"; - reg = <0x114000C0 0x20>; - #gpio-cells = <4>; - }; - - gpc0: gpio-controller@114000E0 { - compatible = "samsung,exynos4-gpio"; - reg = <0x114000E0 0x20>; - #gpio-cells = <4>; - }; - - gpc1: gpio-controller@11400100 { - compatible = "samsung,exynos4-gpio"; - reg = <0x11400100 0x20>; - #gpio-cells = <4>; - }; - - gpc2: gpio-controller@11400120 { - compatible = "samsung,exynos4-gpio"; - reg = <0x11400120 0x20>; - #gpio-cells = <4>; - }; - - gpc3: gpio-controller@11400140 { - compatible = "samsung,exynos4-gpio"; - reg = <0x11400140 0x20>; - #gpio-cells = <4>; - }; - - gpc4: gpio-controller@114002E0 { - compatible = "samsung,exynos4-gpio"; - reg = <0x114002E0 0x20>; - #gpio-cells = <4>; - }; - - gpd0: gpio-controller@11400160 { - compatible = "samsung,exynos4-gpio"; - reg = <0x11400160 0x20>; - #gpio-cells = <4>; - }; - - gpd1: gpio-controller@11400180 { - compatible = "samsung,exynos4-gpio"; - reg = <0x11400180 0x20>; - #gpio-cells = <4>; - }; - - gpy0: gpio-controller@114001A0 { - compatible = "samsung,exynos4-gpio"; - reg = <0x114001A0 0x20>; - #gpio-cells = <4>; - }; - - gpy1: gpio-controller@114001C0 { - compatible = "samsung,exynos4-gpio"; - reg = <0x114001C0 0x20>; - #gpio-cells = <4>; - }; - - gpy2: gpio-controller@114001E0 { - compatible = "samsung,exynos4-gpio"; - reg = <0x114001E0 0x20>; - #gpio-cells = <4>; - }; - - gpy3: gpio-controller@11400200 { - compatible = "samsung,exynos4-gpio"; - reg = <0x11400200 0x20>; - #gpio-cells = <4>; - }; - - gpy4: gpio-controller@11400220 { - compatible = "samsung,exynos4-gpio"; - reg = <0x11400220 0x20>; - #gpio-cells = <4>; - }; - - gpy5: gpio-controller@11400240 { - compatible = "samsung,exynos4-gpio"; - reg = <0x11400240 0x20>; - #gpio-cells = <4>; - }; - - gpy6: gpio-controller@11400260 { - compatible = "samsung,exynos4-gpio"; - reg = <0x11400260 0x20>; - #gpio-cells = <4>; - }; - - gpx0: gpio-controller@11400C00 { - compatible = "samsung,exynos4-gpio"; - reg = <0x11400C00 0x20>; - #gpio-cells = <4>; - }; - - gpx1: gpio-controller@11400C20 { - compatible = "samsung,exynos4-gpio"; - reg = <0x11400C20 0x20>; - #gpio-cells = <4>; - }; - - gpx2: gpio-controller@11400C40 { - compatible = "samsung,exynos4-gpio"; - reg = <0x11400C40 0x20>; - #gpio-cells = <4>; - }; - - gpx3: gpio-controller@11400C60 { - compatible = "samsung,exynos4-gpio"; - reg = <0x11400C60 0x20>; - #gpio-cells = <4>; - }; - - gpe0: gpio-controller@13400000 { - compatible = "samsung,exynos4-gpio"; - reg = <0x13400000 0x20>; - #gpio-cells = <4>; - }; - - gpe1: gpio-controller@13400020 { - compatible = "samsung,exynos4-gpio"; - reg = <0x13400020 0x20>; - #gpio-cells = <4>; - }; - - gpf0: gpio-controller@13400040 { - compatible = "samsung,exynos4-gpio"; - reg = <0x13400040 0x20>; - #gpio-cells = <4>; - }; - - gpf1: gpio-controller@13400060 { - compatible = "samsung,exynos4-gpio"; - reg = <0x13400060 0x20>; - #gpio-cells = <4>; - }; - - gpg0: gpio-controller@13400080 { - compatible = "samsung,exynos4-gpio"; - reg = <0x13400080 0x20>; - #gpio-cells = <4>; - }; - - gpg1: gpio-controller@134000A0 { - compatible = "samsung,exynos4-gpio"; - reg = <0x134000A0 0x20>; - #gpio-cells = <4>; - }; - - gpg2: gpio-controller@134000C0 { - compatible = "samsung,exynos4-gpio"; - reg = <0x134000C0 0x20>; - #gpio-cells = <4>; - }; - - gph0: gpio-controller@134000E0 { - compatible = "samsung,exynos4-gpio"; - reg = <0x134000E0 0x20>; - #gpio-cells = <4>; - }; - - gph1: gpio-controller@13400100 { - compatible = "samsung,exynos4-gpio"; - reg = <0x13400100 0x20>; - #gpio-cells = <4>; - }; - - gpv0: gpio-controller@10D10000 { - compatible = "samsung,exynos4-gpio"; - reg = <0x10D10000 0x20>; - #gpio-cells = <4>; - }; - - gpv1: gpio-controller@10D10020 { - compatible = "samsung,exynos4-gpio"; - reg = <0x10D10020 0x20>; - #gpio-cells = <4>; - }; - - gpv2: gpio-controller@10D10040 { - compatible = "samsung,exynos4-gpio"; - reg = <0x10D10060 0x20>; - #gpio-cells = <4>; - }; - - gpv3: gpio-controller@10D10060 { - compatible = "samsung,exynos4-gpio"; - reg = <0x10D10080 0x20>; - #gpio-cells = <4>; - }; - - gpv4: gpio-controller@10D10080 { - compatible = "samsung,exynos4-gpio"; - reg = <0x10D100C0 0x20>; - #gpio-cells = <4>; - }; - - gpz: gpio-controller@03860000 { - compatible = "samsung,exynos4-gpio"; - reg = <0x03860000 0x20>; - #gpio-cells = <4>; - }; - }; - gsc_0: gsc@0x13e00000 { compatible = "samsung,exynos5-gsc"; reg = <0x13e00000 0x1000>; interrupts = <0 85 0>; + samsung,power-domain = <&pd_gsc>; + clocks = <&clock 256>; + clock-names = "gscl"; }; gsc_1: gsc@0x13e10000 { compatible = "samsung,exynos5-gsc"; reg = <0x13e10000 0x1000>; interrupts = <0 86 0>; + samsung,power-domain = <&pd_gsc>; + clocks = <&clock 257>; + clock-names = "gscl"; }; gsc_2: gsc@0x13e20000 { compatible = "samsung,exynos5-gsc"; reg = <0x13e20000 0x1000>; interrupts = <0 87 0>; + samsung,power-domain = <&pd_gsc>; + clocks = <&clock 258>; + clock-names = "gscl"; }; gsc_3: gsc@0x13e30000 { compatible = "samsung,exynos5-gsc"; reg = <0x13e30000 0x1000>; interrupts = <0 88 0>; + samsung,power-domain = <&pd_gsc>; + clocks = <&clock 259>; + clock-names = "gscl"; }; hdmi { compatible = "samsung,exynos5-hdmi"; reg = <0x14530000 0x70000>; interrupts = <0 95 0>; + clocks = <&clock 333>, <&clock 136>, <&clock 137>, + <&clock 333>, <&clock 333>; + clock-names = "hdmi", "sclk_hdmi", "sclk_pixel", + "sclk_hdmiphy", "hdmiphy"; }; mixer { @@ -627,4 +600,28 @@ reg = <0x14450000 0x10000>; interrupts = <0 94 0>; }; + + dp-controller { + compatible = "samsung,exynos5-dp"; + reg = <0x145b0000 0x1000>; + interrupts = <10 3>; + interrupt-parent = <&combiner>; + #address-cells = <1>; + #size-cells = <0>; + + dptx-phy { + reg = <0x10040720>; + samsung,enable-mask = <1>; + }; + }; + + fimd { + compatible = "samsung,exynos5250-fimd"; + interrupt-parent = <&combiner>; + reg = <0x14400000 0x40000>; + interrupt-names = "fifo", "vsync", "lcd_sys"; + interrupts = <18 4>, <18 5>, <18 6>; + clocks = <&clock 133>, <&clock 339>; + clock-names = "sclk_fimd", "fimd"; + }; }; diff --git a/trunk/arch/arm/boot/dts/exynos5440-sd5v1.dts b/trunk/arch/arm/boot/dts/exynos5440-sd5v1.dts new file mode 100644 index 000000000000..ef747b52b674 --- /dev/null +++ b/trunk/arch/arm/boot/dts/exynos5440-sd5v1.dts @@ -0,0 +1,39 @@ +/* + * SAMSUNG SD5v1 board device tree source + * + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +/dts-v1/; +/include/ "exynos5440.dtsi" + +/ { + model = "SAMSUNG SD5v1 board based on EXYNOS5440"; + compatible = "samsung,sd5v1", "samsung,exynos5440"; + + chosen { + bootargs = "root=/dev/sda2 rw rootwait ignore_loglevel early_printk no_console_suspend mem=2048M@0x80000000 console=ttySAC0,115200"; + }; + + fixed-rate-clocks { + xtal { + compatible = "samsung,clock-xtal"; + clock-frequency = <50000000>; + }; + }; + + gmac: ethernet@00230000 { + fixed_phy; + phy_addr = <1>; + }; + + spi { + status = "disabled"; + }; + +}; diff --git a/trunk/arch/arm/boot/dts/exynos5440-ssdk5440.dts b/trunk/arch/arm/boot/dts/exynos5440-ssdk5440.dts index 81e2c964a900..d55042beb5c5 100644 --- a/trunk/arch/arm/boot/dts/exynos5440-ssdk5440.dts +++ b/trunk/arch/arm/boot/dts/exynos5440-ssdk5440.dts @@ -16,31 +16,18 @@ model = "SAMSUNG SSDK5440 board based on EXYNOS5440"; compatible = "samsung,ssdk5440", "samsung,exynos5440"; - memory { - reg = <0x80000000 0x80000000>; - }; - chosen { - bootargs = "root=/dev/ram0 rw ramdisk=8192 initrd=0x81000000,8M console=ttySAC0,115200 init=/linuxrc"; + bootargs = "root=/dev/sda2 rw rootwait ignore_loglevel early_printk no_console_suspend mem=2048M@0x80000000 console=ttySAC0,115200"; }; spi { status = "disabled"; }; - i2c@F0000 { - status = "disabled"; - }; - - i2c@100000 { - status = "disabled"; - }; - - watchdog { - status = "disabled"; - }; - - rtc { - status = "disabled"; + fixed-rate-clocks { + xtal { + compatible = "samsung,clock-xtal"; + clock-frequency = <50000000>; + }; }; }; diff --git a/trunk/arch/arm/boot/dts/exynos5440.dtsi b/trunk/arch/arm/boot/dts/exynos5440.dtsi index 9a99755920c0..f6b1c8973845 100644 --- a/trunk/arch/arm/boot/dts/exynos5440.dtsi +++ b/trunk/arch/arm/boot/dts/exynos5440.dtsi @@ -16,63 +16,89 @@ interrupt-parent = <&gic>; + clock: clock-controller@0x160000 { + compatible = "samsung,exynos5440-clock"; + reg = <0x160000 0x1000>; + #clock-cells = <1>; + }; + gic:interrupt-controller@2E0000 { compatible = "arm,cortex-a15-gic"; #interrupt-cells = <3>; interrupt-controller; - reg = <0x2E1000 0x1000>, <0x2E2000 0x1000>; + reg = <0x2E1000 0x1000>, + <0x2E2000 0x1000>, + <0x2E4000 0x2000>, + <0x2E6000 0x2000>; + interrupts = <1 9 0xf04>; }; cpus { + #address-cells = <1>; + #size-cells = <0>; + cpu@0 { compatible = "arm,cortex-a15"; - timer { - compatible = "arm,armv7-timer"; - interrupts = <1 13 0xf08>; - clock-frequency = <1000000>; - }; + reg = <0>; }; cpu@1 { compatible = "arm,cortex-a15"; - timer { - compatible = "arm,armv7-timer"; - interrupts = <1 14 0xf08>; - clock-frequency = <1000000>; - }; + reg = <1>; }; cpu@2 { compatible = "arm,cortex-a15"; - timer { - compatible = "arm,armv7-timer"; - interrupts = <1 14 0xf08>; - clock-frequency = <1000000>; - }; + reg = <2>; }; cpu@3 { compatible = "arm,cortex-a15"; - timer { - compatible = "arm,armv7-timer"; - interrupts = <1 14 0xf08>; - clock-frequency = <1000000>; - }; + reg = <3>; }; }; - common { - compatible = "samsung,exynos5440"; + arm-pmu { + compatible = "arm,cortex-a15-pmu", "arm,cortex-a9-pmu"; + interrupts = <0 52 4>, + <0 53 4>, + <0 54 4>, + <0 55 4>; + }; + + timer { + compatible = "arm,cortex-a15-timer", + "arm,armv7-timer"; + interrupts = <1 13 0xf08>, + <1 14 0xf08>, + <1 11 0xf08>, + <1 10 0xf08>; + clock-frequency = <50000000>; + }; + cpufreq@160000 { + compatible = "samsung,exynos5440-cpufreq"; + reg = <0x160000 0x1000>; + interrupts = <0 57 0>; + operating-points = < + /* KHz uV */ + 1200000 1025000 + 1000000 975000 + 800000 925000 + >; }; serial@B0000 { compatible = "samsung,exynos4210-uart"; reg = <0xB0000 0x1000>; interrupts = <0 2 0>; + clocks = <&clock 21>, <&clock 21>; + clock-names = "uart", "clk_uart_baud0"; }; serial@C0000 { compatible = "samsung,exynos4210-uart"; reg = <0xC0000 0x1000>; interrupts = <0 3 0>; + clocks = <&clock 21>, <&clock 21>; + clock-names = "uart", "clk_uart_baud0"; }; spi { @@ -83,11 +109,15 @@ rx-dma-channel = <&pdma0 4>; /* preliminary */ #address-cells = <1>; #size-cells = <0>; + clocks = <&clock 21>, <&clock 16>; + clock-names = "spi", "spi_busclk0"; }; pinctrl { compatible = "samsung,exynos5440-pinctrl"; reg = <0xE0000 0x1000>; + interrupts = <0 37 0>, <0 38 0>, <0 39 0>, <0 40 0>, + <0 41 0>, <0 42 0>, <0 43 0>, <0 44 0>; interrupt-controller; #interrupt-cells = <2>; #gpio-cells = <2>; @@ -110,25 +140,42 @@ }; i2c@F0000 { - compatible = "samsung,s3c2440-i2c"; + compatible = "samsung,exynos5440-i2c"; reg = <0xF0000 0x1000>; interrupts = <0 5 0>; #address-cells = <1>; #size-cells = <0>; + clocks = <&clock 21>; + clock-names = "i2c"; }; i2c@100000 { - compatible = "samsung,s3c2440-i2c"; + compatible = "samsung,exynos5440-i2c"; reg = <0x100000 0x1000>; interrupts = <0 6 0>; #address-cells = <1>; #size-cells = <0>; + clocks = <&clock 21>; + clock-names = "i2c"; }; watchdog { compatible = "samsung,s3c2410-wdt"; reg = <0x110000 0x1000>; interrupts = <0 1 0>; + clocks = <&clock 21>; + clock-names = "watchdog"; + }; + + gmac: ethernet@00230000 { + compatible = "snps,dwmac-3.70a"; + reg = <0x00230000 0x8000>; + interrupt-parent = <&gic>; + interrupts = <0 31 4>; + interrupt-names = "macirq"; + phy-mode = "sgmii"; + clocks = <&clock 25>; + clock-names = "stmmaceth"; }; amba { @@ -138,19 +185,23 @@ interrupt-parent = <&gic>; ranges; - pdma0: pdma@121A0000 { + pdma0: pdma@00121000 { compatible = "arm,pl330", "arm,primecell"; - reg = <0x120000 0x1000>; - interrupts = <0 34 0>; + reg = <0x121000 0x1000>; + interrupts = <0 46 0>; + clocks = <&clock 8>; + clock-names = "apb_pclk"; #dma-cells = <1>; #dma-channels = <8>; #dma-requests = <32>; }; - pdma1: pdma@121B0000 { + pdma1: pdma@00120000 { compatible = "arm,pl330", "arm,primecell"; - reg = <0x121000 0x1000>; - interrupts = <0 35 0>; + reg = <0x120000 0x1000>; + interrupts = <0 47 0>; + clocks = <&clock 8>; + clock-names = "apb_pclk"; #dma-cells = <1>; #dma-channels = <8>; #dma-requests = <32>; @@ -161,5 +212,8 @@ compatible = "samsung,s3c6410-rtc"; reg = <0x130000 0x1000>; interrupts = <0 17 0>, <0 16 0>; + clocks = <&clock 21>; + clock-names = "rtc"; + status = "disabled"; }; }; diff --git a/trunk/arch/arm/boot/dts/imx23-evk.dts b/trunk/arch/arm/boot/dts/imx23-evk.dts index 035c13f9d3c0..da0588a04131 100644 --- a/trunk/arch/arm/boot/dts/imx23-evk.dts +++ b/trunk/arch/arm/boot/dts/imx23-evk.dts @@ -59,8 +59,33 @@ lcdif@80030000 { pinctrl-names = "default"; pinctrl-0 = <&lcdif_24bit_pins_a>; - panel-enable-gpios = <&gpio1 18 0>; + lcd-supply = <®_lcd_3v3>; + display = <&display>; status = "okay"; + + display: display { + bits-per-pixel = <32>; + bus-width = <24>; + + display-timings { + native-mode = <&timing0>; + timing0: timing0 { + clock-frequency = <9200000>; + hactive = <480>; + vactive = <272>; + hback-porch = <15>; + hfront-porch = <8>; + vback-porch = <12>; + vfront-porch = <4>; + hsync-len = <1>; + vsync-len = <1>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <1>; + pixelclk-active = <0>; + }; + }; + }; }; }; @@ -95,6 +120,15 @@ regulator-max-microvolt = <3300000>; gpio = <&gpio1 29 0>; }; + + reg_lcd_3v3: lcd-3v3 { + compatible = "regulator-fixed"; + regulator-name = "lcd-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio1 18 0>; + enable-active-high; + }; }; backlight { diff --git a/trunk/arch/arm/boot/dts/imx23-olinuxino.dts b/trunk/arch/arm/boot/dts/imx23-olinuxino.dts index e7484e4ea659..d107c4af321f 100644 --- a/trunk/arch/arm/boot/dts/imx23-olinuxino.dts +++ b/trunk/arch/arm/boot/dts/imx23-olinuxino.dts @@ -29,6 +29,7 @@ pinctrl-names = "default"; pinctrl-0 = <&mmc0_4bit_pins_a &mmc0_pins_fixup>; bus-width = <4>; + broken-cd; status = "okay"; }; diff --git a/trunk/arch/arm/boot/dts/imx23.dtsi b/trunk/arch/arm/boot/dts/imx23.dtsi index ad2d79324cd3..73fd7d0887b5 100644 --- a/trunk/arch/arm/boot/dts/imx23.dtsi +++ b/trunk/arch/arm/boot/dts/imx23.dtsi @@ -49,9 +49,15 @@ reg = <0x80000000 0x2000>; }; - dma-apbh@80004000 { + dma_apbh: dma-apbh@80004000 { compatible = "fsl,imx23-dma-apbh"; reg = <0x80004000 0x2000>; + interrupts = <0 14 20 0 + 13 13 13 13>; + interrupt-names = "empty", "ssp0", "ssp1", "empty", + "gpmi0", "gpmi1", "gpmi2", "gpmi3"; + #dma-cells = <1>; + dma-channels = <8>; clocks = <&clks 15>; }; @@ -70,6 +76,8 @@ interrupt-names = "gpmi-dma", "bch"; clocks = <&clks 34>; clock-names = "gpmi_io"; + dmas = <&dma_apbh 4>; + dma-names = "rx-tx"; fsl,gpmi-dma-channel = <4>; status = "disabled"; }; @@ -78,6 +86,8 @@ reg = <0x80010000 0x2000>; interrupts = <15 14>; clocks = <&clks 33>; + dmas = <&dma_apbh 1>; + dma-names = "rx-tx"; fsl,ssp-dma-channel = <1>; status = "disabled"; }; @@ -305,9 +315,19 @@ status = "disabled"; }; - dma-apbx@80024000 { + dma_apbx: dma-apbx@80024000 { compatible = "fsl,imx23-dma-apbx"; reg = <0x80024000 0x2000>; + interrupts = <7 5 9 26 + 19 0 25 23 + 60 58 9 0 + 0 0 0 0>; + interrupt-names = "audio-adc", "audio-dac", "spdif-tx", "i2c", + "saif0", "empty", "auart0-rx", "auart0-tx", + "auart1-rx", "auart1-tx", "saif1", "empty", + "empty", "empty", "empty", "empty"; + #dma-cells = <1>; + dma-channels = <16>; clocks = <&clks 16>; }; @@ -344,6 +364,8 @@ reg = <0x80034000 0x2000>; interrupts = <2 20>; clocks = <&clks 33>; + dmas = <&dma_apbh 2>; + dma-names = "rx-tx"; fsl,ssp-dma-channel = <2>; status = "disabled"; }; @@ -369,6 +391,8 @@ saif0: saif@80042000 { reg = <0x80042000 0x2000>; + dmas = <&dma_apbx 4>; + dma-names = "rx-tx"; status = "disabled"; }; @@ -379,16 +403,22 @@ saif1: saif@80046000 { reg = <0x80046000 0x2000>; + dmas = <&dma_apbx 10>; + dma-names = "rx-tx"; status = "disabled"; }; audio-out@80048000 { reg = <0x80048000 0x2000>; + dmas = <&dma_apbx 1>; + dma-names = "tx"; status = "disabled"; }; audio-in@8004c000 { reg = <0x8004c000 0x2000>; + dmas = <&dma_apbx 0>; + dma-names = "rx"; status = "disabled"; }; @@ -401,11 +431,15 @@ spdif@80054000 { reg = <0x80054000 2000>; + dmas = <&dma_apbx 2>; + dma-names = "tx"; status = "disabled"; }; i2c@80058000 { reg = <0x80058000 0x2000>; + dmas = <&dma_apbx 3>; + dma-names = "rx-tx"; status = "disabled"; }; @@ -436,6 +470,8 @@ reg = <0x8006c000 0x2000>; interrupts = <24 25 23>; clocks = <&clks 32>; + dmas = <&dma_apbx 6>, <&dma_apbx 7>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -444,6 +480,8 @@ reg = <0x8006e000 0x2000>; interrupts = <59 60 58>; clocks = <&clks 32>; + dmas = <&dma_apbx 8>, <&dma_apbx 9>; + dma-names = "rx", "tx"; status = "disabled"; }; diff --git a/trunk/arch/arm/boot/dts/imx28-apf28dev.dts b/trunk/arch/arm/boot/dts/imx28-apf28dev.dts index 6d8865bfb4b7..3d905d16cbec 100644 --- a/trunk/arch/arm/boot/dts/imx28-apf28dev.dts +++ b/trunk/arch/arm/boot/dts/imx28-apf28dev.dts @@ -72,7 +72,32 @@ pinctrl-names = "default"; pinctrl-0 = <&lcdif_16bit_pins_a &lcdif_pins_apf28dev>; + display = <&display>; status = "okay"; + + display: display { + bits-per-pixel = <16>; + bus-width = <16>; + + display-timings { + native-mode = <&timing0>; + timing0: timing0 { + clock-frequency = <33000033>; + hactive = <800>; + vactive = <480>; + hback-porch = <96>; + hfront-porch = <96>; + vback-porch = <20>; + vfront-porch = <21>; + hsync-len = <64>; + vsync-len = <4>; + hsync-active = <1>; + vsync-active = <1>; + de-active = <1>; + pixelclk-active = <0>; + }; + }; + }; }; }; diff --git a/trunk/arch/arm/boot/dts/imx28-apx4devkit.dts b/trunk/arch/arm/boot/dts/imx28-apx4devkit.dts index 5171667a7763..43bf3c796cba 100644 --- a/trunk/arch/arm/boot/dts/imx28-apx4devkit.dts +++ b/trunk/arch/arm/boot/dts/imx28-apx4devkit.dts @@ -94,7 +94,32 @@ pinctrl-names = "default"; pinctrl-0 = <&lcdif_24bit_pins_a &lcdif_pins_apx4>; + display = <&display>; status = "okay"; + + display: display { + bits-per-pixel = <32>; + bus-width = <24>; + + display-timings { + native-mode = <&timing0>; + timing0: timing0 { + clock-frequency = <30000000>; + hactive = <800>; + vactive = <480>; + hback-porch = <88>; + hfront-porch = <40>; + vback-porch = <32>; + vfront-porch = <13>; + hsync-len = <48>; + vsync-len = <3>; + hsync-active = <1>; + vsync-active = <1>; + de-active = <1>; + pixelclk-active = <0>; + }; + }; + }; }; }; diff --git a/trunk/arch/arm/boot/dts/imx28-cfa10049.dts b/trunk/arch/arm/boot/dts/imx28-cfa10049.dts index a0d3e9f1738e..063e62059890 100644 --- a/trunk/arch/arm/boot/dts/imx28-cfa10049.dts +++ b/trunk/arch/arm/boot/dts/imx28-cfa10049.dts @@ -30,7 +30,6 @@ reg = <0>; fsl,pinmux-ids = < 0x0073 /* MX28_PAD_GPMI_D7__GPIO_0_7 */ - 0x1153 /* MX28_PAD_LCD_D22__GPIO_1_21 */ 0x1163 /* MX28_PAD_LCD_D22__GPIO_1_22 */ 0x1173 /* MX28_PAD_LCD_D22__GPIO_1_23 */ 0x2153 /* MX28_PAD_SSP2_D5__GPIO_2_21 */ @@ -120,13 +119,48 @@ fsl,voltage = <1>; fsl,pull-up = <0>; }; + + w1_gpio_pins: w1-gpio@0 { + reg = <0>; + fsl,pinmux-ids = < + 0x1153 /* MX28_PAD_LCD_D21__GPIO_1_21 */ + >; + fsl,drive-strength = <1>; + fsl,voltage = <1>; + fsl,pull-up = <0>; /* 0 will enable the keeper */ + }; }; lcdif@80030000 { pinctrl-names = "default"; pinctrl-0 = <&lcdif_18bit_pins_cfa10049 &lcdif_pins_cfa10049>; + display = <&display>; status = "okay"; + + display: display { + bits-per-pixel = <32>; + bus-width = <18>; + + display-timings { + native-mode = <&timing0>; + timing0: timing0 { + clock-frequency = <9216000>; + hactive = <320>; + vactive = <480>; + hback-porch = <2>; + hfront-porch = <2>; + vback-porch = <2>; + vfront-porch = <2>; + hsync-len = <15>; + vsync-len = <15>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <1>; + pixelclk-active = <1>; + }; + }; + }; }; }; @@ -183,6 +217,11 @@ usbphy1: usbphy@8007e000 { status = "okay"; }; + + lradc@80050000 { + status = "okay"; + fsl,lradc-touchscreen-wires = <4>; + }; }; }; @@ -304,5 +343,14 @@ pwms = <&pwm 3 5000000>; brightness-levels = <0 4 8 16 32 64 128 255>; default-brightness-level = <6>; + + }; + + onewire@0 { + compatible = "w1-gpio"; + pinctrl-names = "default"; + pinctrl-0 = <&w1_gpio_pins>; + status = "okay"; + gpios = <&gpio1 21 0>; }; }; diff --git a/trunk/arch/arm/boot/dts/imx28-evk.dts b/trunk/arch/arm/boot/dts/imx28-evk.dts index 2da316e04409..3637bf3b1d59 100644 --- a/trunk/arch/arm/boot/dts/imx28-evk.dts +++ b/trunk/arch/arm/boot/dts/imx28-evk.dts @@ -123,8 +123,33 @@ pinctrl-names = "default"; pinctrl-0 = <&lcdif_24bit_pins_a &lcdif_pins_evk>; - panel-enable-gpios = <&gpio3 30 0>; + lcd-supply = <®_lcd_3v3>; + display = <&display>; status = "okay"; + + display: display { + bits-per-pixel = <32>; + bus-width = <24>; + + display-timings { + native-mode = <&timing0>; + timing0: timing0 { + clock-frequency = <33500000>; + hactive = <800>; + vactive = <480>; + hback-porch = <89>; + hfront-porch = <164>; + vback-porch = <23>; + vfront-porch = <10>; + hsync-len = <10>; + vsync-len = <10>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <1>; + pixelclk-active = <0>; + }; + }; + }; }; can0: can@80032000 { @@ -285,6 +310,15 @@ gpio = <&gpio3 8 0>; enable-active-high; }; + + reg_lcd_3v3: lcd-3v3 { + compatible = "regulator-fixed"; + regulator-name = "lcd-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio3 30 0>; + enable-active-high; + }; }; sound { diff --git a/trunk/arch/arm/boot/dts/imx28-m28evk.dts b/trunk/arch/arm/boot/dts/imx28-m28evk.dts index fd36e1cca104..5aa44e05c9f5 100644 --- a/trunk/arch/arm/boot/dts/imx28-m28evk.dts +++ b/trunk/arch/arm/boot/dts/imx28-m28evk.dts @@ -119,7 +119,32 @@ pinctrl-names = "default"; pinctrl-0 = <&lcdif_24bit_pins_a &lcdif_pins_m28>; + display = <&display>; status = "okay"; + + display: display { + bits-per-pixel = <16>; + bus-width = <18>; + + display-timings { + native-mode = <&timing0>; + timing0: timing0 { + clock-frequency = <33260000>; + hactive = <800>; + vactive = <480>; + hback-porch = <0>; + hfront-porch = <256>; + vback-porch = <0>; + vfront-porch = <45>; + hsync-len = <1>; + vsync-len = <1>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <1>; + pixelclk-active = <1>; + }; + }; + }; }; can0: can@80032000 { @@ -220,6 +245,8 @@ phy-mode = "rmii"; pinctrl-names = "default"; pinctrl-0 = <&mac0_pins_a>; + clocks = <&clks 57>, <&clks 57>; + clock-names = "ipg", "ahb"; status = "okay"; }; diff --git a/trunk/arch/arm/boot/dts/imx28.dtsi b/trunk/arch/arm/boot/dts/imx28.dtsi index 64af2381c1b0..600f7cb51f3e 100644 --- a/trunk/arch/arm/boot/dts/imx28.dtsi +++ b/trunk/arch/arm/boot/dts/imx28.dtsi @@ -61,12 +61,24 @@ hsadc@80002000 { reg = <0x80002000 0x2000>; interrupts = <13 87>; + dmas = <&dma_apbh 12>; + dma-names = "rx"; status = "disabled"; }; - dma-apbh@80004000 { + dma_apbh: dma-apbh@80004000 { compatible = "fsl,imx28-dma-apbh"; reg = <0x80004000 0x2000>; + interrupts = <82 83 84 85 + 88 88 88 88 + 88 88 88 88 + 87 86 0 0>; + interrupt-names = "ssp0", "ssp1", "ssp2", "ssp3", + "gpmi0", "gmpi1", "gpmi2", "gmpi3", + "gpmi4", "gmpi5", "gpmi6", "gmpi7", + "hsadc", "lcdif", "empty", "empty"; + #dma-cells = <1>; + dma-channels = <16>; clocks = <&clks 25>; }; @@ -86,6 +98,8 @@ interrupt-names = "gpmi-dma", "bch"; clocks = <&clks 50>; clock-names = "gpmi_io"; + dmas = <&dma_apbh 4>; + dma-names = "rx-tx"; fsl,gpmi-dma-channel = <4>; status = "disabled"; }; @@ -96,6 +110,8 @@ reg = <0x80010000 0x2000>; interrupts = <96 82>; clocks = <&clks 46>; + dmas = <&dma_apbh 0>; + dma-names = "rx-tx"; fsl,ssp-dma-channel = <0>; status = "disabled"; }; @@ -106,6 +122,8 @@ reg = <0x80012000 0x2000>; interrupts = <97 83>; clocks = <&clks 47>; + dmas = <&dma_apbh 1>; + dma-names = "rx-tx"; fsl,ssp-dma-channel = <1>; status = "disabled"; }; @@ -116,6 +134,8 @@ reg = <0x80014000 0x2000>; interrupts = <98 84>; clocks = <&clks 48>; + dmas = <&dma_apbh 2>; + dma-names = "rx-tx"; fsl,ssp-dma-channel = <2>; status = "disabled"; }; @@ -126,6 +146,8 @@ reg = <0x80016000 0x2000>; interrupts = <99 85>; clocks = <&clks 49>; + dmas = <&dma_apbh 3>; + dma-names = "rx-tx"; fsl,ssp-dma-channel = <3>; status = "disabled"; }; @@ -658,9 +680,19 @@ status = "disabled"; }; - dma-apbx@80024000 { + dma_apbx: dma-apbx@80024000 { compatible = "fsl,imx28-dma-apbx"; reg = <0x80024000 0x2000>; + interrupts = <78 79 66 0 + 80 81 68 69 + 70 71 72 73 + 74 75 76 77>; + interrupt-names = "auart4-rx", "aurat4-tx", "spdif-tx", "empty", + "saif0", "saif1", "i2c0", "i2c1", + "auart0-rx", "auart0-tx", "auart1-rx", "auart1-tx", + "auart2-rx", "auart2-tx", "auart3-rx", "auart3-tx"; + #dma-cells = <1>; + dma-channels = <16>; clocks = <&clks 26>; }; @@ -692,6 +724,8 @@ reg = <0x80030000 0x2000>; interrupts = <38 86>; clocks = <&clks 55>; + dmas = <&dma_apbh 13>; + dma-names = "rx"; status = "disabled"; }; @@ -767,6 +801,8 @@ reg = <0x80042000 0x2000>; interrupts = <59 80>; clocks = <&clks 53>; + dmas = <&dma_apbx 4>; + dma-names = "rx-tx"; fsl,saif-dma-channel = <4>; status = "disabled"; }; @@ -781,6 +817,8 @@ reg = <0x80046000 0x2000>; interrupts = <58 81>; clocks = <&clks 54>; + dmas = <&dma_apbx 5>; + dma-names = "rx-tx"; fsl,saif-dma-channel = <5>; status = "disabled"; }; @@ -796,6 +834,8 @@ spdif@80054000 { reg = <0x80054000 0x2000>; interrupts = <45 66>; + dmas = <&dma_apbx 2>; + dma-names = "tx"; status = "disabled"; }; @@ -812,6 +852,8 @@ reg = <0x80058000 0x2000>; interrupts = <111 68>; clock-frequency = <100000>; + dmas = <&dma_apbx 6>; + dma-names = "rx-tx"; fsl,i2c-dma-channel = <6>; status = "disabled"; }; @@ -823,6 +865,8 @@ reg = <0x8005a000 0x2000>; interrupts = <110 69>; clock-frequency = <100000>; + dmas = <&dma_apbx 7>; + dma-names = "rx-tx"; fsl,i2c-dma-channel = <7>; status = "disabled"; }; @@ -847,6 +891,8 @@ compatible = "fsl,imx28-auart", "fsl,imx23-auart"; reg = <0x8006a000 0x2000>; interrupts = <112 70 71>; + dmas = <&dma_apbx 8>, <&dma_apbx 9>; + dma-names = "rx", "tx"; fsl,auart-dma-channel = <8 9>; clocks = <&clks 45>; status = "disabled"; @@ -856,6 +902,8 @@ compatible = "fsl,imx28-auart", "fsl,imx23-auart"; reg = <0x8006c000 0x2000>; interrupts = <113 72 73>; + dmas = <&dma_apbx 10>, <&dma_apbx 11>; + dma-names = "rx", "tx"; clocks = <&clks 45>; status = "disabled"; }; @@ -864,6 +912,8 @@ compatible = "fsl,imx28-auart", "fsl,imx23-auart"; reg = <0x8006e000 0x2000>; interrupts = <114 74 75>; + dmas = <&dma_apbx 12>, <&dma_apbx 13>; + dma-names = "rx", "tx"; clocks = <&clks 45>; status = "disabled"; }; @@ -872,6 +922,8 @@ compatible = "fsl,imx28-auart", "fsl,imx23-auart"; reg = <0x80070000 0x2000>; interrupts = <115 76 77>; + dmas = <&dma_apbx 14>, <&dma_apbx 15>; + dma-names = "rx", "tx"; clocks = <&clks 45>; status = "disabled"; }; @@ -880,6 +932,8 @@ compatible = "fsl,imx28-auart", "fsl,imx23-auart"; reg = <0x80072000 0x2000>; interrupts = <116 78 79>; + dmas = <&dma_apbx 0>, <&dma_apbx 1>; + dma-names = "rx", "tx"; clocks = <&clks 45>; status = "disabled"; }; @@ -943,8 +997,8 @@ compatible = "fsl,imx28-fec"; reg = <0x800f0000 0x4000>; interrupts = <101>; - clocks = <&clks 57>, <&clks 57>; - clock-names = "ipg", "ahb"; + clocks = <&clks 57>, <&clks 57>, <&clks 64>; + clock-names = "ipg", "ahb", "enet_out"; status = "disabled"; }; diff --git a/trunk/arch/arm/boot/dts/imx6qdl.dtsi b/trunk/arch/arm/boot/dts/imx6qdl.dtsi index 3cca7d39529d..9e8296e4c343 100644 --- a/trunk/arch/arm/boot/dts/imx6qdl.dtsi +++ b/trunk/arch/arm/boot/dts/imx6qdl.dtsi @@ -65,9 +65,13 @@ interrupt-parent = <&intc>; ranges; - dma-apbh@00110000 { + dma_apbh: dma-apbh@00110000 { compatible = "fsl,imx6q-dma-apbh", "fsl,imx28-dma-apbh"; reg = <0x00110000 0x2000>; + interrupts = <0 13 0x04>, <0 13 0x04>, <0 13 0x04>, <0 13 0x04>; + interrupt-names = "gpmi0", "gpmi1", "gpmi2", "gpmi3"; + #dma-cells = <1>; + dma-channels = <4>; clocks = <&clks 106>; }; @@ -83,6 +87,8 @@ <&clks 150>, <&clks 149>; clock-names = "gpmi_io", "gpmi_apb", "gpmi_bch", "gpmi_bch_apb", "per1_bch"; + dmas = <&dma_apbh 0>; + dma-names = "rx-tx"; fsl,gpmi-dma-channel = <0>; status = "disabled"; }; diff --git a/trunk/arch/arm/boot/dts/integratorcp.dts b/trunk/arch/arm/boot/dts/integratorcp.dts index 8b119399025a..ff1aea0ee043 100644 --- a/trunk/arch/arm/boot/dts/integratorcp.dts +++ b/trunk/arch/arm/boot/dts/integratorcp.dts @@ -24,15 +24,15 @@ }; timer0: timer@13000000 { - compatible = "arm,sp804", "arm,primecell"; + compatible = "arm,integrator-cp-timer"; }; timer1: timer@13000100 { - compatible = "arm,sp804", "arm,primecell"; + compatible = "arm,integrator-cp-timer"; }; timer2: timer@13000200 { - compatible = "arm,sp804", "arm,primecell"; + compatible = "arm,integrator-cp-timer"; }; pic: pic@14000000 { diff --git a/trunk/arch/arm/boot/dts/kirkwood-cloudbox.dts b/trunk/arch/arm/boot/dts/kirkwood-cloudbox.dts new file mode 100644 index 000000000000..5f21d4e427b0 --- /dev/null +++ b/trunk/arch/arm/boot/dts/kirkwood-cloudbox.dts @@ -0,0 +1,89 @@ +/dts-v1/; + +/include/ "kirkwood.dtsi" +/include/ "kirkwood-6281.dtsi" + +/ { + model = "LaCie CloudBox"; + compatible = "lacie,cloudbox", "marvell,kirkwood-88f6702", "marvell,kirkwood"; + + memory { + device_type = "memory"; + reg = <0x00000000 0x10000000>; + }; + + chosen { + bootargs = "console=ttyS0,115200n8"; + }; + + ocp@f1000000 { + pinctrl: pinctrl@10000 { + pinctrl-0 = < &pmx_spi &pmx_uart0 + &pmx_cloudbox_sata0 >; + pinctrl-names = "default"; + + pmx_cloudbox_sata0: pmx-cloudbox-sata0 { + marvell,pins = "mpp15"; + marvell,function = "sata0"; + }; + }; + + serial@12000 { + clock-frequency = <166666667>; + status = "okay"; + }; + + sata@80000 { + status = "okay"; + nr-ports = <1>; + }; + + spi@10600 { + status = "okay"; + + flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "mx25l4005a"; + reg = <0>; + spi-max-frequency = <20000000>; + mode = <0>; + + partition@0 { + reg = <0x0 0x80000>; + label = "u-boot"; + }; + }; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + button@1 { + label = "Power push button"; + linux,code = <116>; + gpios = <&gpio0 16 1>; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + + red-fail { + label = "cloudbox:red:fail"; + gpios = <&gpio0 14 0>; + }; + blue-sata { + label = "cloudbox:blue:sata"; + gpios = <&gpio0 15 0>; + }; + }; + + gpio_poweroff { + compatible = "gpio-poweroff"; + gpios = <&gpio0 17 0>; + }; +}; diff --git a/trunk/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts b/trunk/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts new file mode 100644 index 000000000000..1ca66ab83ad6 --- /dev/null +++ b/trunk/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts @@ -0,0 +1,180 @@ +/dts-v1/; + +/include/ "kirkwood.dtsi" +/include/ "kirkwood-6282.dtsi" + +/ { + model = "NETGEAR ReadyNAS Duo v2"; + compatible = "netgear,readynas-duo-v2", "netgear,readynas", "marvell,kirkwood-88f6282", "marvell,kirkwood"; + + memory { /* 256 MB */ + device_type = "memory"; + reg = <0x00000000 0x10000000>; + }; + + chosen { + bootargs = "console=ttyS0,115200n8 earlyprintk"; + }; + + ocp@f1000000 { + pinctrl: pinctrl@10000 { + + pinctrl-0 = < &pmx_uart0 + &pmx_button_power + &pmx_button_backup + &pmx_button_reset + &pmx_led_blue_power + &pmx_led_blue_activity + &pmx_led_blue_disk1 + &pmx_led_blue_disk2 + &pmx_led_blue_backup >; + pinctrl-names = "default"; + + pmx_button_power: pmx-button-power { + marvell,pins = "mpp47"; + marvell,function = "gpio"; + }; + pmx_button_backup: pmx-button-backup { + marvell,pins = "mpp45"; + marvell,function = "gpio"; + }; + pmx_button_reset: pmx-button-reset { + marvell,pins = "mpp13"; + marvell,function = "gpio"; + }; + pmx_led_blue_power: pmx-led-blue-power { + marvell,pins = "mpp31"; + marvell,function = "gpio"; + }; + pmx_led_blue_activity: pmx-led-blue-activity { + marvell,pins = "mpp38"; + marvell,function = "gpio"; + }; + pmx_led_blue_disk1: pmx-led-blue-disk1 { + marvell,pins = "mpp23"; + marvell,function = "gpio"; + }; + pmx_led_blue_disk2: pmx-led-blue-disk2 { + marvell,pins = "mpp22"; + marvell,function = "gpio"; + }; + pmx_led_blue_backup: pmx-led-blue-backup { + marvell,pins = "mpp29"; + marvell,function = "gpio"; + }; + }; + + i2c@11000 { + status = "okay"; + + rs5c372a: rs5c372a@32 { + compatible = "ricoh,rs5c372a"; + reg = <0x32>; + }; + }; + + serial@12000 { + status = "okay"; + }; + + nand@3000000 { + status = "okay"; + + partition@0 { + label = "u-boot"; + reg = <0x0000000 0x180000>; + read-only; + }; + + partition@180000 { + label = "u-boot-env"; + reg = <0x180000 0x20000>; + }; + + partition@200000 { + label = "uImage"; + reg = <0x0200000 0x600000>; + }; + + partition@800000 { + label = "minirootfs"; + reg = <0x0800000 0x1000000>; + }; + + partition@1800000 { + label = "jffs2"; + reg = <0x1800000 0x6800000>; + }; + }; + + sata@80000 { + status = "okay"; + nr-ports = <2>; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + + power_led { + label = "status:blue:power_led"; + gpios = <&gpio0 31 1>; /* GPIO 31 Active Low */ + linux,default-trigger = "default-on"; + }; + activity_led { + label = "status:blue:activity_led"; + gpios = <&gpio1 6 1>; /* GPIO 38 Active Low */ + }; + disk1_led { + label = "status:blue:disk1_led"; + gpios = <&gpio0 23 1>; /* GPIO 23 Active Low */ + }; + disk2_led { + label = "status:blue:disk2_led"; + gpios = <&gpio0 22 1>; /* GPIO 22 Active Low */ + }; + backup_led { + label = "status:blue:backup_led"; + gpios = <&gpio0 29 1>; /* GPIO 29 Active Low*/ + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + button@1 { + label = "Power Button"; + linux,code = <116>; /* KEY_POWER */ + gpios = <&gpio1 15 1>; + }; + button@2 { + label = "Reset Button"; + linux,code = <0x198>; /* KEY_RESTART */ + gpios = <&gpio0 13 1>; + }; + button@3 { + label = "Backup Button"; + linux,code = <133>; /* KEY_COPY */ + gpios = <&gpio1 13 1>; + }; + }; + + regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + usb_power: regulator@1 { + compatible = "regulator-fixed"; + reg = <1>; + regulator-name = "USB 3.0 Power"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + gpio = <&gpio1 14 0>; + }; + }; +}; diff --git a/trunk/arch/arm/boot/dts/kirkwood-ns2mini.dts b/trunk/arch/arm/boot/dts/kirkwood-ns2mini.dts index b79f5eb25589..adab1ab25733 100644 --- a/trunk/arch/arm/boot/dts/kirkwood-ns2mini.dts +++ b/trunk/arch/arm/boot/dts/kirkwood-ns2mini.dts @@ -3,6 +3,7 @@ /include/ "kirkwood-ns2-common.dtsi" / { + /* This machine is embedded in the first LaCie CloudBox product. */ model = "LaCie Network Space Mini v2"; compatible = "lacie,netspace_mini_v2", "marvell,kirkwood-88f6192", "marvell,kirkwood"; diff --git a/trunk/arch/arm/boot/dts/mmp2.dtsi b/trunk/arch/arm/boot/dts/mmp2.dtsi index 1429ac05b36d..4e8b08c628c7 100644 --- a/trunk/arch/arm/boot/dts/mmp2.dtsi +++ b/trunk/arch/arm/boot/dts/mmp2.dtsi @@ -160,7 +160,7 @@ }; gpio@d4019000 { - compatible = "mrvl,mmp-gpio"; + compatible = "marvell,mmp2-gpio"; #address-cells = <1>; #size-cells = <1>; reg = <0xd4019000 0x1000>; diff --git a/trunk/arch/arm/boot/dts/omap2.dtsi b/trunk/arch/arm/boot/dts/omap2.dtsi index 761c4b69b25b..37aa7487d4d8 100644 --- a/trunk/arch/arm/boot/dts/omap2.dtsi +++ b/trunk/arch/arm/boot/dts/omap2.dtsi @@ -26,6 +26,11 @@ }; }; + pmu { + compatible = "arm,arm1136-pmu"; + interrupts = <3>; + }; + soc { compatible = "ti,omap-infra"; mpu { @@ -49,6 +54,18 @@ reg = <0x480FE000 0x1000>; }; + sdma: dma-controller@48056000 { + compatible = "ti,omap2430-sdma", "ti,omap2420-sdma"; + reg = <0x48056000 0x1000>; + interrupts = <12>, + <13>, + <14>, + <15>; + #dma-cells = <1>; + #dma-channels = <32>; + #dma-requests = <64>; + }; + uart1: serial@4806a000 { compatible = "ti,omap2-uart"; ti,hwmods = "uart1"; @@ -68,28 +85,28 @@ }; timer2: timer@4802a000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap2420-timer"; reg = <0x4802a000 0x400>; interrupts = <38>; ti,hwmods = "timer2"; }; timer3: timer@48078000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap2420-timer"; reg = <0x48078000 0x400>; interrupts = <39>; ti,hwmods = "timer3"; }; timer4: timer@4807a000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap2420-timer"; reg = <0x4807a000 0x400>; interrupts = <40>; ti,hwmods = "timer4"; }; timer5: timer@4807c000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap2420-timer"; reg = <0x4807c000 0x400>; interrupts = <41>; ti,hwmods = "timer5"; @@ -97,7 +114,7 @@ }; timer6: timer@4807e000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap2420-timer"; reg = <0x4807e000 0x400>; interrupts = <42>; ti,hwmods = "timer6"; @@ -105,7 +122,7 @@ }; timer7: timer@48080000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap2420-timer"; reg = <0x48080000 0x400>; interrupts = <43>; ti,hwmods = "timer7"; @@ -113,7 +130,7 @@ }; timer8: timer@48082000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap2420-timer"; reg = <0x48082000 0x400>; interrupts = <44>; ti,hwmods = "timer8"; @@ -121,7 +138,7 @@ }; timer9: timer@48084000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap2420-timer"; reg = <0x48084000 0x400>; interrupts = <45>; ti,hwmods = "timer9"; @@ -129,7 +146,7 @@ }; timer10: timer@48086000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap2420-timer"; reg = <0x48086000 0x400>; interrupts = <46>; ti,hwmods = "timer10"; @@ -137,7 +154,7 @@ }; timer11: timer@48088000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap2420-timer"; reg = <0x48088000 0x400>; interrupts = <47>; ti,hwmods = "timer11"; @@ -145,7 +162,7 @@ }; timer12: timer@4808a000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap2420-timer"; reg = <0x4808a000 0x400>; interrupts = <48>; ti,hwmods = "timer12"; diff --git a/trunk/arch/arm/boot/dts/omap2420-h4.dts b/trunk/arch/arm/boot/dts/omap2420-h4.dts index 9b0d07746cba..68282ee13e26 100644 --- a/trunk/arch/arm/boot/dts/omap2420-h4.dts +++ b/trunk/arch/arm/boot/dts/omap2420-h4.dts @@ -18,3 +18,49 @@ reg = <0x80000000 0x4000000>; /* 64 MB */ }; }; + +&gpmc { + ranges = <0 0 0x08000000 0x04000000>; + + nor@0,0 { + compatible = "cfi-flash"; + linux,mtd-name= "intel,ge28f256l18b85"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0 0 0x04000000>; + bank-width = <2>; + + gpmc,mux-add-data = <2>; + gpmc,cs-on-ns = <10>; + gpmc,cs-rd-off-ns = <160>; + gpmc,cs-wr-off-ns = <160>; + gpmc,adv-on-ns = <20>; + gpmc,adv-rd-off-ns = <50>; + gpmc,adv-wr-off-ns = <50>; + gpmc,oe-on-ns = <60>; + gpmc,oe-off-ns = <120>; + gpmc,we-on-ns = <60>; + gpmc,we-off-ns = <120>; + gpmc,rd-cycle-ns = <170>; + gpmc,wr-cycle-ns = <170>; + gpmc,access-ns = <150>; + gpmc,page-burst-access-ns = <10>; + + partition@0 { + label = "bootloader"; + reg = <0 0x20000>; + }; + partition@0x20000 { + label = "params"; + reg = <0x20000 0x20000>; + }; + partition@0x40000 { + label = "kernel"; + reg = <0x40000 0x200000>; + }; + partition@0x240000 { + label = "file-system"; + reg = <0x240000 0x3dc0000>; + }; + }; +}; diff --git a/trunk/arch/arm/boot/dts/omap2420.dtsi b/trunk/arch/arm/boot/dts/omap2420.dtsi index af6560908905..da5b285b73be 100644 --- a/trunk/arch/arm/boot/dts/omap2420.dtsi +++ b/trunk/arch/arm/boot/dts/omap2420.dtsi @@ -29,6 +29,65 @@ pinctrl-single,function-mask = <0x3f>; }; + gpio1: gpio@48018000 { + compatible = "ti,omap2-gpio"; + reg = <0x48018000 0x200>; + interrupts = <29>; + ti,hwmods = "gpio1"; + ti,gpio-always-on; + #gpio-cells = <2>; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + }; + + gpio2: gpio@4801a000 { + compatible = "ti,omap2-gpio"; + reg = <0x4801a000 0x200>; + interrupts = <30>; + ti,hwmods = "gpio2"; + ti,gpio-always-on; + #gpio-cells = <2>; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + }; + + gpio3: gpio@4801c000 { + compatible = "ti,omap2-gpio"; + reg = <0x4801c000 0x200>; + interrupts = <31>; + ti,hwmods = "gpio3"; + ti,gpio-always-on; + #gpio-cells = <2>; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + }; + + gpio4: gpio@4801e000 { + compatible = "ti,omap2-gpio"; + reg = <0x4801e000 0x200>; + interrupts = <32>; + ti,hwmods = "gpio4"; + ti,gpio-always-on; + #gpio-cells = <2>; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + }; + + gpmc: gpmc@6800a000 { + compatible = "ti,omap2420-gpmc"; + reg = <0x6800a000 0x1000>; + #address-cells = <2>; + #size-cells = <1>; + interrupts = <20>; + gpmc,num-cs = <8>; + gpmc,num-waitpins = <4>; + ti,hwmods = "gpmc"; + }; + mcbsp1: mcbsp@48074000 { compatible = "ti,omap2420-mcbsp"; reg = <0x48074000 0xff>; @@ -37,6 +96,9 @@ <60>; /* RX interrupt */ interrupt-names = "tx", "rx"; ti,hwmods = "mcbsp1"; + dmas = <&sdma 31>, + <&sdma 32>; + dma-names = "tx", "rx"; }; mcbsp2: mcbsp@48076000 { @@ -47,10 +109,13 @@ <63>; /* RX interrupt */ interrupt-names = "tx", "rx"; ti,hwmods = "mcbsp2"; + dmas = <&sdma 33>, + <&sdma 34>; + dma-names = "tx", "rx"; }; timer1: timer@48028000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap2420-timer"; reg = <0x48028000 0x400>; interrupts = <37>; ti,hwmods = "timer1"; diff --git a/trunk/arch/arm/boot/dts/omap2430.dtsi b/trunk/arch/arm/boot/dts/omap2430.dtsi index c3924457c9b6..054bc4439568 100644 --- a/trunk/arch/arm/boot/dts/omap2430.dtsi +++ b/trunk/arch/arm/boot/dts/omap2430.dtsi @@ -29,6 +29,76 @@ pinctrl-single,function-mask = <0x3f>; }; + gpio1: gpio@4900c000 { + compatible = "ti,omap2-gpio"; + reg = <0x4900c000 0x200>; + interrupts = <29>; + ti,hwmods = "gpio1"; + ti,gpio-always-on; + #gpio-cells = <2>; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + }; + + gpio2: gpio@4900e000 { + compatible = "ti,omap2-gpio"; + reg = <0x4900e000 0x200>; + interrupts = <30>; + ti,hwmods = "gpio2"; + ti,gpio-always-on; + #gpio-cells = <2>; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + }; + + gpio3: gpio@49010000 { + compatible = "ti,omap2-gpio"; + reg = <0x49010000 0x200>; + interrupts = <31>; + ti,hwmods = "gpio3"; + ti,gpio-always-on; + #gpio-cells = <2>; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + }; + + gpio4: gpio@49012000 { + compatible = "ti,omap2-gpio"; + reg = <0x49012000 0x200>; + interrupts = <32>; + ti,hwmods = "gpio4"; + ti,gpio-always-on; + #gpio-cells = <2>; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + }; + + gpio5: gpio@480b6000 { + compatible = "ti,omap2-gpio"; + reg = <0x480b6000 0x200>; + interrupts = <33>; + ti,hwmods = "gpio5"; + #gpio-cells = <2>; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + }; + + gpmc: gpmc@6e000000 { + compatible = "ti,omap2430-gpmc"; + reg = <0x6e000000 0x1000>; + #address-cells = <2>; + #size-cells = <1>; + interrupts = <20>; + gpmc,num-cs = <8>; + gpmc,num-waitpins = <4>; + ti,hwmods = "gpmc"; + }; + mcbsp1: mcbsp@48074000 { compatible = "ti,omap2430-mcbsp"; reg = <0x48074000 0xff>; @@ -40,6 +110,9 @@ interrupt-names = "common", "tx", "rx", "rx_overflow"; ti,buffer-size = <128>; ti,hwmods = "mcbsp1"; + dmas = <&sdma 31>, + <&sdma 32>; + dma-names = "tx", "rx"; }; mcbsp2: mcbsp@48076000 { @@ -52,6 +125,9 @@ interrupt-names = "common", "tx", "rx"; ti,buffer-size = <128>; ti,hwmods = "mcbsp2"; + dmas = <&sdma 33>, + <&sdma 34>; + dma-names = "tx", "rx"; }; mcbsp3: mcbsp@4808c000 { @@ -64,6 +140,9 @@ interrupt-names = "common", "tx", "rx"; ti,buffer-size = <128>; ti,hwmods = "mcbsp3"; + dmas = <&sdma 17>, + <&sdma 18>; + dma-names = "tx", "rx"; }; mcbsp4: mcbsp@4808e000 { @@ -76,6 +155,9 @@ interrupt-names = "common", "tx", "rx"; ti,buffer-size = <128>; ti,hwmods = "mcbsp4"; + dmas = <&sdma 19>, + <&sdma 20>; + dma-names = "tx", "rx"; }; mcbsp5: mcbsp@48096000 { @@ -88,10 +170,13 @@ interrupt-names = "common", "tx", "rx"; ti,buffer-size = <128>; ti,hwmods = "mcbsp5"; + dmas = <&sdma 21>, + <&sdma 22>; + dma-names = "tx", "rx"; }; timer1: timer@49018000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap2420-timer"; reg = <0x49018000 0x400>; interrupts = <37>; ti,hwmods = "timer1"; diff --git a/trunk/arch/arm/boot/dts/omap3-beagle-xm.dts b/trunk/arch/arm/boot/dts/omap3-beagle-xm.dts index 3705a81c1fc2..3046d1f81be0 100644 --- a/trunk/arch/arm/boot/dts/omap3-beagle-xm.dts +++ b/trunk/arch/arm/boot/dts/omap3-beagle-xm.dts @@ -13,6 +13,12 @@ model = "TI OMAP3 BeagleBoard xM"; compatible = "ti,omap3-beagle-xm, ti,omap3-beagle", "ti,omap3"; + cpus { + cpu@0 { + cpu0-supply = <&vcc>; + }; + }; + memory { device_type = "memory"; reg = <0x80000000 0x20000000>; /* 512 MB */ @@ -20,10 +26,6 @@ leds { compatible = "gpio-leds"; - pmu_stat { - label = "beagleboard::pmu_stat"; - gpios = <&twl_gpio 19 0>; /* LEDB */ - }; heartbeat { label = "beagleboard::usr0"; @@ -38,6 +40,16 @@ }; }; + pwmleds { + compatible = "pwm-leds"; + + pmu_stat { + label = "beagleboard::pmu_stat"; + pwms = <&twl_pwmled 1 7812500>; + max-brightness = <127>; + }; + }; + sound { compatible = "ti,omap-twl4030"; ti,model = "omap3beagle"; @@ -107,3 +119,10 @@ */ ti,pulldowns = <0x03a1c4>; }; + +&usb_otg_hs { + interface-type = <0>; + usb-phy = <&usb2_phy>; + mode = <3>; + power = <50>; +}; diff --git a/trunk/arch/arm/boot/dts/omap3-beagle.dts b/trunk/arch/arm/boot/dts/omap3-beagle.dts index f624dc85d441..6eec69997607 100644 --- a/trunk/arch/arm/boot/dts/omap3-beagle.dts +++ b/trunk/arch/arm/boot/dts/omap3-beagle.dts @@ -7,12 +7,18 @@ */ /dts-v1/; -/include/ "omap3.dtsi" +/include/ "omap34xx.dtsi" / { model = "TI OMAP3 BeagleBoard"; compatible = "ti,omap3-beagle", "ti,omap3"; + cpus { + cpu@0 { + cpu0-supply = <&vcc>; + }; + }; + memory { device_type = "memory"; reg = <0x80000000 0x10000000>; /* 256 MB */ @@ -38,6 +44,57 @@ }; }; + /* HS USB Port 2 RESET */ + hsusb2_reset: hsusb2_reset_reg { + compatible = "regulator-fixed"; + regulator-name = "hsusb2_reset"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio5 19 0>; /* gpio_147 */ + startup-delay-us = <70000>; + enable-active-high; + }; + + /* HS USB Port 2 Power */ + hsusb2_power: hsusb2_power_reg { + compatible = "regulator-fixed"; + regulator-name = "hsusb2_vbus"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&twl_gpio 18 0>; /* GPIO LEDA */ + startup-delay-us = <70000>; + }; + + /* HS USB Host PHY on PORT 2 */ + hsusb2_phy: hsusb2_phy { + compatible = "usb-nop-xceiv"; + reset-supply = <&hsusb2_reset>; + vcc-supply = <&hsusb2_power>; + }; +}; + +&omap3_pmx_core { + pinctrl-names = "default"; + pinctrl-0 = < + &hsusbb2_pins + >; + + hsusbb2_pins: pinmux_hsusbb2_pins { + pinctrl-single,pins = < + 0x5c0 0x3 /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_clk OUTPUT */ + 0x5c2 0x3 /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_stp OUTPUT */ + 0x5c4 0x10b /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dir INPUT | PULLDOWN */ + 0x5c6 0x10b /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_nxt INPUT | PULLDOWN */ + 0x5c8 0x10b /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat0 INPUT | PULLDOWN */ + 0x5cA 0x10b /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat1 INPUT | PULLDOWN */ + 0x1a4 0x10b /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat2 INPUT | PULLDOWN */ + 0x1a6 0x10b /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat3 INPUT | PULLDOWN */ + 0x1a8 0x10b /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat4 INPUT | PULLDOWN */ + 0x1aa 0x10b /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat5 INPUT | PULLDOWN */ + 0x1ac 0x10b /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat6 INPUT | PULLDOWN */ + 0x1ae 0x10b /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat7 INPUT | PULLDOWN */ + >; + }; }; &i2c1 { @@ -65,3 +122,23 @@ &mmc3 { status = "disabled"; }; + +&usbhshost { + port2-mode = "ehci-phy"; +}; + +&usbhsehci { + phys = <0 &hsusb2_phy>; +}; + +&twl_gpio { + ti,use-leds; + /* pullups: BIT(1) */ + ti,pullups = <0x000002>; + /* + * pulldowns: + * BIT(2), BIT(6), BIT(7), BIT(8), BIT(13) + * BIT(15), BIT(16), BIT(17) + */ + ti,pulldowns = <0x03a1c4>; +}; diff --git a/trunk/arch/arm/boot/dts/omap3-devkit8000.dts b/trunk/arch/arm/boot/dts/omap3-devkit8000.dts new file mode 100644 index 000000000000..8a5cdcc6debd --- /dev/null +++ b/trunk/arch/arm/boot/dts/omap3-devkit8000.dts @@ -0,0 +1,169 @@ +/* + * Author: Anil Kumar + * + * 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. + */ +/dts-v1/; + +/include/ "omap34xx.dtsi" +/ { + model = "TimLL OMAP3 Devkit8000"; + compatible = "timll,omap3-devkit8000", "ti,omap3"; + + memory { + device_type = "memory"; + reg = <0x80000000 0x10000000>; /* 256 MB */ + }; + + leds { + compatible = "gpio-leds"; + + heartbeat { + label = "devkit8000::led1"; + gpios = <&gpio6 26 0>; /* 186 -> LED1 */ + default-state = "on"; + linux,default-trigger = "heartbeat"; + }; + + mmc { + label = "devkit8000::led2"; + gpios = <&gpio6 3 0>; /* 163 -> LED2 */ + default-state = "on"; + linux,default-trigger = "none"; + }; + + usr { + label = "devkit8000::led3"; + gpios = <&gpio6 4 0>; /* 164 -> LED3 */ + default-state = "on"; + linux,default-trigger = "usr"; + }; + + }; + + sound { + compatible = "ti,omap-twl4030"; + ti,model = "devkit8000"; + + ti,mcbsp = <&mcbsp2>; + ti,codec = <&twl_audio>; + ti,audio-routing = + "Ext Spk", "PREDRIVEL", + "Ext Spk", "PREDRIVER", + "MAINMIC", "Main Mic", + "Main Mic", "Mic Bias 1"; + }; +}; + +&i2c1 { + clock-frequency = <2600000>; + + twl: twl@48 { + reg = <0x48>; + interrupts = <7>; /* SYS_NIRQ cascaded to intc */ + + twl_audio: audio { + compatible = "ti,twl4030-audio"; + codec { + }; + }; + }; +}; + +&i2c2 { + status = "disabled"; +}; + +&i2c3 { + status = "disabled"; +}; + +/include/ "twl4030.dtsi" + +&mmc1 { + vmmc-supply = <&vmmc1>; + vmmc_aux-supply = <&vsim>; + bus-width = <8>; +}; + +&mmc2 { + status = "disabled"; +}; + +&mmc3 { + status = "disabled"; +}; + +&wdt2 { + status = "disabled"; +}; + +&mcbsp1 { + status = "disabled"; +}; + +&mcbsp3 { + status = "disabled"; +}; + +&mcbsp4 { + status = "disabled"; +}; + +&mcbsp5 { + status = "disabled"; +}; + +&gpmc { + ranges = <0 0 0x30000000 0x04>; /* CS0: NAND */ + + nand@0,0 { + reg = <0 0 0>; /* CS0, offset 0 */ + nand-bus-width = <16>; + + gpmc,sync-clk = <0>; + gpmc,cs-on = <0>; + gpmc,cs-rd-off = <44>; + gpmc,cs-wr-off = <44>; + gpmc,adv-on = <6>; + gpmc,adv-rd-off = <34>; + gpmc,adv-wr-off = <44>; + gpmc,we-off = <40>; + gpmc,oe-off = <54>; + gpmc,access = <64>; + gpmc,rd-cycle = <82>; + gpmc,wr-cycle = <82>; + gpmc,wr-access = <40>; + gpmc,wr-data-mux-bus = <0>; + + #address-cells = <1>; + #size-cells = <1>; + + x-loader@0 { + label = "X-Loader"; + reg = <0 0x80000>; + }; + + bootloaders@80000 { + label = "U-Boot"; + reg = <0x80000 0x1e0000>; + }; + + bootloaders_env@260000 { + label = "U-Boot Env"; + reg = <0x260000 0x20000>; + }; + + kernel@280000 { + label = "Kernel"; + reg = <0x280000 0x400000>; + }; + + filesystem@680000 { + label = "File System"; + reg = <0x680000 0xf980000>; + }; + }; +}; diff --git a/trunk/arch/arm/boot/dts/omap3-evm.dts b/trunk/arch/arm/boot/dts/omap3-evm.dts index e8ba1c247a39..96d1c206a57b 100644 --- a/trunk/arch/arm/boot/dts/omap3-evm.dts +++ b/trunk/arch/arm/boot/dts/omap3-evm.dts @@ -7,12 +7,18 @@ */ /dts-v1/; -/include/ "omap3.dtsi" +/include/ "omap34xx.dtsi" / { model = "TI OMAP3 EVM (OMAP3530, AM/DM37x)"; compatible = "ti,omap3-evm", "ti,omap3"; + cpus { + cpu@0 { + cpu0-supply = <&vcc>; + }; + }; + memory { device_type = "memory"; reg = <0x80000000 0x10000000>; /* 256 MB */ @@ -59,3 +65,10 @@ &twl_gpio { ti,use-leds; }; + +&usb_otg_hs { + interface-type = <0>; + usb-phy = <&usb2_phy>; + mode = <3>; + power = <50>; +}; diff --git a/trunk/arch/arm/boot/dts/omap3-igep.dtsi b/trunk/arch/arm/boot/dts/omap3-igep.dtsi new file mode 100644 index 000000000000..f8fe3b748c3e --- /dev/null +++ b/trunk/arch/arm/boot/dts/omap3-igep.dtsi @@ -0,0 +1,122 @@ +/* + * Device Tree Source for IGEP Technology devices + * + * Copyright (C) 2012 Javier Martinez Canillas + * Copyright (C) 2012 Enric Balletbo i Serra + * + * 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. + */ +/dts-v1/; + +/include/ "omap34xx.dtsi" + +/ { + memory { + device_type = "memory"; + reg = <0x80000000 0x20000000>; /* 512 MB */ + }; + + sound { + compatible = "ti,omap-twl4030"; + ti,model = "igep2"; + ti,mcbsp = <&mcbsp2>; + ti,codec = <&twl_audio>; + }; +}; + +&omap3_pmx_core { + uart1_pins: pinmux_uart1_pins { + pinctrl-single,pins = < + 0x152 0x100 /* uart1_rx.uart1_rx INPUT | MODE0 */ + 0x14c 0 /* uart1_tx.uart1_tx OUTPUT | MODE0 */ + >; + }; + + uart2_pins: pinmux_uart2_pins { + pinctrl-single,pins = < + 0x14a 0x100 /* uart2_rx.uart2_rx INPUT | MODE0 */ + 0x148 0 /* uart2_tx.uart2_tx OUTPUT | MODE0 */ + >; + }; + + uart3_pins: pinmux_uart3_pins { + pinctrl-single,pins = < + 0x16e 0x100 /* uart3_rx.uart3_rx INPUT | MODE0 */ + 0x170 0 /* uart3_tx.uart3_tx OUTPUT | MODE0 */ + >; + }; + + mmc1_pins: pinmux_mmc1_pins { + pinctrl-single,pins = < + 0x114 0x0118 /* sdmmc1_clk.sdmmc1_clk INPUT PULLUP | MODE 0 */ + 0x116 0x0118 /* sdmmc1_cmd.sdmmc1_cmd INPUT PULLUP | MODE 0 */ + 0x118 0x0118 /* sdmmc1_dat0.sdmmc1_dat0 INPUT PULLUP | MODE 0 */ + 0x11a 0x0118 /* sdmmc1_dat1.sdmmc1_dat1 INPUT PULLUP | MODE 0 */ + 0x11c 0x0118 /* sdmmc1_dat2.sdmmc1_dat2 INPUT PULLUP | MODE 0 */ + 0x11e 0x0118 /* sdmmc1_dat3.sdmmc1_dat3 INPUT PULLUP | MODE 0 */ + 0x120 0x0100 /* sdmmc1_dat4.sdmmc1_dat4 INPUT | MODE 0 */ + 0x122 0x0100 /* sdmmc1_dat5.sdmmc1_dat5 INPUT | MODE 0 */ + 0x124 0x0100 /* sdmmc1_dat6.sdmmc1_dat6 INPUT | MODE 0 */ + 0x126 0x0100 /* sdmmc1_dat7.sdmmc1_dat7 INPUT | MODE 0 */ + >; + }; +}; + +&i2c1 { + clock-frequency = <2600000>; + + twl: twl@48 { + reg = <0x48>; + interrupts = <7>; /* SYS_NIRQ cascaded to intc */ + interrupt-parent = <&intc>; + + twl_audio: audio { + compatible = "ti,twl4030-audio"; + codec { + }; + }; + }; +}; + +/include/ "twl4030.dtsi" + +&i2c2 { + clock-frequency = <400000>; +}; + +&mmc1 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins>; + vmmc-supply = <&vmmc1>; + vmmc_aux-supply = <&vsim>; + bus-width = <8>; +}; + +&mmc2 { + status = "disabled"; +}; + +&mmc3 { + status = "disabled"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&uart3_pins>; +}; + +&twl_gpio { + ti,use-leds; +}; diff --git a/trunk/arch/arm/boot/dts/omap3-igep0020.dts b/trunk/arch/arm/boot/dts/omap3-igep0020.dts new file mode 100644 index 000000000000..e2b98490cc9a --- /dev/null +++ b/trunk/arch/arm/boot/dts/omap3-igep0020.dts @@ -0,0 +1,56 @@ +/* + * Device Tree Source for IGEPv2 board + * + * Copyright (C) 2012 Javier Martinez Canillas + * Copyright (C) 2012 Enric Balletbo i Serra + * + * 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/ "omap3-igep.dtsi" + +/ { + model = "IGEPv2"; + compatible = "isee,omap3-igep0020", "ti,omap3"; + + leds { + compatible = "gpio-leds"; + boot { + label = "omap3:green:boot"; + gpios = <&gpio1 26 0>; + default-state = "on"; + }; + + user0 { + label = "omap3:red:user0"; + gpios = <&gpio1 27 0>; + default-state = "off"; + }; + + user1 { + label = "omap3:red:user1"; + gpios = <&gpio1 28 0>; + default-state = "off"; + }; + + user2 { + label = "omap3:green:user1"; + gpios = <&twl_gpio 19 1>; + }; + }; +}; + +&i2c3 { + clock-frequency = <100000>; + + /* + * Display monitor features are burnt in the EEPROM + * as EDID data. + */ + eeprom@50 { + compatible = "ti,eeprom"; + reg = <0x50>; + }; +}; diff --git a/trunk/arch/arm/boot/dts/omap3-igep0030.dts b/trunk/arch/arm/boot/dts/omap3-igep0030.dts new file mode 100644 index 000000000000..9dc48d262ffb --- /dev/null +++ b/trunk/arch/arm/boot/dts/omap3-igep0030.dts @@ -0,0 +1,44 @@ +/* + * Device Tree Source for IGEP COM Module + * + * Copyright (C) 2012 Javier Martinez Canillas + * Copyright (C) 2012 Enric Balletbo i Serra + * + * 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/ "omap3-igep.dtsi" + +/ { + model = "IGEP COM Module"; + compatible = "isee,omap3-igep0030", "ti,omap3"; + + leds { + compatible = "gpio-leds"; + boot { + label = "omap3:green:boot"; + gpios = <&twl_gpio 13 1>; + default-state = "on"; + }; + + user0 { + label = "omap3:red:user0"; + gpios = <&twl_gpio 18 1>; /* LEDA */ + default-state = "off"; + }; + + user1 { + label = "omap3:green:user1"; + gpios = <&twl_gpio 19 1>; /* LEDB */ + default-state = "off"; + }; + + user2 { + label = "omap3:red:user1"; + gpios = <&gpio1 16 1>; + default-state = "off"; + }; + }; +}; diff --git a/trunk/arch/arm/boot/dts/omap3-overo.dtsi b/trunk/arch/arm/boot/dts/omap3-overo.dtsi index 89808ce01673..a626c50041f6 100644 --- a/trunk/arch/arm/boot/dts/omap3-overo.dtsi +++ b/trunk/arch/arm/boot/dts/omap3-overo.dtsi @@ -11,17 +11,26 @@ */ /dts-v1/; -/include/ "omap3.dtsi" +/include/ "omap34xx.dtsi" / { - leds { - compatible = "gpio-leds"; + pwmleds { + compatible = "pwm-leds"; + overo { label = "overo:blue:COM"; - gpios = <&twl_gpio 19 0>; - linux,default-trigger = "mmc0"; + pwms = <&twl_pwmled 1 7812500>; + max-brightness = <127>; }; }; + + sound { + compatible = "ti,omap-twl4030"; + ti,model = "overo"; + + ti,mcbsp = <&mcbsp2>; + ti,codec = <&twl_audio>; + }; }; &i2c1 { @@ -31,6 +40,12 @@ reg = <0x48>; interrupts = <7>; /* SYS_NIRQ cascaded to intc */ interrupt-parent = <&intc>; + + twl_audio: audio { + compatible = "ti,twl4030-audio"; + codec { + }; + }; }; }; @@ -55,3 +70,10 @@ &twl_gpio { ti,use-leds; }; + +&usb_otg_hs { + interface-type = <0>; + usb-phy = <&usb2_phy>; + mode = <3>; + power = <50>; +}; diff --git a/trunk/arch/arm/boot/dts/omap3.dtsi b/trunk/arch/arm/boot/dts/omap3.dtsi index 1acc26148ffc..82a404da1c0d 100644 --- a/trunk/arch/arm/boot/dts/omap3.dtsi +++ b/trunk/arch/arm/boot/dts/omap3.dtsi @@ -26,8 +26,14 @@ }; }; + pmu { + compatible = "arm,cortex-a8-pmu"; + interrupts = <3>; + ti,hwmods = "debugss"; + }; + /* - * The soc node represents the soc top level view. It is uses for IPs + * The soc node represents the soc top level view. It is used for IPs * that are not memory mapped in the MPU view or for the MPU itself. */ soc { @@ -75,76 +81,101 @@ reg = <0x48200000 0x1000>; }; + sdma: dma-controller@48056000 { + compatible = "ti,omap3630-sdma", "ti,omap3430-sdma"; + reg = <0x48056000 0x1000>; + interrupts = <12>, + <13>, + <14>, + <15>; + #dma-cells = <1>; + #dma-channels = <32>; + #dma-requests = <96>; + }; + omap3_pmx_core: pinmux@48002030 { compatible = "ti,omap3-padconf", "pinctrl-single"; reg = <0x48002030 0x05cc>; #address-cells = <1>; #size-cells = <0>; pinctrl-single,register-width = <16>; - pinctrl-single,function-mask = <0x7fff>; + pinctrl-single,function-mask = <0x7f1f>; }; - omap3_pmx_wkup: pinmux@0x48002a58 { + omap3_pmx_wkup: pinmux@0x48002a00 { compatible = "ti,omap3-padconf", "pinctrl-single"; - reg = <0x48002a58 0x5c>; + reg = <0x48002a00 0x5c>; #address-cells = <1>; #size-cells = <0>; pinctrl-single,register-width = <16>; - pinctrl-single,function-mask = <0x7fff>; + pinctrl-single,function-mask = <0x7f1f>; }; gpio1: gpio@48310000 { compatible = "ti,omap3-gpio"; + reg = <0x48310000 0x200>; + interrupts = <29>; ti,hwmods = "gpio1"; + ti,gpio-always-on; gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio2: gpio@49050000 { compatible = "ti,omap3-gpio"; + reg = <0x49050000 0x200>; + interrupts = <30>; ti,hwmods = "gpio2"; gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio3: gpio@49052000 { compatible = "ti,omap3-gpio"; + reg = <0x49052000 0x200>; + interrupts = <31>; ti,hwmods = "gpio3"; gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio4: gpio@49054000 { compatible = "ti,omap3-gpio"; + reg = <0x49054000 0x200>; + interrupts = <32>; ti,hwmods = "gpio4"; gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio5: gpio@49056000 { compatible = "ti,omap3-gpio"; + reg = <0x49056000 0x200>; + interrupts = <33>; ti,hwmods = "gpio5"; gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio6: gpio@49058000 { compatible = "ti,omap3-gpio"; + reg = <0x49058000 0x200>; + interrupts = <34>; ti,hwmods = "gpio6"; gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; uart1: serial@4806a000 { @@ -192,6 +223,16 @@ #size-cells = <0>; ti,hwmods = "mcspi1"; ti,spi-num-cs = <4>; + dmas = <&sdma 35>, + <&sdma 36>, + <&sdma 37>, + <&sdma 38>, + <&sdma 39>, + <&sdma 40>, + <&sdma 41>, + <&sdma 42>; + dma-names = "tx0", "rx0", "tx1", "rx1", + "tx2", "rx2", "tx3", "rx3"; }; mcspi2: spi@4809a000 { @@ -200,6 +241,11 @@ #size-cells = <0>; ti,hwmods = "mcspi2"; ti,spi-num-cs = <2>; + dmas = <&sdma 43>, + <&sdma 44>, + <&sdma 45>, + <&sdma 46>; + dma-names = "tx0", "rx0", "tx1", "rx1"; }; mcspi3: spi@480b8000 { @@ -208,6 +254,11 @@ #size-cells = <0>; ti,hwmods = "mcspi3"; ti,spi-num-cs = <2>; + dmas = <&sdma 15>, + <&sdma 16>, + <&sdma 23>, + <&sdma 24>; + dma-names = "tx0", "rx0", "tx1", "rx1"; }; mcspi4: spi@480ba000 { @@ -216,22 +267,30 @@ #size-cells = <0>; ti,hwmods = "mcspi4"; ti,spi-num-cs = <1>; + dmas = <&sdma 70>, <&sdma 71>; + dma-names = "tx0", "rx0"; }; mmc1: mmc@4809c000 { compatible = "ti,omap3-hsmmc"; ti,hwmods = "mmc1"; ti,dual-volt; + dmas = <&sdma 61>, <&sdma 62>; + dma-names = "tx", "rx"; }; mmc2: mmc@480b4000 { compatible = "ti,omap3-hsmmc"; ti,hwmods = "mmc2"; + dmas = <&sdma 47>, <&sdma 48>; + dma-names = "tx", "rx"; }; mmc3: mmc@480ad000 { compatible = "ti,omap3-hsmmc"; ti,hwmods = "mmc3"; + dmas = <&sdma 77>, <&sdma 78>; + dma-names = "tx", "rx"; }; wdt2: wdt@48314000 { @@ -249,6 +308,9 @@ interrupt-names = "common", "tx", "rx"; ti,buffer-size = <128>; ti,hwmods = "mcbsp1"; + dmas = <&sdma 31>, + <&sdma 32>; + dma-names = "tx", "rx"; }; mcbsp2: mcbsp@49022000 { @@ -263,6 +325,9 @@ interrupt-names = "common", "tx", "rx", "sidetone"; ti,buffer-size = <1280>; ti,hwmods = "mcbsp2", "mcbsp2_sidetone"; + dmas = <&sdma 33>, + <&sdma 34>; + dma-names = "tx", "rx"; }; mcbsp3: mcbsp@49024000 { @@ -277,6 +342,9 @@ interrupt-names = "common", "tx", "rx", "sidetone"; ti,buffer-size = <128>; ti,hwmods = "mcbsp3", "mcbsp3_sidetone"; + dmas = <&sdma 17>, + <&sdma 18>; + dma-names = "tx", "rx"; }; mcbsp4: mcbsp@49026000 { @@ -289,6 +357,9 @@ interrupt-names = "common", "tx", "rx"; ti,buffer-size = <128>; ti,hwmods = "mcbsp4"; + dmas = <&sdma 19>, + <&sdma 20>; + dma-names = "tx", "rx"; }; mcbsp5: mcbsp@48096000 { @@ -301,10 +372,13 @@ interrupt-names = "common", "tx", "rx"; ti,buffer-size = <128>; ti,hwmods = "mcbsp5"; + dmas = <&sdma 21>, + <&sdma 22>; + dma-names = "tx", "rx"; }; timer1: timer@48318000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap3430-timer"; reg = <0x48318000 0x400>; interrupts = <37>; ti,hwmods = "timer1"; @@ -312,28 +386,28 @@ }; timer2: timer@49032000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap3430-timer"; reg = <0x49032000 0x400>; interrupts = <38>; ti,hwmods = "timer2"; }; timer3: timer@49034000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap3430-timer"; reg = <0x49034000 0x400>; interrupts = <39>; ti,hwmods = "timer3"; }; timer4: timer@49036000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap3430-timer"; reg = <0x49036000 0x400>; interrupts = <40>; ti,hwmods = "timer4"; }; timer5: timer@49038000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap3430-timer"; reg = <0x49038000 0x400>; interrupts = <41>; ti,hwmods = "timer5"; @@ -341,7 +415,7 @@ }; timer6: timer@4903a000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap3430-timer"; reg = <0x4903a000 0x400>; interrupts = <42>; ti,hwmods = "timer6"; @@ -349,7 +423,7 @@ }; timer7: timer@4903c000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap3430-timer"; reg = <0x4903c000 0x400>; interrupts = <43>; ti,hwmods = "timer7"; @@ -357,7 +431,7 @@ }; timer8: timer@4903e000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap3430-timer"; reg = <0x4903e000 0x400>; interrupts = <44>; ti,hwmods = "timer8"; @@ -366,7 +440,7 @@ }; timer9: timer@49040000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap3430-timer"; reg = <0x49040000 0x400>; interrupts = <45>; ti,hwmods = "timer9"; @@ -374,7 +448,7 @@ }; timer10: timer@48086000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap3430-timer"; reg = <0x48086000 0x400>; interrupts = <46>; ti,hwmods = "timer10"; @@ -382,7 +456,7 @@ }; timer11: timer@48088000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap3430-timer"; reg = <0x48088000 0x400>; interrupts = <47>; ti,hwmods = "timer11"; @@ -390,12 +464,64 @@ }; timer12: timer@48304000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap3430-timer"; reg = <0x48304000 0x400>; interrupts = <95>; ti,hwmods = "timer12"; ti,timer-alwon; ti,timer-secure; }; + + usbhstll: usbhstll@48062000 { + compatible = "ti,usbhs-tll"; + reg = <0x48062000 0x1000>; + interrupts = <78>; + ti,hwmods = "usb_tll_hs"; + }; + + usbhshost: usbhshost@48064000 { + compatible = "ti,usbhs-host"; + reg = <0x48064000 0x400>; + ti,hwmods = "usb_host_hs"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + usbhsohci: ohci@48064400 { + compatible = "ti,ohci-omap3", "usb-ohci"; + reg = <0x48064400 0x400>; + interrupt-parent = <&intc>; + interrupts = <76>; + }; + + usbhsehci: ehci@48064800 { + compatible = "ti,ehci-omap", "usb-ehci"; + reg = <0x48064800 0x400>; + interrupt-parent = <&intc>; + interrupts = <77>; + }; + }; + + gpmc: gpmc@6e000000 { + compatible = "ti,omap3430-gpmc"; + ti,hwmods = "gpmc"; + reg = <0x6e000000 0x02d0>; + interrupts = <20>; + gpmc,num-cs = <8>; + gpmc,num-waitpins = <4>; + #address-cells = <2>; + #size-cells = <1>; + }; + + usb_otg_hs: usb_otg_hs@480ab000 { + compatible = "ti,omap3-musb"; + reg = <0x480ab000 0x1000>; + interrupts = <0 92 0x4>, <0 93 0x4>; + interrupt-names = "mc", "dma"; + ti,hwmods = "usb_otg_hs"; + multipoint = <1>; + num-eps = <16>; + ram-bits = <12>; + }; }; }; diff --git a/trunk/arch/arm/boot/dts/omap3430-sdp.dts b/trunk/arch/arm/boot/dts/omap3430-sdp.dts new file mode 100644 index 000000000000..144ae43453c4 --- /dev/null +++ b/trunk/arch/arm/boot/dts/omap3430-sdp.dts @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +/dts-v1/; + +/include/ "omap34xx.dtsi" + +/ { + model = "TI OMAP3430 SDP"; + compatible = "ti,omap3430-sdp", "ti,omap3"; + + memory { + device_type = "memory"; + reg = <0x80000000 0x10000000>; /* 256 MB */ + }; +}; + +&i2c1 { + clock-frequency = <2600000>; + + twl: twl@48 { + reg = <0x48>; + interrupts = <7>; /* SYS_NIRQ cascaded to intc */ + }; +}; + +/include/ "twl4030.dtsi" + +&mmc1 { + vmmc-supply = <&vmmc1>; + vmmc_aux-supply = <&vsim>; + bus-width = <8>; +}; + +&mmc2 { + status = "disabled"; +}; + +&mmc3 { + status = "disabled"; +}; + +&gpmc { + ranges = <0 0 0x10000000 0x08000000>, + <1 0 0x28000000 0x08000000>, + <2 0 0x20000000 0x10000000>; + + nor@0,0 { + compatible = "cfi-flash"; + linux,mtd-name= "intel,pf48f6000m0y1be"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0 0 0x08000000>; + bank-width = <2>; + + gpmc,mux-add-data = <2>; + gpmc,cs-on-ns = <0>; + gpmc,cs-rd-off-ns = <186>; + gpmc,cs-wr-off-ns = <186>; + gpmc,adv-on-ns = <12>; + gpmc,adv-rd-off-ns = <48>; + gpmc,adv-wr-off-ns = <48>; + gpmc,oe-on-ns = <54>; + gpmc,oe-off-ns = <168>; + gpmc,we-on-ns = <54>; + gpmc,we-off-ns = <168>; + gpmc,rd-cycle-ns = <186>; + gpmc,wr-cycle-ns = <186>; + gpmc,access-ns = <114>; + gpmc,page-burst-access-ns = <6>; + gpmc,bus-turnaround-ns = <12>; + gpmc,cycle2cycle-delay-ns = <18>; + gpmc,wr-data-mux-bus-ns = <90>; + gpmc,wr-access-ns = <186>; + gpmc,cycle2cycle-samecsen; + gpmc,cycle2cycle-diffcsen; + + partition@0 { + label = "bootloader-nor"; + reg = <0 0x40000>; + }; + partition@0x40000 { + label = "params-nor"; + reg = <0x40000 0x40000>; + }; + partition@0x80000 { + label = "kernel-nor"; + reg = <0x80000 0x200000>; + }; + partition@0x280000 { + label = "filesystem-nor"; + reg = <0x240000 0x7d80000>; + }; + }; + + nand@1,0 { + linux,mtd-name= "micron,mt29f1g08abb"; + #address-cells = <1>; + #size-cells = <1>; + reg = <1 0 0x08000000>; + nand-bus-width = <8>; + + ti,nand-ecc-opt = "sw"; + gpmc,device-nand; + gpmc,cs-on-ns = <0>; + gpmc,cs-rd-off-ns = <36>; + gpmc,cs-wr-off-ns = <36>; + gpmc,adv-on-ns = <6>; + gpmc,adv-rd-off-ns = <24>; + gpmc,adv-wr-off-ns = <36>; + gpmc,oe-on-ns = <6>; + gpmc,oe-off-ns = <48>; + gpmc,we-on-ns = <6>; + gpmc,we-off-ns = <30>; + gpmc,rd-cycle-ns = <72>; + gpmc,wr-cycle-ns = <72>; + gpmc,access-ns = <54>; + gpmc,wr-access-ns = <30>; + + partition@0 { + label = "xloader-nand"; + reg = <0 0x80000>; + }; + partition@0x80000 { + label = "bootloader-nand"; + reg = <0x80000 0x140000>; + }; + partition@0x1c0000 { + label = "params-nand"; + reg = <0x1c0000 0xc0000>; + }; + partition@0x280000 { + label = "kernel-nand"; + reg = <0x280000 0x500000>; + }; + partition@0x780000 { + label = "filesystem-nand"; + reg = <0x780000 0x7880000>; + }; + }; + + onenand@2,0 { + linux,mtd-name= "samsung,kfm2g16q2m-deb8"; + #address-cells = <1>; + #size-cells = <1>; + reg = <2 0 0x10000000>; + + gpmc,device-width = <2>; + gpmc,mux-add-data = <2>; + gpmc,cs-on-ns = <0>; + gpmc,cs-rd-off-ns = <84>; + gpmc,cs-wr-off-ns = <72>; + gpmc,adv-on-ns = <0>; + gpmc,adv-rd-off-ns = <18>; + gpmc,adv-wr-off-ns = <18>; + gpmc,oe-on-ns = <30>; + gpmc,oe-off-ns = <84>; + gpmc,we-on-ns = <0>; + gpmc,we-off-ns = <42>; + gpmc,rd-cycle-ns = <108>; + gpmc,wr-cycle-ns = <96>; + gpmc,access-ns = <78>; + gpmc,wr-data-mux-bus-ns = <30>; + + partition@0 { + label = "xloader-onenand"; + reg = <0 0x80000>; + }; + partition@0x80000 { + label = "bootloader-onenand"; + reg = <0x80000 0x40000>; + }; + partition@0xc0000 { + label = "params-onenand"; + reg = <0xc0000 0x20000>; + }; + partition@0xe0000 { + label = "kernel-onenand"; + reg = <0xe0000 0x200000>; + }; + partition@0x2e0000 { + label = "filesystem-onenand"; + reg = <0x2e0000 0xfd20000>; + }; + }; +}; diff --git a/trunk/arch/arm/boot/dts/omap34xx.dtsi b/trunk/arch/arm/boot/dts/omap34xx.dtsi new file mode 100644 index 000000000000..75ed4ae2e631 --- /dev/null +++ b/trunk/arch/arm/boot/dts/omap34xx.dtsi @@ -0,0 +1,28 @@ +/* + * Device Tree Source for OMAP34xx/OMAP35xx SoC + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +/include/ "omap3.dtsi" + +/ { + cpus { + cpu@0 { + /* OMAP343x/OMAP35xx variants OPP1-5 */ + operating-points = < + /* kHz uV */ + 125000 975000 + 250000 1075000 + 500000 1200000 + 550000 1270000 + 600000 1350000 + >; + clock-latency = <300000>; /* From legacy driver */ + }; + }; +}; diff --git a/trunk/arch/arm/boot/dts/omap36xx.dtsi b/trunk/arch/arm/boot/dts/omap36xx.dtsi index 96bf0287cb9f..f3447bc1b032 100644 --- a/trunk/arch/arm/boot/dts/omap36xx.dtsi +++ b/trunk/arch/arm/boot/dts/omap36xx.dtsi @@ -15,6 +15,19 @@ serial3 = &uart4; }; + cpus { + /* OMAP3630/OMAP37xx 'standard device' variants OPP50 to OPP130 */ + cpu@0 { + operating-points = < + /* kHz uV */ + 300000 1012500 + 600000 1200000 + 800000 1325000 + >; + clock-latency = <300000>; /* From legacy driver */ + }; + }; + ocp { uart4: serial@49042000 { compatible = "ti,omap3-uart"; diff --git a/trunk/arch/arm/boot/dts/omap4-panda-a4.dts b/trunk/arch/arm/boot/dts/omap4-panda-a4.dts index 75466d2abfb5..e30cdf0f5ac1 100644 --- a/trunk/arch/arm/boot/dts/omap4-panda-a4.dts +++ b/trunk/arch/arm/boot/dts/omap4-panda-a4.dts @@ -5,7 +5,10 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -/include/ "omap4-panda.dts" +/dts-v1/; + +/include/ "omap443x.dtsi" +/include/ "omap4-panda-common.dtsi" /* Pandaboard Rev A4+ have external pullups on SCL & SDA */ &dss_hdmi_pins { diff --git a/trunk/arch/arm/boot/dts/omap4-panda-common.dtsi b/trunk/arch/arm/boot/dts/omap4-panda-common.dtsi new file mode 100644 index 000000000000..03bd60deb52b --- /dev/null +++ b/trunk/arch/arm/boot/dts/omap4-panda-common.dtsi @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2011-2013 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +/include/ "elpida_ecb240abacn.dtsi" + +/ { + model = "TI OMAP4 PandaBoard"; + compatible = "ti,omap4-panda", "ti,omap4430", "ti,omap4"; + + memory { + device_type = "memory"; + reg = <0x80000000 0x40000000>; /* 1 GB */ + }; + + leds { + compatible = "gpio-leds"; + heartbeat { + label = "pandaboard::status1"; + gpios = <&gpio1 7 0>; + linux,default-trigger = "heartbeat"; + }; + + mmc { + label = "pandaboard::status2"; + gpios = <&gpio1 8 0>; + linux,default-trigger = "mmc0"; + }; + }; + + sound: sound { + compatible = "ti,abe-twl6040"; + ti,model = "PandaBoard"; + + ti,mclk-freq = <38400000>; + + ti,mcpdm = <&mcpdm>; + + ti,twl6040 = <&twl6040>; + + /* Audio routing */ + ti,audio-routing = + "Headset Stereophone", "HSOL", + "Headset Stereophone", "HSOR", + "Ext Spk", "HFL", + "Ext Spk", "HFR", + "Line Out", "AUXL", + "Line Out", "AUXR", + "HSMIC", "Headset Mic", + "Headset Mic", "Headset Mic Bias", + "AFML", "Line In", + "AFMR", "Line In"; + }; +}; + +&omap4_pmx_core { + pinctrl-names = "default"; + pinctrl-0 = < + &twl6040_pins + &mcpdm_pins + &mcbsp1_pins + &dss_hdmi_pins + &tpd12s015_pins + >; + + twl6040_pins: pinmux_twl6040_pins { + pinctrl-single,pins = < + 0xe0 0x3 /* hdq_sio.gpio_127 OUTPUT | MODE3 */ + 0x160 0x100 /* sys_nirq2.sys_nirq2 INPUT | MODE0 */ + >; + }; + + mcpdm_pins: pinmux_mcpdm_pins { + pinctrl-single,pins = < + 0xc6 0x108 /* abe_pdm_ul_data.abe_pdm_ul_data INPUT PULLDOWN | MODE0 */ + 0xc8 0x108 /* abe_pdm_dl_data.abe_pdm_dl_data INPUT PULLDOWN | MODE0 */ + 0xca 0x118 /* abe_pdm_frame.abe_pdm_frame INPUT PULLUP | MODE0 */ + 0xcc 0x108 /* abe_pdm_lb_clk.abe_pdm_lb_clk INPUT PULLDOWN | MODE0 */ + 0xce 0x108 /* abe_clks.abe_clks INPUT PULLDOWN | MODE0 */ + >; + }; + + mcbsp1_pins: pinmux_mcbsp1_pins { + pinctrl-single,pins = < + 0xbe 0x100 /* abe_mcbsp1_clkx.abe_mcbsp1_clkx INPUT | MODE0 */ + 0xc0 0x108 /* abe_mcbsp1_dr.abe_mcbsp1_dr INPUT PULLDOWN | MODE0 */ + 0xc2 0x8 /* abe_mcbsp1_dx.abe_mcbsp1_dx OUTPUT PULLDOWN | MODE0 */ + 0xc4 0x100 /* abe_mcbsp1_fsx.abe_mcbsp1_fsx INPUT | MODE0 */ + >; + }; + + dss_hdmi_pins: pinmux_dss_hdmi_pins { + pinctrl-single,pins = < + 0x5a 0x118 /* hdmi_cec.hdmi_cec INPUT PULLUP | MODE 0 */ + 0x5c 0x118 /* hdmi_scl.hdmi_scl INPUT PULLUP | MODE 0 */ + 0x5e 0x118 /* hdmi_sda.hdmi_sda INPUT PULLUP | MODE 0 */ + >; + }; + + tpd12s015_pins: pinmux_tpd12s015_pins { + pinctrl-single,pins = < + 0x22 0x3 /* gpmc_a17.gpio_41 OUTPUT | MODE3 */ + 0x48 0x3 /* gpmc_nbe1.gpio_60 OUTPUT | MODE3 */ + 0x58 0x10b /* hdmi_hpd.gpio_63 INPUT PULLDOWN | MODE3 */ + >; + }; + + i2c1_pins: pinmux_i2c1_pins { + pinctrl-single,pins = < + 0xe2 0x118 /* i2c1_scl PULLUP | INPUTENABLE | MODE0 */ + 0xe4 0x118 /* i2c1_sda PULLUP | INPUTENABLE | MODE0 */ + >; + }; + + i2c2_pins: pinmux_i2c2_pins { + pinctrl-single,pins = < + 0xe6 0x118 /* i2c2_scl PULLUP | INPUTENABLE | MODE0 */ + 0xe8 0x118 /* i2c2_sda PULLUP | INPUTENABLE | MODE0 */ + >; + }; + + i2c3_pins: pinmux_i2c3_pins { + pinctrl-single,pins = < + 0xea 0x118 /* i2c3_scl PULLUP | INPUTENABLE | MODE0 */ + 0xec 0x118 /* i2c3_sda PULLUP | INPUTENABLE | MODE0 */ + >; + }; + + i2c4_pins: pinmux_i2c4_pins { + pinctrl-single,pins = < + 0xee 0x118 /* i2c4_scl PULLUP | INPUTENABLE | MODE0 */ + 0xf0 0x118 /* i2c4_sda PULLUP | INPUTENABLE | MODE0 */ + >; + }; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + + clock-frequency = <400000>; + + twl: twl@48 { + reg = <0x48>; + /* SPI = 0, IRQ# = 7, 4 = active high level-sensitive */ + interrupts = <0 7 4>; /* IRQ_SYS_1N cascaded to gic */ + interrupt-parent = <&gic>; + }; + + twl6040: twl@4b { + compatible = "ti,twl6040"; + reg = <0x4b>; + /* SPI = 0, IRQ# = 119, 4 = active high level-sensitive */ + interrupts = <0 119 4>; /* IRQ_SYS_2N cascaded to gic */ + interrupt-parent = <&gic>; + ti,audpwron-gpio = <&gpio4 31 0>; /* gpio line 127 */ + + vio-supply = <&v1v8>; + v2v1-supply = <&v2v1>; + enable-active-high; + }; +}; + +/include/ "twl6030.dtsi" + +&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins>; + + clock-frequency = <400000>; +}; + +&i2c3 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c3_pins>; + + clock-frequency = <100000>; + + /* + * Display monitor features are burnt in their EEPROM as EDID data. + * The EEPROM is connected as I2C slave device. + */ + eeprom@50 { + compatible = "ti,eeprom"; + reg = <0x50>; + }; +}; + +&i2c4 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c4_pins>; + + clock-frequency = <400000>; +}; + +&mmc1 { + vmmc-supply = <&vmmc>; + bus-width = <8>; +}; + +&mmc2 { + status = "disabled"; +}; + +&mmc3 { + status = "disabled"; +}; + +&mmc4 { + status = "disabled"; +}; + +&mmc5 { + ti,non-removable; + bus-width = <4>; +}; + +&emif1 { + cs1-used; + device-handle = <&elpida_ECB240ABACN>; +}; + +&emif2 { + cs1-used; + device-handle = <&elpida_ECB240ABACN>; +}; + +&mcbsp2 { + status = "disabled"; +}; + +&mcbsp3 { + status = "disabled"; +}; + +&dmic { + status = "disabled"; +}; + +&twl_usb_comparator { + usb-supply = <&vusb>; +}; + +&usb_otg_hs { + interface-type = <1>; + mode = <3>; + power = <50>; +}; diff --git a/trunk/arch/arm/boot/dts/omap4-panda-es.dts b/trunk/arch/arm/boot/dts/omap4-panda-es.dts index 73bc1a67e444..f1d8c217ce12 100644 --- a/trunk/arch/arm/boot/dts/omap4-panda-es.dts +++ b/trunk/arch/arm/boot/dts/omap4-panda-es.dts @@ -5,7 +5,10 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -/include/ "omap4-panda.dts" +/dts-v1/; + +/include/ "omap4460.dtsi" +/include/ "omap4-panda-common.dtsi" /* Audio routing is differnet between PandaBoard4430 and PandaBoardES */ &sound { diff --git a/trunk/arch/arm/boot/dts/omap4-panda.dts b/trunk/arch/arm/boot/dts/omap4-panda.dts index 4122efe31cfd..f8b221f0168e 100644 --- a/trunk/arch/arm/boot/dts/omap4-panda.dts +++ b/trunk/arch/arm/boot/dts/omap4-panda.dts @@ -7,202 +7,5 @@ */ /dts-v1/; -/include/ "omap4.dtsi" -/include/ "elpida_ecb240abacn.dtsi" - -/ { - model = "TI OMAP4 PandaBoard"; - compatible = "ti,omap4-panda", "ti,omap4430", "ti,omap4"; - - memory { - device_type = "memory"; - reg = <0x80000000 0x40000000>; /* 1 GB */ - }; - - leds { - compatible = "gpio-leds"; - heartbeat { - label = "pandaboard::status1"; - gpios = <&gpio1 7 0>; - linux,default-trigger = "heartbeat"; - }; - - mmc { - label = "pandaboard::status2"; - gpios = <&gpio1 8 0>; - linux,default-trigger = "mmc0"; - }; - }; - - sound: sound { - compatible = "ti,abe-twl6040"; - ti,model = "PandaBoard"; - - ti,mclk-freq = <38400000>; - - ti,mcpdm = <&mcpdm>; - - ti,twl6040 = <&twl6040>; - - /* Audio routing */ - ti,audio-routing = - "Headset Stereophone", "HSOL", - "Headset Stereophone", "HSOR", - "Ext Spk", "HFL", - "Ext Spk", "HFR", - "Line Out", "AUXL", - "Line Out", "AUXR", - "HSMIC", "Headset Mic", - "Headset Mic", "Headset Mic Bias", - "AFML", "Line In", - "AFMR", "Line In"; - }; -}; - -&omap4_pmx_core { - pinctrl-names = "default"; - pinctrl-0 = < - &twl6040_pins - &mcpdm_pins - &mcbsp1_pins - &dss_hdmi_pins - &tpd12s015_pins - >; - - twl6040_pins: pinmux_twl6040_pins { - pinctrl-single,pins = < - 0xe0 0x3 /* hdq_sio.gpio_127 OUTPUT | MODE3 */ - 0x160 0x100 /* sys_nirq2.sys_nirq2 INPUT | MODE0 */ - >; - }; - - mcpdm_pins: pinmux_mcpdm_pins { - pinctrl-single,pins = < - 0xc6 0x108 /* abe_pdm_ul_data.abe_pdm_ul_data INPUT PULLDOWN | MODE0 */ - 0xc8 0x108 /* abe_pdm_dl_data.abe_pdm_dl_data INPUT PULLDOWN | MODE0 */ - 0xca 0x118 /* abe_pdm_frame.abe_pdm_frame INPUT PULLUP | MODE0 */ - 0xcc 0x108 /* abe_pdm_lb_clk.abe_pdm_lb_clk INPUT PULLDOWN | MODE0 */ - 0xce 0x108 /* abe_clks.abe_clks INPUT PULLDOWN | MODE0 */ - >; - }; - - mcbsp1_pins: pinmux_mcbsp1_pins { - pinctrl-single,pins = < - 0xbe 0x100 /* abe_mcbsp1_clkx.abe_mcbsp1_clkx INPUT | MODE0 */ - 0xc0 0x108 /* abe_mcbsp1_dr.abe_mcbsp1_dr INPUT PULLDOWN | MODE0 */ - 0xc2 0x8 /* abe_mcbsp1_dx.abe_mcbsp1_dx OUTPUT PULLDOWN | MODE0 */ - 0xc4 0x100 /* abe_mcbsp1_fsx.abe_mcbsp1_fsx INPUT | MODE0 */ - >; - }; - - dss_hdmi_pins: pinmux_dss_hdmi_pins { - pinctrl-single,pins = < - 0x5a 0x118 /* hdmi_cec.hdmi_cec INPUT PULLUP | MODE 0 */ - 0x5c 0x118 /* hdmi_scl.hdmi_scl INPUT PULLUP | MODE 0 */ - 0x5e 0x118 /* hdmi_sda.hdmi_sda INPUT PULLUP | MODE 0 */ - >; - }; - - tpd12s015_pins: pinmux_tpd12s015_pins { - pinctrl-single,pins = < - 0x22 0x3 /* gpmc_a17.gpio_41 OUTPUT | MODE3 */ - 0x48 0x3 /* gpmc_nbe1.gpio_60 OUTPUT | MODE3 */ - 0x58 0x10b /* hdmi_hpd.gpio_63 INPUT PULLDOWN | MODE3 */ - >; - }; -}; - -&i2c1 { - clock-frequency = <400000>; - - twl: twl@48 { - reg = <0x48>; - /* SPI = 0, IRQ# = 7, 4 = active high level-sensitive */ - interrupts = <0 7 4>; /* IRQ_SYS_1N cascaded to gic */ - interrupt-parent = <&gic>; - }; - - twl6040: twl@4b { - compatible = "ti,twl6040"; - reg = <0x4b>; - /* SPI = 0, IRQ# = 119, 4 = active high level-sensitive */ - interrupts = <0 119 4>; /* IRQ_SYS_2N cascaded to gic */ - interrupt-parent = <&gic>; - ti,audpwron-gpio = <&gpio4 31 0>; /* gpio line 127 */ - - vio-supply = <&v1v8>; - v2v1-supply = <&v2v1>; - enable-active-high; - }; -}; - -/include/ "twl6030.dtsi" - -&i2c2 { - clock-frequency = <400000>; -}; - -&i2c3 { - clock-frequency = <100000>; - - /* - * Display monitor features are burnt in their EEPROM as EDID data. - * The EEPROM is connected as I2C slave device. - */ - eeprom@50 { - compatible = "ti,eeprom"; - reg = <0x50>; - }; -}; - -&i2c4 { - clock-frequency = <400000>; -}; - -&mmc1 { - vmmc-supply = <&vmmc>; - bus-width = <8>; -}; - -&mmc2 { - status = "disabled"; -}; - -&mmc3 { - status = "disabled"; -}; - -&mmc4 { - status = "disabled"; -}; - -&mmc5 { - ti,non-removable; - bus-width = <4>; -}; - -&emif1 { - cs1-used; - device-handle = <&elpida_ECB240ABACN>; -}; - -&emif2 { - cs1-used; - device-handle = <&elpida_ECB240ABACN>; -}; - -&mcbsp2 { - status = "disabled"; -}; - -&mcbsp3 { - status = "disabled"; -}; - -&dmic { - status = "disabled"; -}; - -&twl_usb_comparator { - usb-supply = <&vusb>; -}; +/include/ "omap443x.dtsi" +/include/ "omap4-panda-common.dtsi" diff --git a/trunk/arch/arm/boot/dts/omap4-sdp.dts b/trunk/arch/arm/boot/dts/omap4-sdp.dts index 43e5258a9372..a35d9cd58063 100644 --- a/trunk/arch/arm/boot/dts/omap4-sdp.dts +++ b/trunk/arch/arm/boot/dts/omap4-sdp.dts @@ -7,7 +7,7 @@ */ /dts-v1/; -/include/ "omap4.dtsi" +/include/ "omap443x.dtsi" /include/ "elpida_ecb240abacn.dtsi" / { @@ -80,6 +80,32 @@ }; }; + pwmleds { + compatible = "pwm-leds"; + kpad { + label = "omap4::keypad"; + pwms = <&twl_pwm 0 7812500>; + max-brightness = <127>; + }; + + charging { + label = "omap4:green:chrg"; + pwms = <&twl_pwmled 0 7812500>; + max-brightness = <255>; + }; + }; + + backlight { + compatible = "pwm-backlight"; + pwms = <&twl_pwm 1 7812500>; + brightness-levels = < + 0 10 20 30 40 + 50 60 70 80 90 + 100 110 120 127 + >; + default-brightness-level = <13>; + }; + sound { compatible = "ti,abe-twl6040"; ti,model = "SDP4430"; @@ -197,6 +223,15 @@ >; }; + mcspi1_pins: pinmux_mcspi1_pins { + pinctrl-single,pins = < + 0xf2 0x100 /* mcspi1_clk.mcspi1_clk INPUT | MODE0 */ + 0xf4 0x100 /* mcspi1_somi.mcspi1_somi INPUT | MODE0 */ + 0xf6 0x100 /* mcspi1_simo.mcspi1_simo INPUT | MODE0 */ + 0xf8 0x100 /* mcspi1_cs0.mcspi1_cs0 INPUT | MODE0*/ + >; + }; + dss_hdmi_pins: pinmux_dss_hdmi_pins { pinctrl-single,pins = < 0x5a 0x118 /* hdmi_cec.hdmi_cec INPUT PULLUP | MODE 0 */ @@ -212,9 +247,40 @@ 0x58 0x10b /* hdmi_hpd.gpio_63 INPUT PULLDOWN | MODE3 */ >; }; + + i2c1_pins: pinmux_i2c1_pins { + pinctrl-single,pins = < + 0xe2 0x118 /* i2c1_scl PULLUP | INPUTENABLE | MODE0 */ + 0xe4 0x118 /* i2c1_sda PULLUP | INPUTENABLE | MODE0 */ + >; + }; + + i2c2_pins: pinmux_i2c2_pins { + pinctrl-single,pins = < + 0xe6 0x118 /* i2c2_scl PULLUP | INPUTENABLE | MODE0 */ + 0xe8 0x118 /* i2c2_sda PULLUP | INPUTENABLE | MODE0 */ + >; + }; + + i2c3_pins: pinmux_i2c3_pins { + pinctrl-single,pins = < + 0xea 0x118 /* i2c3_scl PULLUP | INPUTENABLE | MODE0 */ + 0xec 0x118 /* i2c3_sda PULLUP | INPUTENABLE | MODE0 */ + >; + }; + + i2c4_pins: pinmux_i2c4_pins { + pinctrl-single,pins = < + 0xee 0x118 /* i2c4_scl PULLUP | INPUTENABLE | MODE0 */ + 0xf0 0x118 /* i2c4_sda PULLUP | INPUTENABLE | MODE0 */ + >; + }; }; &i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + clock-frequency = <400000>; twl: twl@48 { @@ -253,10 +319,16 @@ /include/ "twl6030.dtsi" &i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins>; + clock-frequency = <400000>; }; &i2c3 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c3_pins>; + clock-frequency = <400000>; /* @@ -279,6 +351,9 @@ }; &i2c4 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c4_pins>; + clock-frequency = <400000>; /* @@ -292,12 +367,15 @@ }; &mcspi1 { + pinctrl-names = "default"; + pinctrl-0 = <&mcspi1_pins>; + eth@0 { compatible = "ks8851"; spi-max-frequency = <24000000>; reg = <0>; interrupt-parent = <&gpio2>; - interrupts = <2>; /* gpio line 34 */ + interrupts = <2 8>; /* gpio line 34, low triggered */ vdd-supply = <&vdd_eth>; }; }; @@ -428,3 +506,9 @@ &twl_usb_comparator { usb-supply = <&vusb>; }; + +&usb_otg_hs { + interface-type = <1>; + mode = <3>; + power = <50>; +}; diff --git a/trunk/arch/arm/boot/dts/omap4-var-som.dts b/trunk/arch/arm/boot/dts/omap4-var-som.dts index 6601e6af6092..7e04103779c4 100644 --- a/trunk/arch/arm/boot/dts/omap4-var-som.dts +++ b/trunk/arch/arm/boot/dts/omap4-var-som.dts @@ -7,7 +7,7 @@ */ /dts-v1/; -/include/ "omap4.dtsi" +/include/ "omap443x.dtsi" / { model = "Variscite OMAP4 SOM"; @@ -68,7 +68,7 @@ spi-max-frequency = <24000000>; reg = <0>; interrupt-parent = <&gpio6>; - interrupts = <11>; /* gpio line 171 */ + interrupts = <11 8>; /* gpio line 171, low triggered */ vdd-supply = <&vdd_eth>; }; }; diff --git a/trunk/arch/arm/boot/dts/omap4.dtsi b/trunk/arch/arm/boot/dts/omap4.dtsi index 739bb79e410e..2a5642882c8a 100644 --- a/trunk/arch/arm/boot/dts/omap4.dtsi +++ b/trunk/arch/arm/boot/dts/omap4.dtsi @@ -94,6 +94,11 @@ #size-cells = <1>; ranges; ti,hwmods = "l3_main_1", "l3_main_2", "l3_main_3"; + reg = <0x44000000 0x1000>, + <0x44800000 0x2000>, + <0x45000000 0x1000>; + interrupts = <0 9 0x4>, + <0 10 0x4>; counter32k: counter@4a304000 { compatible = "ti,omap-counter32k"; @@ -118,15 +123,28 @@ pinctrl-single,function-mask = <0x7fff>; }; + sdma: dma-controller@4a056000 { + compatible = "ti,omap4430-sdma"; + reg = <0x4a056000 0x1000>; + interrupts = <0 12 0x4>, + <0 13 0x4>, + <0 14 0x4>, + <0 15 0x4>; + #dma-cells = <1>; + #dma-channels = <32>; + #dma-requests = <127>; + }; + gpio1: gpio@4a310000 { compatible = "ti,omap4-gpio"; reg = <0x4a310000 0x200>; interrupts = <0 29 0x4>; ti,hwmods = "gpio1"; + ti,gpio-always-on; gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio2: gpio@48055000 { @@ -137,7 +155,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio3: gpio@48057000 { @@ -148,7 +166,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio4: gpio@48059000 { @@ -159,7 +177,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio5: gpio@4805b000 { @@ -170,7 +188,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio6: gpio@4805d000 { @@ -181,7 +199,18 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; + }; + + gpmc: gpmc@50000000 { + compatible = "ti,omap4430-gpmc"; + reg = <0x50000000 0x1000>; + #address-cells = <2>; + #size-cells = <1>; + interrupts = <0 20 0x4>; + gpmc,num-cs = <8>; + gpmc,num-waitpins = <4>; + ti,hwmods = "gpmc"; }; uart1: serial@4806a000 { @@ -260,6 +289,16 @@ #size-cells = <0>; ti,hwmods = "mcspi1"; ti,spi-num-cs = <4>; + dmas = <&sdma 35>, + <&sdma 36>, + <&sdma 37>, + <&sdma 38>, + <&sdma 39>, + <&sdma 40>, + <&sdma 41>, + <&sdma 42>; + dma-names = "tx0", "rx0", "tx1", "rx1", + "tx2", "rx2", "tx3", "rx3"; }; mcspi2: spi@4809a000 { @@ -270,6 +309,11 @@ #size-cells = <0>; ti,hwmods = "mcspi2"; ti,spi-num-cs = <2>; + dmas = <&sdma 43>, + <&sdma 44>, + <&sdma 45>, + <&sdma 46>; + dma-names = "tx0", "rx0", "tx1", "rx1"; }; mcspi3: spi@480b8000 { @@ -280,6 +324,8 @@ #size-cells = <0>; ti,hwmods = "mcspi3"; ti,spi-num-cs = <2>; + dmas = <&sdma 15>, <&sdma 16>; + dma-names = "tx0", "rx0"; }; mcspi4: spi@480ba000 { @@ -290,6 +336,8 @@ #size-cells = <0>; ti,hwmods = "mcspi4"; ti,spi-num-cs = <1>; + dmas = <&sdma 70>, <&sdma 71>; + dma-names = "tx0", "rx0"; }; mmc1: mmc@4809c000 { @@ -299,6 +347,8 @@ ti,hwmods = "mmc1"; ti,dual-volt; ti,needs-special-reset; + dmas = <&sdma 61>, <&sdma 62>; + dma-names = "tx", "rx"; }; mmc2: mmc@480b4000 { @@ -307,6 +357,8 @@ interrupts = <0 86 0x4>; ti,hwmods = "mmc2"; ti,needs-special-reset; + dmas = <&sdma 47>, <&sdma 48>; + dma-names = "tx", "rx"; }; mmc3: mmc@480ad000 { @@ -315,6 +367,8 @@ interrupts = <0 94 0x4>; ti,hwmods = "mmc3"; ti,needs-special-reset; + dmas = <&sdma 77>, <&sdma 78>; + dma-names = "tx", "rx"; }; mmc4: mmc@480d1000 { @@ -323,6 +377,8 @@ interrupts = <0 96 0x4>; ti,hwmods = "mmc4"; ti,needs-special-reset; + dmas = <&sdma 57>, <&sdma 58>; + dma-names = "tx", "rx"; }; mmc5: mmc@480d5000 { @@ -331,6 +387,8 @@ interrupts = <0 59 0x4>; ti,hwmods = "mmc5"; ti,needs-special-reset; + dmas = <&sdma 59>, <&sdma 60>; + dma-names = "tx", "rx"; }; wdt2: wdt@4a314000 { @@ -347,6 +405,9 @@ reg-names = "mpu", "dma"; interrupts = <0 112 0x4>; ti,hwmods = "mcpdm"; + dmas = <&sdma 65>, + <&sdma 66>; + dma-names = "up_link", "dn_link"; }; dmic: dmic@4012e000 { @@ -356,6 +417,8 @@ reg-names = "mpu", "dma"; interrupts = <0 114 0x4>; ti,hwmods = "dmic"; + dmas = <&sdma 67>; + dma-names = "up_link"; }; mcbsp1: mcbsp@40122000 { @@ -367,6 +430,9 @@ interrupt-names = "common"; ti,buffer-size = <128>; ti,hwmods = "mcbsp1"; + dmas = <&sdma 33>, + <&sdma 34>; + dma-names = "tx", "rx"; }; mcbsp2: mcbsp@40124000 { @@ -378,6 +444,9 @@ interrupt-names = "common"; ti,buffer-size = <128>; ti,hwmods = "mcbsp2"; + dmas = <&sdma 17>, + <&sdma 18>; + dma-names = "tx", "rx"; }; mcbsp3: mcbsp@40126000 { @@ -389,6 +458,9 @@ interrupt-names = "common"; ti,buffer-size = <128>; ti,hwmods = "mcbsp3"; + dmas = <&sdma 19>, + <&sdma 20>; + dma-names = "tx", "rx"; }; mcbsp4: mcbsp@48096000 { @@ -399,6 +471,9 @@ interrupt-names = "common"; ti,buffer-size = <128>; ti,hwmods = "mcbsp4"; + dmas = <&sdma 31>, + <&sdma 32>; + dma-names = "tx", "rx"; }; keypad: keypad@4a31c000 { @@ -438,10 +513,15 @@ #size-cells = <1>; ranges; ti,hwmods = "ocp2scp_usb_phy"; + usb2_phy: usb2phy@4a0ad080 { + compatible = "ti,omap-usb2"; + reg = <0x4a0ad080 0x58>; + ctrl-module = <&omap_control_usb>; + }; }; timer1: timer@4a318000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap3430-timer"; reg = <0x4a318000 0x80>; interrupts = <0 37 0x4>; ti,hwmods = "timer1"; @@ -449,28 +529,28 @@ }; timer2: timer@48032000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap3430-timer"; reg = <0x48032000 0x80>; interrupts = <0 38 0x4>; ti,hwmods = "timer2"; }; timer3: timer@48034000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap4430-timer"; reg = <0x48034000 0x80>; interrupts = <0 39 0x4>; ti,hwmods = "timer3"; }; timer4: timer@48036000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap4430-timer"; reg = <0x48036000 0x80>; interrupts = <0 40 0x4>; ti,hwmods = "timer4"; }; timer5: timer@40138000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap4430-timer"; reg = <0x40138000 0x80>, <0x49038000 0x80>; interrupts = <0 41 0x4>; @@ -479,7 +559,7 @@ }; timer6: timer@4013a000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap4430-timer"; reg = <0x4013a000 0x80>, <0x4903a000 0x80>; interrupts = <0 42 0x4>; @@ -488,7 +568,7 @@ }; timer7: timer@4013c000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap4430-timer"; reg = <0x4013c000 0x80>, <0x4903c000 0x80>; interrupts = <0 43 0x4>; @@ -497,7 +577,7 @@ }; timer8: timer@4013e000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap4430-timer"; reg = <0x4013e000 0x80>, <0x4903e000 0x80>; interrupts = <0 44 0x4>; @@ -507,7 +587,7 @@ }; timer9: timer@4803e000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap4430-timer"; reg = <0x4803e000 0x80>; interrupts = <0 45 0x4>; ti,hwmods = "timer9"; @@ -515,7 +595,7 @@ }; timer10: timer@48086000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap3430-timer"; reg = <0x48086000 0x80>; interrupts = <0 46 0x4>; ti,hwmods = "timer10"; @@ -523,11 +603,62 @@ }; timer11: timer@48088000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap4430-timer"; reg = <0x48088000 0x80>; interrupts = <0 47 0x4>; ti,hwmods = "timer11"; ti,timer-pwm; }; + + usbhstll: usbhstll@4a062000 { + compatible = "ti,usbhs-tll"; + reg = <0x4a062000 0x1000>; + interrupts = <0 78 0x4>; + ti,hwmods = "usb_tll_hs"; + }; + + usbhshost: usbhshost@4a064000 { + compatible = "ti,usbhs-host"; + reg = <0x4a064000 0x800>; + ti,hwmods = "usb_host_hs"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + usbhsohci: ohci@4a064800 { + compatible = "ti,ohci-omap3", "usb-ohci"; + reg = <0x4a064800 0x400>; + interrupt-parent = <&gic>; + interrupts = <0 76 0x4>; + }; + + usbhsehci: ehci@4a064c00 { + compatible = "ti,ehci-omap", "usb-ehci"; + reg = <0x4a064c00 0x400>; + interrupt-parent = <&gic>; + interrupts = <0 77 0x4>; + }; + }; + + omap_control_usb: omap-control-usb@4a002300 { + compatible = "ti,omap-control-usb"; + reg = <0x4a002300 0x4>, + <0x4a00233c 0x4>; + reg-names = "control_dev_conf", "otghs_control"; + ti,type = <1>; + }; + + usb_otg_hs: usb_otg_hs@4a0ab000 { + compatible = "ti,omap4-musb"; + reg = <0x4a0ab000 0x7ff>; + interrupts = <0 92 0x4>, <0 93 0x4>; + interrupt-names = "mc", "dma"; + ti,hwmods = "usb_otg_hs"; + usb-phy = <&usb2_phy>; + multipoint = <1>; + num-eps = <16>; + ram-bits = <12>; + ti,has-mailbox; + }; }; }; diff --git a/trunk/arch/arm/boot/dts/omap443x.dtsi b/trunk/arch/arm/boot/dts/omap443x.dtsi new file mode 100644 index 000000000000..cccf39af4925 --- /dev/null +++ b/trunk/arch/arm/boot/dts/omap443x.dtsi @@ -0,0 +1,27 @@ +/* + * Device Tree Source for OMAP443x SoC + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +/include/ "omap4.dtsi" + +/ { + cpus { + cpu@0 { + /* OMAP443x variants OPP50-OPPNT */ + operating-points = < + /* kHz uV */ + 300000 1025000 + 600000 1200000 + 800000 1313000 + 1008000 1375000 + >; + clock-latency = <300000>; /* From legacy driver */ + }; + }; +}; diff --git a/trunk/arch/arm/boot/dts/omap4460.dtsi b/trunk/arch/arm/boot/dts/omap4460.dtsi new file mode 100644 index 000000000000..2cf227c86099 --- /dev/null +++ b/trunk/arch/arm/boot/dts/omap4460.dtsi @@ -0,0 +1,32 @@ +/* + * Device Tree Source for OMAP4460 SoC + * + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ +/include/ "omap4.dtsi" + +/ { + cpus { + /* OMAP446x 'standard device' variants OPP50 to OPPTurbo */ + cpu@0 { + operating-points = < + /* kHz uV */ + 350000 1025000 + 700000 1200000 + 920000 1313000 + >; + clock-latency = <300000>; /* From legacy driver */ + }; + }; + + pmu { + compatible = "arm,cortex-a9-pmu"; + interrupts = <0 54 0x4>, + <0 55 0x4>; + ti,hwmods = "debugss"; + }; +}; diff --git a/trunk/arch/arm/boot/dts/omap5-evm.dts b/trunk/arch/arm/boot/dts/omap5-evm.dts index 8722c15bbba2..982acd19477d 100644 --- a/trunk/arch/arm/boot/dts/omap5-evm.dts +++ b/trunk/arch/arm/boot/dts/omap5-evm.dts @@ -16,7 +16,7 @@ memory { device_type = "memory"; - reg = <0x80000000 0x80000000>; /* 2 GB */ + reg = <0x80000000 0x7F000000>; /* 2032 MB */ }; vmmcsd_fixed: fixedregulator-mmcsd { @@ -80,6 +80,68 @@ 0x15a 0x100 /* abemcbsp2_clkx.abemcbsp2_clkx INPUT | MODE0 */ >; }; + + i2c1_pins: pinmux_i2c1_pins { + pinctrl-single,pins = < + 0x1b2 0x118 /* i2c1_scl PULLUP | INPUTENABLE | MODE0 */ + 0x1b4 0x118 /* i2c1_sda PULLUP | INPUTENABLE | MODE0 */ + >; + }; + + i2c2_pins: pinmux_i2c2_pins { + pinctrl-single,pins = < + 0x178 0x100 /* i2c2_scl INPUTENABLE | MODE0 */ + 0x17a 0x100 /* i2c2_sda INPUTENABLE | MODE0 */ + >; + }; + + i2c3_pins: pinmux_i2c3_pins { + pinctrl-single,pins = < + 0x13a 0x100 /* i2c3_scl INPUTENABLE | MODE0 */ + 0x13c 0x100 /* i2c3_sda INPUTENABLE | MODE0 */ + >; + }; + + i2c4_pins: pinmux_i2c4_pins { + pinctrl-single,pins = < + 0xb8 0x100 /* i2c4_scl INPUTENABLE | MODE0 */ + 0xba 0x100 /* i2c4_sda INPUTENABLE | MODE0 */ + >; + }; + + i2c5_pins: pinmux_i2c5_pins { + pinctrl-single,pins = < + 0x184 0x100 /* i2c5_scl INPUTENABLE | MODE0 */ + 0x186 0x100 /* i2c5_sda INPUTENABLE | MODE0 */ + >; + }; + + mcspi2_pins: pinmux_mcspi2_pins { + pinctrl-single,pins = < + 0xbc 0x100 /* MCSPI2_CLK INPUTENABLE | MODE0 */ + 0xbe 0x100 /* MCSPI2_SIMO INPUTENABLE | MODE0 */ + 0xc0 0x118 /* MCSPI2_SOMI PULLUP | INPUTENABLE | MODE0*/ + 0xc2 0x0 /* MCSPI2_CS MODE0*/ + >; + }; + + mcspi3_pins: pinmux_mcspi3_pins { + pinctrl-single,pins = < + 0x78 0x101 /* MCSPI2_SOMI INPUTENABLE | MODE1 */ + 0x7a 0x101 /* MCSPI2_CS INPUTENABLE | MODE1 */ + 0x7c 0x101 /* MCSPI2_SIMO INPUTENABLE | MODE1 */ + 0x7e 0x101 /* MCSPI2_CLK INPUTENABLE | MODE1 */ + >; + }; + + mcspi4_pins: pinmux_mcspi4_pins { + pinctrl-single,pins = < + 0x164 0x101 /* MCSPI2_CLK INPUTENABLE | MODE1 */ + 0x168 0x101 /* MCSPI2_SIMO INPUTENABLE | MODE1 */ + 0x16a 0x101 /* MCSPI2_SOMI INPUTENABLE | MODE1 */ + 0x16c 0x101 /* MCSPI2_CS INPUTENABLE | MODE1 */ + >; + }; }; &mmc1 { @@ -106,7 +168,17 @@ status = "disabled"; }; +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + + clock-frequency = <400000>; +}; + &i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins>; + clock-frequency = <400000>; /* Pressure Sensor */ @@ -116,7 +188,17 @@ }; }; +&i2c3 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c3_pins>; + + clock-frequency = <400000>; +}; + &i2c4 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c4_pins>; + clock-frequency = <400000>; /* Temperature Sensor */ @@ -126,6 +208,13 @@ }; }; +&i2c5 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c5_pins>; + + clock-frequency = <400000>; +}; + &keypad { keypad,num-rows = <8>; keypad,num-columns = <8>; @@ -151,3 +240,22 @@ cs1-used; device-handle = <&samsung_K3PE0E000B>; }; + +&mcspi1 { + +}; + +&mcspi2 { + pinctrl-names = "default"; + pinctrl-0 = <&mcspi2_pins>; +}; + +&mcspi3 { + pinctrl-names = "default"; + pinctrl-0 = <&mcspi3_pins>; +}; + +&mcspi4 { + pinctrl-names = "default"; + pinctrl-0 = <&mcspi4_pins>; +}; diff --git a/trunk/arch/arm/boot/dts/omap5.dtsi b/trunk/arch/arm/boot/dts/omap5.dtsi index 790bb2a4b343..3dd7ff825828 100644 --- a/trunk/arch/arm/boot/dts/omap5.dtsi +++ b/trunk/arch/arm/boot/dts/omap5.dtsi @@ -18,6 +18,9 @@ /include/ "skeleton.dtsi" / { + #address-cells = <1>; + #size-cells = <1>; + compatible = "ti,omap5"; interrupt-parent = <&gic>; @@ -33,24 +36,32 @@ cpus { cpu@0 { compatible = "arm,cortex-a15"; - timer { - compatible = "arm,armv7-timer"; - /* 14th PPI IRQ, active low level-sensitive */ - interrupts = <1 14 0x308>; - clock-frequency = <6144000>; - }; }; cpu@1 { compatible = "arm,cortex-a15"; - timer { - compatible = "arm,armv7-timer"; - /* 14th PPI IRQ, active low level-sensitive */ - interrupts = <1 14 0x308>; - clock-frequency = <6144000>; - }; }; }; + timer { + compatible = "arm,armv7-timer"; + /* PPI secure/nonsecure IRQ, active low level-sensitive */ + interrupts = <1 13 0x308>, + <1 14 0x308>, + <1 11 0x308>, + <1 10 0x308>; + clock-frequency = <6144000>; + }; + + gic: interrupt-controller@48211000 { + compatible = "arm,cortex-a15-gic"; + interrupt-controller; + #interrupt-cells = <3>; + reg = <0x48211000 0x1000>, + <0x48212000 0x1000>, + <0x48214000 0x2000>, + <0x48216000 0x2000>; + }; + /* * The soc node represents the soc top level view. It is uses for IPs * that are not memory mapped in the MPU view or for the MPU itself. @@ -76,6 +87,11 @@ #size-cells = <1>; ranges; ti,hwmods = "l3_main_1", "l3_main_2", "l3_main_3"; + reg = <0x44000000 0x2000>, + <0x44800000 0x3000>, + <0x45000000 0x4000>; + interrupts = <0 9 0x4>, + <0 10 0x4>; counter32k: counter@4ae04000 { compatible = "ti,omap-counter32k"; @@ -100,12 +116,16 @@ pinctrl-single,function-mask = <0x7fff>; }; - gic: interrupt-controller@48211000 { - compatible = "arm,cortex-a15-gic"; - interrupt-controller; - #interrupt-cells = <3>; - reg = <0x48211000 0x1000>, - <0x48212000 0x1000>; + sdma: dma-controller@4a056000 { + compatible = "ti,omap4430-sdma"; + reg = <0x4a056000 0x1000>; + interrupts = <0 12 0x4>, + <0 13 0x4>, + <0 14 0x4>, + <0 15 0x4>; + #dma-cells = <1>; + #dma-channels = <32>; + #dma-requests = <127>; }; gpio1: gpio@4ae10000 { @@ -113,10 +133,11 @@ reg = <0x4ae10000 0x200>; interrupts = <0 29 0x4>; ti,hwmods = "gpio1"; + ti,gpio-always-on; gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio2: gpio@48055000 { @@ -127,7 +148,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio3: gpio@48057000 { @@ -138,7 +159,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio4: gpio@48059000 { @@ -149,7 +170,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio5: gpio@4805b000 { @@ -160,7 +181,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio6: gpio@4805d000 { @@ -171,7 +192,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio7: gpio@48051000 { @@ -182,7 +203,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio8: gpio@48053000 { @@ -193,7 +214,18 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; + }; + + gpmc: gpmc@50000000 { + compatible = "ti,omap4430-gpmc"; + reg = <0x50000000 0x1000>; + #address-cells = <2>; + #size-cells = <1>; + interrupts = <0 20 0x4>; + gpmc,num-cs = <8>; + gpmc,num-waitpins = <4>; + ti,hwmods = "gpmc"; }; i2c1: i2c@48070000 { @@ -241,6 +273,65 @@ ti,hwmods = "i2c5"; }; + mcspi1: spi@48098000 { + compatible = "ti,omap4-mcspi"; + reg = <0x48098000 0x200>; + interrupts = <0 65 0x4>; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "mcspi1"; + ti,spi-num-cs = <4>; + dmas = <&sdma 35>, + <&sdma 36>, + <&sdma 37>, + <&sdma 38>, + <&sdma 39>, + <&sdma 40>, + <&sdma 41>, + <&sdma 42>; + dma-names = "tx0", "rx0", "tx1", "rx1", + "tx2", "rx2", "tx3", "rx3"; + }; + + mcspi2: spi@4809a000 { + compatible = "ti,omap4-mcspi"; + reg = <0x4809a000 0x200>; + interrupts = <0 66 0x4>; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "mcspi2"; + ti,spi-num-cs = <2>; + dmas = <&sdma 43>, + <&sdma 44>, + <&sdma 45>, + <&sdma 46>; + dma-names = "tx0", "rx0", "tx1", "rx1"; + }; + + mcspi3: spi@480b8000 { + compatible = "ti,omap4-mcspi"; + reg = <0x480b8000 0x200>; + interrupts = <0 91 0x4>; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "mcspi3"; + ti,spi-num-cs = <2>; + dmas = <&sdma 15>, <&sdma 16>; + dma-names = "tx0", "rx0"; + }; + + mcspi4: spi@480ba000 { + compatible = "ti,omap4-mcspi"; + reg = <0x480ba000 0x200>; + interrupts = <0 48 0x4>; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "mcspi4"; + ti,spi-num-cs = <1>; + dmas = <&sdma 70>, <&sdma 71>; + dma-names = "tx0", "rx0"; + }; + uart1: serial@4806a000 { compatible = "ti,omap4-uart"; reg = <0x4806a000 0x100>; @@ -296,6 +387,8 @@ ti,hwmods = "mmc1"; ti,dual-volt; ti,needs-special-reset; + dmas = <&sdma 61>, <&sdma 62>; + dma-names = "tx", "rx"; }; mmc2: mmc@480b4000 { @@ -304,6 +397,8 @@ interrupts = <0 86 0x4>; ti,hwmods = "mmc2"; ti,needs-special-reset; + dmas = <&sdma 47>, <&sdma 48>; + dma-names = "tx", "rx"; }; mmc3: mmc@480ad000 { @@ -312,6 +407,8 @@ interrupts = <0 94 0x4>; ti,hwmods = "mmc3"; ti,needs-special-reset; + dmas = <&sdma 77>, <&sdma 78>; + dma-names = "tx", "rx"; }; mmc4: mmc@480d1000 { @@ -320,6 +417,8 @@ interrupts = <0 96 0x4>; ti,hwmods = "mmc4"; ti,needs-special-reset; + dmas = <&sdma 57>, <&sdma 58>; + dma-names = "tx", "rx"; }; mmc5: mmc@480d5000 { @@ -328,10 +427,13 @@ interrupts = <0 59 0x4>; ti,hwmods = "mmc5"; ti,needs-special-reset; + dmas = <&sdma 59>, <&sdma 60>; + dma-names = "tx", "rx"; }; keypad: keypad@4ae1c000 { compatible = "ti,omap4-keypad"; + reg = <0x4ae1c000 0x400>; ti,hwmods = "kbd"; }; @@ -342,6 +444,9 @@ reg-names = "mpu", "dma"; interrupts = <0 112 0x4>; ti,hwmods = "mcpdm"; + dmas = <&sdma 65>, + <&sdma 66>; + dma-names = "up_link", "dn_link"; }; dmic: dmic@4012e000 { @@ -351,6 +456,8 @@ reg-names = "mpu", "dma"; interrupts = <0 114 0x4>; ti,hwmods = "dmic"; + dmas = <&sdma 67>; + dma-names = "up_link"; }; mcbsp1: mcbsp@40122000 { @@ -362,6 +469,9 @@ interrupt-names = "common"; ti,buffer-size = <128>; ti,hwmods = "mcbsp1"; + dmas = <&sdma 33>, + <&sdma 34>; + dma-names = "tx", "rx"; }; mcbsp2: mcbsp@40124000 { @@ -373,6 +483,9 @@ interrupt-names = "common"; ti,buffer-size = <128>; ti,hwmods = "mcbsp2"; + dmas = <&sdma 17>, + <&sdma 18>; + dma-names = "tx", "rx"; }; mcbsp3: mcbsp@40126000 { @@ -384,10 +497,13 @@ interrupt-names = "common"; ti,buffer-size = <128>; ti,hwmods = "mcbsp3"; + dmas = <&sdma 19>, + <&sdma 20>; + dma-names = "tx", "rx"; }; timer1: timer@4ae18000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap5430-timer"; reg = <0x4ae18000 0x80>; interrupts = <0 37 0x4>; ti,hwmods = "timer1"; @@ -395,28 +511,28 @@ }; timer2: timer@48032000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap5430-timer"; reg = <0x48032000 0x80>; interrupts = <0 38 0x4>; ti,hwmods = "timer2"; }; timer3: timer@48034000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap5430-timer"; reg = <0x48034000 0x80>; interrupts = <0 39 0x4>; ti,hwmods = "timer3"; }; timer4: timer@48036000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap5430-timer"; reg = <0x48036000 0x80>; interrupts = <0 40 0x4>; ti,hwmods = "timer4"; }; timer5: timer@40138000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap5430-timer"; reg = <0x40138000 0x80>, <0x49038000 0x80>; interrupts = <0 41 0x4>; @@ -425,7 +541,7 @@ }; timer6: timer@4013a000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap5430-timer"; reg = <0x4013a000 0x80>, <0x4903a000 0x80>; interrupts = <0 42 0x4>; @@ -435,7 +551,7 @@ }; timer7: timer@4013c000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap5430-timer"; reg = <0x4013c000 0x80>, <0x4903c000 0x80>; interrupts = <0 43 0x4>; @@ -444,7 +560,7 @@ }; timer8: timer@4013e000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap5430-timer"; reg = <0x4013e000 0x80>, <0x4903e000 0x80>; interrupts = <0 44 0x4>; @@ -454,27 +570,34 @@ }; timer9: timer@4803e000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap5430-timer"; reg = <0x4803e000 0x80>; interrupts = <0 45 0x4>; ti,hwmods = "timer9"; }; timer10: timer@48086000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap5430-timer"; reg = <0x48086000 0x80>; interrupts = <0 46 0x4>; ti,hwmods = "timer10"; }; timer11: timer@48088000 { - compatible = "ti,omap2-timer"; + compatible = "ti,omap5430-timer"; reg = <0x48088000 0x80>; interrupts = <0 47 0x4>; ti,hwmods = "timer11"; ti,timer-pwm; }; + wdt2: wdt@4ae14000 { + compatible = "ti,omap5-wdt", "ti,omap3-wdt"; + reg = <0x4ae14000 0x80>; + interrupts = <0 80 0x4>; + ti,hwmods = "wd_timer2"; + }; + emif1: emif@0x4c000000 { compatible = "ti,emif-4d5"; ti,hwmods = "emif1"; @@ -496,5 +619,53 @@ hw-caps-ll-interface; hw-caps-temp-alert; }; + + omap_control_usb: omap-control-usb@4a002300 { + compatible = "ti,omap-control-usb"; + reg = <0x4a002300 0x4>, + <0x4a002370 0x4>; + reg-names = "control_dev_conf", "phy_power_usb"; + ti,type = <2>; + }; + + omap_dwc3@4a020000 { + compatible = "ti,dwc3"; + ti,hwmods = "usb_otg_ss"; + reg = <0x4a020000 0x1000>; + interrupts = <0 93 4>; + #address-cells = <1>; + #size-cells = <1>; + utmi-mode = <2>; + ranges; + dwc3@4a030000 { + compatible = "synopsys,dwc3"; + reg = <0x4a030000 0x1000>; + interrupts = <0 92 4>; + usb-phy = <&usb2_phy>, <&usb3_phy>; + tx-fifo-resize; + }; + }; + + ocp2scp { + compatible = "ti,omap-ocp2scp"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + ti,hwmods = "ocp2scp1"; + usb2_phy: usb2phy@4a084000 { + compatible = "ti,omap-usb2"; + reg = <0x4a084000 0x7c>; + ctrl-module = <&omap_control_usb>; + }; + + usb3_phy: usb3phy@4a084400 { + compatible = "ti,omap-usb3"; + reg = <0x4a084400 0x80>, + <0x4a084800 0x64>, + <0x4a084c00 0x40>; + reg-names = "phy_rx", "phy_tx", "pll_ctrl"; + ctrl-module = <&omap_control_usb>; + }; + }; }; }; diff --git a/trunk/arch/arm/boot/dts/pxa168.dtsi b/trunk/arch/arm/boot/dts/pxa168.dtsi index 31a718696080..975dad21ac38 100644 --- a/trunk/arch/arm/boot/dts/pxa168.dtsi +++ b/trunk/arch/arm/boot/dts/pxa168.dtsi @@ -77,7 +77,7 @@ }; gpio@d4019000 { - compatible = "mrvl,mmp-gpio"; + compatible = "marvell,mmp-gpio"; #address-cells = <1>; #size-cells = <1>; reg = <0xd4019000 0x1000>; diff --git a/trunk/arch/arm/boot/dts/pxa910.dtsi b/trunk/arch/arm/boot/dts/pxa910.dtsi index 825aaca33034..0247c622f580 100644 --- a/trunk/arch/arm/boot/dts/pxa910.dtsi +++ b/trunk/arch/arm/boot/dts/pxa910.dtsi @@ -89,7 +89,7 @@ }; gpio@d4019000 { - compatible = "mrvl,mmp-gpio"; + compatible = "marvell,mmp-gpio"; #address-cells = <1>; #size-cells = <1>; reg = <0xd4019000 0x1000>; diff --git a/trunk/arch/arm/boot/dts/r8a73a4-ape6evm.dts b/trunk/arch/arm/boot/dts/r8a73a4-ape6evm.dts new file mode 100644 index 000000000000..f603c6946c29 --- /dev/null +++ b/trunk/arch/arm/boot/dts/r8a73a4-ape6evm.dts @@ -0,0 +1,52 @@ +/* + * Device Tree Source for the APE6EVM board + * + * Copyright (C) 2013 Renesas Solutions Corp. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +/dts-v1/; +/include/ "r8a73a4.dtsi" + +/ { + model = "APE6EVM"; + compatible = "renesas,ape6evm", "renesas,r8a73a4"; + + chosen { + bootargs = "console=ttySC0,115200 ignore_loglevel root=/dev/nfs ip=dhcp"; + }; + + memory@40000000 { + device_type = "memory"; + reg = <0 0x40000000 0 0x40000000>; + }; + + ape6evm_fixed_3v3: fixedregulator@0 { + compatible = "regulator-fixed"; + regulator-name = "3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + lbsc { + #address-cells = <1>; + #size-cells = <1>; + + ethernet@8000000 { + compatible = "smsc,lan9118", "smsc,lan9115"; + reg = <0x08000000 0x1000>; + interrupt-parent = <&irqc1>; + interrupts = <8 0x4>; + phy-mode = "mii"; + reg-io-width = <4>; + smsc,irq-active-high; + smsc,irq-push-pull; + vdd33a-supply = <&ape6evm_fixed_3v3>; + vddvario-supply = <&ape6evm_fixed_3v3>; + }; + }; +}; diff --git a/trunk/arch/arm/boot/dts/r8a73a4.dtsi b/trunk/arch/arm/boot/dts/r8a73a4.dtsi new file mode 100644 index 000000000000..fde2a337d1ff --- /dev/null +++ b/trunk/arch/arm/boot/dts/r8a73a4.dtsi @@ -0,0 +1,94 @@ +/* + * Device Tree Source for the r8a73a4 SoC + * + * Copyright (C) 2013 Renesas Solutions Corp. + * Copyright (C) 2013 Magnus Damm + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +/ { + compatible = "renesas,r8a73a4"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0>; + clock-frequency = <1500000000>; + }; + }; + + gic: interrupt-controller@f1001000 { + compatible = "arm,cortex-a15-gic"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0 0xf1001000 0 0x1000>, + <0 0xf1002000 0 0x1000>, + <0 0xf1004000 0 0x2000>, + <0 0xf1006000 0 0x2000>; + interrupts = <1 9 0xf04>; + + gic-cpuif@4 { + compatible = "arm,gic-cpuif"; + cpuif-id = <4>; + cpu = <&cpu0>; + }; + }; + + timer { + compatible = "arm,armv7-timer"; + interrupts = <1 13 0xf08>, + <1 14 0xf08>, + <1 11 0xf08>, + <1 10 0xf08>; + }; + + irqc0: interrupt-controller@e61c0000 { + compatible = "renesas,irqc"; + #interrupt-cells = <2>; + interrupt-controller; + reg = <0 0xe61c0000 0 0x200>; + interrupt-parent = <&gic>; + interrupts = <0 0 4>, <0 1 4>, <0 2 4>, <0 3 4>, + <0 4 4>, <0 5 4>, <0 6 4>, <0 7 4>, + <0 8 4>, <0 9 4>, <0 10 4>, <0 11 4>, + <0 12 4>, <0 13 4>, <0 14 4>, <0 15 4>, + <0 16 4>, <0 17 4>, <0 18 4>, <0 19 4>, + <0 20 4>, <0 21 4>, <0 22 4>, <0 23 4>, + <0 24 4>, <0 25 4>, <0 26 4>, <0 27 4>, + <0 28 4>, <0 29 4>, <0 30 4>, <0 31 4>; + }; + + irqc1: interrupt-controller@e61c0200 { + compatible = "renesas,irqc"; + #interrupt-cells = <2>; + interrupt-controller; + reg = <0 0xe61c0200 0 0x200>; + interrupt-parent = <&gic>; + interrupts = <0 32 4>, <0 33 4>, <0 34 4>, <0 35 4>, + <0 36 4>, <0 37 4>, <0 38 4>, <0 39 4>, + <0 40 4>, <0 41 4>, <0 42 4>, <0 43 4>, + <0 44 4>, <0 45 4>, <0 46 4>, <0 47 4>, + <0 48 4>, <0 49 4>, <0 50 4>, <0 51 4>, + <0 52 4>, <0 53 4>, <0 54 4>, <0 55 4>, + <0 56 4>, <0 57 4>; + }; + + thermal@e61f0000 { + compatible = "renesas,rcar-thermal"; + reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>, + <0 0xe61f0200 0 0x38>, <0 0xe61f0300 0 0x38>; + interrupt-parent = <&gic>; + interrupts = <0 69 4>; + }; +}; diff --git a/trunk/arch/arm/boot/dts/r8a7778-bockw.dts b/trunk/arch/arm/boot/dts/r8a7778-bockw.dts new file mode 100644 index 000000000000..0076b1e8a0fb --- /dev/null +++ b/trunk/arch/arm/boot/dts/r8a7778-bockw.dts @@ -0,0 +1,32 @@ +/* + * Reference Device Tree Source for the Bock-W board + * + * Copyright (C) 2013 Renesas Solutions Corp. + * Copyright (C) 2013 Kuninori Morimoto + * + * based on r8a7779 + * + * Copyright (C) 2013 Renesas Solutions Corp. + * Copyright (C) 2013 Simon Horman + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +/dts-v1/; +/include/ "r8a7778.dtsi" + +/ { + model = "bockw"; + compatible = "renesas,bockw", "renesas,r8a7778"; + + chosen { + bootargs = "console=ttySC0,115200 ignore_loglevel ip=dhcp root=/dev/nfs"; + }; + + memory { + device_type = "memory"; + reg = <0x60000000 0x10000000>; + }; +}; diff --git a/trunk/arch/arm/boot/dts/r8a7778.dtsi b/trunk/arch/arm/boot/dts/r8a7778.dtsi new file mode 100644 index 000000000000..474373559bdc --- /dev/null +++ b/trunk/arch/arm/boot/dts/r8a7778.dtsi @@ -0,0 +1,35 @@ +/* + * Device Tree Source for Renesas r8a7778 + * + * Copyright (C) 2013 Renesas Solutions Corp. + * Copyright (C) 2013 Kuninori Morimoto + * + * based on r8a7779 + * + * Copyright (C) 2013 Renesas Solutions Corp. + * Copyright (C) 2013 Simon Horman + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +/include/ "skeleton.dtsi" + +/ { + compatible = "renesas,r8a7778"; + + cpus { + cpu@0 { + compatible = "arm,cortex-a9"; + }; + }; + + gic: interrupt-controller@fe438000 { + compatible = "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0xfe438000 0x1000>, + <0xfe430000 0x100>; + }; +}; diff --git a/trunk/arch/arm/boot/dts/r8a7779-marzen-reference.dts b/trunk/arch/arm/boot/dts/r8a7779-marzen-reference.dts new file mode 100644 index 000000000000..72be4c87cfb5 --- /dev/null +++ b/trunk/arch/arm/boot/dts/r8a7779-marzen-reference.dts @@ -0,0 +1,47 @@ +/* + * Reference Device Tree Source for the Marzen board + * + * Copyright (C) 2013 Renesas Solutions Corp. + * Copyright (C) 2013 Simon Horman + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +/dts-v1/; +/include/ "r8a7779.dtsi" + +/ { + model = "marzen"; + compatible = "renesas,marzen-reference", "renesas,r8a7779"; + + chosen { + bootargs = "console=ttySC2,115200 earlyprintk=sh-sci.2,115200 ignore_loglevel root=/dev/nfs ip=on"; + }; + + memory { + device_type = "memory"; + reg = <0x60000000 0x40000000>; + }; + + fixedregulator3v3: fixedregulator@0 { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + lan0@18000000 { + compatible = "smsc,lan9220", "smsc,lan9115"; + reg = <0x18000000 0x100>; + phy-mode = "mii"; + interrupt-parent = <&gic>; + interrupts = <0 28 0x4>; + reg-io-width = <4>; + vddvario-supply = <&fixedregulator3v3>; + vdd33a-supply = <&fixedregulator3v3>; + }; +}; diff --git a/trunk/arch/arm/boot/dts/r8a7790-lager.dts b/trunk/arch/arm/boot/dts/r8a7790-lager.dts new file mode 100644 index 000000000000..09a84fce89d6 --- /dev/null +++ b/trunk/arch/arm/boot/dts/r8a7790-lager.dts @@ -0,0 +1,31 @@ +/* + * Device Tree Source for the Lager board + * + * Copyright (C) 2013 Renesas Solutions Corp. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +/dts-v1/; +/include/ "r8a7790.dtsi" + +/ { + model = "Lager"; + compatible = "renesas,lager", "renesas,r8a7790"; + + chosen { + bootargs = "console=ttySC6,115200 ignore_loglevel"; + }; + + memory@40000000 { + device_type = "memory"; + reg = <0 0x40000000 0 0x80000000>; + }; + + lbsc { + #address-cells = <1>; + #size-cells = <1>; + }; +}; diff --git a/trunk/arch/arm/boot/dts/r8a7790.dtsi b/trunk/arch/arm/boot/dts/r8a7790.dtsi new file mode 100644 index 000000000000..7a1711027e41 --- /dev/null +++ b/trunk/arch/arm/boot/dts/r8a7790.dtsi @@ -0,0 +1,63 @@ +/* + * Device Tree Source for the r8a7790 SoC + * + * Copyright (C) 2013 Renesas Solutions Corp. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +/ { + compatible = "renesas,r8a7790"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0>; + clock-frequency = <1300000000>; + }; + }; + + gic: interrupt-controller@f1001000 { + compatible = "arm,cortex-a15-gic"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0 0xf1001000 0 0x1000>, + <0 0xf1002000 0 0x1000>, + <0 0xf1004000 0 0x2000>, + <0 0xf1006000 0 0x2000>; + interrupts = <1 9 0xf04>; + + gic-cpuif@4 { + compatible = "arm,gic-cpuif"; + cpuif-id = <4>; + cpu = <&cpu0>; + }; + }; + + timer { + compatible = "arm,armv7-timer"; + interrupts = <1 13 0xf08>, + <1 14 0xf08>, + <1 11 0xf08>, + <1 10 0xf08>; + }; + + irqc0: interrupt-controller@e61c0000 { + compatible = "renesas,irqc"; + #interrupt-cells = <2>; + interrupt-controller; + reg = <0 0xe61c0000 0 0x200>; + interrupt-parent = <&gic>; + interrupts = <0 0 4>, <0 1 4>, <0 2 4>, <0 3 4>; + }; +}; diff --git a/trunk/arch/arm/boot/dts/sama5d3.dtsi b/trunk/arch/arm/boot/dts/sama5d3.dtsi index 39b0458d365a..2e643ea51cce 100644 --- a/trunk/arch/arm/boot/dts/sama5d3.dtsi +++ b/trunk/arch/arm/boot/dts/sama5d3.dtsi @@ -60,6 +60,8 @@ compatible = "atmel,hsmci"; reg = <0xf0000000 0x600>; interrupts = <21 4 0>; + dmas = <&dma0 2 0>; + dma-names = "rxtx"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_mmc0_clk_cmd_dat0 &pinctrl_mmc0_dat1_3 &pinctrl_mmc0_dat4_7>; status = "disabled"; @@ -111,6 +113,9 @@ compatible = "atmel,at91sam9x5-i2c"; reg = <0xf0014000 0x4000>; interrupts = <18 4 6>; + dmas = <&dma0 2 7>, + <&dma0 2 8>; + dma-names = "tx", "rx"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c0>; #address-cells = <1>; @@ -122,6 +127,9 @@ compatible = "atmel,at91sam9x5-i2c"; reg = <0xf0018000 0x4000>; interrupts = <19 4 6>; + dmas = <&dma0 2 9>, + <&dma0 2 10>; + dma-names = "tx", "rx"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c1>; #address-cells = <1>; @@ -167,6 +175,8 @@ compatible = "atmel,hsmci"; reg = <0xf8000000 0x600>; interrupts = <22 4 0>; + dmas = <&dma1 2 0>; + dma-names = "rxtx"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3>; status = "disabled"; @@ -178,6 +188,8 @@ compatible = "atmel,hsmci"; reg = <0xf8004000 0x600>; interrupts = <23 4 0>; + dmas = <&dma1 2 1>; + dma-names = "rxtx"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_mmc2_clk_cmd_dat0 &pinctrl_mmc2_dat1_3>; status = "disabled"; @@ -294,6 +306,9 @@ compatible = "atmel,at91sam9x5-i2c"; reg = <0xf801c000 0x4000>; interrupts = <20 4 6>; + dmas = <&dma1 2 11>, + <&dma1 2 12>; + dma-names = "tx", "rx"; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -348,14 +363,14 @@ compatible = "atmel,at91sam9g45-dma"; reg = <0xffffe600 0x200>; interrupts = <30 4 0>; - #dma-cells = <1>; + #dma-cells = <2>; }; dma1: dma-controller@ffffe800 { compatible = "atmel,at91sam9g45-dma"; reg = <0xffffe800 0x200>; interrupts = <31 4 0>; - #dma-cells = <1>; + #dma-cells = <2>; }; ramc0: ramc@ffffea00 { diff --git a/trunk/arch/arm/boot/dts/sama5d34ek.dts b/trunk/arch/arm/boot/dts/sama5d34ek.dts index d2739f8d7ae9..6bebfcdcb1d1 100644 --- a/trunk/arch/arm/boot/dts/sama5d34ek.dts +++ b/trunk/arch/arm/boot/dts/sama5d34ek.dts @@ -12,7 +12,7 @@ / { model = "Atmel SAMA5D34-EK"; - compatible = "atmel,sama5d34ek", "atmel,sama5ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d3", "atmel,sama5"; + compatible = "atmel,sama5d34ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d3", "atmel,sama5"; ahb { apb { diff --git a/trunk/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts b/trunk/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts new file mode 100644 index 000000000000..5972abb55f9c --- /dev/null +++ b/trunk/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts @@ -0,0 +1,79 @@ +/* + * Device Tree Source for the KZM-A9-GT board + * + * Copyright (C) 2012 Horms Solutions Ltd. + * + * Based on sh73a0-kzm9g.dts + * Copyright (C) 2012 Renesas Solutions Corp. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +/dts-v1/; +/include/ "sh73a0.dtsi" + +/ { + model = "KZM-A9-GT"; + compatible = "renesas,kzm9g-reference", "renesas,sh73a0"; + + chosen { + bootargs = "console=tty0 console=ttySC4,115200 root=/dev/nfs ip=dhcp ignore_loglevel earlyprintk=sh-sci.4,115200"; + }; + + memory { + device_type = "memory"; + reg = <0x41000000 0x1e800000>; + }; + + reg_1p8v: regulator@0 { + compatible = "regulator-fixed"; + regulator-name = "fixed-1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + }; + + reg_3p3v: regulator@1 { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + }; + + lan9220@10000000 { + compatible = "smsc,lan9220", "smsc,lan9115"; + reg = <0x10000000 0x100>; + phy-mode = "mii"; + interrupt-parent = <&irqpin0>; + interrupts = <3 0>; /* active low */ + reg-io-width = <4>; + smsc,irq-push-pull; + smsc,save-mac-address; + vddvario-supply = <®_1p8v>; + vdd33a-supply = <®_3p3v>; + }; +}; + +&mmcif { + bus-width = <8>; + vmmc-supply = <®_1p8v>; + status = "okay"; +}; + +&sdhi0 { + vmmc-supply = <®_3p3v>; + bus-width = <4>; + status = "okay"; +}; + +&sdhi2 { + vmmc-supply = <®_3p3v>; + bus-width = <4>; + broken-cd; + status = "okay"; +}; diff --git a/trunk/arch/arm/boot/dts/sh73a0-reference.dtsi b/trunk/arch/arm/boot/dts/sh73a0-reference.dtsi deleted file mode 100644 index d4bb0125b2b2..000000000000 --- a/trunk/arch/arm/boot/dts/sh73a0-reference.dtsi +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Device Tree Source for the SH73A0 SoC - * - * Copyright (C) 2012 Renesas Solutions Corp. - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ - -/include/ "sh73a0.dtsi" - -/ { - compatible = "renesas,sh73a0"; - - mmcif: mmcif@0x10010000 { - compatible = "renesas,sh-mmcif"; - reg = <0xe6bd0000 0x100>; - interrupt-parent = <&gic>; - interrupts = <0 140 0x4 - 0 141 0x4>; - reg-io-width = <4>; - }; -}; diff --git a/trunk/arch/arm/boot/dts/sh73a0.dtsi b/trunk/arch/arm/boot/dts/sh73a0.dtsi index 8a59465d0231..ec40bf78289e 100644 --- a/trunk/arch/arm/boot/dts/sh73a0.dtsi +++ b/trunk/arch/arm/boot/dts/sh73a0.dtsi @@ -38,6 +38,87 @@ <0xf0000100 0x100>; }; + irqpin0: irqpin@e6900000 { + compatible = "renesas,intc-irqpin"; + #interrupt-cells = <2>; + interrupt-controller; + reg = <0xe6900000 4>, + <0xe6900010 4>, + <0xe6900020 1>, + <0xe6900040 1>, + <0xe6900060 1>; + interrupt-parent = <&gic>; + interrupts = <0 1 0x4 + 0 2 0x4 + 0 3 0x4 + 0 4 0x4 + 0 5 0x4 + 0 6 0x4 + 0 7 0x4 + 0 8 0x4>; + }; + + irqpin1: irqpin@e6900004 { + compatible = "renesas,intc-irqpin"; + #interrupt-cells = <2>; + interrupt-controller; + reg = <0xe6900004 4>, + <0xe6900014 4>, + <0xe6900024 1>, + <0xe6900044 1>, + <0xe6900064 1>; + interrupt-parent = <&gic>; + interrupts = <0 9 0x4 + 0 10 0x4 + 0 11 0x4 + 0 12 0x4 + 0 13 0x4 + 0 14 0x4 + 0 15 0x4 + 0 16 0x4>; + control-parent; + }; + + irqpin2: irqpin@e6900008 { + compatible = "renesas,intc-irqpin"; + #interrupt-cells = <2>; + interrupt-controller; + reg = <0xe6900008 4>, + <0xe6900018 4>, + <0xe6900028 1>, + <0xe6900048 1>, + <0xe6900068 1>; + interrupt-parent = <&gic>; + interrupts = <0 17 0x4 + 0 18 0x4 + 0 19 0x4 + 0 20 0x4 + 0 21 0x4 + 0 22 0x4 + 0 23 0x4 + 0 24 0x4>; + }; + + irqpin3: irqpin@e690000c { + compatible = "renesas,intc-irqpin"; + #interrupt-cells = <2>; + interrupt-controller; + reg = <0xe690000c 4>, + <0xe690001c 4>, + <0xe690002c 1>, + <0xe690004c 1>, + <0xe690006c 1>; + interrupt-parent = <&gic>; + interrupts = <0 25 0x4 + 0 26 0x4 + 0 27 0x4 + 0 28 0x4 + 0 29 0x4 + 0 30 0x4 + 0 31 0x4 + 0 32 0x4>; + }; + i2c0: i2c@0xe6820000 { #address-cells = <1>; #size-cells = <0>; @@ -97,4 +178,48 @@ 0 189 0x4 0 190 0x4>; }; + + mmcif: mmcif@0x10010000 { + compatible = "renesas,sh-mmcif"; + reg = <0xe6bd0000 0x100>; + interrupt-parent = <&gic>; + interrupts = <0 140 0x4 + 0 141 0x4>; + reg-io-width = <4>; + status = "disabled"; + }; + + sdhi0: sdhi@0xee100000 { + compatible = "renesas,r8a7740-sdhi"; + reg = <0xee100000 0x100>; + interrupt-parent = <&gic>; + interrupts = <0 83 4 + 0 84 4 + 0 85 4>; + cap-sd-highspeed; + status = "disabled"; + }; + + /* SDHI1 and SDHI2 have no CD pins, no need for CD IRQ */ + sdhi1: sdhi@0xee120000 { + compatible = "renesas,r8a7740-sdhi"; + reg = <0xee120000 0x100>; + interrupt-parent = <&gic>; + interrupts = <0 88 4 + 0 89 4>; + toshiba,mmc-wrprotect-disable; + cap-sd-highspeed; + status = "disabled"; + }; + + sdhi2: sdhi@0xee140000 { + compatible = "renesas,r8a7740-sdhi"; + reg = <0xee140000 0x100>; + interrupt-parent = <&gic>; + interrupts = <0 104 4 + 0 105 4>; + toshiba,mmc-wrprotect-disable; + cap-sd-highspeed; + status = "disabled"; + }; }; diff --git a/trunk/arch/arm/boot/dts/spear1340.dtsi b/trunk/arch/arm/boot/dts/spear1340.dtsi index c511c4772efd..54d128d35681 100644 --- a/trunk/arch/arm/boot/dts/spear1340.dtsi +++ b/trunk/arch/arm/boot/dts/spear1340.dtsi @@ -113,6 +113,9 @@ reg = <0xb4100000 0x1000>; interrupts = <0 105 0x4>; status = "disabled"; + dmas = <&dwdma0 0x600 0 0 1>, /* 0xC << 11 */ + <&dwdma0 0x680 0 1 0>; /* 0xD << 7 */ + dma-names = "tx", "rx"; }; thermal@e07008c4 { diff --git a/trunk/arch/arm/boot/dts/spear13xx.dtsi b/trunk/arch/arm/boot/dts/spear13xx.dtsi index b4ca60f4eb42..45597fd91050 100644 --- a/trunk/arch/arm/boot/dts/spear13xx.dtsi +++ b/trunk/arch/arm/boot/dts/spear13xx.dtsi @@ -98,13 +98,24 @@ reg = <0xb2800000 0x1000>; interrupts = <0 29 0x4>; status = "disabled"; + dmas = <&dwdma0 0 0 0 0>; + dma-names = "data"; }; - dma@ea800000 { + dwdma0: dma@ea800000 { compatible = "snps,dma-spear1340"; reg = <0xea800000 0x1000>; interrupts = <0 19 0x4>; status = "disabled"; + + dma-channels = <8>; + #dma-cells = <3>; + dma-requests = <32>; + chan_allocation_order = <1>; + chan_priority = <1>; + block_size = <0xfff>; + dma-masters = <2>; + data_width = <3 3 0 0>; }; dma@eb000000 { @@ -112,6 +123,15 @@ reg = <0xeb000000 0x1000>; interrupts = <0 59 0x4>; status = "disabled"; + + dma-requests = <32>; + dma-channels = <8>; + dma-masters = <2>; + #dma-cells = <3>; + chan_allocation_order = <1>; + chan_priority = <1>; + block_size = <0xfff>; + data_width = <3 3 0 0>; }; fsmc: flash@b0000000 { @@ -261,6 +281,9 @@ #size-cells = <0>; interrupts = <0 31 0x4>; status = "disabled"; + dmas = <&dwdma0 0x2000 0 0 0>, /* 0x4 << 11 */ + <&dwdma0 0x0280 0 0 0>; /* 0x5 << 7 */ + dma-names = "tx", "rx"; }; rtc@e0580000 { diff --git a/trunk/arch/arm/boot/dts/tegra114-dalmore.dts b/trunk/arch/arm/boot/dts/tegra114-dalmore.dts index 6ebc1b704190..72c1f27af7f3 100644 --- a/trunk/arch/arm/boot/dts/tegra114-dalmore.dts +++ b/trunk/arch/arm/boot/dts/tegra114-dalmore.dts @@ -10,15 +10,835 @@ reg = <0x80000000 0x40000000>; }; + pinmux { + pinctrl-names = "default"; + pinctrl-0 = <&state_default>; + + state_default: pinmux { + clk1_out_pw4 { + nvidia,pins = "clk1_out_pw4"; + nvidia,function = "extperiph1"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + }; + dap1_din_pn1 { + nvidia,pins = "dap1_din_pn1"; + nvidia,function = "i2s0"; + nvidia,pull = <0>; + nvidia,tristate = <1>; + nvidia,enable-input = <1>; + }; + dap1_dout_pn2 { + nvidia,pins = "dap1_dout_pn2", + "dap1_fs_pn0", + "dap1_sclk_pn3"; + nvidia,function = "i2s0"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + }; + dap2_din_pa4 { + nvidia,pins = "dap2_din_pa4"; + nvidia,function = "i2s1"; + nvidia,pull = <0>; + nvidia,tristate = <1>; + nvidia,enable-input = <1>; + }; + dap2_dout_pa5 { + nvidia,pins = "dap2_dout_pa5", + "dap2_fs_pa2", + "dap2_sclk_pa3"; + nvidia,function = "i2s1"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + }; + dap4_din_pp5 { + nvidia,pins = "dap4_din_pp5", + "dap4_dout_pp6", + "dap4_fs_pp4", + "dap4_sclk_pp7"; + nvidia,function = "i2s3"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + }; + dvfs_pwm_px0 { + nvidia,pins = "dvfs_pwm_px0", + "dvfs_clk_px2"; + nvidia,function = "cldvfs"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + }; + ulpi_clk_py0 { + nvidia,pins = "ulpi_clk_py0", + "ulpi_data0_po1", + "ulpi_data1_po2", + "ulpi_data2_po3", + "ulpi_data3_po4", + "ulpi_data4_po5", + "ulpi_data5_po6", + "ulpi_data6_po7", + "ulpi_data7_po0"; + nvidia,function = "ulpi"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + }; + ulpi_dir_py1 { + nvidia,pins = "ulpi_dir_py1", + "ulpi_nxt_py2"; + nvidia,function = "ulpi"; + nvidia,pull = <0>; + nvidia,tristate = <1>; + nvidia,enable-input = <1>; + }; + ulpi_stp_py3 { + nvidia,pins = "ulpi_stp_py3"; + nvidia,function = "ulpi"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + }; + cam_i2c_scl_pbb1 { + nvidia,pins = "cam_i2c_scl_pbb1", + "cam_i2c_sda_pbb2"; + nvidia,function = "i2c3"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + nvidia,lock = <0>; + nvidia,open-drain = <0>; + }; + cam_mclk_pcc0 { + nvidia,pins = "cam_mclk_pcc0", + "pbb0"; + nvidia,function = "vi_alt3"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + nvidia,lock = <0>; + }; + gen2_i2c_scl_pt5 { + nvidia,pins = "gen2_i2c_scl_pt5", + "gen2_i2c_sda_pt6"; + nvidia,function = "i2c2"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + nvidia,lock = <0>; + nvidia,open-drain = <0>; + }; + gmi_a16_pj7 { + nvidia,pins = "gmi_a16_pj7"; + nvidia,function = "uartd"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + }; + gmi_a17_pb0 { + nvidia,pins = "gmi_a17_pb0", + "gmi_a18_pb1"; + nvidia,function = "uartd"; + nvidia,pull = <0>; + nvidia,tristate = <1>; + nvidia,enable-input = <1>; + }; + gmi_a19_pk7 { + nvidia,pins = "gmi_a19_pk7"; + nvidia,function = "uartd"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + }; + gmi_ad5_pg5 { + nvidia,pins = "gmi_ad5_pg5", + "gmi_cs6_n_pi3", + "gmi_wr_n_pi0"; + nvidia,function = "spi4"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + }; + gmi_ad6_pg6 { + nvidia,pins = "gmi_ad6_pg6", + "gmi_ad7_pg7"; + nvidia,function = "spi4"; + nvidia,pull = <2>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + }; + gmi_ad12_ph4 { + nvidia,pins = "gmi_ad12_ph4"; + nvidia,function = "rsvd4"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + }; + gmi_ad9_ph1 { + nvidia,pins = "gmi_ad9_ph1"; + nvidia,function = "pwm1"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + }; + gmi_cs1_n_pj2 { + nvidia,pins = "gmi_cs1_n_pj2", + "gmi_oe_n_pi1"; + nvidia,function = "soc"; + nvidia,pull = <0>; + nvidia,tristate = <1>; + nvidia,enable-input = <1>; + }; + clk2_out_pw5 { + nvidia,pins = "clk2_out_pw5"; + nvidia,function = "extperiph2"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + }; + sdmmc1_clk_pz0 { + nvidia,pins = "sdmmc1_clk_pz0"; + nvidia,function = "sdmmc1"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + }; + sdmmc1_cmd_pz1 { + nvidia,pins = "sdmmc1_cmd_pz1", + "sdmmc1_dat0_py7", + "sdmmc1_dat1_py6", + "sdmmc1_dat2_py5", + "sdmmc1_dat3_py4"; + nvidia,function = "sdmmc1"; + nvidia,pull = <2>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + }; + sdmmc1_wp_n_pv3 { + nvidia,pins = "sdmmc1_wp_n_pv3"; + nvidia,function = "spi4"; + nvidia,pull = <2>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + }; + sdmmc3_clk_pa6 { + nvidia,pins = "sdmmc3_clk_pa6"; + nvidia,function = "sdmmc3"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + }; + sdmmc3_cmd_pa7 { + nvidia,pins = "sdmmc3_cmd_pa7", + "sdmmc3_dat0_pb7", + "sdmmc3_dat1_pb6", + "sdmmc3_dat2_pb5", + "sdmmc3_dat3_pb4", + "kb_col4_pq4", + "sdmmc3_clk_lb_out_pee4", + "sdmmc3_clk_lb_in_pee5"; + nvidia,function = "sdmmc3"; + nvidia,pull = <2>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + }; + sdmmc4_clk_pcc4 { + nvidia,pins = "sdmmc4_clk_pcc4"; + nvidia,function = "sdmmc4"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + }; + sdmmc4_cmd_pt7 { + nvidia,pins = "sdmmc4_cmd_pt7", + "sdmmc4_dat0_paa0", + "sdmmc4_dat1_paa1", + "sdmmc4_dat2_paa2", + "sdmmc4_dat3_paa3", + "sdmmc4_dat4_paa4", + "sdmmc4_dat5_paa5", + "sdmmc4_dat6_paa6", + "sdmmc4_dat7_paa7"; + nvidia,function = "sdmmc4"; + nvidia,pull = <2>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + }; + clk_32k_out_pa0 { + nvidia,pins = "clk_32k_out_pa0"; + nvidia,function = "blink"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + }; + kb_col0_pq0 { + nvidia,pins = "kb_col0_pq0", + "kb_col1_pq1", + "kb_col2_pq2", + "kb_row0_pr0", + "kb_row1_pr1", + "kb_row2_pr2"; + nvidia,function = "kbc"; + nvidia,pull = <2>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + }; + dap3_din_pp1 { + nvidia,pins = "dap3_din_pp1", + "dap3_sclk_pp3"; + nvidia,function = "displayb"; + nvidia,pull = <0>; + nvidia,tristate = <1>; + nvidia,enable-input = <0>; + }; + pv0 { + nvidia,pins = "pv0"; + nvidia,function = "rsvd4"; + nvidia,pull = <0>; + nvidia,tristate = <1>; + nvidia,enable-input = <0>; + }; + kb_row7_pr7 { + nvidia,pins = "kb_row7_pr7"; + nvidia,function = "rsvd2"; + nvidia,pull = <2>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + }; + kb_row10_ps2 { + nvidia,pins = "kb_row10_ps2"; + nvidia,function = "uarta"; + nvidia,pull = <0>; + nvidia,tristate = <1>; + nvidia,enable-input = <1>; + }; + kb_row9_ps1 { + nvidia,pins = "kb_row9_ps1"; + nvidia,function = "uarta"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + }; + pwr_i2c_scl_pz6 { + nvidia,pins = "pwr_i2c_scl_pz6", + "pwr_i2c_sda_pz7"; + nvidia,function = "i2cpwr"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + nvidia,lock = <0>; + nvidia,open-drain = <0>; + }; + sys_clk_req_pz5 { + nvidia,pins = "sys_clk_req_pz5"; + nvidia,function = "sysclk"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + }; + core_pwr_req { + nvidia,pins = "core_pwr_req"; + nvidia,function = "pwron"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + }; + cpu_pwr_req { + nvidia,pins = "cpu_pwr_req"; + nvidia,function = "cpu"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + }; + pwr_int_n { + nvidia,pins = "pwr_int_n"; + nvidia,function = "pmi"; + nvidia,pull = <0>; + nvidia,tristate = <1>; + nvidia,enable-input = <1>; + }; + reset_out_n { + nvidia,pins = "reset_out_n"; + nvidia,function = "reset_out_n"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + }; + clk3_out_pee0 { + nvidia,pins = "clk3_out_pee0"; + nvidia,function = "extperiph3"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + }; + gen1_i2c_scl_pc4 { + nvidia,pins = "gen1_i2c_scl_pc4", + "gen1_i2c_sda_pc5"; + nvidia,function = "i2c1"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + nvidia,lock = <0>; + nvidia,open-drain = <0>; + }; + uart2_cts_n_pj5 { + nvidia,pins = "uart2_cts_n_pj5"; + nvidia,function = "uartb"; + nvidia,pull = <0>; + nvidia,tristate = <1>; + nvidia,enable-input = <1>; + }; + uart2_rts_n_pj6 { + nvidia,pins = "uart2_rts_n_pj6"; + nvidia,function = "uartb"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + }; + uart2_rxd_pc3 { + nvidia,pins = "uart2_rxd_pc3"; + nvidia,function = "irda"; + nvidia,pull = <0>; + nvidia,tristate = <1>; + nvidia,enable-input = <1>; + }; + uart2_txd_pc2 { + nvidia,pins = "uart2_txd_pc2"; + nvidia,function = "irda"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + }; + uart3_cts_n_pa1 { + nvidia,pins = "uart3_cts_n_pa1", + "uart3_rxd_pw7"; + nvidia,function = "uartc"; + nvidia,pull = <0>; + nvidia,tristate = <1>; + nvidia,enable-input = <1>; + }; + uart3_rts_n_pc0 { + nvidia,pins = "uart3_rts_n_pc0", + "uart3_txd_pw6"; + nvidia,function = "uartc"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + }; + owr { + nvidia,pins = "owr"; + nvidia,function = "owr"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + }; + hdmi_cec_pee3 { + nvidia,pins = "hdmi_cec_pee3"; + nvidia,function = "cec"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + nvidia,lock = <0>; + nvidia,open-drain = <0>; + }; + ddc_scl_pv4 { + nvidia,pins = "ddc_scl_pv4", + "ddc_sda_pv5"; + nvidia,function = "i2c4"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + nvidia,lock = <0>; + nvidia,rcv-sel = <1>; + }; + spdif_in_pk6 { + nvidia,pins = "spdif_in_pk6"; + nvidia,function = "usb"; + nvidia,pull = <2>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + nvidia,lock = <0>; + }; + usb_vbus_en0_pn4 { + nvidia,pins = "usb_vbus_en0_pn4"; + nvidia,function = "usb"; + nvidia,pull = <2>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + nvidia,lock = <0>; + nvidia,open-drain = <1>; + }; + gpio_x6_aud_px6 { + nvidia,pins = "gpio_x6_aud_px6"; + nvidia,function = "spi6"; + nvidia,pull = <2>; + nvidia,tristate = <1>; + nvidia,enable-input = <1>; + }; + gpio_x4_aud_px4 { + nvidia,pins = "gpio_x4_aud_px4", + "gpio_x7_aud_px7"; + nvidia,function = "rsvd1"; + nvidia,pull = <1>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + }; + gpio_x5_aud_px5 { + nvidia,pins = "gpio_x5_aud_px5"; + nvidia,function = "rsvd1"; + nvidia,pull = <2>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + }; + gpio_w2_aud_pw2 { + nvidia,pins = "gpio_w2_aud_pw2"; + nvidia,function = "rsvd2"; + nvidia,pull = <2>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + }; + gpio_w3_aud_pw3 { + nvidia,pins = "gpio_w3_aud_pw3"; + nvidia,function = "spi6"; + nvidia,pull = <2>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + }; + gpio_x1_aud_px1 { + nvidia,pins = "gpio_x1_aud_px1"; + nvidia,function = "rsvd4"; + nvidia,pull = <1>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + }; + gpio_x3_aud_px3 { + nvidia,pins = "gpio_x3_aud_px3"; + nvidia,function = "rsvd4"; + nvidia,pull = <2>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + }; + dap3_fs_pp0 { + nvidia,pins = "dap3_fs_pp0"; + nvidia,function = "i2s2"; + nvidia,pull = <1>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + }; + dap3_dout_pp2 { + nvidia,pins = "dap3_dout_pp2"; + nvidia,function = "i2s2"; + nvidia,pull = <1>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + }; + pv1 { + nvidia,pins = "pv1"; + nvidia,function = "rsvd1"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + }; + pbb3 { + nvidia,pins = "pbb3", + "pbb5", + "pbb6", + "pbb7"; + nvidia,function = "rsvd4"; + nvidia,pull = <1>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + }; + pcc1 { + nvidia,pins = "pcc1", + "pcc2"; + nvidia,function = "rsvd4"; + nvidia,pull = <1>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + }; + gmi_ad0_pg0 { + nvidia,pins = "gmi_ad0_pg0", + "gmi_ad1_pg1"; + nvidia,function = "gmi"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + }; + gmi_ad10_ph2 { + nvidia,pins = "gmi_ad10_ph2", + "gmi_ad11_ph3", + "gmi_ad13_ph5", + "gmi_ad8_ph0", + "gmi_clk_pk1"; + nvidia,function = "gmi"; + nvidia,pull = <1>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + }; + gmi_ad2_pg2 { + nvidia,pins = "gmi_ad2_pg2", + "gmi_ad3_pg3"; + nvidia,function = "gmi"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + }; + gmi_adv_n_pk0 { + nvidia,pins = "gmi_adv_n_pk0", + "gmi_cs0_n_pj0", + "gmi_cs2_n_pk3", + "gmi_cs4_n_pk2", + "gmi_cs7_n_pi6", + "gmi_dqs_p_pj3", + "gmi_iordy_pi5", + "gmi_wp_n_pc7"; + nvidia,function = "gmi"; + nvidia,pull = <2>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + }; + gmi_cs3_n_pk4 { + nvidia,pins = "gmi_cs3_n_pk4"; + nvidia,function = "gmi"; + nvidia,pull = <2>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + }; + clk2_req_pcc5 { + nvidia,pins = "clk2_req_pcc5"; + nvidia,function = "rsvd4"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + }; + kb_col3_pq3 { + nvidia,pins = "kb_col3_pq3", + "kb_col6_pq6", + "kb_col7_pq7"; + nvidia,function = "kbc"; + nvidia,pull = <2>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + }; + kb_col5_pq5 { + nvidia,pins = "kb_col5_pq5"; + nvidia,function = "kbc"; + nvidia,pull = <2>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + }; + kb_row3_pr3 { + nvidia,pins = "kb_row3_pr3", + "kb_row4_pr4", + "kb_row6_pr6", + "kb_row8_ps0"; + nvidia,function = "kbc"; + nvidia,pull = <1>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + }; + clk3_req_pee1 { + nvidia,pins = "clk3_req_pee1"; + nvidia,function = "rsvd4"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + }; + pu4 { + nvidia,pins = "pu4"; + nvidia,function = "displayb"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <0>; + }; + pu5 { + nvidia,pins = "pu5", + "pu6"; + nvidia,function = "displayb"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + }; + hdmi_int_pn7 { + nvidia,pins = "hdmi_int_pn7"; + nvidia,function = "rsvd1"; + nvidia,pull = <1>; + nvidia,tristate = <0>; + nvidia,enable-input = <1>; + }; + clk1_req_pee2 { + nvidia,pins = "clk1_req_pee2", + "usb_vbus_en1_pn5"; + nvidia,function = "rsvd4"; + nvidia,pull = <1>; + nvidia,tristate = <1>; + nvidia,enable-input = <0>; + }; + + drive_sdio1 { + nvidia,pins = "drive_sdio1"; + nvidia,high-speed-mode = <1>; + nvidia,schmitt = <0>; + nvidia,low-power-mode = <3>; + nvidia,pull-down-strength = <36>; + nvidia,pull-up-strength = <20>; + nvidia,slew-rate-rising = <2>; + nvidia,slew-rate-falling = <2>; + }; + drive_sdio3 { + nvidia,pins = "drive_sdio3"; + nvidia,high-speed-mode = <1>; + nvidia,schmitt = <0>; + nvidia,low-power-mode = <3>; + nvidia,pull-down-strength = <22>; + nvidia,pull-up-strength = <36>; + nvidia,slew-rate-rising = <0>; + nvidia,slew-rate-falling = <0>; + }; + drive_gma { + nvidia,pins = "drive_gma"; + nvidia,high-speed-mode = <1>; + nvidia,schmitt = <0>; + nvidia,low-power-mode = <3>; + nvidia,pull-down-strength = <2>; + nvidia,pull-up-strength = <1>; + nvidia,slew-rate-rising = <0>; + nvidia,slew-rate-falling = <0>; + nvidia,drive-type = <1>; + }; + }; + }; + serial@70006300 { status = "okay"; - clock-frequency = <408000000>; + }; + + i2c@7000c000 { + status = "okay"; + clock-frequency = <100000>; + + battery: smart-battery { + compatible = "ti,bq20z45", "sbs,sbs-battery"; + reg = <0xb>; + battery-name = "battery"; + sbs,i2c-retry-count = <2>; + sbs,poll-retry-count = <100>; + }; + }; + + i2c@7000d000 { + status = "okay"; + clock-frequency = <400000>; + + tps51632 { + compatible = "ti,tps51632"; + reg = <0x43>; + regulator-name = "vdd-cpu"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1520000>; + regulator-boot-on; + regulator-always-on; + }; + + tps65090 { + compatible = "ti,tps65090"; + reg = <0x48>; + interrupt-parent = <&gpio>; + interrupts = <72 0x04>; /* gpio PJ0 */ + + vsys1-supply = <&vdd_ac_bat_reg>; + vsys2-supply = <&vdd_ac_bat_reg>; + vsys3-supply = <&vdd_ac_bat_reg>; + infet1-supply = <&vdd_ac_bat_reg>; + infet2-supply = <&vdd_ac_bat_reg>; + infet3-supply = <&tps65090_dcdc2_reg>; + infet4-supply = <&tps65090_dcdc2_reg>; + infet5-supply = <&tps65090_dcdc2_reg>; + infet6-supply = <&tps65090_dcdc2_reg>; + infet7-supply = <&tps65090_dcdc2_reg>; + vsys-l1-supply = <&vdd_ac_bat_reg>; + vsys-l2-supply = <&vdd_ac_bat_reg>; + + regulators { + tps65090_dcdc1_reg: dcdc1 { + regulator-name = "vdd-sys-5v0"; + regulator-always-on; + regulator-boot-on; + }; + + tps65090_dcdc2_reg: dcdc2 { + regulator-name = "vdd-sys-3v3"; + regulator-always-on; + regulator-boot-on; + }; + + dcdc3 { + regulator-name = "vdd-ao"; + regulator-always-on; + regulator-boot-on; + }; + + fet1 { + regulator-name = "vdd-lcd-bl"; + }; + + fet3 { + regulator-name = "vdd-modem-3v3"; + }; + + fet4 { + regulator-name = "avdd-lcd"; + }; + + fet5 { + regulator-name = "vdd-lvds"; + }; + + fet6 { + regulator-name = "vdd-sd-slot"; + regulator-always-on; + regulator-boot-on; + }; + + fet7 { + regulator-name = "vdd-com-3v3"; + }; + + ldo1 { + regulator-name = "vdd-sby-5v0"; + regulator-always-on; + regulator-boot-on; + }; + + ldo2 { + regulator-name = "vdd-sby-3v3"; + regulator-always-on; + regulator-boot-on; + }; + }; + }; }; pmc { nvidia,invert-interrupt; }; + sdhci@78000400 { + cd-gpios = <&gpio 170 1>; /* gpio PV2 */ + bus-width = <4>; + status = "okay"; + }; + + sdhci@78000600 { + bus-width = <8>; + status = "okay"; + non-removable; + }; + clocks { compatible = "simple-bus"; #address-cells = <1>; @@ -31,4 +851,74 @@ clock-frequency = <32768>; }; }; + + regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + vdd_ac_bat_reg: regulator@0 { + compatible = "regulator-fixed"; + reg = <0>; + regulator-name = "vdd_ac_bat"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + dvdd_ts_reg: regulator@1 { + compatible = "regulator-fixed"; + reg = <1>; + regulator-name = "dvdd_ts"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + enable-active-high; + gpio = <&gpio 61 0>; /* GPIO PH5 */ + }; + + lcd_bl_en_reg: regulator@2 { + compatible = "regulator-fixed"; + reg = <2>; + regulator-name = "lcd_bl_en"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&gpio 58 0>; /* GPIO PH2 */ + }; + + usb1_vbus_reg: regulator@3 { + compatible = "regulator-fixed"; + reg = <3>; + regulator-name = "usb1_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&gpio 108 0>; /* GPIO PN4 */ + gpio-open-drain; + vin-supply = <&tps65090_dcdc1_reg>; + }; + + usb3_vbus_reg: regulator@4 { + compatible = "regulator-fixed"; + reg = <4>; + regulator-name = "usb2_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&gpio 86 0>; /* GPIO PK6 */ + gpio-open-drain; + vin-supply = <&tps65090_dcdc1_reg>; + }; + + vdd_hdmi_reg: regulator@5 { + compatible = "regulator-fixed"; + reg = <5>; + regulator-name = "vdd_hdmi_5v0"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&gpio 81 0>; /* GPIO PK1 */ + vin-supply = <&tps65090_dcdc1_reg>; + }; + }; }; diff --git a/trunk/arch/arm/boot/dts/tegra114-pluto.dts b/trunk/arch/arm/boot/dts/tegra114-pluto.dts index 5deb8692b350..6bbc8efae9c0 100644 --- a/trunk/arch/arm/boot/dts/tegra114-pluto.dts +++ b/trunk/arch/arm/boot/dts/tegra114-pluto.dts @@ -12,7 +12,6 @@ serial@70006300 { status = "okay"; - clock-frequency = <408000000>; }; pmc { diff --git a/trunk/arch/arm/boot/dts/tegra114.dtsi b/trunk/arch/arm/boot/dts/tegra114.dtsi index c0b527d15fda..629415ffd8dc 100644 --- a/trunk/arch/arm/boot/dts/tegra114.dtsi +++ b/trunk/arch/arm/boot/dts/tegra114.dtsi @@ -4,6 +4,13 @@ compatible = "nvidia,tegra114"; interrupt-parent = <&gic>; + aliases { + serial0 = &uarta; + serial1 = &uartb; + serial2 = &uartc; + serial3 = &uartd; + }; + gic: interrupt-controller { compatible = "arm,cortex-a15-gic"; #interrupt-cells = <3>; @@ -24,14 +31,53 @@ 0 42 0x04 0 121 0x04 0 122 0x04>; + clocks = <&tegra_car 5>; }; tegra_car: clock { - compatible = "nvidia,tegra114-car, nvidia,tegra30-car"; + compatible = "nvidia,tegra114-car"; reg = <0x60006000 0x1000>; #clock-cells = <1>; }; + apbdma: dma { + compatible = "nvidia,tegra114-apbdma"; + reg = <0x6000a000 0x1400>; + interrupts = <0 104 0x04 + 0 105 0x04 + 0 106 0x04 + 0 107 0x04 + 0 108 0x04 + 0 109 0x04 + 0 110 0x04 + 0 111 0x04 + 0 112 0x04 + 0 113 0x04 + 0 114 0x04 + 0 115 0x04 + 0 116 0x04 + 0 117 0x04 + 0 118 0x04 + 0 119 0x04 + 0 128 0x04 + 0 129 0x04 + 0 130 0x04 + 0 131 0x04 + 0 132 0x04 + 0 133 0x04 + 0 134 0x04 + 0 135 0x04 + 0 136 0x04 + 0 137 0x04 + 0 138 0x04 + 0 139 0x04 + 0 140 0x04 + 0 141 0x04 + 0 142 0x04 + 0 143 0x04>; + clocks = <&tegra_car 34>; + }; + ahb: ahb { compatible = "nvidia,tegra114-ahb", "nvidia,tegra30-ahb"; reg = <0x6000c004 0x14c>; @@ -60,35 +106,186 @@ 0x70003000 0x40c>; /* Mux registers */ }; - serial@70006000 { + /* + * There are two serial driver i.e. 8250 based simple serial + * driver and APB DMA based serial driver for higher baudrate + * and performace. To enable the 8250 based driver, the compatible + * is "nvidia,tegra114-uart", "nvidia,tegra20-uart" and to enable + * the APB DMA based serial driver, the comptible is + * "nvidia,tegra114-hsuart", "nvidia,tegra30-hsuart". + */ + uarta: serial@70006000 { compatible = "nvidia,tegra114-uart", "nvidia,tegra20-uart"; reg = <0x70006000 0x40>; reg-shift = <2>; interrupts = <0 36 0x04>; + nvidia,dma-request-selector = <&apbdma 8>; status = "disabled"; + clocks = <&tegra_car 6>; }; - serial@70006040 { + uartb: serial@70006040 { compatible = "nvidia,tegra114-uart", "nvidia,tegra20-uart"; reg = <0x70006040 0x40>; reg-shift = <2>; interrupts = <0 37 0x04>; + nvidia,dma-request-selector = <&apbdma 9>; status = "disabled"; + clocks = <&tegra_car 192>; }; - serial@70006200 { + uartc: serial@70006200 { compatible = "nvidia,tegra114-uart", "nvidia,tegra20-uart"; reg = <0x70006200 0x100>; reg-shift = <2>; interrupts = <0 46 0x04>; + nvidia,dma-request-selector = <&apbdma 10>; status = "disabled"; + clocks = <&tegra_car 55>; }; - serial@70006300 { + uartd: serial@70006300 { compatible = "nvidia,tegra114-uart", "nvidia,tegra20-uart"; reg = <0x70006300 0x100>; reg-shift = <2>; interrupts = <0 90 0x04>; + nvidia,dma-request-selector = <&apbdma 19>; + status = "disabled"; + clocks = <&tegra_car 65>; + }; + + pwm: pwm { + compatible = "nvidia,tegra114-pwm", "nvidia,tegra20-pwm"; + reg = <0x7000a000 0x100>; + #pwm-cells = <2>; + clocks = <&tegra_car 17>; + status = "disabled"; + }; + + i2c@7000c000 { + compatible = "nvidia,tegra114-i2c"; + reg = <0x7000c000 0x100>; + interrupts = <0 38 0x04>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car 12>; + clock-names = "div-clk"; + status = "disabled"; + }; + + i2c@7000c400 { + compatible = "nvidia,tegra114-i2c"; + reg = <0x7000c400 0x100>; + interrupts = <0 84 0x04>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car 54>; + clock-names = "div-clk"; + status = "disabled"; + }; + + i2c@7000c500 { + compatible = "nvidia,tegra114-i2c"; + reg = <0x7000c500 0x100>; + interrupts = <0 92 0x04>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car 67>; + clock-names = "div-clk"; + status = "disabled"; + }; + + i2c@7000c700 { + compatible = "nvidia,tegra114-i2c"; + reg = <0x7000c700 0x100>; + interrupts = <0 120 0x04>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car 103>; + clock-names = "div-clk"; + status = "disabled"; + }; + + i2c@7000d000 { + compatible = "nvidia,tegra114-i2c"; + reg = <0x7000d000 0x100>; + interrupts = <0 53 0x04>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car 47>; + clock-names = "div-clk"; + status = "disabled"; + }; + + spi@7000d400 { + compatible = "nvidia,tegra114-spi"; + reg = <0x7000d400 0x200>; + interrupts = <0 59 0x04>; + nvidia,dma-request-selector = <&apbdma 15>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car 41>; + clock-names = "spi"; + status = "disabled"; + }; + + spi@7000d600 { + compatible = "nvidia,tegra114-spi"; + reg = <0x7000d600 0x200>; + interrupts = <0 82 0x04>; + nvidia,dma-request-selector = <&apbdma 16>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car 44>; + clock-names = "spi"; + status = "disabled"; + }; + + spi@7000d800 { + compatible = "nvidia,tegra114-spi"; + reg = <0x7000d800 0x200>; + interrupts = <0 83 0x04>; + nvidia,dma-request-selector = <&apbdma 17>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car 46>; + clock-names = "spi"; + status = "disabled"; + }; + + spi@7000da00 { + compatible = "nvidia,tegra114-spi"; + reg = <0x7000da00 0x200>; + interrupts = <0 93 0x04>; + nvidia,dma-request-selector = <&apbdma 18>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car 68>; + clock-names = "spi"; + status = "disabled"; + }; + + spi@7000dc00 { + compatible = "nvidia,tegra114-spi"; + reg = <0x7000dc00 0x200>; + interrupts = <0 94 0x04>; + nvidia,dma-request-selector = <&apbdma 27>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car 104>; + clock-names = "spi"; + status = "disabled"; + }; + + spi@7000de00 { + compatible = "nvidia,tegra114-spi"; + reg = <0x7000de00 0x200>; + interrupts = <0 79 0x04>; + nvidia,dma-request-selector = <&apbdma 28>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car 105>; + clock-names = "spi"; status = "disabled"; }; @@ -96,6 +293,15 @@ compatible = "nvidia,tegra114-rtc", "nvidia,tegra20-rtc"; reg = <0x7000e000 0x100>; interrupts = <0 2 0x04>; + clocks = <&tegra_car 4>; + }; + + kbc { + compatible = "nvidia,tegra114-kbc"; + reg = <0x7000e200 0x100>; + interrupts = <0 85 0x04>; + clocks = <&tegra_car 36>; + status = "disabled"; }; pmc { @@ -116,6 +322,38 @@ nvidia,ahb = <&ahb>; }; + sdhci@78000000 { + compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci"; + reg = <0x78000000 0x200>; + interrupts = <0 14 0x04>; + clocks = <&tegra_car 14>; + status = "disable"; + }; + + sdhci@78000200 { + compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci"; + reg = <0x78000200 0x200>; + interrupts = <0 15 0x04>; + clocks = <&tegra_car 9>; + status = "disable"; + }; + + sdhci@78000400 { + compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci"; + reg = <0x78000400 0x200>; + interrupts = <0 19 0x04>; + clocks = <&tegra_car 69>; + status = "disable"; + }; + + sdhci@78000600 { + compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci"; + reg = <0x78000600 0x200>; + interrupts = <0 31 0x04>; + clocks = <&tegra_car 15>; + status = "disable"; + }; + cpus { #address-cells = <1>; #size-cells = <0>; diff --git a/trunk/arch/arm/boot/dts/tegra20-colibri-512.dtsi b/trunk/arch/arm/boot/dts/tegra20-colibri-512.dtsi index 4e3afdef28a8..a573b94b7c93 100644 --- a/trunk/arch/arm/boot/dts/tegra20-colibri-512.dtsi +++ b/trunk/arch/arm/boot/dts/tegra20-colibri-512.dtsi @@ -361,6 +361,15 @@ }; }; + pmc { + nvidia,suspend-mode = <2>; + nvidia,cpu-pwr-good-time = <5000>; + nvidia,cpu-pwr-off-time = <5000>; + nvidia,core-pwr-good-time = <3845 3845>; + nvidia,core-pwr-off-time = <3875>; + nvidia,sys-clock-req-active-high; + }; + memory-controller@7000f400 { emc-table@83250 { reg = <83250>; @@ -473,6 +482,9 @@ "Mic", "MIC1"; nvidia,ac97-controller = <&ac97>; + + clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>; + clock-names = "pll_a", "pll_a_out0", "mclk"; }; regulators { diff --git a/trunk/arch/arm/boot/dts/tegra20-harmony.dts b/trunk/arch/arm/boot/dts/tegra20-harmony.dts index ae9d5a20834e..e7d5de4e00b9 100644 --- a/trunk/arch/arm/boot/dts/tegra20-harmony.dts +++ b/trunk/arch/arm/boot/dts/tegra20-harmony.dts @@ -416,6 +416,12 @@ pmc { nvidia,invert-interrupt; + nvidia,suspend-mode = <2>; + nvidia,cpu-pwr-good-time = <5000>; + nvidia,cpu-pwr-off-time = <5000>; + nvidia,core-pwr-good-time = <3845 3845>; + nvidia,core-pwr-off-time = <3875>; + nvidia,sys-clock-req-active-high; }; usb@c5000000 { @@ -464,6 +470,17 @@ }; }; + gpio-keys { + compatible = "gpio-keys"; + + power { + label = "Power"; + gpios = <&gpio 170 1>; /* gpio PV2, active low */ + linux,code = <116>; /* KEY_POWER */ + gpio-key,wakeup; + }; + }; + kbc { status = "okay"; nvidia,debounce-delay-ms = <2>; @@ -669,5 +686,8 @@ nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */ nvidia,int-mic-en-gpios = <&gpio 184 0>; /*gpio PX0 */ nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */ + + clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>; + clock-names = "pll_a", "pll_a_out0", "mclk"; }; }; diff --git a/trunk/arch/arm/boot/dts/tegra20-medcom-wide.dts b/trunk/arch/arm/boot/dts/tegra20-medcom-wide.dts index a2d6d6541f83..ace23437da89 100644 --- a/trunk/arch/arm/boot/dts/tegra20-medcom-wide.dts +++ b/trunk/arch/arm/boot/dts/tegra20-medcom-wide.dts @@ -6,6 +6,10 @@ model = "Avionic Design Medcom-Wide board"; compatible = "ad,medcom-wide", "ad,tamonten", "nvidia,tegra20"; + pwm { + status = "okay"; + }; + i2c@7000c000 { wm8903: wm8903@1a { compatible = "wlf,wm8903"; @@ -54,5 +58,8 @@ nvidia,spkr-en-gpios = <&wm8903 2 0>; nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */ + + clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>; + clock-names = "pll_a", "pll_a_out0", "mclk"; }; }; diff --git a/trunk/arch/arm/boot/dts/tegra20-paz00.dts b/trunk/arch/arm/boot/dts/tegra20-paz00.dts index fd60940e4063..e3e0c9977df4 100644 --- a/trunk/arch/arm/boot/dts/tegra20-paz00.dts +++ b/trunk/arch/arm/boot/dts/tegra20-paz00.dts @@ -415,6 +415,12 @@ pmc { nvidia,invert-interrupt; + nvidia,suspend-mode = <2>; + nvidia,cpu-pwr-good-time = <2000>; + nvidia,cpu-pwr-off-time = <0>; + nvidia,core-pwr-good-time = <3845 3845>; + nvidia,core-pwr-off-time = <0>; + nvidia,sys-clock-req-active-high; }; usb@c5000000 { @@ -445,6 +451,7 @@ sdhci@c8000600 { status = "okay"; bus-width = <8>; + non-removable; }; clocks { @@ -514,5 +521,8 @@ nvidia,audio-codec = <&alc5632>; nvidia,i2s-controller = <&tegra_i2s1>; nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */ + + clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>; + clock-names = "pll_a", "pll_a_out0", "mclk"; }; }; diff --git a/trunk/arch/arm/boot/dts/tegra20-plutux.dts b/trunk/arch/arm/boot/dts/tegra20-plutux.dts index 289480026fbf..1a17cc30bb9d 100644 --- a/trunk/arch/arm/boot/dts/tegra20-plutux.dts +++ b/trunk/arch/arm/boot/dts/tegra20-plutux.dts @@ -52,5 +52,8 @@ nvidia,spkr-en-gpios = <&wm8903 2 0>; nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */ + + clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>; + clock-names = "pll_a", "pll_a_out0", "mclk"; }; }; diff --git a/trunk/arch/arm/boot/dts/tegra20-seaboard.dts b/trunk/arch/arm/boot/dts/tegra20-seaboard.dts index 4ee700a33ca5..cee4c34010fe 100644 --- a/trunk/arch/arm/boot/dts/tegra20-seaboard.dts +++ b/trunk/arch/arm/boot/dts/tegra20-seaboard.dts @@ -517,6 +517,12 @@ pmc { nvidia,invert-interrupt; + nvidia,suspend-mode = <2>; + nvidia,cpu-pwr-good-time = <5000>; + nvidia,cpu-pwr-off-time = <5000>; + nvidia,core-pwr-good-time = <3845 3845>; + nvidia,core-pwr-off-time = <3875>; + nvidia,sys-clock-req-active-high; }; memory-controller@7000f400 { @@ -580,6 +586,7 @@ status = "okay"; power-gpios = <&gpio 86 0>; /* gpio PK6 */ bus-width = <4>; + keep-power-in-suspend; }; sdhci@c8000400 { @@ -593,6 +600,7 @@ sdhci@c8000600 { status = "okay"; bus-width = <8>; + non-removable; }; clocks { @@ -821,5 +829,8 @@ nvidia,spkr-en-gpios = <&wm8903 2 0>; nvidia,hp-det-gpios = <&gpio 185 0>; /* gpio PX1 */ + + clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>; + clock-names = "pll_a", "pll_a_out0", "mclk"; }; }; diff --git a/trunk/arch/arm/boot/dts/tegra20-tamonten.dtsi b/trunk/arch/arm/boot/dts/tegra20-tamonten.dtsi index c19025725918..50b3ec16b93a 100644 --- a/trunk/arch/arm/boot/dts/tegra20-tamonten.dtsi +++ b/trunk/arch/arm/boot/dts/tegra20-tamonten.dtsi @@ -458,6 +458,12 @@ pmc { nvidia,invert-interrupt; + nvidia,suspend-mode = <2>; + nvidia,cpu-pwr-good-time = <5000>; + nvidia,cpu-pwr-off-time = <5000>; + nvidia,core-pwr-good-time = <3845 3845>; + nvidia,core-pwr-off-time = <3875>; + nvidia,sys-clock-req-active-high; }; usb@c5008000 { diff --git a/trunk/arch/arm/boot/dts/tegra20-tec.dts b/trunk/arch/arm/boot/dts/tegra20-tec.dts index 402b21004bef..742f0b38d21d 100644 --- a/trunk/arch/arm/boot/dts/tegra20-tec.dts +++ b/trunk/arch/arm/boot/dts/tegra20-tec.dts @@ -52,5 +52,8 @@ nvidia,spkr-en-gpios = <&wm8903 2 0>; nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */ + + clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>; + clock-names = "pll_a", "pll_a_out0", "mclk"; }; }; diff --git a/trunk/arch/arm/boot/dts/tegra20-trimslice.dts b/trunk/arch/arm/boot/dts/tegra20-trimslice.dts index a9f3f06580f5..9cc78a15d739 100644 --- a/trunk/arch/arm/boot/dts/tegra20-trimslice.dts +++ b/trunk/arch/arm/boot/dts/tegra20-trimslice.dts @@ -300,6 +300,15 @@ }; }; + pmc { + nvidia,suspend-mode = <2>; + nvidia,cpu-pwr-good-time = <5000>; + nvidia,cpu-pwr-off-time = <5000>; + nvidia,core-pwr-good-time = <3845 3845>; + nvidia,core-pwr-off-time = <3875>; + nvidia,sys-clock-req-active-high; + }; + usb@c5000000 { status = "okay"; nvidia,vbus-gpio = <&gpio 170 0>; /* gpio PV2 */ @@ -343,6 +352,17 @@ }; }; + gpio-keys { + compatible = "gpio-keys"; + + power { + label = "Power"; + gpios = <&gpio 190 1>; /* gpio PX6, active low */ + linux,code = <116>; /* KEY_POWER */ + gpio-key,wakeup; + }; + }; + poweroff { compatible = "gpio-poweroff"; gpios = <&gpio 191 1>; /* gpio PX7, active low */ @@ -376,5 +396,8 @@ compatible = "nvidia,tegra-audio-trimslice"; nvidia,i2s-controller = <&tegra_i2s1>; nvidia,audio-codec = <&codec>; + + clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>; + clock-names = "pll_a", "pll_a_out0", "mclk"; }; }; diff --git a/trunk/arch/arm/boot/dts/tegra20-ventana.dts b/trunk/arch/arm/boot/dts/tegra20-ventana.dts index f544806e9618..dd38f1f03834 100644 --- a/trunk/arch/arm/boot/dts/tegra20-ventana.dts +++ b/trunk/arch/arm/boot/dts/tegra20-ventana.dts @@ -493,6 +493,12 @@ pmc { nvidia,invert-interrupt; + nvidia,suspend-mode = <2>; + nvidia,cpu-pwr-good-time = <2000>; + nvidia,cpu-pwr-off-time = <100>; + nvidia,core-pwr-good-time = <3845 3845>; + nvidia,core-pwr-off-time = <458>; + nvidia,sys-clock-req-active-high; }; usb@c5000000 { @@ -516,6 +522,7 @@ status = "okay"; power-gpios = <&gpio 86 0>; /* gpio PK6 */ bus-width = <4>; + keep-power-in-suspend; }; sdhci@c8000400 { @@ -529,6 +536,7 @@ sdhci@c8000600 { status = "okay"; bus-width = <8>; + non-removable; }; clocks { @@ -544,6 +552,17 @@ }; }; + gpio-keys { + compatible = "gpio-keys"; + + power { + label = "Power"; + gpios = <&gpio 170 1>; /* gpio PV2, active low */ + linux,code = <116>; /* KEY_POWER */ + gpio-key,wakeup; + }; + }; + regulators { compatible = "simple-bus"; #address-cells = <1>; @@ -620,5 +639,8 @@ nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */ nvidia,int-mic-en-gpios = <&gpio 184 0>; /* gpio PX0 */ nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */ + + clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>; + clock-names = "pll_a", "pll_a_out0", "mclk"; }; }; diff --git a/trunk/arch/arm/boot/dts/tegra20-whistler.dts b/trunk/arch/arm/boot/dts/tegra20-whistler.dts index 258cf945f515..d2567f83aaff 100644 --- a/trunk/arch/arm/boot/dts/tegra20-whistler.dts +++ b/trunk/arch/arm/boot/dts/tegra20-whistler.dts @@ -496,6 +496,14 @@ pmc { nvidia,invert-interrupt; + nvidia,suspend-mode = <2>; + nvidia,cpu-pwr-good-time = <2000>; + nvidia,cpu-pwr-off-time = <1000>; + nvidia,core-pwr-good-time = <0 3845>; + nvidia,core-pwr-off-time = <93727>; + nvidia,core-power-req-active-high; + nvidia,sys-clock-req-active-high; + nvidia,combined-power-req; }; usb@c5000000 { @@ -518,6 +526,7 @@ sdhci@c8000600 { status = "okay"; bus-width = <8>; + non-removable; }; clocks { @@ -539,6 +548,7 @@ nvidia,repeat-delay-ms = <160>; nvidia,kbc-row-pins = <0 1 2>; nvidia,kbc-col-pins = <16 17>; + nvidia,wakeup-source; linux,keymap = <0x00000074 /* KEY_POWER */ 0x01000066 /* KEY_HOME */ 0x0101009E /* KEY_BACK */ @@ -573,5 +583,8 @@ nvidia,i2s-controller = <&tegra_i2s1>; nvidia,audio-codec = <&codec>; + + clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>; + clock-names = "pll_a", "pll_a_out0", "mclk"; }; }; diff --git a/trunk/arch/arm/boot/dts/tegra20.dtsi b/trunk/arch/arm/boot/dts/tegra20.dtsi index fc7febc2b386..56a91106041b 100644 --- a/trunk/arch/arm/boot/dts/tegra20.dtsi +++ b/trunk/arch/arm/boot/dts/tegra20.dtsi @@ -209,7 +209,7 @@ compatible = "nvidia,tegra20-das"; reg = <0x70000c00 0x80>; }; - + tegra_ac97: ac97 { compatible = "nvidia,tegra20-ac97"; reg = <0x70002000 0x200>; @@ -299,6 +299,7 @@ reg = <0x7000a000 0x100>; #pwm-cells = <2>; clocks = <&tegra_car 17>; + status = "disabled"; }; rtc { @@ -442,31 +443,6 @@ #size-cells = <0>; }; - phy1: usb-phy@c5000400 { - compatible = "nvidia,tegra20-usb-phy"; - reg = <0xc5000400 0x3c00>; - phy_type = "utmi"; - nvidia,has-legacy-mode; - clocks = <&tegra_car 22>, <&tegra_car 127>; - clock-names = "phy", "pll_u"; - }; - - phy2: usb-phy@c5004400 { - compatible = "nvidia,tegra20-usb-phy"; - reg = <0xc5004400 0x3c00>; - phy_type = "ulpi"; - clocks = <&tegra_car 94>, <&tegra_car 127>; - clock-names = "phy", "pll_u"; - }; - - phy3: usb-phy@c5008400 { - compatible = "nvidia,tegra20-usb-phy"; - reg = <0xc5008400 0x3C00>; - phy_type = "utmi"; - clocks = <&tegra_car 22>, <&tegra_car 127>; - clock-names = "phy", "pll_u"; - }; - usb@c5000000 { compatible = "nvidia,tegra20-ehci", "usb-ehci"; reg = <0xc5000000 0x4000>; @@ -479,6 +455,15 @@ status = "disabled"; }; + phy1: usb-phy@c5000400 { + compatible = "nvidia,tegra20-usb-phy"; + reg = <0xc5000400 0x3c00>; + phy_type = "utmi"; + nvidia,has-legacy-mode; + clocks = <&tegra_car 22>, <&tegra_car 127>; + clock-names = "phy", "pll_u"; + }; + usb@c5004000 { compatible = "nvidia,tegra20-ehci", "usb-ehci"; reg = <0xc5004000 0x4000>; @@ -489,6 +474,14 @@ status = "disabled"; }; + phy2: usb-phy@c5004400 { + compatible = "nvidia,tegra20-usb-phy"; + reg = <0xc5004400 0x3c00>; + phy_type = "ulpi"; + clocks = <&tegra_car 93>, <&tegra_car 127>; + clock-names = "phy", "pll_u"; + }; + usb@c5008000 { compatible = "nvidia,tegra20-ehci", "usb-ehci"; reg = <0xc5008000 0x4000>; @@ -499,6 +492,14 @@ status = "disabled"; }; + phy3: usb-phy@c5008400 { + compatible = "nvidia,tegra20-usb-phy"; + reg = <0xc5008400 0x3c00>; + phy_type = "utmi"; + clocks = <&tegra_car 22>, <&tegra_car 127>; + clock-names = "phy", "pll_u"; + }; + sdhci@c8000000 { compatible = "nvidia,tegra20-sdhci"; reg = <0xc8000000 0x200>; diff --git a/trunk/arch/arm/boot/dts/tegra30-beaver.dts b/trunk/arch/arm/boot/dts/tegra30-beaver.dts index 6248b2445b32..b732f7c13a66 100644 --- a/trunk/arch/arm/boot/dts/tegra30-beaver.dts +++ b/trunk/arch/arm/boot/dts/tegra30-beaver.dts @@ -253,6 +253,13 @@ pmc { status = "okay"; nvidia,invert-interrupt; + nvidia,suspend-mode = <2>; + nvidia,cpu-pwr-good-time = <2000>; + nvidia,cpu-pwr-off-time = <200>; + nvidia,core-pwr-good-time = <3845 3845>; + nvidia,core-pwr-off-time = <0>; + nvidia,core-power-req-active-high; + nvidia,sys-clock-req-active-high; }; sdhci@78000000 { @@ -266,6 +273,7 @@ sdhci@78000600 { status = "okay"; bus-width = <8>; + non-removable; }; clocks { diff --git a/trunk/arch/arm/boot/dts/tegra30-cardhu-a02.dts b/trunk/arch/arm/boot/dts/tegra30-cardhu-a02.dts index adc88aa50eb6..e392bd2dab9b 100644 --- a/trunk/arch/arm/boot/dts/tegra30-cardhu-a02.dts +++ b/trunk/arch/arm/boot/dts/tegra30-cardhu-a02.dts @@ -88,6 +88,7 @@ status = "okay"; power-gpios = <&gpio 28 0>; /* gpio PD4 */ bus-width = <4>; + keep-power-in-suspend; }; }; diff --git a/trunk/arch/arm/boot/dts/tegra30-cardhu-a04.dts b/trunk/arch/arm/boot/dts/tegra30-cardhu-a04.dts index 08163e145d57..d0db6c7e774f 100644 --- a/trunk/arch/arm/boot/dts/tegra30-cardhu-a04.dts +++ b/trunk/arch/arm/boot/dts/tegra30-cardhu-a04.dts @@ -100,5 +100,6 @@ status = "okay"; power-gpios = <&gpio 27 0>; /* gpio PD3 */ bus-width = <4>; + keep-power-in-suspend; }; }; diff --git a/trunk/arch/arm/boot/dts/tegra30-cardhu.dtsi b/trunk/arch/arm/boot/dts/tegra30-cardhu.dtsi index 65bf2b63174e..01b4c26fad96 100644 --- a/trunk/arch/arm/boot/dts/tegra30-cardhu.dtsi +++ b/trunk/arch/arm/boot/dts/tegra30-cardhu.dtsi @@ -307,6 +307,13 @@ pmc { status = "okay"; nvidia,invert-interrupt; + nvidia,suspend-mode = <2>; + nvidia,cpu-pwr-good-time = <2000>; + nvidia,cpu-pwr-off-time = <200>; + nvidia,core-pwr-good-time = <3845 3845>; + nvidia,core-pwr-off-time = <0>; + nvidia,core-power-req-active-high; + nvidia,sys-clock-req-active-high; }; sdhci@78000000 { @@ -320,6 +327,7 @@ sdhci@78000600 { status = "okay"; bus-width = <8>; + non-removable; }; clocks { @@ -509,5 +517,8 @@ nvidia,spkr-en-gpios = <&wm8903 2 0>; nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */ + + clocks = <&tegra_car 184>, <&tegra_car 185>, <&tegra_car 120>; + clock-names = "pll_a", "pll_a_out0", "mclk"; }; }; diff --git a/trunk/arch/arm/boot/dts/tegra30.dtsi b/trunk/arch/arm/boot/dts/tegra30.dtsi index 9fe7a92b4c85..15ded605142a 100644 --- a/trunk/arch/arm/boot/dts/tegra30.dtsi +++ b/trunk/arch/arm/boot/dts/tegra30.dtsi @@ -286,6 +286,7 @@ reg = <0x7000a000 0x100>; #pwm-cells = <2>; clocks = <&tegra_car 17>; + status = "disabled"; }; rtc { diff --git a/trunk/arch/arm/boot/dts/twl4030.dtsi b/trunk/arch/arm/boot/dts/twl4030.dtsi index ed0bc9546837..b3034da00a37 100644 --- a/trunk/arch/arm/boot/dts/twl4030.dtsi +++ b/trunk/arch/arm/boot/dts/twl4030.dtsi @@ -23,6 +23,12 @@ compatible = "ti,twl4030-wdt"; }; + vcc: regulator-vdd1 { + compatible = "ti,twl4030-vdd1"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <1450000>; + }; + vdac: regulator-vdac { compatible = "ti,twl4030-vdac"; regulator-min-microvolt = <1800000>; @@ -67,7 +73,7 @@ #interrupt-cells = <1>; }; - twl4030-usb { + usb2_phy: twl4030-usb { compatible = "ti,twl4030-usb"; interrupts = <10>, <4>; usb1v5-supply = <&vusb1v5>; @@ -75,4 +81,14 @@ usb3v1-supply = <&vusb3v1>; usb_mode = <1>; }; + + twl_pwm: pwm { + compatible = "ti,twl4030-pwm"; + #pwm-cells = <2>; + }; + + twl_pwmled: pwmled { + compatible = "ti,twl4030-pwmled"; + #pwm-cells = <2>; + }; }; diff --git a/trunk/arch/arm/boot/dts/twl6030.dtsi b/trunk/arch/arm/boot/dts/twl6030.dtsi index 9996cfc5ee80..2e3bd3172b23 100644 --- a/trunk/arch/arm/boot/dts/twl6030.dtsi +++ b/trunk/arch/arm/boot/dts/twl6030.dtsi @@ -91,4 +91,16 @@ compatible = "ti,twl6030-usb"; interrupts = <4>, <10>; }; + + twl_pwm: pwm { + /* provides two PWMs (id 0, 1 for PWM1 and PWM2) */ + compatible = "ti,twl6030-pwm"; + #pwm-cells = <2>; + }; + + twl_pwmled: pwmled { + /* provides one PWM (id 0 for Charging indicator LED) */ + compatible = "ti,twl6030-pwmled"; + #pwm-cells = <2>; + }; }; diff --git a/trunk/arch/arm/boot/dts/versatile-ab.dts b/trunk/arch/arm/boot/dts/versatile-ab.dts index e2fe3195c0d1..dde75ae8b4b1 100644 --- a/trunk/arch/arm/boot/dts/versatile-ab.dts +++ b/trunk/arch/arm/boot/dts/versatile-ab.dts @@ -121,6 +121,18 @@ interrupts = <0>; }; + timer@101e2000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x101e2000 0x1000>; + interrupts = <4>; + }; + + timer@101e3000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x101e3000 0x1000>; + interrupts = <5>; + }; + gpio0: gpio@101e4000 { compatible = "arm,pl061", "arm,primecell"; reg = <0x101e4000 0x1000>; diff --git a/trunk/arch/arm/boot/dts/vexpress-v2p-ca9.dts b/trunk/arch/arm/boot/dts/vexpress-v2p-ca9.dts index 1420bb14d95c..62d9b225dcce 100644 --- a/trunk/arch/arm/boot/dts/vexpress-v2p-ca9.dts +++ b/trunk/arch/arm/boot/dts/vexpress-v2p-ca9.dts @@ -98,6 +98,7 @@ <0 49 4>; clocks = <&oscclk2>, <&oscclk2>; clock-names = "timclk", "apb_pclk"; + status = "disabled"; }; watchdog@100e5000 { diff --git a/trunk/arch/arm/boot/dts/vt8500.dtsi b/trunk/arch/arm/boot/dts/vt8500.dtsi index 68c8dc644383..4a4b96f6827e 100644 --- a/trunk/arch/arm/boot/dts/vt8500.dtsi +++ b/trunk/arch/arm/boot/dts/vt8500.dtsi @@ -25,11 +25,13 @@ #interrupt-cells = <1>; }; - gpio: gpio-controller@d8110000 { - compatible = "via,vt8500-gpio"; - gpio-controller; + pinctrl: pinctrl@d8110000 { + compatible = "via,vt8500-pinctrl"; reg = <0xd8110000 0x10000>; - #gpio-cells = <3>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-controller; + #gpio-cells = <2>; }; pmc@d8130000 { diff --git a/trunk/arch/arm/boot/dts/wm8505.dtsi b/trunk/arch/arm/boot/dts/wm8505.dtsi index 398b8bca791e..b2bf359e852f 100644 --- a/trunk/arch/arm/boot/dts/wm8505.dtsi +++ b/trunk/arch/arm/boot/dts/wm8505.dtsi @@ -40,11 +40,13 @@ interrupts = <56 57 58 59 60 61 62 63>; }; - gpio: gpio-controller@d8110000 { - compatible = "wm,wm8505-gpio"; - gpio-controller; + pinctrl: pinctrl@d8110000 { + compatible = "wm,wm8505-pinctrl"; reg = <0xd8110000 0x10000>; - #gpio-cells = <3>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-controller; + #gpio-cells = <2>; }; pmc@d8130000 { diff --git a/trunk/arch/arm/boot/dts/wm8650.dtsi b/trunk/arch/arm/boot/dts/wm8650.dtsi index 9313407bbc30..dd8464eeb40d 100644 --- a/trunk/arch/arm/boot/dts/wm8650.dtsi +++ b/trunk/arch/arm/boot/dts/wm8650.dtsi @@ -34,11 +34,13 @@ interrupts = <56 57 58 59 60 61 62 63>; }; - gpio: gpio-controller@d8110000 { - compatible = "wm,wm8650-gpio"; - gpio-controller; + pinctrl: pinctrl@d8110000 { + compatible = "wm,wm8650-pinctrl"; reg = <0xd8110000 0x10000>; - #gpio-cells = <3>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-controller; + #gpio-cells = <2>; }; pmc@d8130000 { diff --git a/trunk/arch/arm/boot/dts/wm8850.dtsi b/trunk/arch/arm/boot/dts/wm8850.dtsi index 7149cd13e3b9..fc790d0aee66 100644 --- a/trunk/arch/arm/boot/dts/wm8850.dtsi +++ b/trunk/arch/arm/boot/dts/wm8850.dtsi @@ -41,11 +41,13 @@ interrupts = <56 57 58 59 60 61 62 63>; }; - gpio: gpio-controller@d8110000 { - compatible = "wm,wm8650-gpio"; - gpio-controller; + pinctrl: pinctrl@d8110000 { + compatible = "wm,wm8850-pinctrl"; reg = <0xd8110000 0x10000>; - #gpio-cells = <3>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-controller; + #gpio-cells = <2>; }; pmc@d8130000 { diff --git a/trunk/arch/arm/boot/dts/xenvm-4.2.dts b/trunk/arch/arm/boot/dts/xenvm-4.2.dts index ec3f9528e180..336915151398 100644 --- a/trunk/arch/arm/boot/dts/xenvm-4.2.dts +++ b/trunk/arch/arm/boot/dts/xenvm-4.2.dts @@ -29,6 +29,19 @@ compatible = "arm,cortex-a15"; reg = <0>; }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <1>; + }; + }; + + psci { + compatible = "arm,psci"; + method = "hvc"; + cpu_off = <1>; + cpu_on = <2>; }; memory@80000000 { diff --git a/trunk/arch/arm/boot/dts/zynq-7000.dtsi b/trunk/arch/arm/boot/dts/zynq-7000.dtsi index 9e1c339c4491..14fb2e609bab 100644 --- a/trunk/arch/arm/boot/dts/zynq-7000.dtsi +++ b/trunk/arch/arm/boot/dts/zynq-7000.dtsi @@ -118,56 +118,30 @@ }; ttc0: ttc0@f8001000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "xlnx,ttc"; + interrupt-parent = <&intc>; + interrupts = < 0 10 4 0 11 4 0 12 4 >; + compatible = "cdns,ttc"; reg = <0xF8001000 0x1000>; clocks = <&cpu_clk 3>; clock-names = "cpu_1x"; clock-ranges; - - ttc0_0: ttc0.0 { - status = "disabled"; - reg = <0>; - interrupts = <0 10 4>; - }; - ttc0_1: ttc0.1 { - status = "disabled"; - reg = <1>; - interrupts = <0 11 4>; - }; - ttc0_2: ttc0.2 { - status = "disabled"; - reg = <2>; - interrupts = <0 12 4>; - }; }; ttc1: ttc1@f8002000 { - #interrupt-parent = <&intc>; - #address-cells = <1>; - #size-cells = <0>; - compatible = "xlnx,ttc"; + interrupt-parent = <&intc>; + interrupts = < 0 37 4 0 38 4 0 39 4 >; + compatible = "cdns,ttc"; reg = <0xF8002000 0x1000>; clocks = <&cpu_clk 3>; clock-names = "cpu_1x"; clock-ranges; - - ttc1_0: ttc1.0 { - status = "disabled"; - reg = <0>; - interrupts = <0 37 4>; - }; - ttc1_1: ttc1.1 { - status = "disabled"; - reg = <1>; - interrupts = <0 38 4>; - }; - ttc1_2: ttc1.2 { - status = "disabled"; - reg = <2>; - interrupts = <0 39 4>; - }; }; + scutimer: scutimer@f8f00600 { + interrupt-parent = <&intc>; + interrupts = < 1 13 0x301 >; + compatible = "arm,cortex-a9-twd-timer"; + reg = < 0xf8f00600 0x20 >; + clocks = <&cpu_clk 1>; + } ; }; }; diff --git a/trunk/arch/arm/boot/dts/zynq-zc702.dts b/trunk/arch/arm/boot/dts/zynq-zc702.dts index c772942a399a..86f44d5b0265 100644 --- a/trunk/arch/arm/boot/dts/zynq-zc702.dts +++ b/trunk/arch/arm/boot/dts/zynq-zc702.dts @@ -32,13 +32,3 @@ &ps_clk { clock-frequency = <33333330>; }; - -&ttc0_0 { - status = "ok"; - compatible = "xlnx,ttc-counter-clocksource"; -}; - -&ttc0_1 { - status = "ok"; - compatible = "xlnx,ttc-counter-clockevent"; -}; diff --git a/trunk/arch/arm/common/Makefile b/trunk/arch/arm/common/Makefile index dc8dd0de5c0f..48434cbe3e89 100644 --- a/trunk/arch/arm/common/Makefile +++ b/trunk/arch/arm/common/Makefile @@ -2,6 +2,8 @@ # Makefile for the linux kernel. # +obj-y += firmware.o + obj-$(CONFIG_ICST) += icst.o obj-$(CONFIG_SA1111) += sa1111.o obj-$(CONFIG_PCI_HOST_VIA82C505) += via82c505.o @@ -11,3 +13,6 @@ obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o obj-$(CONFIG_SHARP_SCOOP) += scoop.o obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o +obj-$(CONFIG_MCPM) += mcpm_head.o mcpm_entry.o mcpm_platsmp.o vlock.o +AFLAGS_mcpm_head.o := -march=armv7-a +AFLAGS_vlock.o := -march=armv7-a diff --git a/trunk/arch/arm/common/firmware.c b/trunk/arch/arm/common/firmware.c new file mode 100644 index 000000000000..27ddccb1131f --- /dev/null +++ b/trunk/arch/arm/common/firmware.c @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2012 Samsung Electronics. + * Kyungmin Park + * Tomasz Figa + * + * 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 +#include + +#include + +static const struct firmware_ops default_firmware_ops; + +const struct firmware_ops *firmware_ops = &default_firmware_ops; diff --git a/trunk/arch/arm/common/mcpm_entry.c b/trunk/arch/arm/common/mcpm_entry.c new file mode 100644 index 000000000000..370236dd1a03 --- /dev/null +++ b/trunk/arch/arm/common/mcpm_entry.c @@ -0,0 +1,263 @@ +/* + * arch/arm/common/mcpm_entry.c -- entry point for multi-cluster PM + * + * Created by: Nicolas Pitre, March 2012 + * Copyright: (C) 2012-2013 Linaro Limited + * + * 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 +#include +#include + +#include +#include +#include +#include + +extern unsigned long mcpm_entry_vectors[MAX_NR_CLUSTERS][MAX_CPUS_PER_CLUSTER]; + +void mcpm_set_entry_vector(unsigned cpu, unsigned cluster, void *ptr) +{ + unsigned long val = ptr ? virt_to_phys(ptr) : 0; + mcpm_entry_vectors[cluster][cpu] = val; + sync_cache_w(&mcpm_entry_vectors[cluster][cpu]); +} + +static const struct mcpm_platform_ops *platform_ops; + +int __init mcpm_platform_register(const struct mcpm_platform_ops *ops) +{ + if (platform_ops) + return -EBUSY; + platform_ops = ops; + return 0; +} + +int mcpm_cpu_power_up(unsigned int cpu, unsigned int cluster) +{ + if (!platform_ops) + return -EUNATCH; /* try not to shadow power_up errors */ + might_sleep(); + return platform_ops->power_up(cpu, cluster); +} + +typedef void (*phys_reset_t)(unsigned long); + +void mcpm_cpu_power_down(void) +{ + phys_reset_t phys_reset; + + BUG_ON(!platform_ops); + BUG_ON(!irqs_disabled()); + + /* + * Do this before calling into the power_down method, + * as it might not always be safe to do afterwards. + */ + setup_mm_for_reboot(); + + platform_ops->power_down(); + + /* + * It is possible for a power_up request to happen concurrently + * with a power_down request for the same CPU. In this case the + * power_down method might not be able to actually enter a + * powered down state with the WFI instruction if the power_up + * method has removed the required reset condition. The + * power_down method is then allowed to return. We must perform + * a re-entry in the kernel as if the power_up method just had + * deasserted reset on the CPU. + * + * To simplify race issues, the platform specific implementation + * must accommodate for the possibility of unordered calls to + * power_down and power_up with a usage count. Therefore, if a + * call to power_up is issued for a CPU that is not down, then + * the next call to power_down must not attempt a full shutdown + * but only do the minimum (normally disabling L1 cache and CPU + * coherency) and return just as if a concurrent power_up request + * had happened as described above. + */ + + phys_reset = (phys_reset_t)(unsigned long)virt_to_phys(cpu_reset); + phys_reset(virt_to_phys(mcpm_entry_point)); + + /* should never get here */ + BUG(); +} + +void mcpm_cpu_suspend(u64 expected_residency) +{ + phys_reset_t phys_reset; + + BUG_ON(!platform_ops); + BUG_ON(!irqs_disabled()); + + /* Very similar to mcpm_cpu_power_down() */ + setup_mm_for_reboot(); + platform_ops->suspend(expected_residency); + phys_reset = (phys_reset_t)(unsigned long)virt_to_phys(cpu_reset); + phys_reset(virt_to_phys(mcpm_entry_point)); + BUG(); +} + +int mcpm_cpu_powered_up(void) +{ + if (!platform_ops) + return -EUNATCH; + if (platform_ops->powered_up) + platform_ops->powered_up(); + return 0; +} + +struct sync_struct mcpm_sync; + +/* + * __mcpm_cpu_going_down: Indicates that the cpu is being torn down. + * This must be called at the point of committing to teardown of a CPU. + * The CPU cache (SCTRL.C bit) is expected to still be active. + */ +void __mcpm_cpu_going_down(unsigned int cpu, unsigned int cluster) +{ + mcpm_sync.clusters[cluster].cpus[cpu].cpu = CPU_GOING_DOWN; + sync_cache_w(&mcpm_sync.clusters[cluster].cpus[cpu].cpu); +} + +/* + * __mcpm_cpu_down: Indicates that cpu teardown is complete and that the + * cluster can be torn down without disrupting this CPU. + * To avoid deadlocks, this must be called before a CPU is powered down. + * The CPU cache (SCTRL.C bit) is expected to be off. + * However L2 cache might or might not be active. + */ +void __mcpm_cpu_down(unsigned int cpu, unsigned int cluster) +{ + dmb(); + mcpm_sync.clusters[cluster].cpus[cpu].cpu = CPU_DOWN; + sync_cache_w(&mcpm_sync.clusters[cluster].cpus[cpu].cpu); + dsb_sev(); +} + +/* + * __mcpm_outbound_leave_critical: Leave the cluster teardown critical section. + * @state: the final state of the cluster: + * CLUSTER_UP: no destructive teardown was done and the cluster has been + * restored to the previous state (CPU cache still active); or + * CLUSTER_DOWN: the cluster has been torn-down, ready for power-off + * (CPU cache disabled, L2 cache either enabled or disabled). + */ +void __mcpm_outbound_leave_critical(unsigned int cluster, int state) +{ + dmb(); + mcpm_sync.clusters[cluster].cluster = state; + sync_cache_w(&mcpm_sync.clusters[cluster].cluster); + dsb_sev(); +} + +/* + * __mcpm_outbound_enter_critical: Enter the cluster teardown critical section. + * This function should be called by the last man, after local CPU teardown + * is complete. CPU cache expected to be active. + * + * Returns: + * false: the critical section was not entered because an inbound CPU was + * observed, or the cluster is already being set up; + * true: the critical section was entered: it is now safe to tear down the + * cluster. + */ +bool __mcpm_outbound_enter_critical(unsigned int cpu, unsigned int cluster) +{ + unsigned int i; + struct mcpm_sync_struct *c = &mcpm_sync.clusters[cluster]; + + /* Warn inbound CPUs that the cluster is being torn down: */ + c->cluster = CLUSTER_GOING_DOWN; + sync_cache_w(&c->cluster); + + /* Back out if the inbound cluster is already in the critical region: */ + sync_cache_r(&c->inbound); + if (c->inbound == INBOUND_COMING_UP) + goto abort; + + /* + * Wait for all CPUs to get out of the GOING_DOWN state, so that local + * teardown is complete on each CPU before tearing down the cluster. + * + * If any CPU has been woken up again from the DOWN state, then we + * shouldn't be taking the cluster down at all: abort in that case. + */ + sync_cache_r(&c->cpus); + for (i = 0; i < MAX_CPUS_PER_CLUSTER; i++) { + int cpustate; + + if (i == cpu) + continue; + + while (1) { + cpustate = c->cpus[i].cpu; + if (cpustate != CPU_GOING_DOWN) + break; + + wfe(); + sync_cache_r(&c->cpus[i].cpu); + } + + switch (cpustate) { + case CPU_DOWN: + continue; + + default: + goto abort; + } + } + + return true; + +abort: + __mcpm_outbound_leave_critical(cluster, CLUSTER_UP); + return false; +} + +int __mcpm_cluster_state(unsigned int cluster) +{ + sync_cache_r(&mcpm_sync.clusters[cluster].cluster); + return mcpm_sync.clusters[cluster].cluster; +} + +extern unsigned long mcpm_power_up_setup_phys; + +int __init mcpm_sync_init( + void (*power_up_setup)(unsigned int affinity_level)) +{ + unsigned int i, j, mpidr, this_cluster; + + BUILD_BUG_ON(MCPM_SYNC_CLUSTER_SIZE * MAX_NR_CLUSTERS != sizeof mcpm_sync); + BUG_ON((unsigned long)&mcpm_sync & (__CACHE_WRITEBACK_GRANULE - 1)); + + /* + * Set initial CPU and cluster states. + * Only one cluster is assumed to be active at this point. + */ + for (i = 0; i < MAX_NR_CLUSTERS; i++) { + mcpm_sync.clusters[i].cluster = CLUSTER_DOWN; + mcpm_sync.clusters[i].inbound = INBOUND_NOT_COMING_UP; + for (j = 0; j < MAX_CPUS_PER_CLUSTER; j++) + mcpm_sync.clusters[i].cpus[j].cpu = CPU_DOWN; + } + mpidr = read_cpuid_mpidr(); + this_cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); + for_each_online_cpu(i) + mcpm_sync.clusters[this_cluster].cpus[i].cpu = CPU_UP; + mcpm_sync.clusters[this_cluster].cluster = CLUSTER_UP; + sync_cache_w(&mcpm_sync); + + if (power_up_setup) { + mcpm_power_up_setup_phys = virt_to_phys(power_up_setup); + sync_cache_w(&mcpm_power_up_setup_phys); + } + + return 0; +} diff --git a/trunk/arch/arm/common/mcpm_head.S b/trunk/arch/arm/common/mcpm_head.S new file mode 100644 index 000000000000..8178705c4b24 --- /dev/null +++ b/trunk/arch/arm/common/mcpm_head.S @@ -0,0 +1,219 @@ +/* + * arch/arm/common/mcpm_head.S -- kernel entry point for multi-cluster PM + * + * Created by: Nicolas Pitre, March 2012 + * Copyright: (C) 2012-2013 Linaro Limited + * + * 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. + * + * + * Refer to Documentation/arm/cluster-pm-race-avoidance.txt + * for details of the synchronisation algorithms used here. + */ + +#include +#include + +#include "vlock.h" + +.if MCPM_SYNC_CLUSTER_CPUS +.error "cpus must be the first member of struct mcpm_sync_struct" +.endif + + .macro pr_dbg string +#if defined(CONFIG_DEBUG_LL) && defined(DEBUG) + b 1901f +1902: .asciz "CPU" +1903: .asciz " cluster" +1904: .asciz ": \string" + .align +1901: adr r0, 1902b + bl printascii + mov r0, r9 + bl printhex8 + adr r0, 1903b + bl printascii + mov r0, r10 + bl printhex8 + adr r0, 1904b + bl printascii +#endif + .endm + + .arm + .align + +ENTRY(mcpm_entry_point) + + THUMB( adr r12, BSYM(1f) ) + THUMB( bx r12 ) + THUMB( .thumb ) +1: + mrc p15, 0, r0, c0, c0, 5 @ MPIDR + ubfx r9, r0, #0, #8 @ r9 = cpu + ubfx r10, r0, #8, #8 @ r10 = cluster + mov r3, #MAX_CPUS_PER_CLUSTER + mla r4, r3, r10, r9 @ r4 = canonical CPU index + cmp r4, #(MAX_CPUS_PER_CLUSTER * MAX_NR_CLUSTERS) + blo 2f + + /* We didn't expect this CPU. Try to cheaply make it quiet. */ +1: wfi + wfe + b 1b + +2: pr_dbg "kernel mcpm_entry_point\n" + + /* + * MMU is off so we need to get to various variables in a + * position independent way. + */ + adr r5, 3f + ldmia r5, {r6, r7, r8, r11} + add r6, r5, r6 @ r6 = mcpm_entry_vectors + ldr r7, [r5, r7] @ r7 = mcpm_power_up_setup_phys + add r8, r5, r8 @ r8 = mcpm_sync + add r11, r5, r11 @ r11 = first_man_locks + + mov r0, #MCPM_SYNC_CLUSTER_SIZE + mla r8, r0, r10, r8 @ r8 = sync cluster base + + @ Signal that this CPU is coming UP: + mov r0, #CPU_COMING_UP + mov r5, #MCPM_SYNC_CPU_SIZE + mla r5, r9, r5, r8 @ r5 = sync cpu address + strb r0, [r5] + + @ At this point, the cluster cannot unexpectedly enter the GOING_DOWN + @ state, because there is at least one active CPU (this CPU). + + mov r0, #VLOCK_SIZE + mla r11, r0, r10, r11 @ r11 = cluster first man lock + mov r0, r11 + mov r1, r9 @ cpu + bl vlock_trylock @ implies DMB + + cmp r0, #0 @ failed to get the lock? + bne mcpm_setup_wait @ wait for cluster setup if so + + ldrb r0, [r8, #MCPM_SYNC_CLUSTER_CLUSTER] + cmp r0, #CLUSTER_UP @ cluster already up? + bne mcpm_setup @ if not, set up the cluster + + @ Otherwise, release the first man lock and skip setup: + mov r0, r11 + bl vlock_unlock + b mcpm_setup_complete + +mcpm_setup: + @ Control dependency implies strb not observable before previous ldrb. + + @ Signal that the cluster is being brought up: + mov r0, #INBOUND_COMING_UP + strb r0, [r8, #MCPM_SYNC_CLUSTER_INBOUND] + dmb + + @ Any CPU trying to take the cluster into CLUSTER_GOING_DOWN from this + @ point onwards will observe INBOUND_COMING_UP and abort. + + @ Wait for any previously-pending cluster teardown operations to abort + @ or complete: +mcpm_teardown_wait: + ldrb r0, [r8, #MCPM_SYNC_CLUSTER_CLUSTER] + cmp r0, #CLUSTER_GOING_DOWN + bne first_man_setup + wfe + b mcpm_teardown_wait + +first_man_setup: + dmb + + @ If the outbound gave up before teardown started, skip cluster setup: + + cmp r0, #CLUSTER_UP + beq mcpm_setup_leave + + @ power_up_setup is now responsible for setting up the cluster: + + cmp r7, #0 + mov r0, #1 @ second (cluster) affinity level + blxne r7 @ Call power_up_setup if defined + dmb + + mov r0, #CLUSTER_UP + strb r0, [r8, #MCPM_SYNC_CLUSTER_CLUSTER] + dmb + +mcpm_setup_leave: + @ Leave the cluster setup critical section: + + mov r0, #INBOUND_NOT_COMING_UP + strb r0, [r8, #MCPM_SYNC_CLUSTER_INBOUND] + dsb + sev + + mov r0, r11 + bl vlock_unlock @ implies DMB + b mcpm_setup_complete + + @ In the contended case, non-first men wait here for cluster setup + @ to complete: +mcpm_setup_wait: + ldrb r0, [r8, #MCPM_SYNC_CLUSTER_CLUSTER] + cmp r0, #CLUSTER_UP + wfene + bne mcpm_setup_wait + dmb + +mcpm_setup_complete: + @ If a platform-specific CPU setup hook is needed, it is + @ called from here. + + cmp r7, #0 + mov r0, #0 @ first (CPU) affinity level + blxne r7 @ Call power_up_setup if defined + dmb + + @ Mark the CPU as up: + + mov r0, #CPU_UP + strb r0, [r5] + + @ Observability order of CPU_UP and opening of the gate does not matter. + +mcpm_entry_gated: + ldr r5, [r6, r4, lsl #2] @ r5 = CPU entry vector + cmp r5, #0 + wfeeq + beq mcpm_entry_gated + dmb + + pr_dbg "released\n" + bx r5 + + .align 2 + +3: .word mcpm_entry_vectors - . + .word mcpm_power_up_setup_phys - 3b + .word mcpm_sync - 3b + .word first_man_locks - 3b + +ENDPROC(mcpm_entry_point) + + .bss + + .align CACHE_WRITEBACK_ORDER + .type first_man_locks, #object +first_man_locks: + .space VLOCK_SIZE * MAX_NR_CLUSTERS + .align CACHE_WRITEBACK_ORDER + + .type mcpm_entry_vectors, #object +ENTRY(mcpm_entry_vectors) + .space 4 * MAX_NR_CLUSTERS * MAX_CPUS_PER_CLUSTER + + .type mcpm_power_up_setup_phys, #object +ENTRY(mcpm_power_up_setup_phys) + .space 4 @ set by mcpm_sync_init() diff --git a/trunk/arch/arm/common/mcpm_platsmp.c b/trunk/arch/arm/common/mcpm_platsmp.c new file mode 100644 index 000000000000..3caed0db6986 --- /dev/null +++ b/trunk/arch/arm/common/mcpm_platsmp.c @@ -0,0 +1,89 @@ +/* + * linux/arch/arm/mach-vexpress/mcpm_platsmp.c + * + * Created by: Nicolas Pitre, November 2012 + * Copyright: (C) 2012-2013 Linaro Limited + * + * 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. + * + * Code to handle secondary CPU bringup and hotplug for the cluster power API. + */ + +#include +#include +#include + +#include +#include +#include + +static void __init simple_smp_init_cpus(void) +{ +} + +static int __cpuinit mcpm_boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + unsigned int mpidr, pcpu, pcluster, ret; + extern void secondary_startup(void); + + mpidr = cpu_logical_map(cpu); + pcpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); + pcluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); + pr_debug("%s: logical CPU %d is physical CPU %d cluster %d\n", + __func__, cpu, pcpu, pcluster); + + mcpm_set_entry_vector(pcpu, pcluster, NULL); + ret = mcpm_cpu_power_up(pcpu, pcluster); + if (ret) + return ret; + mcpm_set_entry_vector(pcpu, pcluster, secondary_startup); + arch_send_wakeup_ipi_mask(cpumask_of(cpu)); + dsb_sev(); + return 0; +} + +static void __cpuinit mcpm_secondary_init(unsigned int cpu) +{ + mcpm_cpu_powered_up(); +} + +#ifdef CONFIG_HOTPLUG_CPU + +static int mcpm_cpu_disable(unsigned int cpu) +{ + /* + * We assume all CPUs may be shut down. + * This would be the hook to use for eventual Secure + * OS migration requests as described in the PSCI spec. + */ + return 0; +} + +static void mcpm_cpu_die(unsigned int cpu) +{ + unsigned int mpidr, pcpu, pcluster; + mpidr = read_cpuid_mpidr(); + pcpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); + pcluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); + mcpm_set_entry_vector(pcpu, pcluster, NULL); + mcpm_cpu_power_down(); +} + +#endif + +static struct smp_operations __initdata mcpm_smp_ops = { + .smp_init_cpus = simple_smp_init_cpus, + .smp_boot_secondary = mcpm_boot_secondary, + .smp_secondary_init = mcpm_secondary_init, +#ifdef CONFIG_HOTPLUG_CPU + .cpu_disable = mcpm_cpu_disable, + .cpu_die = mcpm_cpu_die, +#endif +}; + +void __init mcpm_smp_set_ops(void) +{ + smp_set_ops(&mcpm_smp_ops); +} diff --git a/trunk/arch/arm/common/timer-sp.c b/trunk/arch/arm/common/timer-sp.c index 9d2d3ba339ff..ddc740769601 100644 --- a/trunk/arch/arm/common/timer-sp.c +++ b/trunk/arch/arm/common/timer-sp.c @@ -25,33 +25,29 @@ #include #include #include +#include +#include +#include #include #include +#include -static long __init sp804_get_clock_rate(const char *name) +static long __init sp804_get_clock_rate(struct clk *clk) { - struct clk *clk; long rate; int err; - clk = clk_get_sys("sp804", name); - if (IS_ERR(clk)) { - pr_err("sp804: %s clock not found: %d\n", name, - (int)PTR_ERR(clk)); - return PTR_ERR(clk); - } - err = clk_prepare(clk); if (err) { - pr_err("sp804: %s clock failed to prepare: %d\n", name, err); + pr_err("sp804: clock failed to prepare: %d\n", err); clk_put(clk); return err; } err = clk_enable(clk); if (err) { - pr_err("sp804: %s clock failed to enable: %d\n", name, err); + pr_err("sp804: clock failed to enable: %d\n", err); clk_unprepare(clk); clk_put(clk); return err; @@ -59,7 +55,7 @@ static long __init sp804_get_clock_rate(const char *name) rate = clk_get_rate(clk); if (rate < 0) { - pr_err("sp804: %s clock failed to get rate: %ld\n", name, rate); + pr_err("sp804: clock failed to get rate: %ld\n", rate); clk_disable(clk); clk_unprepare(clk); clk_put(clk); @@ -77,9 +73,21 @@ static u32 sp804_read(void) void __init __sp804_clocksource_and_sched_clock_init(void __iomem *base, const char *name, + struct clk *clk, int use_sched_clock) { - long rate = sp804_get_clock_rate(name); + long rate; + + if (!clk) { + clk = clk_get_sys("sp804", name); + if (IS_ERR(clk)) { + pr_err("sp804: clock not found: %d\n", + (int)PTR_ERR(clk)); + return; + } + } + + rate = sp804_get_clock_rate(clk); if (rate < 0) return; @@ -171,12 +179,20 @@ static struct irqaction sp804_timer_irq = { .dev_id = &sp804_clockevent, }; -void __init sp804_clockevents_init(void __iomem *base, unsigned int irq, - const char *name) +void __init __sp804_clockevents_init(void __iomem *base, unsigned int irq, struct clk *clk, const char *name) { struct clock_event_device *evt = &sp804_clockevent; - long rate = sp804_get_clock_rate(name); + long rate; + if (!clk) + clk = clk_get_sys("sp804", name); + if (IS_ERR(clk)) { + pr_err("sp804: %s clock not found: %d\n", name, + (int)PTR_ERR(clk)); + return; + } + + rate = sp804_get_clock_rate(clk); if (rate < 0) return; @@ -186,6 +202,98 @@ void __init sp804_clockevents_init(void __iomem *base, unsigned int irq, evt->irq = irq; evt->cpumask = cpu_possible_mask; + writel(0, base + TIMER_CTRL); + setup_irq(irq, &sp804_timer_irq); clockevents_config_and_register(evt, rate, 0xf, 0xffffffff); } + +static void __init sp804_of_init(struct device_node *np) +{ + static bool initialized = false; + void __iomem *base; + int irq; + u32 irq_num = 0; + struct clk *clk1, *clk2; + const char *name = of_get_property(np, "compatible", NULL); + + base = of_iomap(np, 0); + if (WARN_ON(!base)) + return; + + /* Ensure timers are disabled */ + writel(0, base + TIMER_CTRL); + writel(0, base + TIMER_2_BASE + TIMER_CTRL); + + if (initialized || !of_device_is_available(np)) + goto err; + + clk1 = of_clk_get(np, 0); + if (IS_ERR(clk1)) + clk1 = NULL; + + /* Get the 2nd clock if the timer has 2 timer clocks */ + if (of_count_phandle_with_args(np, "clocks", "#clock-cells") == 3) { + clk2 = of_clk_get(np, 1); + if (IS_ERR(clk2)) { + pr_err("sp804: %s clock not found: %d\n", np->name, + (int)PTR_ERR(clk2)); + goto err; + } + } else + clk2 = clk1; + + irq = irq_of_parse_and_map(np, 0); + if (irq <= 0) + goto err; + + of_property_read_u32(np, "arm,sp804-has-irq", &irq_num); + if (irq_num == 2) { + __sp804_clockevents_init(base + TIMER_2_BASE, irq, clk2, name); + __sp804_clocksource_and_sched_clock_init(base, name, clk1, 1); + } else { + __sp804_clockevents_init(base, irq, clk1 , name); + __sp804_clocksource_and_sched_clock_init(base + TIMER_2_BASE, + name, clk2, 1); + } + initialized = true; + + return; +err: + iounmap(base); +} +CLOCKSOURCE_OF_DECLARE(sp804, "arm,sp804", sp804_of_init); + +static void __init integrator_cp_of_init(struct device_node *np) +{ + static int init_count = 0; + void __iomem *base; + int irq; + const char *name = of_get_property(np, "compatible", NULL); + + base = of_iomap(np, 0); + if (WARN_ON(!base)) + return; + + /* Ensure timer is disabled */ + writel(0, base + TIMER_CTRL); + + if (init_count == 2 || !of_device_is_available(np)) + goto err; + + if (!init_count) + sp804_clocksource_init(base, name); + else { + irq = irq_of_parse_and_map(np, 0); + if (irq <= 0) + goto err; + + sp804_clockevents_init(base, irq, name); + } + + init_count++; + return; +err: + iounmap(base); +} +CLOCKSOURCE_OF_DECLARE(intcp, "arm,integrator-cp-timer", integrator_cp_of_init); diff --git a/trunk/arch/arm/common/vlock.S b/trunk/arch/arm/common/vlock.S new file mode 100644 index 000000000000..ff198583f683 --- /dev/null +++ b/trunk/arch/arm/common/vlock.S @@ -0,0 +1,108 @@ +/* + * vlock.S - simple voting lock implementation for ARM + * + * Created by: Dave Martin, 2012-08-16 + * Copyright: (C) 2012-2013 Linaro Limited + * + * 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. + * + * 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. + * + * + * This algorithm is described in more detail in + * Documentation/arm/vlocks.txt. + */ + +#include +#include "vlock.h" + +/* Select different code if voting flags can fit in a single word. */ +#if VLOCK_VOTING_SIZE > 4 +#define FEW(x...) +#define MANY(x...) x +#else +#define FEW(x...) x +#define MANY(x...) +#endif + +@ voting lock for first-man coordination + +.macro voting_begin rbase:req, rcpu:req, rscratch:req + mov \rscratch, #1 + strb \rscratch, [\rbase, \rcpu] + dmb +.endm + +.macro voting_end rbase:req, rcpu:req, rscratch:req + dmb + mov \rscratch, #0 + strb \rscratch, [\rbase, \rcpu] + dsb + sev +.endm + +/* + * The vlock structure must reside in Strongly-Ordered or Device memory. + * This implementation deliberately eliminates most of the barriers which + * would be required for other memory types, and assumes that independent + * writes to neighbouring locations within a cacheline do not interfere + * with one another. + */ + +@ r0: lock structure base +@ r1: CPU ID (0-based index within cluster) +ENTRY(vlock_trylock) + add r1, r1, #VLOCK_VOTING_OFFSET + + voting_begin r0, r1, r2 + + ldrb r2, [r0, #VLOCK_OWNER_OFFSET] @ check whether lock is held + cmp r2, #VLOCK_OWNER_NONE + bne trylock_fail @ fail if so + + @ Control dependency implies strb not observable before previous ldrb. + + strb r1, [r0, #VLOCK_OWNER_OFFSET] @ submit my vote + + voting_end r0, r1, r2 @ implies DMB + + @ Wait for the current round of voting to finish: + + MANY( mov r3, #VLOCK_VOTING_OFFSET ) +0: + MANY( ldr r2, [r0, r3] ) + FEW( ldr r2, [r0, #VLOCK_VOTING_OFFSET] ) + cmp r2, #0 + wfene + bne 0b + MANY( add r3, r3, #4 ) + MANY( cmp r3, #VLOCK_VOTING_OFFSET + VLOCK_VOTING_SIZE ) + MANY( bne 0b ) + + @ Check who won: + + dmb + ldrb r2, [r0, #VLOCK_OWNER_OFFSET] + eor r0, r1, r2 @ zero if I won, else nonzero + bx lr + +trylock_fail: + voting_end r0, r1, r2 + mov r0, #1 @ nonzero indicates that I lost + bx lr +ENDPROC(vlock_trylock) + +@ r0: lock structure base +ENTRY(vlock_unlock) + dmb + mov r1, #VLOCK_OWNER_NONE + strb r1, [r0, #VLOCK_OWNER_OFFSET] + dsb + sev + bx lr +ENDPROC(vlock_unlock) diff --git a/trunk/arch/arm/common/vlock.h b/trunk/arch/arm/common/vlock.h new file mode 100644 index 000000000000..3b441475a59b --- /dev/null +++ b/trunk/arch/arm/common/vlock.h @@ -0,0 +1,29 @@ +/* + * vlock.h - simple voting lock implementation + * + * Created by: Dave Martin, 2012-08-16 + * Copyright: (C) 2012-2013 Linaro Limited + * + * 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. + * + * 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. + */ + +#ifndef __VLOCK_H +#define __VLOCK_H + +#include + +/* Offsets and sizes are rounded to a word (4 bytes) */ +#define VLOCK_OWNER_OFFSET 0 +#define VLOCK_VOTING_OFFSET 4 +#define VLOCK_VOTING_SIZE ((MAX_CPUS_PER_CLUSTER + 3) / 4 * 4) +#define VLOCK_SIZE (VLOCK_VOTING_OFFSET + VLOCK_VOTING_SIZE) +#define VLOCK_OWNER_NONE 0 + +#endif /* ! __VLOCK_H */ diff --git a/trunk/arch/arm/configs/at91sam9g45_defconfig b/trunk/arch/arm/configs/at91sam9g45_defconfig index 5f551b76cb65..18964cdacd68 100644 --- a/trunk/arch/arm/configs/at91sam9g45_defconfig +++ b/trunk/arch/arm/configs/at91sam9g45_defconfig @@ -173,7 +173,6 @@ CONFIG_MMC=y # CONFIG_MMC_BLOCK_BOUNCE is not set CONFIG_SDIO_UART=m CONFIG_MMC_ATMELMCI=y -CONFIG_MMC_ATMELMCI_DMA=y CONFIG_LEDS_ATMEL_PWM=y CONFIG_LEDS_GPIO=y CONFIG_LEDS_TRIGGER_TIMER=y diff --git a/trunk/arch/arm/configs/bockw_defconfig b/trunk/arch/arm/configs/bockw_defconfig new file mode 100644 index 000000000000..6524cdf3b08d --- /dev/null +++ b/trunk/arch/arm/configs/bockw_defconfig @@ -0,0 +1,94 @@ +# CONFIG_ARM_PATCH_PHYS_VIRT is not set +CONFIG_KERNEL_LZMA=y +CONFIG_NO_HZ=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=16 +CONFIG_SYSCTL_SYSCALL=y +CONFIG_EMBEDDED=y +CONFIG_SLAB=y +# CONFIG_IOSCHED_CFQ is not set +CONFIG_ARCH_SHMOBILE=y +CONFIG_ARCH_R8A7778=y +CONFIG_MACH_BOCKW=y +CONFIG_MEMORY_START=0x60000000 +CONFIG_MEMORY_SIZE=0x10000000 +CONFIG_SHMOBILE_TIMER_HZ=1024 +# CONFIG_SH_TIMER_CMT is not set +# CONFIG_EM_TIMER_STI is not set +CONFIG_ARM_ERRATA_430973=y +CONFIG_ARM_ERRATA_458693=y +CONFIG_ARM_ERRATA_460075=y +CONFIG_ARM_ERRATA_743622=y +CONFIG_ARM_ERRATA_754322=y +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +CONFIG_HIGHMEM=y +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_ARM_APPENDED_DTB=y +CONFIG_CMDLINE="console=ttySC0,115200 ignore_loglevel root=/dev/nfs ip=dhcp" +CONFIG_CMDLINE_FORCE=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_SUSPEND is not set +CONFIG_NET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_IPV6 is not set +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +# CONFIG_STANDALONE is not set +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +# CONFIG_FW_LOADER is not set +CONFIG_NETDEVICES=y +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_CIRRUS is not set +# CONFIG_NET_VENDOR_FARADAY is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_SEEQ is not set +CONFIG_SMSC911X=y +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_INPUT is not set +# CONFIG_SERIO is not set +# CONFIG_VT is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVKMEM is not set +CONFIG_SERIAL_SH_SCI=y +CONFIG_SERIAL_SH_SCI_NR_UARTS=6 +CONFIG_SERIAL_SH_SCI_CONSOLE=y +# CONFIG_HW_RANDOM is not set +# CONFIG_HWMON is not set +# CONFIG_USB_SUPPORT is not set +CONFIG_UIO=y +CONFIG_UIO_PDRV_GENIRQ=y +# CONFIG_IOMMU_SUPPORT is not set +# CONFIG_DNOTIFY is not set +# CONFIG_INOTIFY_USER is not set +CONFIG_TMPFS=y +# CONFIG_MISC_FILESYSTEMS is not set +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_SWAP=y +CONFIG_NFS_V4_1=y +CONFIG_ROOT_NFS=y +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +# CONFIG_SCHED_DEBUG is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_FTRACE is not set +# CONFIG_ARM_UNWIND is not set +CONFIG_AVERAGE=y diff --git a/trunk/arch/arm/configs/da8xx_omapl_defconfig b/trunk/arch/arm/configs/da8xx_omapl_defconfig index 9aaad36a1728..7c868139bdb0 100644 --- a/trunk/arch/arm/configs/da8xx_omapl_defconfig +++ b/trunk/arch/arm/configs/da8xx_omapl_defconfig @@ -5,6 +5,7 @@ CONFIG_POSIX_MQUEUE=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 +CONFIG_CGROUPS=y CONFIG_BLK_DEV_INITRD=y CONFIG_EXPERT=y CONFIG_MODULES=y diff --git a/trunk/arch/arm/configs/davinci_all_defconfig b/trunk/arch/arm/configs/davinci_all_defconfig index 3edc78a40b66..c86fd75e181a 100644 --- a/trunk/arch/arm/configs/davinci_all_defconfig +++ b/trunk/arch/arm/configs/davinci_all_defconfig @@ -5,6 +5,7 @@ CONFIG_POSIX_MQUEUE=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 +CONFIG_CGROUPS=y CONFIG_BLK_DEV_INITRD=y CONFIG_EXPERT=y CONFIG_MODULES=y diff --git a/trunk/arch/arm/configs/imx_v4_v5_defconfig b/trunk/arch/arm/configs/imx_v4_v5_defconfig index 02c657af4005..f07a847b00c9 100644 --- a/trunk/arch/arm/configs/imx_v4_v5_defconfig +++ b/trunk/arch/arm/configs/imx_v4_v5_defconfig @@ -109,6 +109,7 @@ CONFIG_I2C_IMX=y CONFIG_SPI=y CONFIG_SPI_IMX=y CONFIG_SPI_SPIDEV=y +CONFIG_GPIO_SYSFS=y CONFIG_W1=y CONFIG_W1_MASTER_MXC=y CONFIG_W1_SLAVE_THERM=y diff --git a/trunk/arch/arm/configs/imx_v6_v7_defconfig b/trunk/arch/arm/configs/imx_v6_v7_defconfig index 088d6c11a0fa..6ec010f248b5 100644 --- a/trunk/arch/arm/configs/imx_v6_v7_defconfig +++ b/trunk/arch/arm/configs/imx_v6_v7_defconfig @@ -9,6 +9,7 @@ CONFIG_CGROUPS=y CONFIG_RELAY=y CONFIG_BLK_DEV_INITRD=y CONFIG_EXPERT=y +CONFIG_PERF_EVENTS=y # CONFIG_SLUB_DEBUG is not set # CONFIG_COMPAT_BRK is not set CONFIG_MODULES=y diff --git a/trunk/arch/arm/configs/kirkwood_defconfig b/trunk/arch/arm/configs/kirkwood_defconfig index 3d8667f648b8..a1d8252e9ec7 100644 --- a/trunk/arch/arm/configs/kirkwood_defconfig +++ b/trunk/arch/arm/configs/kirkwood_defconfig @@ -10,45 +10,48 @@ CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set CONFIG_ARCH_KIRKWOOD=y +CONFIG_MACH_D2NET_V2=y CONFIG_MACH_DB88F6281_BP=y +CONFIG_MACH_DOCKSTAR=y +CONFIG_MACH_ESATA_SHEEVAPLUG=y +CONFIG_MACH_GURUPLUG=y +CONFIG_MACH_INETSPACE_V2=y +CONFIG_MACH_MV88F6281GTW_GE=y +CONFIG_MACH_NET2BIG_V2=y +CONFIG_MACH_NET5BIG_V2=y +CONFIG_MACH_NETSPACE_MAX_V2=y +CONFIG_MACH_NETSPACE_V2=y +CONFIG_MACH_OPENRD_BASE=y +CONFIG_MACH_OPENRD_CLIENT=y +CONFIG_MACH_OPENRD_ULTIMATE=y CONFIG_MACH_RD88F6192_NAS=y CONFIG_MACH_RD88F6281=y -CONFIG_MACH_MV88F6281GTW_GE=y CONFIG_MACH_SHEEVAPLUG=y -CONFIG_MACH_ESATA_SHEEVAPLUG=y -CONFIG_MACH_GURUPLUG=y -CONFIG_MACH_DREAMPLUG_DT=y -CONFIG_MACH_ICONNECT_DT=y +CONFIG_MACH_T5325=y +CONFIG_MACH_TS219=y +CONFIG_MACH_TS41X=y +CONFIG_MACH_CLOUDBOX_DT=y CONFIG_MACH_DLINK_KIRKWOOD_DT=y -CONFIG_MACH_IB62X0_DT=y -CONFIG_MACH_TS219_DT=y CONFIG_MACH_DOCKSTAR_DT=y +CONFIG_MACH_DREAMPLUG_DT=y CONFIG_MACH_GOFLEXNET_DT=y -CONFIG_MACH_LSXL_DT=y +CONFIG_MACH_GURUPLUG_DT=y +CONFIG_MACH_IB62X0_DT=y +CONFIG_MACH_ICONNECT_DT=y +CONFIG_MACH_INETSPACE_V2_DT=y CONFIG_MACH_IOMEGA_IX2_200_DT=y CONFIG_MACH_KM_KIRKWOOD_DT=y -CONFIG_MACH_INETSPACE_V2_DT=y +CONFIG_MACH_LSXL_DT=y CONFIG_MACH_MPLCEC4_DT=y -CONFIG_MACH_NETSPACE_V2_DT=y -CONFIG_MACH_NETSPACE_MAX_V2_DT=y CONFIG_MACH_NETSPACE_LITE_V2_DT=y +CONFIG_MACH_NETSPACE_MAX_V2_DT=y CONFIG_MACH_NETSPACE_MINI_V2_DT=y +CONFIG_MACH_NETSPACE_V2_DT=y +CONFIG_MACH_NSA310_DT=y CONFIG_MACH_OPENBLOCKS_A6_DT=y +CONFIG_MACH_READYNAS_DT=y CONFIG_MACH_TOPKICK_DT=y -CONFIG_MACH_TS219=y -CONFIG_MACH_TS41X=y -CONFIG_MACH_DOCKSTAR=y -CONFIG_MACH_OPENRD_BASE=y -CONFIG_MACH_OPENRD_CLIENT=y -CONFIG_MACH_OPENRD_ULTIMATE=y -CONFIG_MACH_NETSPACE_V2=y -CONFIG_MACH_INETSPACE_V2=y -CONFIG_MACH_NETSPACE_MAX_V2=y -CONFIG_MACH_D2NET_V2=y -CONFIG_MACH_NET2BIG_V2=y -CONFIG_MACH_NET5BIG_V2=y -CONFIG_MACH_T5325=y -CONFIG_MACH_NSA310_DT=y +CONFIG_MACH_TS219_DT=y # CONFIG_CPU_FEROCEON_OLD_ID is not set CONFIG_PREEMPT=y CONFIG_AEABI=y diff --git a/trunk/arch/arm/configs/msm_defconfig b/trunk/arch/arm/configs/msm_defconfig index 2b8f7affc1eb..690b5f9c7462 100644 --- a/trunk/arch/arm/configs/msm_defconfig +++ b/trunk/arch/arm/configs/msm_defconfig @@ -1,72 +1,137 @@ -CONFIG_EXPERIMENTAL=y +CONFIG_SYSVIPC=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_BLK_DEV_INITRD=y -CONFIG_SLAB=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS_ALL=y +CONFIG_EMBEDDED=y +# CONFIG_SLUB_DEBUG is not set +# CONFIG_COMPAT_BRK is not set +CONFIG_PROFILING=y +CONFIG_OPROFILE=y +CONFIG_KPROBES=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_PARTITION_ADVANCED=y CONFIG_ARCH_MSM=y -CONFIG_MACH_HALIBUT=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y +CONFIG_ARCH_MSM8X60=y +CONFIG_ARCH_MSM8960=y +CONFIG_SMP=y CONFIG_PREEMPT=y CONFIG_AEABI=y -# CONFIG_OABI_COMPAT is not set -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="mem=64M console=ttyMSM,115200n8" -CONFIG_PM=y +CONFIG_HIGHMEM=y +CONFIG_HIGHPTE=y +CONFIG_CLEANCACHE=y +CONFIG_CC_STACKPROTECTOR=y +CONFIG_ARM_APPENDED_DTB=y +CONFIG_ARM_ATAG_DTB_COMPAT=y +CONFIG_AUTO_ZRELADDR=y +CONFIG_VFP=y +CONFIG_NEON=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_NET=y +CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_INET=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_DIAG is not set +# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set -CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y +CONFIG_CFG80211=y +CONFIG_RFKILL=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_SCSI=y +CONFIG_SCSI_TGT=y +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_SG=y +CONFIG_CHR_DEV_SCH=y +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SCAN_ASYNC=y CONFIG_NETDEVICES=y CONFIG_DUMMY=y -CONFIG_NET_ETHERNET=y -CONFIG_SMC91X=y -CONFIG_PPP=y -CONFIG_PPP_ASYNC=y -CONFIG_PPP_DEFLATE=y -CONFIG_PPP_BSDCOMP=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_PHYLIB=y +CONFIG_SLIP=y +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_MODE_SLIP6=y +CONFIG_USB_USBNET=y +# CONFIG_USB_NET_AX8817X is not set +# CONFIG_USB_NET_ZAURUS is not set CONFIG_INPUT_EVDEV=y # CONFIG_KEYBOARD_ATKBD is not set -# CONFIG_INPUT_MOUSE is not set +# CONFIG_MOUSE_PS2 is not set +CONFIG_INPUT_JOYSTICK=y CONFIG_INPUT_TOUCHSCREEN=y CONFIG_INPUT_MISC=y -# CONFIG_SERIO is not set -CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_INPUT_UINPUT=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_LEGACY_PTYS is not set CONFIG_SERIAL_MSM=y CONFIG_SERIAL_MSM_CONSOLE=y -# CONFIG_LEGACY_PTYS is not set -# CONFIG_HW_RANDOM is not set +CONFIG_HW_RANDOM=y CONFIG_I2C=y -# CONFIG_HWMON is not set -CONFIG_VIDEO_OUTPUT_CONTROL=y +CONFIG_I2C_CHARDEV=y +CONFIG_SPI=y +CONFIG_SSBI=y +CONFIG_DEBUG_GPIO=y +CONFIG_GPIO_SYSFS=y +CONFIG_POWER_SUPPLY=y +CONFIG_THERMAL=y +CONFIG_REGULATOR=y +CONFIG_MEDIA_SUPPORT=y CONFIG_FB=y -CONFIG_FB_MODE_HELPERS=y -CONFIG_FB_TILEBLITTING=y -CONFIG_FB_MSM=y -# CONFIG_VGA_CONSOLE is not set -CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_DYNAMIC_MINORS=y +# CONFIG_SND_ARM is not set +# CONFIG_SND_SPI is not set +# CONFIG_SND_USB is not set +CONFIG_SND_SOC=y +CONFIG_HID_BATTERY_STRENGTH=y +CONFIG_USB=y +CONFIG_USB_PHY=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_MON=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_MSM=y +CONFIG_USB_ACM=y +CONFIG_USB_SERIAL=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_DEBUG_FILES=y +CONFIG_USB_GADGET_VBUS_DRAW=500 CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_INOTIFY=y +CONFIG_RTC_CLASS=y +CONFIG_STAGING=y +CONFIG_MSM_IOMMU=y +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT4_FS=y +CONFIG_FUSE_FS=y +CONFIG_VFAT_FS=y CONFIG_TMPFS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_CIFS=y +CONFIG_PRINTK_TIME=y CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_KERNEL=y -CONFIG_SCHEDSTATS=y -CONFIG_DEBUG_MUTEXES=y -CONFIG_DEBUG_SPINLOCK_SLEEP=y +CONFIG_LOCKUP_DETECTOR=y +# CONFIG_DETECT_HUNG_TASK is not set +# CONFIG_SCHED_DEBUG is not set +CONFIG_TIMER_STATS=y CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_LL=y +CONFIG_DYNAMIC_DEBUG=y diff --git a/trunk/arch/arm/configs/omap2plus_defconfig b/trunk/arch/arm/configs/omap2plus_defconfig index bd07864f14a0..c1ef64bc5abd 100644 --- a/trunk/arch/arm/configs/omap2plus_defconfig +++ b/trunk/arch/arm/configs/omap2plus_defconfig @@ -93,6 +93,7 @@ CONFIG_BLK_DEV_RAM_SIZE=16384 CONFIG_SENSORS_LIS3LV02D=m CONFIG_SENSORS_TSL2550=m CONFIG_SENSORS_LIS3_I2C=m +CONFIG_BMP085_I2C=m CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_SCSI_MULTI_LUN=y @@ -136,6 +137,8 @@ CONFIG_SERIAL_8250_DETECT_IRQ=y CONFIG_SERIAL_8250_RSA=y CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_OMAP=y +CONFIG_SERIAL_OMAP_CONSOLE=y CONFIG_HW_RANDOM=y CONFIG_I2C_CHARDEV=y CONFIG_SPI=y @@ -152,6 +155,7 @@ CONFIG_OMAP_WATCHDOG=y CONFIG_TWL4030_WATCHDOG=y CONFIG_MFD_TPS65217=y CONFIG_MFD_TPS65910=y +CONFIG_TWL6040_CORE=y CONFIG_REGULATOR_TWL4030=y CONFIG_REGULATOR_TPS65023=y CONFIG_REGULATOR_TPS6507X=y @@ -194,6 +198,7 @@ CONFIG_SND_USB_AUDIO=m CONFIG_SND_SOC=m CONFIG_SND_OMAP_SOC=m CONFIG_SND_OMAP_SOC_OMAP_TWL4030=m +CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040=m CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=m CONFIG_USB=y CONFIG_USB_DEBUG=y diff --git a/trunk/arch/arm/include/asm/arch_timer.h b/trunk/arch/arm/include/asm/arch_timer.h index 7ade91d8cc6f..7c1bfc0aea0c 100644 --- a/trunk/arch/arm/include/asm/arch_timer.h +++ b/trunk/arch/arm/include/asm/arch_timer.h @@ -10,8 +10,7 @@ #include #ifdef CONFIG_ARM_ARCH_TIMER -int arch_timer_of_register(void); -int arch_timer_sched_clock_init(void); +int arch_timer_arch_init(void); /* * These register accessors are marked inline so the compiler can @@ -110,16 +109,6 @@ static inline void __cpuinit arch_counter_set_user_access(void) asm volatile("mcr p15, 0, %0, c14, c1, 0" : : "r" (cntkctl)); } -#else -static inline int arch_timer_of_register(void) -{ - return -ENXIO; -} - -static inline int arch_timer_sched_clock_init(void) -{ - return -ENXIO; -} #endif #endif diff --git a/trunk/arch/arm/include/asm/atomic.h b/trunk/arch/arm/include/asm/atomic.h index c79f61faa3a5..da1c77d39327 100644 --- a/trunk/arch/arm/include/asm/atomic.h +++ b/trunk/arch/arm/include/asm/atomic.h @@ -243,6 +243,29 @@ typedef struct { #define ATOMIC64_INIT(i) { (i) } +#ifdef CONFIG_ARM_LPAE +static inline u64 atomic64_read(const atomic64_t *v) +{ + u64 result; + + __asm__ __volatile__("@ atomic64_read\n" +" ldrd %0, %H0, [%1]" + : "=&r" (result) + : "r" (&v->counter), "Qo" (v->counter) + ); + + return result; +} + +static inline void atomic64_set(atomic64_t *v, u64 i) +{ + __asm__ __volatile__("@ atomic64_set\n" +" strd %2, %H2, [%1]" + : "=Qo" (v->counter) + : "r" (&v->counter), "r" (i) + ); +} +#else static inline u64 atomic64_read(const atomic64_t *v) { u64 result; @@ -269,6 +292,7 @@ static inline void atomic64_set(atomic64_t *v, u64 i) : "r" (&v->counter), "r" (i) : "cc"); } +#endif static inline void atomic64_add(u64 i, atomic64_t *v) { diff --git a/trunk/arch/arm/include/asm/cacheflush.h b/trunk/arch/arm/include/asm/cacheflush.h index e1489c54cd12..bff71388e72a 100644 --- a/trunk/arch/arm/include/asm/cacheflush.h +++ b/trunk/arch/arm/include/asm/cacheflush.h @@ -363,4 +363,79 @@ static inline void flush_cache_vunmap(unsigned long start, unsigned long end) flush_cache_all(); } +/* + * Memory synchronization helpers for mixed cached vs non cached accesses. + * + * Some synchronization algorithms have to set states in memory with the + * cache enabled or disabled depending on the code path. It is crucial + * to always ensure proper cache maintenance to update main memory right + * away in that case. + * + * Any cached write must be followed by a cache clean operation. + * Any cached read must be preceded by a cache invalidate operation. + * Yet, in the read case, a cache flush i.e. atomic clean+invalidate + * operation is needed to avoid discarding possible concurrent writes to the + * accessed memory. + * + * Also, in order to prevent a cached writer from interfering with an + * adjacent non-cached writer, each state variable must be located to + * a separate cache line. + */ + +/* + * This needs to be >= the max cache writeback size of all + * supported platforms included in the current kernel configuration. + * This is used to align state variables to their own cache lines. + */ +#define __CACHE_WRITEBACK_ORDER 6 /* guessed from existing platforms */ +#define __CACHE_WRITEBACK_GRANULE (1 << __CACHE_WRITEBACK_ORDER) + +/* + * There is no __cpuc_clean_dcache_area but we use it anyway for + * code intent clarity, and alias it to __cpuc_flush_dcache_area. + */ +#define __cpuc_clean_dcache_area __cpuc_flush_dcache_area + +/* + * Ensure preceding writes to *p by this CPU are visible to + * subsequent reads by other CPUs: + */ +static inline void __sync_cache_range_w(volatile void *p, size_t size) +{ + char *_p = (char *)p; + + __cpuc_clean_dcache_area(_p, size); + outer_clean_range(__pa(_p), __pa(_p + size)); +} + +/* + * Ensure preceding writes to *p by other CPUs are visible to + * subsequent reads by this CPU. We must be careful not to + * discard data simultaneously written by another CPU, hence the + * usage of flush rather than invalidate operations. + */ +static inline void __sync_cache_range_r(volatile void *p, size_t size) +{ + char *_p = (char *)p; + +#ifdef CONFIG_OUTER_CACHE + if (outer_cache.flush_range) { + /* + * Ensure dirty data migrated from other CPUs into our cache + * are cleaned out safely before the outer cache is cleaned: + */ + __cpuc_clean_dcache_area(_p, size); + + /* Clean and invalidate stale data for *p from outer ... */ + outer_flush_range(__pa(_p), __pa(_p + size)); + } +#endif + + /* ... and inner cache: */ + __cpuc_flush_dcache_area(_p, size); +} + +#define sync_cache_w(ptr) __sync_cache_range_w(ptr, sizeof *(ptr)) +#define sync_cache_r(ptr) __sync_cache_range_r(ptr, sizeof *(ptr)) + #endif diff --git a/trunk/arch/arm/include/asm/cmpxchg.h b/trunk/arch/arm/include/asm/cmpxchg.h index 7eb18c1d8d6c..4f009c10540d 100644 --- a/trunk/arch/arm/include/asm/cmpxchg.h +++ b/trunk/arch/arm/include/asm/cmpxchg.h @@ -233,15 +233,15 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr, ((__typeof__(*(ptr)))atomic64_cmpxchg(container_of((ptr), \ atomic64_t, \ counter), \ - (unsigned long)(o), \ - (unsigned long)(n))) + (unsigned long long)(o), \ + (unsigned long long)(n))) #define cmpxchg64_local(ptr, o, n) \ ((__typeof__(*(ptr)))local64_cmpxchg(container_of((ptr), \ local64_t, \ a), \ - (unsigned long)(o), \ - (unsigned long)(n))) + (unsigned long long)(o), \ + (unsigned long long)(n))) #endif /* __LINUX_ARM_ARCH__ >= 6 */ diff --git a/trunk/arch/arm/include/asm/cp15.h b/trunk/arch/arm/include/asm/cp15.h index 5ef4d8015a60..1f3262e99d81 100644 --- a/trunk/arch/arm/include/asm/cp15.h +++ b/trunk/arch/arm/include/asm/cp15.h @@ -42,6 +42,8 @@ #define vectors_high() (0) #endif +#ifdef CONFIG_CPU_CP15 + extern unsigned long cr_no_alignment; /* defined in entry-armv.S */ extern unsigned long cr_alignment; /* defined in entry-armv.S */ @@ -82,6 +84,18 @@ static inline void set_copro_access(unsigned int val) isb(); } -#endif +#else /* ifdef CONFIG_CPU_CP15 */ + +/* + * cr_alignment and cr_no_alignment are tightly coupled to cp15 (at least in the + * minds of the developers). Yielding 0 for machines without a cp15 (and making + * it read-only) is fine for most cases and saves quite some #ifdeffery. + */ +#define cr_no_alignment UL(0) +#define cr_alignment UL(0) + +#endif /* ifdef CONFIG_CPU_CP15 / else */ + +#endif /* ifndef __ASSEMBLY__ */ #endif diff --git a/trunk/arch/arm/include/asm/cputype.h b/trunk/arch/arm/include/asm/cputype.h index ad41ec2471e8..7652712d1d14 100644 --- a/trunk/arch/arm/include/asm/cputype.h +++ b/trunk/arch/arm/include/asm/cputype.h @@ -38,6 +38,24 @@ #define MPIDR_AFFINITY_LEVEL(mpidr, level) \ ((mpidr >> (MPIDR_LEVEL_BITS * level)) & MPIDR_LEVEL_MASK) +#define ARM_CPU_IMP_ARM 0x41 +#define ARM_CPU_IMP_INTEL 0x69 + +#define ARM_CPU_PART_ARM1136 0xB360 +#define ARM_CPU_PART_ARM1156 0xB560 +#define ARM_CPU_PART_ARM1176 0xB760 +#define ARM_CPU_PART_ARM11MPCORE 0xB020 +#define ARM_CPU_PART_CORTEX_A8 0xC080 +#define ARM_CPU_PART_CORTEX_A9 0xC090 +#define ARM_CPU_PART_CORTEX_A5 0xC050 +#define ARM_CPU_PART_CORTEX_A15 0xC0F0 +#define ARM_CPU_PART_CORTEX_A7 0xC070 + +#define ARM_CPU_XSCALE_ARCH_MASK 0xe000 +#define ARM_CPU_XSCALE_ARCH_V1 0x2000 +#define ARM_CPU_XSCALE_ARCH_V2 0x4000 +#define ARM_CPU_XSCALE_ARCH_V3 0x6000 + extern unsigned int processor_id; #ifdef CONFIG_CPU_CP15 @@ -50,6 +68,7 @@ extern unsigned int processor_id; : "cc"); \ __val; \ }) + #define read_cpuid_ext(ext_reg) \ ({ \ unsigned int __val; \ @@ -59,29 +78,24 @@ extern unsigned int processor_id; : "cc"); \ __val; \ }) -#else -#define read_cpuid(reg) (processor_id) -#define read_cpuid_ext(reg) 0 -#endif -#define ARM_CPU_IMP_ARM 0x41 -#define ARM_CPU_IMP_INTEL 0x69 +#else /* ifdef CONFIG_CPU_CP15 */ -#define ARM_CPU_PART_ARM1136 0xB360 -#define ARM_CPU_PART_ARM1156 0xB560 -#define ARM_CPU_PART_ARM1176 0xB760 -#define ARM_CPU_PART_ARM11MPCORE 0xB020 -#define ARM_CPU_PART_CORTEX_A8 0xC080 -#define ARM_CPU_PART_CORTEX_A9 0xC090 -#define ARM_CPU_PART_CORTEX_A5 0xC050 -#define ARM_CPU_PART_CORTEX_A15 0xC0F0 -#define ARM_CPU_PART_CORTEX_A7 0xC070 +/* + * read_cpuid and read_cpuid_ext should only ever be called on machines that + * have cp15 so warn on other usages. + */ +#define read_cpuid(reg) \ + ({ \ + WARN_ON_ONCE(1); \ + 0; \ + }) -#define ARM_CPU_XSCALE_ARCH_MASK 0xe000 -#define ARM_CPU_XSCALE_ARCH_V1 0x2000 -#define ARM_CPU_XSCALE_ARCH_V2 0x4000 -#define ARM_CPU_XSCALE_ARCH_V3 0x6000 +#define read_cpuid_ext(reg) read_cpuid(reg) + +#endif /* ifdef CONFIG_CPU_CP15 / else */ +#ifdef CONFIG_CPU_CP15 /* * The CPU ID never changes at run time, so we might as well tell the * compiler that it's constant. Use this function to read the CPU ID @@ -92,6 +106,15 @@ static inline unsigned int __attribute_const__ read_cpuid_id(void) return read_cpuid(CPUID_ID); } +#else /* ifdef CONFIG_CPU_CP15 */ + +static inline unsigned int __attribute_const__ read_cpuid_id(void) +{ + return processor_id; +} + +#endif /* ifdef CONFIG_CPU_CP15 / else */ + static inline unsigned int __attribute_const__ read_cpuid_implementor(void) { return (read_cpuid_id() & 0xFF000000) >> 24; diff --git a/trunk/arch/arm/include/asm/firmware.h b/trunk/arch/arm/include/asm/firmware.h new file mode 100644 index 000000000000..15631300c238 --- /dev/null +++ b/trunk/arch/arm/include/asm/firmware.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2012 Samsung Electronics. + * Kyungmin Park + * Tomasz Figa + * + * 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. + */ + +#ifndef __ASM_ARM_FIRMWARE_H +#define __ASM_ARM_FIRMWARE_H + +#include + +/* + * struct firmware_ops + * + * A structure to specify available firmware operations. + * + * A filled up structure can be registered with register_firmware_ops(). + */ +struct firmware_ops { + /* + * Enters CPU idle mode + */ + int (*do_idle)(void); + /* + * Sets boot address of specified physical CPU + */ + int (*set_cpu_boot_addr)(int cpu, unsigned long boot_addr); + /* + * Boots specified physical CPU + */ + int (*cpu_boot)(int cpu); + /* + * Initializes L2 cache + */ + int (*l2x0_init)(void); +}; + +/* Global pointer for current firmware_ops structure, can't be NULL. */ +extern const struct firmware_ops *firmware_ops; + +/* + * call_firmware_op(op, ...) + * + * Checks if firmware operation is present and calls it, + * otherwise returns -ENOSYS + */ +#define call_firmware_op(op, ...) \ + ((firmware_ops->op) ? firmware_ops->op(__VA_ARGS__) : (-ENOSYS)) + +/* + * register_firmware_ops(ops) + * + * A function to register platform firmware_ops struct. + */ +static inline void register_firmware_ops(const struct firmware_ops *ops) +{ + BUG_ON(!ops); + + firmware_ops = ops; +} + +#endif diff --git a/trunk/arch/arm/include/asm/glue-df.h b/trunk/arch/arm/include/asm/glue-df.h index 8cacbcda76da..b6e9f2c108b5 100644 --- a/trunk/arch/arm/include/asm/glue-df.h +++ b/trunk/arch/arm/include/asm/glue-df.h @@ -18,12 +18,12 @@ * ================ * * We have the following to choose from: - * arm6 - ARM6 style * arm7 - ARM7 style * v4_early - ARMv4 without Thumb early abort handler * v4t_late - ARMv4 with Thumb late abort handler * v4t_early - ARMv4 with Thumb early abort handler - * v5tej_early - ARMv5 with Thumb and Java early abort handler + * v5t_early - ARMv5 with Thumb early abort handler + * v5tj_early - ARMv5 with Thumb and Java early abort handler * xscale - ARMv5 with Thumb with Xscale extensions * v6_early - ARMv6 generic early abort handler * v7_early - ARMv7 generic early abort handler @@ -39,19 +39,19 @@ # endif #endif -#ifdef CONFIG_CPU_ABRT_LV4T +#ifdef CONFIG_CPU_ABRT_EV4 # ifdef CPU_DABORT_HANDLER # define MULTI_DABORT 1 # else -# define CPU_DABORT_HANDLER v4t_late_abort +# define CPU_DABORT_HANDLER v4_early_abort # endif #endif -#ifdef CONFIG_CPU_ABRT_EV4 +#ifdef CONFIG_CPU_ABRT_LV4T # ifdef CPU_DABORT_HANDLER # define MULTI_DABORT 1 # else -# define CPU_DABORT_HANDLER v4_early_abort +# define CPU_DABORT_HANDLER v4t_late_abort # endif #endif @@ -63,19 +63,19 @@ # endif #endif -#ifdef CONFIG_CPU_ABRT_EV5TJ +#ifdef CONFIG_CPU_ABRT_EV5T # ifdef CPU_DABORT_HANDLER # define MULTI_DABORT 1 # else -# define CPU_DABORT_HANDLER v5tj_early_abort +# define CPU_DABORT_HANDLER v5t_early_abort # endif #endif -#ifdef CONFIG_CPU_ABRT_EV5T +#ifdef CONFIG_CPU_ABRT_EV5TJ # ifdef CPU_DABORT_HANDLER # define MULTI_DABORT 1 # else -# define CPU_DABORT_HANDLER v5t_early_abort +# define CPU_DABORT_HANDLER v5tj_early_abort # endif #endif diff --git a/trunk/arch/arm/include/asm/hardware/timer-sp.h b/trunk/arch/arm/include/asm/hardware/timer-sp.h index 2dd9d3f83f29..bb28af7c32de 100644 --- a/trunk/arch/arm/include/asm/hardware/timer-sp.h +++ b/trunk/arch/arm/include/asm/hardware/timer-sp.h @@ -1,15 +1,23 @@ +struct clk; + void __sp804_clocksource_and_sched_clock_init(void __iomem *, - const char *, int); + const char *, struct clk *, int); +void __sp804_clockevents_init(void __iomem *, unsigned int, + struct clk *, const char *); static inline void sp804_clocksource_init(void __iomem *base, const char *name) { - __sp804_clocksource_and_sched_clock_init(base, name, 0); + __sp804_clocksource_and_sched_clock_init(base, name, NULL, 0); } static inline void sp804_clocksource_and_sched_clock_init(void __iomem *base, const char *name) { - __sp804_clocksource_and_sched_clock_init(base, name, 1); + __sp804_clocksource_and_sched_clock_init(base, name, NULL, 1); } -void sp804_clockevents_init(void __iomem *, unsigned int, const char *); +static inline void sp804_clockevents_init(void __iomem *base, unsigned int irq, const char *name) +{ + __sp804_clockevents_init(base, irq, NULL, name); + +} diff --git a/trunk/arch/arm/include/asm/idmap.h b/trunk/arch/arm/include/asm/idmap.h index 1a66f907e5cc..bf863edb517d 100644 --- a/trunk/arch/arm/include/asm/idmap.h +++ b/trunk/arch/arm/include/asm/idmap.h @@ -8,7 +8,6 @@ #define __idmap __section(.idmap.text) noinline notrace extern pgd_t *idmap_pgd; -extern pgd_t *hyp_pgd; void setup_mm_for_reboot(void); diff --git a/trunk/arch/arm/include/asm/kvm_arm.h b/trunk/arch/arm/include/asm/kvm_arm.h index 7c3d813e15df..124623e5ef14 100644 --- a/trunk/arch/arm/include/asm/kvm_arm.h +++ b/trunk/arch/arm/include/asm/kvm_arm.h @@ -211,4 +211,8 @@ #define HSR_HVC_IMM_MASK ((1UL << 16) - 1) +#define HSR_DABT_S1PTW (1U << 7) +#define HSR_DABT_CM (1U << 8) +#define HSR_DABT_EA (1U << 9) + #endif /* __ARM_KVM_ARM_H__ */ diff --git a/trunk/arch/arm/include/asm/kvm_asm.h b/trunk/arch/arm/include/asm/kvm_asm.h index e4956f4e23e1..18d50322a9e2 100644 --- a/trunk/arch/arm/include/asm/kvm_asm.h +++ b/trunk/arch/arm/include/asm/kvm_asm.h @@ -75,7 +75,7 @@ extern char __kvm_hyp_code_end[]; extern void __kvm_tlb_flush_vmid(struct kvm *kvm); extern void __kvm_flush_vm_context(void); -extern void __kvm_tlb_flush_vmid(struct kvm *kvm); +extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa); extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu); #endif diff --git a/trunk/arch/arm/include/asm/kvm_emulate.h b/trunk/arch/arm/include/asm/kvm_emulate.h index fd611996bfb5..82b4babead2c 100644 --- a/trunk/arch/arm/include/asm/kvm_emulate.h +++ b/trunk/arch/arm/include/asm/kvm_emulate.h @@ -22,11 +22,12 @@ #include #include #include +#include -u32 *vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num); -u32 *vcpu_spsr(struct kvm_vcpu *vcpu); +unsigned long *vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num); +unsigned long *vcpu_spsr(struct kvm_vcpu *vcpu); -int kvm_handle_wfi(struct kvm_vcpu *vcpu, struct kvm_run *run); +bool kvm_condition_valid(struct kvm_vcpu *vcpu); void kvm_skip_instr(struct kvm_vcpu *vcpu, bool is_wide_instr); void kvm_inject_undefined(struct kvm_vcpu *vcpu); void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr); @@ -37,14 +38,14 @@ static inline bool vcpu_mode_is_32bit(struct kvm_vcpu *vcpu) return 1; } -static inline u32 *vcpu_pc(struct kvm_vcpu *vcpu) +static inline unsigned long *vcpu_pc(struct kvm_vcpu *vcpu) { - return (u32 *)&vcpu->arch.regs.usr_regs.ARM_pc; + return &vcpu->arch.regs.usr_regs.ARM_pc; } -static inline u32 *vcpu_cpsr(struct kvm_vcpu *vcpu) +static inline unsigned long *vcpu_cpsr(struct kvm_vcpu *vcpu) { - return (u32 *)&vcpu->arch.regs.usr_regs.ARM_cpsr; + return &vcpu->arch.regs.usr_regs.ARM_cpsr; } static inline void vcpu_set_thumb(struct kvm_vcpu *vcpu) @@ -69,4 +70,96 @@ static inline bool kvm_vcpu_reg_is_pc(struct kvm_vcpu *vcpu, int reg) return reg == 15; } +static inline u32 kvm_vcpu_get_hsr(struct kvm_vcpu *vcpu) +{ + return vcpu->arch.fault.hsr; +} + +static inline unsigned long kvm_vcpu_get_hfar(struct kvm_vcpu *vcpu) +{ + return vcpu->arch.fault.hxfar; +} + +static inline phys_addr_t kvm_vcpu_get_fault_ipa(struct kvm_vcpu *vcpu) +{ + return ((phys_addr_t)vcpu->arch.fault.hpfar & HPFAR_MASK) << 8; +} + +static inline unsigned long kvm_vcpu_get_hyp_pc(struct kvm_vcpu *vcpu) +{ + return vcpu->arch.fault.hyp_pc; +} + +static inline bool kvm_vcpu_dabt_isvalid(struct kvm_vcpu *vcpu) +{ + return kvm_vcpu_get_hsr(vcpu) & HSR_ISV; +} + +static inline bool kvm_vcpu_dabt_iswrite(struct kvm_vcpu *vcpu) +{ + return kvm_vcpu_get_hsr(vcpu) & HSR_WNR; +} + +static inline bool kvm_vcpu_dabt_issext(struct kvm_vcpu *vcpu) +{ + return kvm_vcpu_get_hsr(vcpu) & HSR_SSE; +} + +static inline int kvm_vcpu_dabt_get_rd(struct kvm_vcpu *vcpu) +{ + return (kvm_vcpu_get_hsr(vcpu) & HSR_SRT_MASK) >> HSR_SRT_SHIFT; +} + +static inline bool kvm_vcpu_dabt_isextabt(struct kvm_vcpu *vcpu) +{ + return kvm_vcpu_get_hsr(vcpu) & HSR_DABT_EA; +} + +static inline bool kvm_vcpu_dabt_iss1tw(struct kvm_vcpu *vcpu) +{ + return kvm_vcpu_get_hsr(vcpu) & HSR_DABT_S1PTW; +} + +/* Get Access Size from a data abort */ +static inline int kvm_vcpu_dabt_get_as(struct kvm_vcpu *vcpu) +{ + switch ((kvm_vcpu_get_hsr(vcpu) >> 22) & 0x3) { + case 0: + return 1; + case 1: + return 2; + case 2: + return 4; + default: + kvm_err("Hardware is weird: SAS 0b11 is reserved\n"); + return -EFAULT; + } +} + +/* This one is not specific to Data Abort */ +static inline bool kvm_vcpu_trap_il_is32bit(struct kvm_vcpu *vcpu) +{ + return kvm_vcpu_get_hsr(vcpu) & HSR_IL; +} + +static inline u8 kvm_vcpu_trap_get_class(struct kvm_vcpu *vcpu) +{ + return kvm_vcpu_get_hsr(vcpu) >> HSR_EC_SHIFT; +} + +static inline bool kvm_vcpu_trap_is_iabt(struct kvm_vcpu *vcpu) +{ + return kvm_vcpu_trap_get_class(vcpu) == HSR_EC_IABT; +} + +static inline u8 kvm_vcpu_trap_get_fault(struct kvm_vcpu *vcpu) +{ + return kvm_vcpu_get_hsr(vcpu) & HSR_FSC_TYPE; +} + +static inline u32 kvm_vcpu_hvc_get_imm(struct kvm_vcpu *vcpu) +{ + return kvm_vcpu_get_hsr(vcpu) & HSR_HVC_IMM_MASK; +} + #endif /* __ARM_KVM_EMULATE_H__ */ diff --git a/trunk/arch/arm/include/asm/kvm_host.h b/trunk/arch/arm/include/asm/kvm_host.h index d1736a53b12d..57cb786a6203 100644 --- a/trunk/arch/arm/include/asm/kvm_host.h +++ b/trunk/arch/arm/include/asm/kvm_host.h @@ -80,6 +80,15 @@ struct kvm_mmu_memory_cache { void *objects[KVM_NR_MEM_OBJS]; }; +struct kvm_vcpu_fault_info { + u32 hsr; /* Hyp Syndrome Register */ + u32 hxfar; /* Hyp Data/Inst. Fault Address Register */ + u32 hpfar; /* Hyp IPA Fault Address Register */ + u32 hyp_pc; /* PC when exception was taken from Hyp mode */ +}; + +typedef struct vfp_hard_struct kvm_cpu_context_t; + struct kvm_vcpu_arch { struct kvm_regs regs; @@ -93,13 +102,13 @@ struct kvm_vcpu_arch { u32 midr; /* Exception Information */ - u32 hsr; /* Hyp Syndrome Register */ - u32 hxfar; /* Hyp Data/Inst Fault Address Register */ - u32 hpfar; /* Hyp IPA Fault Address Register */ + struct kvm_vcpu_fault_info fault; /* Floating point registers (VFP and Advanced SIMD/NEON) */ struct vfp_hard_struct vfp_guest; - struct vfp_hard_struct *vfp_host; + + /* Host FP context */ + kvm_cpu_context_t *host_cpu_context; /* VGIC state */ struct vgic_cpu vgic_cpu; @@ -122,9 +131,6 @@ struct kvm_vcpu_arch { /* Interrupt related fields */ u32 irq_lines; /* IRQ and FIQ levels */ - /* Hyp exception information */ - u32 hyp_pc; /* PC when exception was taken from Hyp mode */ - /* Cache some mmu pages needed inside spinlock regions */ struct kvm_mmu_memory_cache mmu_page_cache; @@ -181,4 +187,41 @@ struct kvm_one_reg; int kvm_arm_coproc_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *); int kvm_arm_coproc_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *); +int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run, + int exception_index); + +static inline void __cpu_init_hyp_mode(unsigned long long boot_pgd_ptr, + unsigned long long pgd_ptr, + unsigned long hyp_stack_ptr, + unsigned long vector_ptr) +{ + /* + * Call initialization code, and switch to the full blown HYP + * code. The init code doesn't need to preserve these + * registers as r0-r3 are already callee saved according to + * the AAPCS. + * Note that we slightly misuse the prototype by casing the + * stack pointer to a void *. + * + * We don't have enough registers to perform the full init in + * one go. Install the boot PGD first, and then install the + * runtime PGD, stack pointer and vectors. The PGDs are always + * passed as the third argument, in order to be passed into + * r2-r3 to the init code (yes, this is compliant with the + * PCS!). + */ + + kvm_call_hyp(NULL, 0, boot_pgd_ptr); + + kvm_call_hyp((void*)hyp_stack_ptr, vector_ptr, pgd_ptr); +} + +static inline int kvm_arch_dev_ioctl_check_extension(long ext) +{ + return 0; +} + +int kvm_perf_init(void); +int kvm_perf_teardown(void); + #endif /* __ARM_KVM_HOST_H__ */ diff --git a/trunk/arch/arm/include/asm/kvm_mmu.h b/trunk/arch/arm/include/asm/kvm_mmu.h index 421a20b34874..472ac7091003 100644 --- a/trunk/arch/arm/include/asm/kvm_mmu.h +++ b/trunk/arch/arm/include/asm/kvm_mmu.h @@ -19,9 +19,33 @@ #ifndef __ARM_KVM_MMU_H__ #define __ARM_KVM_MMU_H__ +#include +#include + +/* + * We directly use the kernel VA for the HYP, as we can directly share + * the mapping (HTTBR "covers" TTBR1). + */ +#define HYP_PAGE_OFFSET_MASK UL(~0) +#define HYP_PAGE_OFFSET PAGE_OFFSET +#define KERN_TO_HYP(kva) (kva) + +/* + * Our virtual mapping for the boot-time MMU-enable code. Must be + * shared across all the page-tables. Conveniently, we use the vectors + * page, where no kernel data will ever be shared with HYP. + */ +#define TRAMPOLINE_VA UL(CONFIG_VECTORS_BASE) + +#ifndef __ASSEMBLY__ + +#include +#include + int create_hyp_mappings(void *from, void *to); int create_hyp_io_mappings(void *from, void *to, phys_addr_t); -void free_hyp_pmds(void); +void free_boot_hyp_pgd(void); +void free_hyp_pgds(void); int kvm_alloc_stage2_pgd(struct kvm *kvm); void kvm_free_stage2_pgd(struct kvm *kvm); @@ -33,9 +57,21 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run); void kvm_mmu_free_memory_caches(struct kvm_vcpu *vcpu); phys_addr_t kvm_mmu_get_httbr(void); +phys_addr_t kvm_mmu_get_boot_httbr(void); +phys_addr_t kvm_get_idmap_vector(void); int kvm_mmu_init(void); void kvm_clear_hyp_idmap(void); +static inline void kvm_set_pte(pte_t *pte, pte_t new_pte) +{ + pte_val(*pte) = new_pte; + /* + * flush_pmd_entry just takes a void pointer and cleans the necessary + * cache entries, so we can reuse the function for ptes. + */ + flush_pmd_entry(pte); +} + static inline bool kvm_is_write_fault(unsigned long hsr) { unsigned long hsr_ec = hsr >> HSR_EC_SHIFT; @@ -47,4 +83,53 @@ static inline bool kvm_is_write_fault(unsigned long hsr) return true; } +static inline void kvm_clean_pgd(pgd_t *pgd) +{ + clean_dcache_area(pgd, PTRS_PER_S2_PGD * sizeof(pgd_t)); +} + +static inline void kvm_clean_pmd_entry(pmd_t *pmd) +{ + clean_pmd_entry(pmd); +} + +static inline void kvm_clean_pte(pte_t *pte) +{ + clean_pte_table(pte); +} + +static inline void kvm_set_s2pte_writable(pte_t *pte) +{ + pte_val(*pte) |= L_PTE_S2_RDWR; +} + +struct kvm; + +static inline void coherent_icache_guest_page(struct kvm *kvm, gfn_t gfn) +{ + /* + * If we are going to insert an instruction page and the icache is + * either VIPT or PIPT, there is a potential problem where the host + * (or another VM) may have used the same page as this guest, and we + * read incorrect data from the icache. If we're using a PIPT cache, + * we can invalidate just that page, but if we are using a VIPT cache + * we need to invalidate the entire icache - damn shame - as written + * in the ARM ARM (DDI 0406C.b - Page B3-1393). + * + * VIVT caches are tagged using both the ASID and the VMID and doesn't + * need any kind of flushing (DDI 0406C.b - Page B3-1392). + */ + if (icache_is_pipt()) { + unsigned long hva = gfn_to_hva(kvm, gfn); + __cpuc_coherent_user_range(hva, hva + PAGE_SIZE); + } else if (!icache_is_vivt_asid_tagged()) { + /* any kind of VIPT cache */ + __flush_icache_all(); + } +} + +#define kvm_flush_dcache_to_poc(a,l) __cpuc_flush_dcache_area((a), (l)) + +#endif /* !__ASSEMBLY__ */ + #endif /* __ARM_KVM_MMU_H__ */ diff --git a/trunk/arch/arm/include/asm/kvm_vgic.h b/trunk/arch/arm/include/asm/kvm_vgic.h index ab97207d9cd3..343744e4809c 100644 --- a/trunk/arch/arm/include/asm/kvm_vgic.h +++ b/trunk/arch/arm/include/asm/kvm_vgic.h @@ -21,7 +21,6 @@ #include #include -#include #include #include #include diff --git a/trunk/arch/arm/include/asm/mach/pci.h b/trunk/arch/arm/include/asm/mach/pci.h index 5cf2e979b4be..7d2c3c843801 100644 --- a/trunk/arch/arm/include/asm/mach/pci.h +++ b/trunk/arch/arm/include/asm/mach/pci.h @@ -30,6 +30,11 @@ struct hw_pci { void (*postinit)(void); u8 (*swizzle)(struct pci_dev *dev, u8 *pin); int (*map_irq)(const struct pci_dev *dev, u8 slot, u8 pin); + resource_size_t (*align_resource)(struct pci_dev *dev, + const struct resource *res, + resource_size_t start, + resource_size_t size, + resource_size_t align); }; /* @@ -51,6 +56,12 @@ struct pci_sys_data { u8 (*swizzle)(struct pci_dev *, u8 *); /* IRQ mapping */ int (*map_irq)(const struct pci_dev *, u8, u8); + /* Resource alignement requirements */ + resource_size_t (*align_resource)(struct pci_dev *dev, + const struct resource *res, + resource_size_t start, + resource_size_t size, + resource_size_t align); void *private_data; /* platform controller private data */ }; diff --git a/trunk/arch/arm/include/asm/mcpm.h b/trunk/arch/arm/include/asm/mcpm.h new file mode 100644 index 000000000000..0f7b7620e9a5 --- /dev/null +++ b/trunk/arch/arm/include/asm/mcpm.h @@ -0,0 +1,209 @@ +/* + * arch/arm/include/asm/mcpm.h + * + * Created by: Nicolas Pitre, April 2012 + * Copyright: (C) 2012-2013 Linaro Limited + * + * 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. + */ + +#ifndef MCPM_H +#define MCPM_H + +/* + * Maximum number of possible clusters / CPUs per cluster. + * + * This should be sufficient for quite a while, while keeping the + * (assembly) code simpler. When this starts to grow then we'll have + * to consider dynamic allocation. + */ +#define MAX_CPUS_PER_CLUSTER 4 +#define MAX_NR_CLUSTERS 2 + +#ifndef __ASSEMBLY__ + +#include +#include + +/* + * Platform specific code should use this symbol to set up secondary + * entry location for processors to use when released from reset. + */ +extern void mcpm_entry_point(void); + +/* + * This is used to indicate where the given CPU from given cluster should + * branch once it is ready to re-enter the kernel using ptr, or NULL if it + * should be gated. A gated CPU is held in a WFE loop until its vector + * becomes non NULL. + */ +void mcpm_set_entry_vector(unsigned cpu, unsigned cluster, void *ptr); + +/* + * CPU/cluster power operations API for higher subsystems to use. + */ + +/** + * mcpm_cpu_power_up - make given CPU in given cluster runable + * + * @cpu: CPU number within given cluster + * @cluster: cluster number for the CPU + * + * The identified CPU is brought out of reset. If the cluster was powered + * down then it is brought up as well, taking care not to let the other CPUs + * in the cluster run, and ensuring appropriate cluster setup. + * + * Caller must ensure the appropriate entry vector is initialized with + * mcpm_set_entry_vector() prior to calling this. + * + * This must be called in a sleepable context. However, the implementation + * is strongly encouraged to return early and let the operation happen + * asynchronously, especially when significant delays are expected. + * + * If the operation cannot be performed then an error code is returned. + */ +int mcpm_cpu_power_up(unsigned int cpu, unsigned int cluster); + +/** + * mcpm_cpu_power_down - power the calling CPU down + * + * The calling CPU is powered down. + * + * If this CPU is found to be the "last man standing" in the cluster + * then the cluster is prepared for power-down too. + * + * This must be called with interrupts disabled. + * + * This does not return. Re-entry in the kernel is expected via + * mcpm_entry_point. + */ +void mcpm_cpu_power_down(void); + +/** + * mcpm_cpu_suspend - bring the calling CPU in a suspended state + * + * @expected_residency: duration in microseconds the CPU is expected + * to remain suspended, or 0 if unknown/infinity. + * + * The calling CPU is suspended. The expected residency argument is used + * as a hint by the platform specific backend to implement the appropriate + * sleep state level according to the knowledge it has on wake-up latency + * for the given hardware. + * + * If this CPU is found to be the "last man standing" in the cluster + * then the cluster may be prepared for power-down too, if the expected + * residency makes it worthwhile. + * + * This must be called with interrupts disabled. + * + * This does not return. Re-entry in the kernel is expected via + * mcpm_entry_point. + */ +void mcpm_cpu_suspend(u64 expected_residency); + +/** + * mcpm_cpu_powered_up - housekeeping workafter a CPU has been powered up + * + * This lets the platform specific backend code perform needed housekeeping + * work. This must be called by the newly activated CPU as soon as it is + * fully operational in kernel space, before it enables interrupts. + * + * If the operation cannot be performed then an error code is returned. + */ +int mcpm_cpu_powered_up(void); + +/* + * Platform specific methods used in the implementation of the above API. + */ +struct mcpm_platform_ops { + int (*power_up)(unsigned int cpu, unsigned int cluster); + void (*power_down)(void); + void (*suspend)(u64); + void (*powered_up)(void); +}; + +/** + * mcpm_platform_register - register platform specific power methods + * + * @ops: mcpm_platform_ops structure to register + * + * An error is returned if the registration has been done previously. + */ +int __init mcpm_platform_register(const struct mcpm_platform_ops *ops); + +/* Synchronisation structures for coordinating safe cluster setup/teardown: */ + +/* + * When modifying this structure, make sure you update the MCPM_SYNC_ defines + * to match. + */ +struct mcpm_sync_struct { + /* individual CPU states */ + struct { + s8 cpu __aligned(__CACHE_WRITEBACK_GRANULE); + } cpus[MAX_CPUS_PER_CLUSTER]; + + /* cluster state */ + s8 cluster __aligned(__CACHE_WRITEBACK_GRANULE); + + /* inbound-side state */ + s8 inbound __aligned(__CACHE_WRITEBACK_GRANULE); +}; + +struct sync_struct { + struct mcpm_sync_struct clusters[MAX_NR_CLUSTERS]; +}; + +extern unsigned long sync_phys; /* physical address of *mcpm_sync */ + +void __mcpm_cpu_going_down(unsigned int cpu, unsigned int cluster); +void __mcpm_cpu_down(unsigned int cpu, unsigned int cluster); +void __mcpm_outbound_leave_critical(unsigned int cluster, int state); +bool __mcpm_outbound_enter_critical(unsigned int this_cpu, unsigned int cluster); +int __mcpm_cluster_state(unsigned int cluster); + +int __init mcpm_sync_init( + void (*power_up_setup)(unsigned int affinity_level)); + +void __init mcpm_smp_set_ops(void); + +#else + +/* + * asm-offsets.h causes trouble when included in .c files, and cacheflush.h + * cannot be included in asm files. Let's work around the conflict like this. + */ +#include +#define __CACHE_WRITEBACK_GRANULE CACHE_WRITEBACK_GRANULE + +#endif /* ! __ASSEMBLY__ */ + +/* Definitions for mcpm_sync_struct */ +#define CPU_DOWN 0x11 +#define CPU_COMING_UP 0x12 +#define CPU_UP 0x13 +#define CPU_GOING_DOWN 0x14 + +#define CLUSTER_DOWN 0x21 +#define CLUSTER_UP 0x22 +#define CLUSTER_GOING_DOWN 0x23 + +#define INBOUND_NOT_COMING_UP 0x31 +#define INBOUND_COMING_UP 0x32 + +/* + * Offsets for the mcpm_sync_struct members, for use in asm. + * We don't want to make them global to the kernel via asm-offsets.c. + */ +#define MCPM_SYNC_CLUSTER_CPUS 0 +#define MCPM_SYNC_CPU_SIZE __CACHE_WRITEBACK_GRANULE +#define MCPM_SYNC_CLUSTER_CLUSTER \ + (MCPM_SYNC_CLUSTER_CPUS + MCPM_SYNC_CPU_SIZE * MAX_CPUS_PER_CLUSTER) +#define MCPM_SYNC_CLUSTER_INBOUND \ + (MCPM_SYNC_CLUSTER_CLUSTER + __CACHE_WRITEBACK_GRANULE) +#define MCPM_SYNC_CLUSTER_SIZE \ + (MCPM_SYNC_CLUSTER_INBOUND + __CACHE_WRITEBACK_GRANULE) + +#endif diff --git a/trunk/arch/arm/include/asm/sched_clock.h b/trunk/arch/arm/include/asm/sched_clock.h index e3f757263438..3d520ddca61b 100644 --- a/trunk/arch/arm/include/asm/sched_clock.h +++ b/trunk/arch/arm/include/asm/sched_clock.h @@ -11,4 +11,6 @@ extern void sched_clock_postinit(void); extern void setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate); +extern unsigned long long (*sched_clock_func)(void); + #endif diff --git a/trunk/arch/arm/include/asm/thread_info.h b/trunk/arch/arm/include/asm/thread_info.h index cddda1f41f0f..1995d1a84060 100644 --- a/trunk/arch/arm/include/asm/thread_info.h +++ b/trunk/arch/arm/include/asm/thread_info.h @@ -152,6 +152,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, #define TIF_SYSCALL_AUDIT 9 #define TIF_SYSCALL_TRACEPOINT 10 #define TIF_SECCOMP 11 /* seccomp syscall filtering active */ +#define TIF_NOHZ 12 /* in adaptive nohz mode */ #define TIF_USING_IWMMXT 17 #define TIF_MEMDIE 18 /* is terminating due to OOM killer */ #define TIF_RESTORE_SIGMASK 20 diff --git a/trunk/arch/arm/include/asm/tlbflush.h b/trunk/arch/arm/include/asm/tlbflush.h index ab865e65a84c..a3625d141c1d 100644 --- a/trunk/arch/arm/include/asm/tlbflush.h +++ b/trunk/arch/arm/include/asm/tlbflush.h @@ -166,7 +166,7 @@ # define v6wbi_always_flags (-1UL) #endif -#define v7wbi_tlb_flags_smp (TLB_WB | TLB_DCLEAN | TLB_BARRIER | \ +#define v7wbi_tlb_flags_smp (TLB_WB | TLB_BARRIER | \ TLB_V7_UIS_FULL | TLB_V7_UIS_PAGE | \ TLB_V7_UIS_ASID | TLB_V7_UIS_BP) #define v7wbi_tlb_flags_up (TLB_WB | TLB_DCLEAN | TLB_BARRIER | \ diff --git a/trunk/arch/arm/include/asm/xen/hypercall.h b/trunk/arch/arm/include/asm/xen/hypercall.h index 8a823253d775..799f42ecca63 100644 --- a/trunk/arch/arm/include/asm/xen/hypercall.h +++ b/trunk/arch/arm/include/asm/xen/hypercall.h @@ -46,6 +46,7 @@ int HYPERVISOR_event_channel_op(int cmd, void *arg); unsigned long HYPERVISOR_hvm_op(int op, void *arg); int HYPERVISOR_memory_op(unsigned int cmd, void *arg); int HYPERVISOR_physdev_op(int cmd, void *arg); +int HYPERVISOR_vcpu_op(int cmd, int vcpuid, void *extra_args); static inline void MULTI_update_va_mapping(struct multicall_entry *mcl, unsigned long va, diff --git a/trunk/arch/arm/include/debug/mvebu.S b/trunk/arch/arm/include/debug/mvebu.S index 865c6d02b332..df191afa3be1 100644 --- a/trunk/arch/arm/include/debug/mvebu.S +++ b/trunk/arch/arm/include/debug/mvebu.S @@ -12,7 +12,7 @@ */ #define ARMADA_370_XP_REGS_PHYS_BASE 0xd0000000 -#define ARMADA_370_XP_REGS_VIRT_BASE 0xfeb00000 +#define ARMADA_370_XP_REGS_VIRT_BASE 0xfec00000 .macro addruart, rp, rv, tmp ldr \rp, =ARMADA_370_XP_REGS_PHYS_BASE diff --git a/trunk/arch/arm/include/debug/pxa.S b/trunk/arch/arm/include/debug/pxa.S new file mode 100644 index 000000000000..e1e795aa3d7f --- /dev/null +++ b/trunk/arch/arm/include/debug/pxa.S @@ -0,0 +1,33 @@ +/* + * Early serial output macro for Marvell PXA/MMP SoC + * + * Copyright (C) 1994-1999 Russell King + * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks + * + * Copyright (C) 2013 Haojian Zhuang + * + * 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. +*/ + +#if defined(CONFIG_DEBUG_PXA_UART1) +#define PXA_UART_REG_PHYS_BASE 0x40100000 +#define PXA_UART_REG_VIRT_BASE 0xf2100000 +#elif defined(CONFIG_DEBUG_MMP_UART2) +#define PXA_UART_REG_PHYS_BASE 0xd4017000 +#define PXA_UART_REG_VIRT_BASE 0xfe017000 +#elif defined(CONFIG_DEBUG_MMP_UART3) +#define PXA_UART_REG_PHYS_BASE 0xd4018000 +#define PXA_UART_REG_VIRT_BASE 0xfe018000 +#else +#error "Select uart for DEBUG_LL" +#endif + + .macro addruart, rp, rv, tmp + ldr \rp, =PXA_UART_REG_PHYS_BASE + ldr \rv, =PXA_UART_REG_VIRT_BASE + .endm + +#define UART_SHIFT 2 +#include diff --git a/trunk/arch/arm/include/debug/uncompress.h b/trunk/arch/arm/include/debug/uncompress.h new file mode 100644 index 000000000000..0e2949b0fae9 --- /dev/null +++ b/trunk/arch/arm/include/debug/uncompress.h @@ -0,0 +1,7 @@ +#ifdef CONFIG_DEBUG_UNCOMPRESS +extern void putc(int c); +#else +static inline void putc(int c) {} +#endif +static inline void flush(void) {} +static inline void arch_decomp_setup(void) {} diff --git a/trunk/arch/arm/include/uapi/asm/kvm.h b/trunk/arch/arm/include/uapi/asm/kvm.h index 023bfeb367bf..c1ee007523d7 100644 --- a/trunk/arch/arm/include/uapi/asm/kvm.h +++ b/trunk/arch/arm/include/uapi/asm/kvm.h @@ -53,12 +53,12 @@ #define KVM_ARM_FIQ_spsr fiq_regs[7] struct kvm_regs { - struct pt_regs usr_regs;/* R0_usr - R14_usr, PC, CPSR */ - __u32 svc_regs[3]; /* SP_svc, LR_svc, SPSR_svc */ - __u32 abt_regs[3]; /* SP_abt, LR_abt, SPSR_abt */ - __u32 und_regs[3]; /* SP_und, LR_und, SPSR_und */ - __u32 irq_regs[3]; /* SP_irq, LR_irq, SPSR_irq */ - __u32 fiq_regs[8]; /* R8_fiq - R14_fiq, SPSR_fiq */ + struct pt_regs usr_regs; /* R0_usr - R14_usr, PC, CPSR */ + unsigned long svc_regs[3]; /* SP_svc, LR_svc, SPSR_svc */ + unsigned long abt_regs[3]; /* SP_abt, LR_abt, SPSR_abt */ + unsigned long und_regs[3]; /* SP_und, LR_und, SPSR_und */ + unsigned long irq_regs[3]; /* SP_irq, LR_irq, SPSR_irq */ + unsigned long fiq_regs[8]; /* R8_fiq - R14_fiq, SPSR_fiq */ }; /* Supported Processor Types */ diff --git a/trunk/arch/arm/kernel/arch_timer.c b/trunk/arch/arm/kernel/arch_timer.c index d957a51435d8..59dcdced6e30 100644 --- a/trunk/arch/arm/kernel/arch_timer.c +++ b/trunk/arch/arm/kernel/arch_timer.c @@ -22,9 +22,11 @@ static unsigned long arch_timer_read_counter_long(void) return arch_timer_read_counter(); } -static u32 arch_timer_read_counter_u32(void) +static u32 sched_clock_mult __read_mostly; + +static unsigned long long notrace arch_timer_sched_clock(void) { - return arch_timer_read_counter(); + return arch_timer_read_counter() * sched_clock_mult; } static struct delay_timer arch_delay_timer; @@ -37,25 +39,20 @@ static void __init arch_timer_delay_timer_register(void) register_current_timer_delay(&arch_delay_timer); } -int __init arch_timer_of_register(void) +int __init arch_timer_arch_init(void) { - int ret; + u32 arch_timer_rate = arch_timer_get_rate(); - ret = arch_timer_init(); - if (ret) - return ret; + if (arch_timer_rate == 0) + return -ENXIO; arch_timer_delay_timer_register(); - return 0; -} - -int __init arch_timer_sched_clock_init(void) -{ - if (arch_timer_get_rate() == 0) - return -ENXIO; + /* Cache the sched_clock multiplier to save a divide in the hot path. */ + sched_clock_mult = NSEC_PER_SEC / arch_timer_rate; + sched_clock_func = arch_timer_sched_clock; + pr_info("sched_clock: ARM arch timer >56 bits at %ukHz, resolution %uns\n", + arch_timer_rate / 1000, sched_clock_mult); - setup_sched_clock(arch_timer_read_counter_u32, - 32, arch_timer_get_rate()); return 0; } diff --git a/trunk/arch/arm/kernel/asm-offsets.c b/trunk/arch/arm/kernel/asm-offsets.c index 923eec7105cf..ee68cce6b48e 100644 --- a/trunk/arch/arm/kernel/asm-offsets.c +++ b/trunk/arch/arm/kernel/asm-offsets.c @@ -149,12 +149,16 @@ int main(void) DEFINE(DMA_BIDIRECTIONAL, DMA_BIDIRECTIONAL); DEFINE(DMA_TO_DEVICE, DMA_TO_DEVICE); DEFINE(DMA_FROM_DEVICE, DMA_FROM_DEVICE); + BLANK(); + DEFINE(CACHE_WRITEBACK_ORDER, __CACHE_WRITEBACK_ORDER); + DEFINE(CACHE_WRITEBACK_GRANULE, __CACHE_WRITEBACK_GRANULE); + BLANK(); #ifdef CONFIG_KVM_ARM_HOST DEFINE(VCPU_KVM, offsetof(struct kvm_vcpu, kvm)); DEFINE(VCPU_MIDR, offsetof(struct kvm_vcpu, arch.midr)); DEFINE(VCPU_CP15, offsetof(struct kvm_vcpu, arch.cp15)); DEFINE(VCPU_VFP_GUEST, offsetof(struct kvm_vcpu, arch.vfp_guest)); - DEFINE(VCPU_VFP_HOST, offsetof(struct kvm_vcpu, arch.vfp_host)); + DEFINE(VCPU_VFP_HOST, offsetof(struct kvm_vcpu, arch.host_cpu_context)); DEFINE(VCPU_REGS, offsetof(struct kvm_vcpu, arch.regs)); DEFINE(VCPU_USR_REGS, offsetof(struct kvm_vcpu, arch.regs.usr_regs)); DEFINE(VCPU_SVC_REGS, offsetof(struct kvm_vcpu, arch.regs.svc_regs)); @@ -165,10 +169,10 @@ int main(void) DEFINE(VCPU_PC, offsetof(struct kvm_vcpu, arch.regs.usr_regs.ARM_pc)); DEFINE(VCPU_CPSR, offsetof(struct kvm_vcpu, arch.regs.usr_regs.ARM_cpsr)); DEFINE(VCPU_IRQ_LINES, offsetof(struct kvm_vcpu, arch.irq_lines)); - DEFINE(VCPU_HSR, offsetof(struct kvm_vcpu, arch.hsr)); - DEFINE(VCPU_HxFAR, offsetof(struct kvm_vcpu, arch.hxfar)); - DEFINE(VCPU_HPFAR, offsetof(struct kvm_vcpu, arch.hpfar)); - DEFINE(VCPU_HYP_PC, offsetof(struct kvm_vcpu, arch.hyp_pc)); + DEFINE(VCPU_HSR, offsetof(struct kvm_vcpu, arch.fault.hsr)); + DEFINE(VCPU_HxFAR, offsetof(struct kvm_vcpu, arch.fault.hxfar)); + DEFINE(VCPU_HPFAR, offsetof(struct kvm_vcpu, arch.fault.hpfar)); + DEFINE(VCPU_HYP_PC, offsetof(struct kvm_vcpu, arch.fault.hyp_pc)); #ifdef CONFIG_KVM_ARM_VGIC DEFINE(VCPU_VGIC_CPU, offsetof(struct kvm_vcpu, arch.vgic_cpu)); DEFINE(VGIC_CPU_HCR, offsetof(struct vgic_cpu, vgic_hcr)); diff --git a/trunk/arch/arm/kernel/bios32.c b/trunk/arch/arm/kernel/bios32.c index a1f73b502ef0..b2ed73c45489 100644 --- a/trunk/arch/arm/kernel/bios32.c +++ b/trunk/arch/arm/kernel/bios32.c @@ -462,6 +462,7 @@ static void pcibios_init_hw(struct hw_pci *hw, struct list_head *head) sys->busnr = busnr; sys->swizzle = hw->swizzle; sys->map_irq = hw->map_irq; + sys->align_resource = hw->align_resource; INIT_LIST_HEAD(&sys->resources); if (hw->private_data) @@ -574,6 +575,8 @@ char * __init pcibios_setup(char *str) resource_size_t pcibios_align_resource(void *data, const struct resource *res, resource_size_t size, resource_size_t align) { + struct pci_dev *dev = data; + struct pci_sys_data *sys = dev->sysdata; resource_size_t start = res->start; if (res->flags & IORESOURCE_IO && start & 0x300) @@ -581,6 +584,9 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res, start = (start + align - 1) & ~(align - 1); + if (sys->align_resource) + return sys->align_resource(dev, res, start, size, align); + return start; } diff --git a/trunk/arch/arm/kernel/devtree.c b/trunk/arch/arm/kernel/devtree.c index 70f1bdeb241b..5af04f6daa33 100644 --- a/trunk/arch/arm/kernel/devtree.c +++ b/trunk/arch/arm/kernel/devtree.c @@ -180,6 +180,13 @@ struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys) unsigned long dt_root; const char *model; +#ifdef CONFIG_ARCH_MULTIPLATFORM + DT_MACHINE_START(GENERIC_DT, "Generic DT based system") + MACHINE_END + + mdesc_best = (struct machine_desc *)&__mach_desc_GENERIC_DT; +#endif + if (!dt_phys) return NULL; diff --git a/trunk/arch/arm/kernel/entry-armv.S b/trunk/arch/arm/kernel/entry-armv.S index 0f82098c9bfe..582b405befc5 100644 --- a/trunk/arch/arm/kernel/entry-armv.S +++ b/trunk/arch/arm/kernel/entry-armv.S @@ -192,18 +192,6 @@ __dabt_svc: svc_entry mov r2, sp dabt_helper - - @ - @ IRQs off again before pulling preserved data off the stack - @ - disable_irq_notrace - -#ifdef CONFIG_TRACE_IRQFLAGS - tst r5, #PSR_I_BIT - bleq trace_hardirqs_on - tst r5, #PSR_I_BIT - blne trace_hardirqs_off -#endif svc_exit r5 @ return from exception UNWIND(.fnend ) ENDPROC(__dabt_svc) @@ -223,12 +211,7 @@ __irq_svc: blne svc_preempt #endif -#ifdef CONFIG_TRACE_IRQFLAGS - @ The parent context IRQs must have been enabled to get here in - @ the first place, so there's no point checking the PSR I bit. - bl trace_hardirqs_on -#endif - svc_exit r5 @ return from exception + svc_exit r5, irq = 1 @ return from exception UNWIND(.fnend ) ENDPROC(__irq_svc) @@ -295,22 +278,8 @@ __und_svc_fault: mov r0, sp @ struct pt_regs *regs bl __und_fault - @ - @ IRQs off again before pulling preserved data off the stack - @ __und_svc_finish: - disable_irq_notrace - - @ - @ restore SPSR and restart the instruction - @ ldr r5, [sp, #S_PSR] @ Get SVC cpsr -#ifdef CONFIG_TRACE_IRQFLAGS - tst r5, #PSR_I_BIT - bleq trace_hardirqs_on - tst r5, #PSR_I_BIT - blne trace_hardirqs_off -#endif svc_exit r5 @ return from exception UNWIND(.fnend ) ENDPROC(__und_svc) @@ -320,18 +289,6 @@ __pabt_svc: svc_entry mov r2, sp @ regs pabt_helper - - @ - @ IRQs off again before pulling preserved data off the stack - @ - disable_irq_notrace - -#ifdef CONFIG_TRACE_IRQFLAGS - tst r5, #PSR_I_BIT - bleq trace_hardirqs_on - tst r5, #PSR_I_BIT - blne trace_hardirqs_off -#endif svc_exit r5 @ return from exception UNWIND(.fnend ) ENDPROC(__pabt_svc) @@ -396,6 +353,7 @@ ENDPROC(__pabt_svc) #ifdef CONFIG_IRQSOFF_TRACER bl trace_hardirqs_off #endif + ct_user_exit save = 0 .endm .macro kuser_cmpxchg_check @@ -562,21 +520,21 @@ ENDPROC(__und_usr) @ Fall-through from Thumb-2 __und_usr @ #ifdef CONFIG_NEON + get_thread_info r10 @ get current thread adr r6, .LCneon_thumb_opcodes b 2f #endif call_fpe: + get_thread_info r10 @ get current thread #ifdef CONFIG_NEON adr r6, .LCneon_arm_opcodes -2: - ldr r7, [r6], #4 @ mask value - cmp r7, #0 @ end mask? - beq 1f - and r8, r0, r7 +2: ldr r5, [r6], #4 @ mask value ldr r7, [r6], #4 @ opcode bits matching in mask + cmp r5, #0 @ end mask? + beq 1f + and r8, r0, r5 cmp r8, r7 @ NEON instruction? bne 2b - get_thread_info r10 mov r7, #1 strb r7, [r10, #TI_USED_CP + 10] @ mark CP#10 as used strb r7, [r10, #TI_USED_CP + 11] @ mark CP#11 as used @@ -586,7 +544,6 @@ call_fpe: tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27 tstne r0, #0x04000000 @ bit 26 set on both ARM and Thumb-2 moveq pc, lr - get_thread_info r10 @ get current thread and r8, r0, #0x00000f00 @ mask out CP number THUMB( lsr r8, r8, #8 ) mov r7, #1 diff --git a/trunk/arch/arm/kernel/entry-common.S b/trunk/arch/arm/kernel/entry-common.S index fefd7f971437..bc5bc0a97131 100644 --- a/trunk/arch/arm/kernel/entry-common.S +++ b/trunk/arch/arm/kernel/entry-common.S @@ -35,12 +35,11 @@ ret_fast_syscall: ldr r1, [tsk, #TI_FLAGS] tst r1, #_TIF_WORK_MASK bne fast_work_pending -#if defined(CONFIG_IRQSOFF_TRACER) asm_trace_hardirqs_on -#endif /* perform architecture specific actions before user return */ arch_ret_to_user r1, lr + ct_user_enter restore_user_regs fast = 1, offset = S_OFF UNWIND(.fnend ) @@ -71,11 +70,11 @@ ENTRY(ret_to_user_from_irq) tst r1, #_TIF_WORK_MASK bne work_pending no_work_pending: -#if defined(CONFIG_IRQSOFF_TRACER) asm_trace_hardirqs_on -#endif + /* perform architecture specific actions before user return */ arch_ret_to_user r1, lr + ct_user_enter save = 0 restore_user_regs fast = 0, offset = 0 ENDPROC(ret_to_user_from_irq) @@ -406,6 +405,7 @@ ENTRY(vector_swi) mcr p15, 0, ip, c1, c0 @ update control register #endif enable_irq + ct_user_exit get_thread_info tsk adr tbl, sys_call_table @ load syscall table pointer diff --git a/trunk/arch/arm/kernel/entry-header.S b/trunk/arch/arm/kernel/entry-header.S index 9a8531eadd3d..160f3376ba6d 100644 --- a/trunk/arch/arm/kernel/entry-header.S +++ b/trunk/arch/arm/kernel/entry-header.S @@ -74,7 +74,24 @@ .endm #ifndef CONFIG_THUMB2_KERNEL - .macro svc_exit, rpsr + .macro svc_exit, rpsr, irq = 0 + .if \irq != 0 + @ IRQs already off +#ifdef CONFIG_TRACE_IRQFLAGS + @ The parent context IRQs must have been enabled to get here in + @ the first place, so there's no point checking the PSR I bit. + bl trace_hardirqs_on +#endif + .else + @ IRQs off again before pulling preserved data off the stack + disable_irq_notrace +#ifdef CONFIG_TRACE_IRQFLAGS + tst \rpsr, #PSR_I_BIT + bleq trace_hardirqs_on + tst \rpsr, #PSR_I_BIT + blne trace_hardirqs_off +#endif + .endif msr spsr_cxsf, \rpsr #if defined(CONFIG_CPU_V6) ldr r0, [sp] @@ -120,7 +137,24 @@ mov pc, \reg .endm #else /* CONFIG_THUMB2_KERNEL */ - .macro svc_exit, rpsr + .macro svc_exit, rpsr, irq = 0 + .if \irq != 0 + @ IRQs already off +#ifdef CONFIG_TRACE_IRQFLAGS + @ The parent context IRQs must have been enabled to get here in + @ the first place, so there's no point checking the PSR I bit. + bl trace_hardirqs_on +#endif + .else + @ IRQs off again before pulling preserved data off the stack + disable_irq_notrace +#ifdef CONFIG_TRACE_IRQFLAGS + tst \rpsr, #PSR_I_BIT + bleq trace_hardirqs_on + tst \rpsr, #PSR_I_BIT + blne trace_hardirqs_off +#endif + .endif ldr lr, [sp, #S_SP] @ top of the stack ldrd r0, r1, [sp, #S_LR] @ calling lr and pc clrex @ clear the exclusive monitor @@ -163,6 +197,34 @@ .endm #endif /* !CONFIG_THUMB2_KERNEL */ +/* + * Context tracking subsystem. Used to instrument transitions + * between user and kernel mode. + */ + .macro ct_user_exit, save = 1 +#ifdef CONFIG_CONTEXT_TRACKING + .if \save + stmdb sp!, {r0-r3, ip, lr} + bl user_exit + ldmia sp!, {r0-r3, ip, lr} + .else + bl user_exit + .endif +#endif + .endm + + .macro ct_user_enter, save = 1 +#ifdef CONFIG_CONTEXT_TRACKING + .if \save + stmdb sp!, {r0-r3, ip, lr} + bl user_enter + ldmia sp!, {r0-r3, ip, lr} + .else + bl user_enter + .endif +#endif + .endm + /* * These are the registers used in the syscall handler, and allow us to * have in theory up to 7 arguments to a function - r0 to r6. diff --git a/trunk/arch/arm/kernel/head-common.S b/trunk/arch/arm/kernel/head-common.S index 854bd22380d3..5b391a689b47 100644 --- a/trunk/arch/arm/kernel/head-common.S +++ b/trunk/arch/arm/kernel/head-common.S @@ -98,8 +98,9 @@ __mmap_switched: str r9, [r4] @ Save processor ID str r1, [r5] @ Save machine type str r2, [r6] @ Save atags pointer - bic r4, r0, #CR_A @ Clear 'A' bit - stmia r7, {r0, r4} @ Save control register values + cmp r7, #0 + bicne r4, r0, #CR_A @ Clear 'A' bit + stmneia r7, {r0, r4} @ Save control register values b start_kernel ENDPROC(__mmap_switched) @@ -113,7 +114,11 @@ __mmap_switched_data: .long processor_id @ r4 .long __machine_arch_type @ r5 .long __atags_pointer @ r6 +#ifdef CONFIG_CPU_CP15 .long cr_alignment @ r7 +#else + .long 0 @ r7 +#endif .long init_thread_union + THREAD_START_SP @ sp .size __mmap_switched_data, . - __mmap_switched_data diff --git a/trunk/arch/arm/kernel/head-nommu.S b/trunk/arch/arm/kernel/head-nommu.S index 2c228a07e58c..6a2e09c952c7 100644 --- a/trunk/arch/arm/kernel/head-nommu.S +++ b/trunk/arch/arm/kernel/head-nommu.S @@ -32,15 +32,21 @@ * numbers for r1. * */ - .arm __HEAD + +#ifdef CONFIG_CPU_THUMBONLY + .thumb +ENTRY(stext) +#else + .arm ENTRY(stext) THUMB( adr r9, BSYM(1f) ) @ Kernel is always entered in ARM. THUMB( bx r9 ) @ If this is a Thumb-2 kernel, THUMB( .thumb ) @ switch to Thumb now. THUMB(1: ) +#endif setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode @ and irqs disabled diff --git a/trunk/arch/arm/kernel/process.c b/trunk/arch/arm/kernel/process.c index ae58d3b37d9d..f21970316836 100644 --- a/trunk/arch/arm/kernel/process.c +++ b/trunk/arch/arm/kernel/process.c @@ -407,15 +407,16 @@ unsigned long arch_randomize_brk(struct mm_struct *mm) * atomic helpers and the signal restart code. Insert it into the * gate_vma so that it is visible through ptrace and /proc//mem. */ -static struct vm_area_struct gate_vma; +static struct vm_area_struct gate_vma = { + .vm_start = 0xffff0000, + .vm_end = 0xffff0000 + PAGE_SIZE, + .vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC, + .vm_mm = &init_mm, +}; static int __init gate_vma_init(void) { - gate_vma.vm_start = 0xffff0000; - gate_vma.vm_end = 0xffff0000 + PAGE_SIZE; - gate_vma.vm_page_prot = PAGE_READONLY_EXEC; - gate_vma.vm_flags = VM_READ | VM_EXEC | - VM_MAYREAD | VM_MAYEXEC; + gate_vma.vm_page_prot = PAGE_READONLY_EXEC; return 0; } arch_initcall(gate_vma_init); diff --git a/trunk/arch/arm/kernel/return_address.c b/trunk/arch/arm/kernel/return_address.c index 8085417555dd..fafedd86885d 100644 --- a/trunk/arch/arm/kernel/return_address.c +++ b/trunk/arch/arm/kernel/return_address.c @@ -26,7 +26,7 @@ static int save_return_addr(struct stackframe *frame, void *d) struct return_address_data *data = d; if (!data->level) { - data->addr = (void *)frame->lr; + data->addr = (void *)frame->pc; return 1; } else { @@ -41,7 +41,8 @@ void *return_address(unsigned int level) struct stackframe frame; register unsigned long current_sp asm ("sp"); - data.level = level + 1; + data.level = level + 2; + data.addr = NULL; frame.fp = (unsigned long)__builtin_frame_address(0); frame.sp = current_sp; diff --git a/trunk/arch/arm/kernel/sched_clock.c b/trunk/arch/arm/kernel/sched_clock.c index 59d2adb764a9..e8edcaa0e432 100644 --- a/trunk/arch/arm/kernel/sched_clock.c +++ b/trunk/arch/arm/kernel/sched_clock.c @@ -20,6 +20,7 @@ struct clock_data { u64 epoch_ns; u32 epoch_cyc; u32 epoch_cyc_copy; + unsigned long rate; u32 mult; u32 shift; bool suspended; @@ -113,11 +114,14 @@ void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate) u64 res, wrap; char r_unit; + if (cd.rate > rate) + return; + BUG_ON(bits > 32); WARN_ON(!irqs_disabled()); - WARN_ON(read_sched_clock != jiffy_sched_clock_read); read_sched_clock = read; sched_clock_mask = (1 << bits) - 1; + cd.rate = rate; /* calculate the mult/shift to convert counter ticks to ns. */ clocks_calc_mult_shift(&cd.mult, &cd.shift, rate, NSEC_PER_SEC, 0); @@ -161,12 +165,19 @@ void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate) pr_debug("Registered %pF as sched_clock source\n", read); } -unsigned long long notrace sched_clock(void) +static unsigned long long notrace sched_clock_32(void) { u32 cyc = read_sched_clock(); return cyc_to_sched_clock(cyc, sched_clock_mask); } +unsigned long long __read_mostly (*sched_clock_func)(void) = sched_clock_32; + +unsigned long long notrace sched_clock(void) +{ + return sched_clock_func(); +} + void __init sched_clock_postinit(void) { /* diff --git a/trunk/arch/arm/kernel/setup.c b/trunk/arch/arm/kernel/setup.c index 234e339196c0..1522c7ae31b0 100644 --- a/trunk/arch/arm/kernel/setup.c +++ b/trunk/arch/arm/kernel/setup.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -290,10 +291,10 @@ static int cpu_has_aliasing_icache(unsigned int arch) static void __init cacheid_init(void) { - unsigned int cachetype = read_cpuid_cachetype(); unsigned int arch = cpu_architecture(); if (arch >= CPU_ARCH_ARMv6) { + unsigned int cachetype = read_cpuid_cachetype(); if ((cachetype & (7 << 29)) == 4 << 29) { /* ARMv7 register format */ arch = CPU_ARCH_ARMv7; @@ -389,7 +390,7 @@ static void __init feat_v6_fixup(void) * * cpu_init sets up the per-CPU stacks. */ -void cpu_init(void) +void notrace cpu_init(void) { unsigned int cpu = smp_processor_id(); struct stack *stk = &stacks[cpu]; @@ -659,9 +660,19 @@ struct screen_info screen_info = { static int __init customize_machine(void) { - /* customizes platform devices, or adds new ones */ + /* + * customizes platform devices, or adds new ones + * On DT based machines, we fall back to populating the + * machine from the device tree, if no callback is provided, + * otherwise we would always need an init_machine callback. + */ if (machine_desc->init_machine) machine_desc->init_machine(); +#ifdef CONFIG_OF + else + of_platform_populate(NULL, of_default_bus_match_table, + NULL, NULL); +#endif return 0; } arch_initcall(customize_machine); diff --git a/trunk/arch/arm/kernel/smp.c b/trunk/arch/arm/kernel/smp.c index 4619177bcfe6..47ab90563bf4 100644 --- a/trunk/arch/arm/kernel/smp.c +++ b/trunk/arch/arm/kernel/smp.c @@ -211,6 +211,13 @@ void __cpuinit __cpu_die(unsigned int cpu) } printk(KERN_NOTICE "CPU%u: shutdown\n", cpu); + /* + * platform_cpu_kill() is generally expected to do the powering off + * and/or cutting of clocks to the dying CPU. Optionally, this may + * be done by the CPU which is dying in preference to supporting + * this call, but that means there is _no_ synchronisation between + * the requesting CPU and the dying CPU actually losing power. + */ if (!platform_cpu_kill(cpu)) printk("CPU%u: unable to kill\n", cpu); } @@ -230,14 +237,41 @@ void __ref cpu_die(void) idle_task_exit(); local_irq_disable(); - mb(); - /* Tell __cpu_die() that this CPU is now safe to dispose of */ + /* + * Flush the data out of the L1 cache for this CPU. This must be + * before the completion to ensure that data is safely written out + * before platform_cpu_kill() gets called - which may disable + * *this* CPU and power down its cache. + */ + flush_cache_louis(); + + /* + * Tell __cpu_die() that this CPU is now safe to dispose of. Once + * this returns, power and/or clocks can be removed at any point + * from this CPU and its cache by platform_cpu_kill(). + */ RCU_NONIDLE(complete(&cpu_died)); /* - * actual CPU shutdown procedure is at least platform (if not - * CPU) specific. + * Ensure that the cache lines associated with that completion are + * written out. This covers the case where _this_ CPU is doing the + * powering down, to ensure that the completion is visible to the + * CPU waiting for this one. + */ + flush_cache_louis(); + + /* + * The actual CPU shutdown procedure is at least platform (if not + * CPU) specific. This may remove power, or it may simply spin. + * + * Platforms are generally expected *NOT* to return from this call, + * although there are some which do because they have no way to + * power down the CPU. These platforms are the _only_ reason we + * have a return path which uses the fragment of assembly below. + * + * The return path should not be used for platforms which can + * power off the CPU. */ if (smp_ops.cpu_die) smp_ops.cpu_die(cpu); diff --git a/trunk/arch/arm/kernel/smp_scu.c b/trunk/arch/arm/kernel/smp_scu.c index 45eac87ed66a..5bc1a63284e3 100644 --- a/trunk/arch/arm/kernel/smp_scu.c +++ b/trunk/arch/arm/kernel/smp_scu.c @@ -41,7 +41,7 @@ void scu_enable(void __iomem *scu_base) #ifdef CONFIG_ARM_ERRATA_764369 /* Cortex-A9 only */ - if ((read_cpuid(CPUID_ID) & 0xff0ffff0) == 0x410fc090) { + if ((read_cpuid_id() & 0xff0ffff0) == 0x410fc090) { scu_ctrl = __raw_readl(scu_base + 0x30); if (!(scu_ctrl & 1)) __raw_writel(scu_ctrl | 0x1, scu_base + 0x30); diff --git a/trunk/arch/arm/kernel/smp_tlb.c b/trunk/arch/arm/kernel/smp_tlb.c index e82e1d248772..9a52a07aa40e 100644 --- a/trunk/arch/arm/kernel/smp_tlb.c +++ b/trunk/arch/arm/kernel/smp_tlb.c @@ -98,21 +98,21 @@ static void broadcast_tlb_a15_erratum(void) return; dummy_flush_tlb_a15_erratum(); - smp_call_function_many(cpu_online_mask, ipi_flush_tlb_a15_erratum, - NULL, 1); + smp_call_function(ipi_flush_tlb_a15_erratum, NULL, 1); } static void broadcast_tlb_mm_a15_erratum(struct mm_struct *mm) { - int cpu; + int cpu, this_cpu; cpumask_t mask = { CPU_BITS_NONE }; if (!erratum_a15_798181()) return; dummy_flush_tlb_a15_erratum(); + this_cpu = get_cpu(); for_each_online_cpu(cpu) { - if (cpu == smp_processor_id()) + if (cpu == this_cpu) continue; /* * We only need to send an IPI if the other CPUs are running @@ -127,6 +127,7 @@ static void broadcast_tlb_mm_a15_erratum(struct mm_struct *mm) cpumask_set_cpu(cpu, &mask); } smp_call_function_many(&mask, ipi_flush_tlb_a15_erratum, NULL, 1); + put_cpu(); } void flush_tlb_all(void) diff --git a/trunk/arch/arm/kernel/swp_emulate.c b/trunk/arch/arm/kernel/swp_emulate.c index 087fc321e9e5..b1b89882b113 100644 --- a/trunk/arch/arm/kernel/swp_emulate.c +++ b/trunk/arch/arm/kernel/swp_emulate.c @@ -99,7 +99,7 @@ static const struct file_operations proc_status_fops = { .open = proc_status_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = single_release, }; #endif diff --git a/trunk/arch/arm/kernel/time.c b/trunk/arch/arm/kernel/time.c index 955d92d265e5..abff4e9aaee0 100644 --- a/trunk/arch/arm/kernel/time.c +++ b/trunk/arch/arm/kernel/time.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -115,6 +116,10 @@ int __init register_persistent_clock(clock_access_fn read_boot, void __init time_init(void) { - machine_desc->init_time(); + if (machine_desc->init_time) + machine_desc->init_time(); + else + clocksource_of_init(); + sched_clock_postinit(); } diff --git a/trunk/arch/arm/kernel/vmlinux.lds.S b/trunk/arch/arm/kernel/vmlinux.lds.S index b571484e9f03..a871b8e00fca 100644 --- a/trunk/arch/arm/kernel/vmlinux.lds.S +++ b/trunk/arch/arm/kernel/vmlinux.lds.S @@ -20,7 +20,7 @@ VMLINUX_SYMBOL(__idmap_text_start) = .; \ *(.idmap.text) \ VMLINUX_SYMBOL(__idmap_text_end) = .; \ - ALIGN_FUNCTION(); \ + . = ALIGN(32); \ VMLINUX_SYMBOL(__hyp_idmap_text_start) = .; \ *(.hyp.idmap.text) \ VMLINUX_SYMBOL(__hyp_idmap_text_end) = .; @@ -315,3 +315,8 @@ SECTIONS */ ASSERT((__proc_info_end - __proc_info_begin), "missing CPU support") ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined") +/* + * The HYP init code can't be more than a page long. + * The above comment applies as well. + */ +ASSERT(((__hyp_idmap_text_end - __hyp_idmap_text_start) <= PAGE_SIZE), "HYP init code too big") diff --git a/trunk/arch/arm/kvm/Kconfig b/trunk/arch/arm/kvm/Kconfig index 49dd64e579c2..370e1a8af6ac 100644 --- a/trunk/arch/arm/kvm/Kconfig +++ b/trunk/arch/arm/kvm/Kconfig @@ -41,9 +41,9 @@ config KVM_ARM_HOST Provides host support for ARM processors. config KVM_ARM_MAX_VCPUS - int "Number maximum supported virtual CPUs per VM" - depends on KVM_ARM_HOST - default 4 + int "Number maximum supported virtual CPUs per VM" if KVM_ARM_HOST + default 4 if KVM_ARM_HOST + default 0 help Static number of max supported virtual CPUs per VM. diff --git a/trunk/arch/arm/kvm/Makefile b/trunk/arch/arm/kvm/Makefile index fc96ce6f2357..53c5ed83d16f 100644 --- a/trunk/arch/arm/kvm/Makefile +++ b/trunk/arch/arm/kvm/Makefile @@ -17,7 +17,7 @@ AFLAGS_interrupts.o := -Wa,-march=armv7-a$(plus_virt) kvm-arm-y = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o) obj-y += kvm-arm.o init.o interrupts.o -obj-y += arm.o guest.o mmu.o emulate.o reset.o -obj-y += coproc.o coproc_a15.o mmio.o psci.o +obj-y += arm.o handle_exit.o guest.o mmu.o emulate.o reset.o +obj-y += coproc.o coproc_a15.o mmio.o psci.o perf.o obj-$(CONFIG_KVM_ARM_VGIC) += vgic.o obj-$(CONFIG_KVM_ARM_TIMER) += arch_timer.o diff --git a/trunk/arch/arm/kvm/arch_timer.c b/trunk/arch/arm/kvm/arch_timer.c index 6ac938d46297..c55b6089e923 100644 --- a/trunk/arch/arm/kvm/arch_timer.c +++ b/trunk/arch/arm/kvm/arch_timer.c @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -64,7 +65,7 @@ static void kvm_timer_inject_irq(struct kvm_vcpu *vcpu) { struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; - timer->cntv_ctl |= 1 << 1; /* Mask the interrupt in the guest */ + timer->cntv_ctl |= ARCH_TIMER_CTRL_IT_MASK; kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id, vcpu->arch.timer_cpu.irq->irq, vcpu->arch.timer_cpu.irq->level); @@ -133,8 +134,8 @@ void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu) cycle_t cval, now; u64 ns; - /* Check if the timer is enabled and unmasked first */ - if ((timer->cntv_ctl & 3) != 1) + if ((timer->cntv_ctl & ARCH_TIMER_CTRL_IT_MASK) || + !(timer->cntv_ctl & ARCH_TIMER_CTRL_ENABLE)) return; cval = timer->cntv_cval; diff --git a/trunk/arch/arm/kvm/arm.c b/trunk/arch/arm/kvm/arm.c index 842098d78f58..37d216d814cd 100644 --- a/trunk/arch/arm/kvm/arm.c +++ b/trunk/arch/arm/kvm/arm.c @@ -16,6 +16,7 @@ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include #include #include #include @@ -30,11 +31,9 @@ #define CREATE_TRACE_POINTS #include "trace.h" -#include #include #include #include -#include #include #include #include @@ -44,14 +43,13 @@ #include #include #include -#include #ifdef REQUIRES_VIRT __asm__(".arch_extension virt"); #endif static DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_page); -static struct vfp_hard_struct __percpu *kvm_host_vfp_state; +static kvm_cpu_context_t __percpu *kvm_host_cpu_state; static unsigned long hyp_default_vectors; /* Per-CPU variable containing the currently running vcpu. */ @@ -209,7 +207,7 @@ int kvm_dev_ioctl_check_extension(long ext) r = KVM_MAX_VCPUS; break; default: - r = 0; + r = kvm_arch_dev_ioctl_check_extension(ext); break; } return r; @@ -221,27 +219,18 @@ long kvm_arch_dev_ioctl(struct file *filp, return -EINVAL; } -int kvm_arch_set_memory_region(struct kvm *kvm, - struct kvm_userspace_memory_region *mem, - struct kvm_memory_slot old, - int user_alloc) -{ - return 0; -} - int kvm_arch_prepare_memory_region(struct kvm *kvm, struct kvm_memory_slot *memslot, - struct kvm_memory_slot old, struct kvm_userspace_memory_region *mem, - bool user_alloc) + enum kvm_mr_change change) { return 0; } void kvm_arch_commit_memory_region(struct kvm *kvm, struct kvm_userspace_memory_region *mem, - struct kvm_memory_slot old, - bool user_alloc) + const struct kvm_memory_slot *old, + enum kvm_mr_change change) { } @@ -304,22 +293,6 @@ int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) return 0; } -int __attribute_const__ kvm_target_cpu(void) -{ - unsigned long implementor = read_cpuid_implementor(); - unsigned long part_number = read_cpuid_part_number(); - - if (implementor != ARM_CPU_IMP_ARM) - return -EINVAL; - - switch (part_number) { - case ARM_CPU_PART_CORTEX_A15: - return KVM_ARM_TARGET_CORTEX_A15; - default: - return -EINVAL; - } -} - int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) { int ret; @@ -345,7 +318,7 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) { vcpu->cpu = cpu; - vcpu->arch.vfp_host = this_cpu_ptr(kvm_host_vfp_state); + vcpu->arch.host_cpu_context = this_cpu_ptr(kvm_host_cpu_state); /* * Check whether this vcpu requires the cache to be flushed on @@ -482,163 +455,6 @@ static void update_vttbr(struct kvm *kvm) spin_unlock(&kvm_vmid_lock); } -static int handle_svc_hyp(struct kvm_vcpu *vcpu, struct kvm_run *run) -{ - /* SVC called from Hyp mode should never get here */ - kvm_debug("SVC called from Hyp mode shouldn't go here\n"); - BUG(); - return -EINVAL; /* Squash warning */ -} - -static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run) -{ - trace_kvm_hvc(*vcpu_pc(vcpu), *vcpu_reg(vcpu, 0), - vcpu->arch.hsr & HSR_HVC_IMM_MASK); - - if (kvm_psci_call(vcpu)) - return 1; - - kvm_inject_undefined(vcpu); - return 1; -} - -static int handle_smc(struct kvm_vcpu *vcpu, struct kvm_run *run) -{ - if (kvm_psci_call(vcpu)) - return 1; - - kvm_inject_undefined(vcpu); - return 1; -} - -static int handle_pabt_hyp(struct kvm_vcpu *vcpu, struct kvm_run *run) -{ - /* The hypervisor should never cause aborts */ - kvm_err("Prefetch Abort taken from Hyp mode at %#08x (HSR: %#08x)\n", - vcpu->arch.hxfar, vcpu->arch.hsr); - return -EFAULT; -} - -static int handle_dabt_hyp(struct kvm_vcpu *vcpu, struct kvm_run *run) -{ - /* This is either an error in the ws. code or an external abort */ - kvm_err("Data Abort taken from Hyp mode at %#08x (HSR: %#08x)\n", - vcpu->arch.hxfar, vcpu->arch.hsr); - return -EFAULT; -} - -typedef int (*exit_handle_fn)(struct kvm_vcpu *, struct kvm_run *); -static exit_handle_fn arm_exit_handlers[] = { - [HSR_EC_WFI] = kvm_handle_wfi, - [HSR_EC_CP15_32] = kvm_handle_cp15_32, - [HSR_EC_CP15_64] = kvm_handle_cp15_64, - [HSR_EC_CP14_MR] = kvm_handle_cp14_access, - [HSR_EC_CP14_LS] = kvm_handle_cp14_load_store, - [HSR_EC_CP14_64] = kvm_handle_cp14_access, - [HSR_EC_CP_0_13] = kvm_handle_cp_0_13_access, - [HSR_EC_CP10_ID] = kvm_handle_cp10_id, - [HSR_EC_SVC_HYP] = handle_svc_hyp, - [HSR_EC_HVC] = handle_hvc, - [HSR_EC_SMC] = handle_smc, - [HSR_EC_IABT] = kvm_handle_guest_abort, - [HSR_EC_IABT_HYP] = handle_pabt_hyp, - [HSR_EC_DABT] = kvm_handle_guest_abort, - [HSR_EC_DABT_HYP] = handle_dabt_hyp, -}; - -/* - * A conditional instruction is allowed to trap, even though it - * wouldn't be executed. So let's re-implement the hardware, in - * software! - */ -static bool kvm_condition_valid(struct kvm_vcpu *vcpu) -{ - unsigned long cpsr, cond, insn; - - /* - * Exception Code 0 can only happen if we set HCR.TGE to 1, to - * catch undefined instructions, and then we won't get past - * the arm_exit_handlers test anyway. - */ - BUG_ON(((vcpu->arch.hsr & HSR_EC) >> HSR_EC_SHIFT) == 0); - - /* Top two bits non-zero? Unconditional. */ - if (vcpu->arch.hsr >> 30) - return true; - - cpsr = *vcpu_cpsr(vcpu); - - /* Is condition field valid? */ - if ((vcpu->arch.hsr & HSR_CV) >> HSR_CV_SHIFT) - cond = (vcpu->arch.hsr & HSR_COND) >> HSR_COND_SHIFT; - else { - /* This can happen in Thumb mode: examine IT state. */ - unsigned long it; - - it = ((cpsr >> 8) & 0xFC) | ((cpsr >> 25) & 0x3); - - /* it == 0 => unconditional. */ - if (it == 0) - return true; - - /* The cond for this insn works out as the top 4 bits. */ - cond = (it >> 4); - } - - /* Shift makes it look like an ARM-mode instruction */ - insn = cond << 28; - return arm_check_condition(insn, cpsr) != ARM_OPCODE_CONDTEST_FAIL; -} - -/* - * Return > 0 to return to guest, < 0 on error, 0 (and set exit_reason) on - * proper exit to QEMU. - */ -static int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run, - int exception_index) -{ - unsigned long hsr_ec; - - switch (exception_index) { - case ARM_EXCEPTION_IRQ: - return 1; - case ARM_EXCEPTION_UNDEFINED: - kvm_err("Undefined exception in Hyp mode at: %#08x\n", - vcpu->arch.hyp_pc); - BUG(); - panic("KVM: Hypervisor undefined exception!\n"); - case ARM_EXCEPTION_DATA_ABORT: - case ARM_EXCEPTION_PREF_ABORT: - case ARM_EXCEPTION_HVC: - hsr_ec = (vcpu->arch.hsr & HSR_EC) >> HSR_EC_SHIFT; - - if (hsr_ec >= ARRAY_SIZE(arm_exit_handlers) - || !arm_exit_handlers[hsr_ec]) { - kvm_err("Unknown exception class: %#08lx, " - "hsr: %#08x\n", hsr_ec, - (unsigned int)vcpu->arch.hsr); - BUG(); - } - - /* - * See ARM ARM B1.14.1: "Hyp traps on instructions - * that fail their condition code check" - */ - if (!kvm_condition_valid(vcpu)) { - bool is_wide = vcpu->arch.hsr & HSR_IL; - kvm_skip_instr(vcpu, is_wide); - return 1; - } - - return arm_exit_handlers[hsr_ec](vcpu, run); - default: - kvm_pr_unimpl("Unsupported exception type: %d", - exception_index); - run->exit_reason = KVM_EXIT_INTERNAL_ERROR; - return 0; - } -} - static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu) { if (likely(vcpu->arch.has_run_once)) @@ -815,7 +631,8 @@ static int vcpu_interrupt_line(struct kvm_vcpu *vcpu, int number, bool level) return 0; } -int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_level) +int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_level, + bool line_status) { u32 irq = irq_level->irq; unsigned int irq_type, vcpu_idx, irq_num; @@ -970,40 +787,48 @@ long kvm_arch_vm_ioctl(struct file *filp, } } -static void cpu_init_hyp_mode(void *vector) +static void cpu_init_hyp_mode(void *dummy) { + unsigned long long boot_pgd_ptr; unsigned long long pgd_ptr; - unsigned long pgd_low, pgd_high; unsigned long hyp_stack_ptr; unsigned long stack_page; unsigned long vector_ptr; /* Switch from the HYP stub to our own HYP init vector */ - __hyp_set_vectors((unsigned long)vector); + __hyp_set_vectors(kvm_get_idmap_vector()); + boot_pgd_ptr = (unsigned long long)kvm_mmu_get_boot_httbr(); pgd_ptr = (unsigned long long)kvm_mmu_get_httbr(); - pgd_low = (pgd_ptr & ((1ULL << 32) - 1)); - pgd_high = (pgd_ptr >> 32ULL); stack_page = __get_cpu_var(kvm_arm_hyp_stack_page); hyp_stack_ptr = stack_page + PAGE_SIZE; vector_ptr = (unsigned long)__kvm_hyp_vector; - /* - * Call initialization code, and switch to the full blown - * HYP code. The init code doesn't need to preserve these registers as - * r1-r3 and r12 are already callee save according to the AAPCS. - * Note that we slightly misuse the prototype by casing the pgd_low to - * a void *. - */ - kvm_call_hyp((void *)pgd_low, pgd_high, hyp_stack_ptr, vector_ptr); + __cpu_init_hyp_mode(boot_pgd_ptr, pgd_ptr, hyp_stack_ptr, vector_ptr); +} + +static int hyp_init_cpu_notify(struct notifier_block *self, + unsigned long action, void *cpu) +{ + switch (action) { + case CPU_STARTING: + case CPU_STARTING_FROZEN: + cpu_init_hyp_mode(NULL); + break; + } + + return NOTIFY_OK; } +static struct notifier_block hyp_init_cpu_nb = { + .notifier_call = hyp_init_cpu_notify, +}; + /** * Inits Hyp-mode on all online CPUs */ static int init_hyp_mode(void) { - phys_addr_t init_phys_addr; int cpu; int err = 0; @@ -1035,24 +860,6 @@ static int init_hyp_mode(void) per_cpu(kvm_arm_hyp_stack_page, cpu) = stack_page; } - /* - * Execute the init code on each CPU. - * - * Note: The stack is not mapped yet, so don't do anything else than - * initializing the hypervisor mode on each CPU using a local stack - * space for temporary storage. - */ - init_phys_addr = virt_to_phys(__kvm_hyp_init); - for_each_online_cpu(cpu) { - smp_call_function_single(cpu, cpu_init_hyp_mode, - (void *)(long)init_phys_addr, 1); - } - - /* - * Unmap the identity mapping - */ - kvm_clear_hyp_idmap(); - /* * Map the Hyp-code called directly from the host */ @@ -1076,33 +883,38 @@ static int init_hyp_mode(void) } /* - * Map the host VFP structures + * Map the host CPU structures */ - kvm_host_vfp_state = alloc_percpu(struct vfp_hard_struct); - if (!kvm_host_vfp_state) { + kvm_host_cpu_state = alloc_percpu(kvm_cpu_context_t); + if (!kvm_host_cpu_state) { err = -ENOMEM; - kvm_err("Cannot allocate host VFP state\n"); + kvm_err("Cannot allocate host CPU state\n"); goto out_free_mappings; } for_each_possible_cpu(cpu) { - struct vfp_hard_struct *vfp; + kvm_cpu_context_t *cpu_ctxt; - vfp = per_cpu_ptr(kvm_host_vfp_state, cpu); - err = create_hyp_mappings(vfp, vfp + 1); + cpu_ctxt = per_cpu_ptr(kvm_host_cpu_state, cpu); + err = create_hyp_mappings(cpu_ctxt, cpu_ctxt + 1); if (err) { - kvm_err("Cannot map host VFP state: %d\n", err); - goto out_free_vfp; + kvm_err("Cannot map host CPU state: %d\n", err); + goto out_free_context; } } + /* + * Execute the init code on each CPU. + */ + on_each_cpu(cpu_init_hyp_mode, NULL, 1); + /* * Init HYP view of VGIC */ err = kvm_vgic_hyp_init(); if (err) - goto out_free_vfp; + goto out_free_context; #ifdef CONFIG_KVM_ARM_VGIC vgic_present = true; @@ -1115,12 +927,19 @@ static int init_hyp_mode(void) if (err) goto out_free_mappings; +#ifndef CONFIG_HOTPLUG_CPU + free_boot_hyp_pgd(); +#endif + + kvm_perf_init(); + kvm_info("Hyp mode initialized successfully\n"); + return 0; -out_free_vfp: - free_percpu(kvm_host_vfp_state); +out_free_context: + free_percpu(kvm_host_cpu_state); out_free_mappings: - free_hyp_pmds(); + free_hyp_pgds(); out_free_stack_pages: for_each_possible_cpu(cpu) free_page(per_cpu(kvm_arm_hyp_stack_page, cpu)); @@ -1129,27 +948,42 @@ static int init_hyp_mode(void) return err; } +static void check_kvm_target_cpu(void *ret) +{ + *(int *)ret = kvm_target_cpu(); +} + /** * Initialize Hyp-mode and memory mappings on all CPUs. */ int kvm_arch_init(void *opaque) { int err; + int ret, cpu; if (!is_hyp_mode_available()) { kvm_err("HYP mode not available\n"); return -ENODEV; } - if (kvm_target_cpu() < 0) { - kvm_err("Target CPU not supported!\n"); - return -ENODEV; + for_each_online_cpu(cpu) { + smp_call_function_single(cpu, check_kvm_target_cpu, &ret, 1); + if (ret < 0) { + kvm_err("Error, CPU %d not supported!\n", cpu); + return -ENODEV; + } } err = init_hyp_mode(); if (err) goto out_err; + err = register_cpu_notifier(&hyp_init_cpu_nb); + if (err) { + kvm_err("Cannot register HYP init CPU notifier (%d)\n", err); + goto out_err; + } + kvm_coproc_table_init(); return 0; out_err: @@ -1159,6 +993,7 @@ int kvm_arch_init(void *opaque) /* NOP: Compiling as a module not supported */ void kvm_arch_exit(void) { + kvm_perf_teardown(); } static int arm_init(void) diff --git a/trunk/arch/arm/kvm/coproc.c b/trunk/arch/arm/kvm/coproc.c index 7bed7556077a..8eea97be1ed5 100644 --- a/trunk/arch/arm/kvm/coproc.c +++ b/trunk/arch/arm/kvm/coproc.c @@ -76,7 +76,7 @@ static bool access_dcsw(struct kvm_vcpu *vcpu, const struct coproc_params *p, const struct coproc_reg *r) { - u32 val; + unsigned long val; int cpu; if (!p->is_write) @@ -293,12 +293,12 @@ static int emulate_cp15(struct kvm_vcpu *vcpu, if (likely(r->access(vcpu, params, r))) { /* Skip instruction, since it was emulated */ - kvm_skip_instr(vcpu, (vcpu->arch.hsr >> 25) & 1); + kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); return 1; } /* If access function fails, it should complain. */ } else { - kvm_err("Unsupported guest CP15 access at: %08x\n", + kvm_err("Unsupported guest CP15 access at: %08lx\n", *vcpu_pc(vcpu)); print_cp_instr(params); } @@ -315,14 +315,14 @@ int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run) { struct coproc_params params; - params.CRm = (vcpu->arch.hsr >> 1) & 0xf; - params.Rt1 = (vcpu->arch.hsr >> 5) & 0xf; - params.is_write = ((vcpu->arch.hsr & 1) == 0); + params.CRm = (kvm_vcpu_get_hsr(vcpu) >> 1) & 0xf; + params.Rt1 = (kvm_vcpu_get_hsr(vcpu) >> 5) & 0xf; + params.is_write = ((kvm_vcpu_get_hsr(vcpu) & 1) == 0); params.is_64bit = true; - params.Op1 = (vcpu->arch.hsr >> 16) & 0xf; + params.Op1 = (kvm_vcpu_get_hsr(vcpu) >> 16) & 0xf; params.Op2 = 0; - params.Rt2 = (vcpu->arch.hsr >> 10) & 0xf; + params.Rt2 = (kvm_vcpu_get_hsr(vcpu) >> 10) & 0xf; params.CRn = 0; return emulate_cp15(vcpu, ¶ms); @@ -347,14 +347,14 @@ int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run) { struct coproc_params params; - params.CRm = (vcpu->arch.hsr >> 1) & 0xf; - params.Rt1 = (vcpu->arch.hsr >> 5) & 0xf; - params.is_write = ((vcpu->arch.hsr & 1) == 0); + params.CRm = (kvm_vcpu_get_hsr(vcpu) >> 1) & 0xf; + params.Rt1 = (kvm_vcpu_get_hsr(vcpu) >> 5) & 0xf; + params.is_write = ((kvm_vcpu_get_hsr(vcpu) & 1) == 0); params.is_64bit = false; - params.CRn = (vcpu->arch.hsr >> 10) & 0xf; - params.Op1 = (vcpu->arch.hsr >> 14) & 0x7; - params.Op2 = (vcpu->arch.hsr >> 17) & 0x7; + params.CRn = (kvm_vcpu_get_hsr(vcpu) >> 10) & 0xf; + params.Op1 = (kvm_vcpu_get_hsr(vcpu) >> 14) & 0x7; + params.Op2 = (kvm_vcpu_get_hsr(vcpu) >> 17) & 0x7; params.Rt2 = 0; return emulate_cp15(vcpu, ¶ms); diff --git a/trunk/arch/arm/kvm/coproc.h b/trunk/arch/arm/kvm/coproc.h index 992adfafa2ff..b7301d3e4799 100644 --- a/trunk/arch/arm/kvm/coproc.h +++ b/trunk/arch/arm/kvm/coproc.h @@ -84,7 +84,7 @@ static inline bool read_zero(struct kvm_vcpu *vcpu, static inline bool write_to_read_only(struct kvm_vcpu *vcpu, const struct coproc_params *params) { - kvm_debug("CP15 write to read-only register at: %08x\n", + kvm_debug("CP15 write to read-only register at: %08lx\n", *vcpu_pc(vcpu)); print_cp_instr(params); return false; @@ -93,7 +93,7 @@ static inline bool write_to_read_only(struct kvm_vcpu *vcpu, static inline bool read_from_write_only(struct kvm_vcpu *vcpu, const struct coproc_params *params) { - kvm_debug("CP15 read to write-only register at: %08x\n", + kvm_debug("CP15 read to write-only register at: %08lx\n", *vcpu_pc(vcpu)); print_cp_instr(params); return false; diff --git a/trunk/arch/arm/kvm/emulate.c b/trunk/arch/arm/kvm/emulate.c index d61450ac6665..bdede9e7da51 100644 --- a/trunk/arch/arm/kvm/emulate.c +++ b/trunk/arch/arm/kvm/emulate.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include "trace.h" @@ -109,10 +110,10 @@ static const unsigned long vcpu_reg_offsets[VCPU_NR_MODES][15] = { * Return a pointer to the register number valid in the current mode of * the virtual CPU. */ -u32 *vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num) +unsigned long *vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num) { - u32 *reg_array = (u32 *)&vcpu->arch.regs; - u32 mode = *vcpu_cpsr(vcpu) & MODE_MASK; + unsigned long *reg_array = (unsigned long *)&vcpu->arch.regs; + unsigned long mode = *vcpu_cpsr(vcpu) & MODE_MASK; switch (mode) { case USR_MODE...SVC_MODE: @@ -141,9 +142,9 @@ u32 *vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num) /* * Return the SPSR for the current mode of the virtual CPU. */ -u32 *vcpu_spsr(struct kvm_vcpu *vcpu) +unsigned long *vcpu_spsr(struct kvm_vcpu *vcpu) { - u32 mode = *vcpu_cpsr(vcpu) & MODE_MASK; + unsigned long mode = *vcpu_cpsr(vcpu) & MODE_MASK; switch (mode) { case SVC_MODE: return &vcpu->arch.regs.KVM_ARM_SVC_spsr; @@ -160,20 +161,48 @@ u32 *vcpu_spsr(struct kvm_vcpu *vcpu) } } -/** - * kvm_handle_wfi - handle a wait-for-interrupts instruction executed by a guest - * @vcpu: the vcpu pointer - * @run: the kvm_run structure pointer - * - * Simply sets the wait_for_interrupts flag on the vcpu structure, which will - * halt execution of world-switches and schedule other host processes until - * there is an incoming IRQ or FIQ to the VM. +/* + * A conditional instruction is allowed to trap, even though it + * wouldn't be executed. So let's re-implement the hardware, in + * software! */ -int kvm_handle_wfi(struct kvm_vcpu *vcpu, struct kvm_run *run) +bool kvm_condition_valid(struct kvm_vcpu *vcpu) { - trace_kvm_wfi(*vcpu_pc(vcpu)); - kvm_vcpu_block(vcpu); - return 1; + unsigned long cpsr, cond, insn; + + /* + * Exception Code 0 can only happen if we set HCR.TGE to 1, to + * catch undefined instructions, and then we won't get past + * the arm_exit_handlers test anyway. + */ + BUG_ON(!kvm_vcpu_trap_get_class(vcpu)); + + /* Top two bits non-zero? Unconditional. */ + if (kvm_vcpu_get_hsr(vcpu) >> 30) + return true; + + cpsr = *vcpu_cpsr(vcpu); + + /* Is condition field valid? */ + if ((kvm_vcpu_get_hsr(vcpu) & HSR_CV) >> HSR_CV_SHIFT) + cond = (kvm_vcpu_get_hsr(vcpu) & HSR_COND) >> HSR_COND_SHIFT; + else { + /* This can happen in Thumb mode: examine IT state. */ + unsigned long it; + + it = ((cpsr >> 8) & 0xFC) | ((cpsr >> 25) & 0x3); + + /* it == 0 => unconditional. */ + if (it == 0) + return true; + + /* The cond for this insn works out as the top 4 bits. */ + cond = (it >> 4); + } + + /* Shift makes it look like an ARM-mode instruction */ + insn = cond << 28; + return arm_check_condition(insn, cpsr) != ARM_OPCODE_CONDTEST_FAIL; } /** @@ -257,9 +286,9 @@ static u32 exc_vector_base(struct kvm_vcpu *vcpu) */ void kvm_inject_undefined(struct kvm_vcpu *vcpu) { - u32 new_lr_value; - u32 new_spsr_value; - u32 cpsr = *vcpu_cpsr(vcpu); + unsigned long new_lr_value; + unsigned long new_spsr_value; + unsigned long cpsr = *vcpu_cpsr(vcpu); u32 sctlr = vcpu->arch.cp15[c1_SCTLR]; bool is_thumb = (cpsr & PSR_T_BIT); u32 vect_offset = 4; @@ -291,9 +320,9 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu) */ static void inject_abt(struct kvm_vcpu *vcpu, bool is_pabt, unsigned long addr) { - u32 new_lr_value; - u32 new_spsr_value; - u32 cpsr = *vcpu_cpsr(vcpu); + unsigned long new_lr_value; + unsigned long new_spsr_value; + unsigned long cpsr = *vcpu_cpsr(vcpu); u32 sctlr = vcpu->arch.cp15[c1_SCTLR]; bool is_thumb = (cpsr & PSR_T_BIT); u32 vect_offset; diff --git a/trunk/arch/arm/kvm/guest.c b/trunk/arch/arm/kvm/guest.c index 2339d9609d36..152d03612181 100644 --- a/trunk/arch/arm/kvm/guest.c +++ b/trunk/arch/arm/kvm/guest.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -180,6 +181,22 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, return -EINVAL; } +int __attribute_const__ kvm_target_cpu(void) +{ + unsigned long implementor = read_cpuid_implementor(); + unsigned long part_number = read_cpuid_part_number(); + + if (implementor != ARM_CPU_IMP_ARM) + return -EINVAL; + + switch (part_number) { + case ARM_CPU_PART_CORTEX_A15: + return KVM_ARM_TARGET_CORTEX_A15; + default: + return -EINVAL; + } +} + int kvm_vcpu_set_target(struct kvm_vcpu *vcpu, const struct kvm_vcpu_init *init) { diff --git a/trunk/arch/arm/kvm/handle_exit.c b/trunk/arch/arm/kvm/handle_exit.c new file mode 100644 index 000000000000..3d74a0be47db --- /dev/null +++ b/trunk/arch/arm/kvm/handle_exit.c @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2012 - Virtual Open Systems and Columbia University + * Author: Christoffer Dall + * + * 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. + * + * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "trace.h" + +#include "trace.h" + +typedef int (*exit_handle_fn)(struct kvm_vcpu *, struct kvm_run *); + +static int handle_svc_hyp(struct kvm_vcpu *vcpu, struct kvm_run *run) +{ + /* SVC called from Hyp mode should never get here */ + kvm_debug("SVC called from Hyp mode shouldn't go here\n"); + BUG(); + return -EINVAL; /* Squash warning */ +} + +static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run) +{ + trace_kvm_hvc(*vcpu_pc(vcpu), *vcpu_reg(vcpu, 0), + kvm_vcpu_hvc_get_imm(vcpu)); + + if (kvm_psci_call(vcpu)) + return 1; + + kvm_inject_undefined(vcpu); + return 1; +} + +static int handle_smc(struct kvm_vcpu *vcpu, struct kvm_run *run) +{ + if (kvm_psci_call(vcpu)) + return 1; + + kvm_inject_undefined(vcpu); + return 1; +} + +static int handle_pabt_hyp(struct kvm_vcpu *vcpu, struct kvm_run *run) +{ + /* The hypervisor should never cause aborts */ + kvm_err("Prefetch Abort taken from Hyp mode at %#08lx (HSR: %#08x)\n", + kvm_vcpu_get_hfar(vcpu), kvm_vcpu_get_hsr(vcpu)); + return -EFAULT; +} + +static int handle_dabt_hyp(struct kvm_vcpu *vcpu, struct kvm_run *run) +{ + /* This is either an error in the ws. code or an external abort */ + kvm_err("Data Abort taken from Hyp mode at %#08lx (HSR: %#08x)\n", + kvm_vcpu_get_hfar(vcpu), kvm_vcpu_get_hsr(vcpu)); + return -EFAULT; +} + +/** + * kvm_handle_wfi - handle a wait-for-interrupts instruction executed by a guest + * @vcpu: the vcpu pointer + * @run: the kvm_run structure pointer + * + * Simply sets the wait_for_interrupts flag on the vcpu structure, which will + * halt execution of world-switches and schedule other host processes until + * there is an incoming IRQ or FIQ to the VM. + */ +static int kvm_handle_wfi(struct kvm_vcpu *vcpu, struct kvm_run *run) +{ + trace_kvm_wfi(*vcpu_pc(vcpu)); + kvm_vcpu_block(vcpu); + return 1; +} + +static exit_handle_fn arm_exit_handlers[] = { + [HSR_EC_WFI] = kvm_handle_wfi, + [HSR_EC_CP15_32] = kvm_handle_cp15_32, + [HSR_EC_CP15_64] = kvm_handle_cp15_64, + [HSR_EC_CP14_MR] = kvm_handle_cp14_access, + [HSR_EC_CP14_LS] = kvm_handle_cp14_load_store, + [HSR_EC_CP14_64] = kvm_handle_cp14_access, + [HSR_EC_CP_0_13] = kvm_handle_cp_0_13_access, + [HSR_EC_CP10_ID] = kvm_handle_cp10_id, + [HSR_EC_SVC_HYP] = handle_svc_hyp, + [HSR_EC_HVC] = handle_hvc, + [HSR_EC_SMC] = handle_smc, + [HSR_EC_IABT] = kvm_handle_guest_abort, + [HSR_EC_IABT_HYP] = handle_pabt_hyp, + [HSR_EC_DABT] = kvm_handle_guest_abort, + [HSR_EC_DABT_HYP] = handle_dabt_hyp, +}; + +static exit_handle_fn kvm_get_exit_handler(struct kvm_vcpu *vcpu) +{ + u8 hsr_ec = kvm_vcpu_trap_get_class(vcpu); + + if (hsr_ec >= ARRAY_SIZE(arm_exit_handlers) || + !arm_exit_handlers[hsr_ec]) { + kvm_err("Unknown exception class: hsr: %#08x\n", + (unsigned int)kvm_vcpu_get_hsr(vcpu)); + BUG(); + } + + return arm_exit_handlers[hsr_ec]; +} + +/* + * Return > 0 to return to guest, < 0 on error, 0 (and set exit_reason) on + * proper exit to userspace. + */ +int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run, + int exception_index) +{ + exit_handle_fn exit_handler; + + switch (exception_index) { + case ARM_EXCEPTION_IRQ: + return 1; + case ARM_EXCEPTION_UNDEFINED: + kvm_err("Undefined exception in Hyp mode at: %#08lx\n", + kvm_vcpu_get_hyp_pc(vcpu)); + BUG(); + panic("KVM: Hypervisor undefined exception!\n"); + case ARM_EXCEPTION_DATA_ABORT: + case ARM_EXCEPTION_PREF_ABORT: + case ARM_EXCEPTION_HVC: + /* + * See ARM ARM B1.14.1: "Hyp traps on instructions + * that fail their condition code check" + */ + if (!kvm_condition_valid(vcpu)) { + kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); + return 1; + } + + exit_handler = kvm_get_exit_handler(vcpu); + + return exit_handler(vcpu, run); + default: + kvm_pr_unimpl("Unsupported exception type: %d", + exception_index); + run->exit_reason = KVM_EXIT_INTERNAL_ERROR; + return 0; + } +} diff --git a/trunk/arch/arm/kvm/init.S b/trunk/arch/arm/kvm/init.S index 9f37a79b880b..f048338135f7 100644 --- a/trunk/arch/arm/kvm/init.S +++ b/trunk/arch/arm/kvm/init.S @@ -21,13 +21,33 @@ #include #include #include +#include /******************************************************************** * Hypervisor initialization * - should be called with: - * r0,r1 = Hypervisor pgd pointer - * r2 = top of Hyp stack (kernel VA) - * r3 = pointer to hyp vectors + * r0 = top of Hyp stack (kernel VA) + * r1 = pointer to hyp vectors + * r2,r3 = Hypervisor pgd pointer + * + * The init scenario is: + * - We jump in HYP with four parameters: boot HYP pgd, runtime HYP pgd, + * runtime stack, runtime vectors + * - Enable the MMU with the boot pgd + * - Jump to a target into the trampoline page (remember, this is the same + * physical page!) + * - Now switch to the runtime pgd (same VA, and still the same physical + * page!) + * - Invalidate TLBs + * - Set stack and vectors + * - Profit! (or eret, if you only care about the code). + * + * As we only have four registers available to pass parameters (and we + * need six), we split the init in two phases: + * - Phase 1: r0 = 0, r1 = 0, r2,r3 contain the boot PGD. + * Provides the basic HYP init, and enable the MMU. + * - Phase 2: r0 = ToS, r1 = vectors, r2,r3 contain the runtime PGD. + * Switches to the runtime PGD, set stack and vectors. */ .text @@ -47,22 +67,25 @@ __kvm_hyp_init: W(b) . __do_hyp_init: + cmp r0, #0 @ We have a SP? + bne phase2 @ Yes, second stage init + @ Set the HTTBR to point to the hypervisor PGD pointer passed - mcrr p15, 4, r0, r1, c2 + mcrr p15, 4, r2, r3, c2 @ Set the HTCR and VTCR to the same shareability and cacheability @ settings as the non-secure TTBCR and with T0SZ == 0. mrc p15, 4, r0, c2, c0, 2 @ HTCR - ldr r12, =HTCR_MASK - bic r0, r0, r12 + ldr r2, =HTCR_MASK + bic r0, r0, r2 mrc p15, 0, r1, c2, c0, 2 @ TTBCR and r1, r1, #(HTCR_MASK & ~TTBCR_T0SZ) orr r0, r0, r1 mcr p15, 4, r0, c2, c0, 2 @ HTCR mrc p15, 4, r1, c2, c1, 2 @ VTCR - ldr r12, =VTCR_MASK - bic r1, r1, r12 + ldr r2, =VTCR_MASK + bic r1, r1, r2 bic r0, r0, #(~VTCR_HTCR_SH) @ clear non-reusable HTCR bits orr r1, r0, r1 orr r1, r1, #(KVM_VTCR_SL0 | KVM_VTCR_T0SZ | KVM_VTCR_S) @@ -85,24 +108,41 @@ __do_hyp_init: @ - Memory alignment checks: enabled @ - MMU: enabled (this code must be run from an identity mapping) mrc p15, 4, r0, c1, c0, 0 @ HSCR - ldr r12, =HSCTLR_MASK - bic r0, r0, r12 + ldr r2, =HSCTLR_MASK + bic r0, r0, r2 mrc p15, 0, r1, c1, c0, 0 @ SCTLR - ldr r12, =(HSCTLR_EE | HSCTLR_FI | HSCTLR_I | HSCTLR_C) - and r1, r1, r12 - ARM( ldr r12, =(HSCTLR_M | HSCTLR_A) ) - THUMB( ldr r12, =(HSCTLR_M | HSCTLR_A | HSCTLR_TE) ) - orr r1, r1, r12 + ldr r2, =(HSCTLR_EE | HSCTLR_FI | HSCTLR_I | HSCTLR_C) + and r1, r1, r2 + ARM( ldr r2, =(HSCTLR_M | HSCTLR_A) ) + THUMB( ldr r2, =(HSCTLR_M | HSCTLR_A | HSCTLR_TE) ) + orr r1, r1, r2 orr r0, r0, r1 isb mcr p15, 4, r0, c1, c0, 0 @ HSCR - isb - @ Set stack pointer and return to the kernel - mov sp, r2 + @ End of init phase-1 + eret + +phase2: + @ Set stack pointer + mov sp, r0 @ Set HVBAR to point to the HYP vectors - mcr p15, 4, r3, c12, c0, 0 @ HVBAR + mcr p15, 4, r1, c12, c0, 0 @ HVBAR + + @ Jump to the trampoline page + ldr r0, =TRAMPOLINE_VA + adr r1, target + bfi r0, r1, #0, #PAGE_SHIFT + mov pc, r0 + +target: @ We're now in the trampoline code, switch page tables + mcrr p15, 4, r2, r3, c2 + isb + + @ Invalidate the old TLBs + mcr p15, 4, r0, c8, c7, 0 @ TLBIALLH + dsb eret diff --git a/trunk/arch/arm/kvm/interrupts.S b/trunk/arch/arm/kvm/interrupts.S index 8ca87ab0919d..f7793df62f58 100644 --- a/trunk/arch/arm/kvm/interrupts.S +++ b/trunk/arch/arm/kvm/interrupts.S @@ -35,15 +35,18 @@ __kvm_hyp_code_start: /******************************************************************** * Flush per-VMID TLBs * - * void __kvm_tlb_flush_vmid(struct kvm *kvm); + * void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa); * * We rely on the hardware to broadcast the TLB invalidation to all CPUs * inside the inner-shareable domain (which is the case for all v7 * implementations). If we come across a non-IS SMP implementation, we'll * have to use an IPI based mechanism. Until then, we stick to the simple * hardware assisted version. + * + * As v7 does not support flushing per IPA, just nuke the whole TLB + * instead, ignoring the ipa value. */ -ENTRY(__kvm_tlb_flush_vmid) +ENTRY(__kvm_tlb_flush_vmid_ipa) push {r2, r3} add r0, r0, #KVM_VTTBR @@ -60,7 +63,7 @@ ENTRY(__kvm_tlb_flush_vmid) pop {r2, r3} bx lr -ENDPROC(__kvm_tlb_flush_vmid) +ENDPROC(__kvm_tlb_flush_vmid_ipa) /******************************************************************** * Flush TLBs and instruction caches of all CPUs inside the inner-shareable @@ -235,9 +238,9 @@ ENTRY(kvm_call_hyp) * instruction is issued since all traps are disabled when running the host * kernel as per the Hyp-mode initialization at boot time. * - * HVC instructions cause a trap to the vector page + offset 0x18 (see hyp_hvc + * HVC instructions cause a trap to the vector page + offset 0x14 (see hyp_hvc * below) when the HVC instruction is called from SVC mode (i.e. a guest or the - * host kernel) and they cause a trap to the vector page + offset 0xc when HVC + * host kernel) and they cause a trap to the vector page + offset 0x8 when HVC * instructions are called from within Hyp-mode. * * Hyp-ABI: Calling HYP-mode functions from host (in SVC mode): diff --git a/trunk/arch/arm/kvm/mmio.c b/trunk/arch/arm/kvm/mmio.c index 98a870ff1a5c..72a12f2171b2 100644 --- a/trunk/arch/arm/kvm/mmio.c +++ b/trunk/arch/arm/kvm/mmio.c @@ -33,16 +33,16 @@ */ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run) { - __u32 *dest; + unsigned long *dest; unsigned int len; int mask; if (!run->mmio.is_write) { dest = vcpu_reg(vcpu, vcpu->arch.mmio_decode.rt); - memset(dest, 0, sizeof(int)); + *dest = 0; len = run->mmio.len; - if (len > 4) + if (len > sizeof(unsigned long)) return -EINVAL; memcpy(dest, run->mmio.data, len); @@ -50,7 +50,8 @@ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run) trace_kvm_mmio(KVM_TRACE_MMIO_READ, len, run->mmio.phys_addr, *((u64 *)run->mmio.data)); - if (vcpu->arch.mmio_decode.sign_extend && len < 4) { + if (vcpu->arch.mmio_decode.sign_extend && + len < sizeof(unsigned long)) { mask = 1U << ((len * 8) - 1); *dest = (*dest ^ mask) - mask; } @@ -65,40 +66,29 @@ static int decode_hsr(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, unsigned long rt, len; bool is_write, sign_extend; - if ((vcpu->arch.hsr >> 8) & 1) { + if (kvm_vcpu_dabt_isextabt(vcpu)) { /* cache operation on I/O addr, tell guest unsupported */ - kvm_inject_dabt(vcpu, vcpu->arch.hxfar); + kvm_inject_dabt(vcpu, kvm_vcpu_get_hfar(vcpu)); return 1; } - if ((vcpu->arch.hsr >> 7) & 1) { + if (kvm_vcpu_dabt_iss1tw(vcpu)) { /* page table accesses IO mem: tell guest to fix its TTBR */ - kvm_inject_dabt(vcpu, vcpu->arch.hxfar); + kvm_inject_dabt(vcpu, kvm_vcpu_get_hfar(vcpu)); return 1; } - switch ((vcpu->arch.hsr >> 22) & 0x3) { - case 0: - len = 1; - break; - case 1: - len = 2; - break; - case 2: - len = 4; - break; - default: - kvm_err("Hardware is weird: SAS 0b11 is reserved\n"); - return -EFAULT; - } + len = kvm_vcpu_dabt_get_as(vcpu); + if (unlikely(len < 0)) + return len; - is_write = vcpu->arch.hsr & HSR_WNR; - sign_extend = vcpu->arch.hsr & HSR_SSE; - rt = (vcpu->arch.hsr & HSR_SRT_MASK) >> HSR_SRT_SHIFT; + is_write = kvm_vcpu_dabt_iswrite(vcpu); + sign_extend = kvm_vcpu_dabt_issext(vcpu); + rt = kvm_vcpu_dabt_get_rd(vcpu); if (kvm_vcpu_reg_is_pc(vcpu, rt)) { /* IO memory trying to read/write pc */ - kvm_inject_pabt(vcpu, vcpu->arch.hxfar); + kvm_inject_pabt(vcpu, kvm_vcpu_get_hfar(vcpu)); return 1; } @@ -112,7 +102,7 @@ static int decode_hsr(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, * The MMIO instruction is emulated and should not be re-executed * in the guest. */ - kvm_skip_instr(vcpu, (vcpu->arch.hsr >> 25) & 1); + kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); return 0; } @@ -130,7 +120,7 @@ int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run, * space do its magic. */ - if (vcpu->arch.hsr & HSR_ISV) { + if (kvm_vcpu_dabt_isvalid(vcpu)) { ret = decode_hsr(vcpu, fault_ipa, &mmio); if (ret) return ret; diff --git a/trunk/arch/arm/kvm/mmu.c b/trunk/arch/arm/kvm/mmu.c index 99e07c7dd745..965706578f13 100644 --- a/trunk/arch/arm/kvm/mmu.c +++ b/trunk/arch/arm/kvm/mmu.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -28,28 +27,23 @@ #include #include #include -#include -#include #include "trace.h" extern char __hyp_idmap_text_start[], __hyp_idmap_text_end[]; +static pgd_t *boot_hyp_pgd; +static pgd_t *hyp_pgd; static DEFINE_MUTEX(kvm_hyp_pgd_mutex); -static void kvm_tlb_flush_vmid(struct kvm *kvm) -{ - kvm_call_hyp(__kvm_tlb_flush_vmid, kvm); -} +static void *init_bounce_page; +static unsigned long hyp_idmap_start; +static unsigned long hyp_idmap_end; +static phys_addr_t hyp_idmap_vector; -static void kvm_set_pte(pte_t *pte, pte_t new_pte) +static void kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa) { - pte_val(*pte) = new_pte; - /* - * flush_pmd_entry just takes a void pointer and cleans the necessary - * cache entries, so we can reuse the function for ptes. - */ - flush_pmd_entry(pte); + kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, kvm, ipa); } static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache, @@ -84,88 +78,165 @@ static void *mmu_memory_cache_alloc(struct kvm_mmu_memory_cache *mc) return p; } -static void free_ptes(pmd_t *pmd, unsigned long addr) +static void clear_pud_entry(pud_t *pud) { - pte_t *pte; - unsigned int i; + pmd_t *pmd_table = pmd_offset(pud, 0); + pud_clear(pud); + pmd_free(NULL, pmd_table); + put_page(virt_to_page(pud)); +} - for (i = 0; i < PTRS_PER_PMD; i++, addr += PMD_SIZE) { - if (!pmd_none(*pmd) && pmd_table(*pmd)) { - pte = pte_offset_kernel(pmd, addr); - pte_free_kernel(NULL, pte); - } - pmd++; +static void clear_pmd_entry(pmd_t *pmd) +{ + pte_t *pte_table = pte_offset_kernel(pmd, 0); + pmd_clear(pmd); + pte_free_kernel(NULL, pte_table); + put_page(virt_to_page(pmd)); +} + +static bool pmd_empty(pmd_t *pmd) +{ + struct page *pmd_page = virt_to_page(pmd); + return page_count(pmd_page) == 1; +} + +static void clear_pte_entry(pte_t *pte) +{ + if (pte_present(*pte)) { + kvm_set_pte(pte, __pte(0)); + put_page(virt_to_page(pte)); } } -/** - * free_hyp_pmds - free a Hyp-mode level-2 tables and child level-3 tables - * - * Assumes this is a page table used strictly in Hyp-mode and therefore contains - * only mappings in the kernel memory area, which is above PAGE_OFFSET. - */ -void free_hyp_pmds(void) +static bool pte_empty(pte_t *pte) +{ + struct page *pte_page = virt_to_page(pte); + return page_count(pte_page) == 1; +} + +static void unmap_range(pgd_t *pgdp, unsigned long long start, u64 size) { pgd_t *pgd; pud_t *pud; pmd_t *pmd; - unsigned long addr; + pte_t *pte; + unsigned long long addr = start, end = start + size; + u64 range; - mutex_lock(&kvm_hyp_pgd_mutex); - for (addr = PAGE_OFFSET; addr != 0; addr += PGDIR_SIZE) { - pgd = hyp_pgd + pgd_index(addr); + while (addr < end) { + pgd = pgdp + pgd_index(addr); pud = pud_offset(pgd, addr); - - if (pud_none(*pud)) + if (pud_none(*pud)) { + addr += PUD_SIZE; continue; - BUG_ON(pud_bad(*pud)); + } pmd = pmd_offset(pud, addr); - free_ptes(pmd, addr); - pmd_free(NULL, pmd); - pud_clear(pud); + if (pmd_none(*pmd)) { + addr += PMD_SIZE; + continue; + } + + pte = pte_offset_kernel(pmd, addr); + clear_pte_entry(pte); + range = PAGE_SIZE; + + /* If we emptied the pte, walk back up the ladder */ + if (pte_empty(pte)) { + clear_pmd_entry(pmd); + range = PMD_SIZE; + if (pmd_empty(pmd)) { + clear_pud_entry(pud); + range = PUD_SIZE; + } + } + + addr += range; + } +} + +/** + * free_boot_hyp_pgd - free HYP boot page tables + * + * Free the HYP boot page tables. The bounce page is also freed. + */ +void free_boot_hyp_pgd(void) +{ + mutex_lock(&kvm_hyp_pgd_mutex); + + if (boot_hyp_pgd) { + unmap_range(boot_hyp_pgd, hyp_idmap_start, PAGE_SIZE); + unmap_range(boot_hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE); + kfree(boot_hyp_pgd); + boot_hyp_pgd = NULL; } + + if (hyp_pgd) + unmap_range(hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE); + + kfree(init_bounce_page); + init_bounce_page = NULL; + mutex_unlock(&kvm_hyp_pgd_mutex); } -static void create_hyp_pte_mappings(pmd_t *pmd, unsigned long start, - unsigned long end) +/** + * free_hyp_pgds - free Hyp-mode page tables + * + * Assumes hyp_pgd is a page table used strictly in Hyp-mode and + * therefore contains either mappings in the kernel memory area (above + * PAGE_OFFSET), or device mappings in the vmalloc range (from + * VMALLOC_START to VMALLOC_END). + * + * boot_hyp_pgd should only map two pages for the init code. + */ +void free_hyp_pgds(void) { - pte_t *pte; unsigned long addr; - struct page *page; - for (addr = start & PAGE_MASK; addr < end; addr += PAGE_SIZE) { - pte = pte_offset_kernel(pmd, addr); - BUG_ON(!virt_addr_valid(addr)); - page = virt_to_page(addr); - kvm_set_pte(pte, mk_pte(page, PAGE_HYP)); + free_boot_hyp_pgd(); + + mutex_lock(&kvm_hyp_pgd_mutex); + + if (hyp_pgd) { + for (addr = PAGE_OFFSET; virt_addr_valid(addr); addr += PGDIR_SIZE) + unmap_range(hyp_pgd, KERN_TO_HYP(addr), PGDIR_SIZE); + for (addr = VMALLOC_START; is_vmalloc_addr((void*)addr); addr += PGDIR_SIZE) + unmap_range(hyp_pgd, KERN_TO_HYP(addr), PGDIR_SIZE); + kfree(hyp_pgd); + hyp_pgd = NULL; } + + mutex_unlock(&kvm_hyp_pgd_mutex); } -static void create_hyp_io_pte_mappings(pmd_t *pmd, unsigned long start, - unsigned long end, - unsigned long *pfn_base) +static void create_hyp_pte_mappings(pmd_t *pmd, unsigned long start, + unsigned long end, unsigned long pfn, + pgprot_t prot) { pte_t *pte; unsigned long addr; - for (addr = start & PAGE_MASK; addr < end; addr += PAGE_SIZE) { + addr = start; + do { pte = pte_offset_kernel(pmd, addr); - BUG_ON(pfn_valid(*pfn_base)); - kvm_set_pte(pte, pfn_pte(*pfn_base, PAGE_HYP_DEVICE)); - (*pfn_base)++; - } + kvm_set_pte(pte, pfn_pte(pfn, prot)); + get_page(virt_to_page(pte)); + kvm_flush_dcache_to_poc(pte, sizeof(*pte)); + pfn++; + } while (addr += PAGE_SIZE, addr != end); } static int create_hyp_pmd_mappings(pud_t *pud, unsigned long start, - unsigned long end, unsigned long *pfn_base) + unsigned long end, unsigned long pfn, + pgprot_t prot) { pmd_t *pmd; pte_t *pte; unsigned long addr, next; - for (addr = start; addr < end; addr = next) { + addr = start; + do { pmd = pmd_offset(pud, addr); BUG_ON(pmd_sect(*pmd)); @@ -177,42 +248,34 @@ static int create_hyp_pmd_mappings(pud_t *pud, unsigned long start, return -ENOMEM; } pmd_populate_kernel(NULL, pmd, pte); + get_page(virt_to_page(pmd)); + kvm_flush_dcache_to_poc(pmd, sizeof(*pmd)); } next = pmd_addr_end(addr, end); - /* - * If pfn_base is NULL, we map kernel pages into HYP with the - * virtual address. Otherwise, this is considered an I/O - * mapping and we map the physical region starting at - * *pfn_base to [start, end[. - */ - if (!pfn_base) - create_hyp_pte_mappings(pmd, addr, next); - else - create_hyp_io_pte_mappings(pmd, addr, next, pfn_base); - } + create_hyp_pte_mappings(pmd, addr, next, pfn, prot); + pfn += (next - addr) >> PAGE_SHIFT; + } while (addr = next, addr != end); return 0; } -static int __create_hyp_mappings(void *from, void *to, unsigned long *pfn_base) +static int __create_hyp_mappings(pgd_t *pgdp, + unsigned long start, unsigned long end, + unsigned long pfn, pgprot_t prot) { - unsigned long start = (unsigned long)from; - unsigned long end = (unsigned long)to; pgd_t *pgd; pud_t *pud; pmd_t *pmd; unsigned long addr, next; int err = 0; - BUG_ON(start > end); - if (start < PAGE_OFFSET) - return -EINVAL; - mutex_lock(&kvm_hyp_pgd_mutex); - for (addr = start; addr < end; addr = next) { - pgd = hyp_pgd + pgd_index(addr); + addr = start & PAGE_MASK; + end = PAGE_ALIGN(end); + do { + pgd = pgdp + pgd_index(addr); pud = pud_offset(pgd, addr); if (pud_none_or_clear_bad(pud)) { @@ -223,43 +286,64 @@ static int __create_hyp_mappings(void *from, void *to, unsigned long *pfn_base) goto out; } pud_populate(NULL, pud, pmd); + get_page(virt_to_page(pud)); + kvm_flush_dcache_to_poc(pud, sizeof(*pud)); } next = pgd_addr_end(addr, end); - err = create_hyp_pmd_mappings(pud, addr, next, pfn_base); + err = create_hyp_pmd_mappings(pud, addr, next, pfn, prot); if (err) goto out; - } + pfn += (next - addr) >> PAGE_SHIFT; + } while (addr = next, addr != end); out: mutex_unlock(&kvm_hyp_pgd_mutex); return err; } /** - * create_hyp_mappings - map a kernel virtual address range in Hyp mode + * create_hyp_mappings - duplicate a kernel virtual address range in Hyp mode * @from: The virtual kernel start address of the range * @to: The virtual kernel end address of the range (exclusive) * - * The same virtual address as the kernel virtual address is also used in - * Hyp-mode mapping to the same underlying physical pages. - * - * Note: Wrapping around zero in the "to" address is not supported. + * The same virtual address as the kernel virtual address is also used + * in Hyp-mode mapping (modulo HYP_PAGE_OFFSET) to the same underlying + * physical pages. */ int create_hyp_mappings(void *from, void *to) { - return __create_hyp_mappings(from, to, NULL); + unsigned long phys_addr = virt_to_phys(from); + unsigned long start = KERN_TO_HYP((unsigned long)from); + unsigned long end = KERN_TO_HYP((unsigned long)to); + + /* Check for a valid kernel memory mapping */ + if (!virt_addr_valid(from) || !virt_addr_valid(to - 1)) + return -EINVAL; + + return __create_hyp_mappings(hyp_pgd, start, end, + __phys_to_pfn(phys_addr), PAGE_HYP); } /** - * create_hyp_io_mappings - map a physical IO range in Hyp mode - * @from: The virtual HYP start address of the range - * @to: The virtual HYP end address of the range (exclusive) - * @addr: The physical start address which gets mapped + * create_hyp_io_mappings - duplicate a kernel IO mapping into Hyp mode + * @from: The kernel start VA of the range + * @to: The kernel end VA of the range (exclusive) + * @phys_addr: The physical start address which gets mapped + * + * The resulting HYP VA is the same as the kernel VA, modulo + * HYP_PAGE_OFFSET. */ -int create_hyp_io_mappings(void *from, void *to, phys_addr_t addr) +int create_hyp_io_mappings(void *from, void *to, phys_addr_t phys_addr) { - unsigned long pfn = __phys_to_pfn(addr); - return __create_hyp_mappings(from, to, &pfn); + unsigned long start = KERN_TO_HYP((unsigned long)from); + unsigned long end = KERN_TO_HYP((unsigned long)to); + + /* Check for a valid kernel IO mapping */ + if (!is_vmalloc_addr(from) || !is_vmalloc_addr(to - 1)) + return -EINVAL; + + return __create_hyp_mappings(hyp_pgd, start, end, + __phys_to_pfn(phys_addr), PAGE_HYP_DEVICE); } /** @@ -290,48 +374,12 @@ int kvm_alloc_stage2_pgd(struct kvm *kvm) VM_BUG_ON((unsigned long)pgd & (S2_PGD_SIZE - 1)); memset(pgd, 0, PTRS_PER_S2_PGD * sizeof(pgd_t)); - clean_dcache_area(pgd, PTRS_PER_S2_PGD * sizeof(pgd_t)); + kvm_clean_pgd(pgd); kvm->arch.pgd = pgd; return 0; } -static void clear_pud_entry(pud_t *pud) -{ - pmd_t *pmd_table = pmd_offset(pud, 0); - pud_clear(pud); - pmd_free(NULL, pmd_table); - put_page(virt_to_page(pud)); -} - -static void clear_pmd_entry(pmd_t *pmd) -{ - pte_t *pte_table = pte_offset_kernel(pmd, 0); - pmd_clear(pmd); - pte_free_kernel(NULL, pte_table); - put_page(virt_to_page(pmd)); -} - -static bool pmd_empty(pmd_t *pmd) -{ - struct page *pmd_page = virt_to_page(pmd); - return page_count(pmd_page) == 1; -} - -static void clear_pte_entry(pte_t *pte) -{ - if (pte_present(*pte)) { - kvm_set_pte(pte, __pte(0)); - put_page(virt_to_page(pte)); - } -} - -static bool pte_empty(pte_t *pte) -{ - struct page *pte_page = virt_to_page(pte); - return page_count(pte_page) == 1; -} - /** * unmap_stage2_range -- Clear stage2 page table entries to unmap a range * @kvm: The VM pointer @@ -345,43 +393,7 @@ static bool pte_empty(pte_t *pte) */ static void unmap_stage2_range(struct kvm *kvm, phys_addr_t start, u64 size) { - pgd_t *pgd; - pud_t *pud; - pmd_t *pmd; - pte_t *pte; - phys_addr_t addr = start, end = start + size; - u64 range; - - while (addr < end) { - pgd = kvm->arch.pgd + pgd_index(addr); - pud = pud_offset(pgd, addr); - if (pud_none(*pud)) { - addr += PUD_SIZE; - continue; - } - - pmd = pmd_offset(pud, addr); - if (pmd_none(*pmd)) { - addr += PMD_SIZE; - continue; - } - - pte = pte_offset_kernel(pmd, addr); - clear_pte_entry(pte); - range = PAGE_SIZE; - - /* If we emptied the pte, walk back up the ladder */ - if (pte_empty(pte)) { - clear_pmd_entry(pmd); - range = PMD_SIZE; - if (pmd_empty(pmd)) { - clear_pud_entry(pud); - range = PUD_SIZE; - } - } - - addr += range; - } + unmap_range(kvm->arch.pgd, start, size); } /** @@ -422,22 +434,22 @@ static int stage2_set_pte(struct kvm *kvm, struct kvm_mmu_memory_cache *cache, return 0; /* ignore calls from kvm_set_spte_hva */ pmd = mmu_memory_cache_alloc(cache); pud_populate(NULL, pud, pmd); - pmd += pmd_index(addr); get_page(virt_to_page(pud)); - } else - pmd = pmd_offset(pud, addr); + } + + pmd = pmd_offset(pud, addr); /* Create 2nd stage page table mapping - Level 2 */ if (pmd_none(*pmd)) { if (!cache) return 0; /* ignore calls from kvm_set_spte_hva */ pte = mmu_memory_cache_alloc(cache); - clean_pte_table(pte); + kvm_clean_pte(pte); pmd_populate_kernel(NULL, pmd, pte); - pte += pte_index(addr); get_page(virt_to_page(pmd)); - } else - pte = pte_offset_kernel(pmd, addr); + } + + pte = pte_offset_kernel(pmd, addr); if (iomap && pte_present(*pte)) return -EFAULT; @@ -446,7 +458,7 @@ static int stage2_set_pte(struct kvm *kvm, struct kvm_mmu_memory_cache *cache, old_pte = *pte; kvm_set_pte(pte, *new_pte); if (pte_present(old_pte)) - kvm_tlb_flush_vmid(kvm); + kvm_tlb_flush_vmid_ipa(kvm, addr); else get_page(virt_to_page(pte)); @@ -473,7 +485,8 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa, pfn = __phys_to_pfn(pa); for (addr = guest_ipa; addr < end; addr += PAGE_SIZE) { - pte_t pte = pfn_pte(pfn, PAGE_S2_DEVICE | L_PTE_S2_RDWR); + pte_t pte = pfn_pte(pfn, PAGE_S2_DEVICE); + kvm_set_s2pte_writable(&pte); ret = mmu_topup_memory_cache(&cache, 2, 2); if (ret) @@ -492,29 +505,6 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa, return ret; } -static void coherent_icache_guest_page(struct kvm *kvm, gfn_t gfn) -{ - /* - * If we are going to insert an instruction page and the icache is - * either VIPT or PIPT, there is a potential problem where the host - * (or another VM) may have used the same page as this guest, and we - * read incorrect data from the icache. If we're using a PIPT cache, - * we can invalidate just that page, but if we are using a VIPT cache - * we need to invalidate the entire icache - damn shame - as written - * in the ARM ARM (DDI 0406C.b - Page B3-1393). - * - * VIVT caches are tagged using both the ASID and the VMID and doesn't - * need any kind of flushing (DDI 0406C.b - Page B3-1392). - */ - if (icache_is_pipt()) { - unsigned long hva = gfn_to_hva(kvm, gfn); - __cpuc_coherent_user_range(hva, hva + PAGE_SIZE); - } else if (!icache_is_vivt_asid_tagged()) { - /* any kind of VIPT cache */ - __flush_icache_all(); - } -} - static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, gfn_t gfn, struct kvm_memory_slot *memslot, unsigned long fault_status) @@ -526,7 +516,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, unsigned long mmu_seq; struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache; - write_fault = kvm_is_write_fault(vcpu->arch.hsr); + write_fault = kvm_is_write_fault(kvm_vcpu_get_hsr(vcpu)); if (fault_status == FSC_PERM && !write_fault) { kvm_err("Unexpected L2 read permission error\n"); return -EFAULT; @@ -560,7 +550,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, if (mmu_notifier_retry(vcpu->kvm, mmu_seq)) goto out_unlock; if (writable) { - pte_val(new_pte) |= L_PTE_S2_RDWR; + kvm_set_s2pte_writable(&new_pte); kvm_set_pfn_dirty(pfn); } stage2_set_pte(vcpu->kvm, memcache, fault_ipa, &new_pte, false); @@ -585,7 +575,6 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, */ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run) { - unsigned long hsr_ec; unsigned long fault_status; phys_addr_t fault_ipa; struct kvm_memory_slot *memslot; @@ -593,18 +582,17 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run) gfn_t gfn; int ret, idx; - hsr_ec = vcpu->arch.hsr >> HSR_EC_SHIFT; - is_iabt = (hsr_ec == HSR_EC_IABT); - fault_ipa = ((phys_addr_t)vcpu->arch.hpfar & HPFAR_MASK) << 8; + is_iabt = kvm_vcpu_trap_is_iabt(vcpu); + fault_ipa = kvm_vcpu_get_fault_ipa(vcpu); - trace_kvm_guest_fault(*vcpu_pc(vcpu), vcpu->arch.hsr, - vcpu->arch.hxfar, fault_ipa); + trace_kvm_guest_fault(*vcpu_pc(vcpu), kvm_vcpu_get_hsr(vcpu), + kvm_vcpu_get_hfar(vcpu), fault_ipa); /* Check the stage-2 fault is trans. fault or write fault */ - fault_status = (vcpu->arch.hsr & HSR_FSC_TYPE); + fault_status = kvm_vcpu_trap_get_fault(vcpu); if (fault_status != FSC_FAULT && fault_status != FSC_PERM) { - kvm_err("Unsupported fault status: EC=%#lx DFCS=%#lx\n", - hsr_ec, fault_status); + kvm_err("Unsupported fault status: EC=%#x DFCS=%#lx\n", + kvm_vcpu_trap_get_class(vcpu), fault_status); return -EFAULT; } @@ -614,7 +602,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run) if (!kvm_is_visible_gfn(vcpu->kvm, gfn)) { if (is_iabt) { /* Prefetch Abort on I/O address */ - kvm_inject_pabt(vcpu, vcpu->arch.hxfar); + kvm_inject_pabt(vcpu, kvm_vcpu_get_hfar(vcpu)); ret = 1; goto out_unlock; } @@ -626,8 +614,13 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run) goto out_unlock; } - /* Adjust page offset */ - fault_ipa |= vcpu->arch.hxfar & ~PAGE_MASK; + /* + * The IPA is reported as [MAX:12], so we need to + * complement it with the bottom 12 bits from the + * faulting VA. This is always 12 bits, irrespective + * of the page size. + */ + fault_ipa |= kvm_vcpu_get_hfar(vcpu) & ((1 << 12) - 1); ret = io_mem_abort(vcpu, run, fault_ipa); goto out_unlock; } @@ -682,7 +675,7 @@ static void handle_hva_to_gpa(struct kvm *kvm, static void kvm_unmap_hva_handler(struct kvm *kvm, gpa_t gpa, void *data) { unmap_stage2_range(kvm, gpa, PAGE_SIZE); - kvm_tlb_flush_vmid(kvm); + kvm_tlb_flush_vmid_ipa(kvm, gpa); } int kvm_unmap_hva(struct kvm *kvm, unsigned long hva) @@ -736,47 +729,105 @@ void kvm_mmu_free_memory_caches(struct kvm_vcpu *vcpu) phys_addr_t kvm_mmu_get_httbr(void) { - VM_BUG_ON(!virt_addr_valid(hyp_pgd)); return virt_to_phys(hyp_pgd); } +phys_addr_t kvm_mmu_get_boot_httbr(void) +{ + return virt_to_phys(boot_hyp_pgd); +} + +phys_addr_t kvm_get_idmap_vector(void) +{ + return hyp_idmap_vector; +} + int kvm_mmu_init(void) { - if (!hyp_pgd) { + int err; + + hyp_idmap_start = virt_to_phys(__hyp_idmap_text_start); + hyp_idmap_end = virt_to_phys(__hyp_idmap_text_end); + hyp_idmap_vector = virt_to_phys(__kvm_hyp_init); + + if ((hyp_idmap_start ^ hyp_idmap_end) & PAGE_MASK) { + /* + * Our init code is crossing a page boundary. Allocate + * a bounce page, copy the code over and use that. + */ + size_t len = __hyp_idmap_text_end - __hyp_idmap_text_start; + phys_addr_t phys_base; + + init_bounce_page = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!init_bounce_page) { + kvm_err("Couldn't allocate HYP init bounce page\n"); + err = -ENOMEM; + goto out; + } + + memcpy(init_bounce_page, __hyp_idmap_text_start, len); + /* + * Warning: the code we just copied to the bounce page + * must be flushed to the point of coherency. + * Otherwise, the data may be sitting in L2, and HYP + * mode won't be able to observe it as it runs with + * caches off at that point. + */ + kvm_flush_dcache_to_poc(init_bounce_page, len); + + phys_base = virt_to_phys(init_bounce_page); + hyp_idmap_vector += phys_base - hyp_idmap_start; + hyp_idmap_start = phys_base; + hyp_idmap_end = phys_base + len; + + kvm_info("Using HYP init bounce page @%lx\n", + (unsigned long)phys_base); + } + + hyp_pgd = kzalloc(PTRS_PER_PGD * sizeof(pgd_t), GFP_KERNEL); + boot_hyp_pgd = kzalloc(PTRS_PER_PGD * sizeof(pgd_t), GFP_KERNEL); + if (!hyp_pgd || !boot_hyp_pgd) { kvm_err("Hyp mode PGD not allocated\n"); - return -ENOMEM; + err = -ENOMEM; + goto out; } - return 0; -} + /* Create the idmap in the boot page tables */ + err = __create_hyp_mappings(boot_hyp_pgd, + hyp_idmap_start, hyp_idmap_end, + __phys_to_pfn(hyp_idmap_start), + PAGE_HYP); -/** - * kvm_clear_idmap - remove all idmaps from the hyp pgd - * - * Free the underlying pmds for all pgds in range and clear the pgds (but - * don't free them) afterwards. - */ -void kvm_clear_hyp_idmap(void) -{ - unsigned long addr, end; - unsigned long next; - pgd_t *pgd = hyp_pgd; - pud_t *pud; - pmd_t *pmd; + if (err) { + kvm_err("Failed to idmap %lx-%lx\n", + hyp_idmap_start, hyp_idmap_end); + goto out; + } - addr = virt_to_phys(__hyp_idmap_text_start); - end = virt_to_phys(__hyp_idmap_text_end); + /* Map the very same page at the trampoline VA */ + err = __create_hyp_mappings(boot_hyp_pgd, + TRAMPOLINE_VA, TRAMPOLINE_VA + PAGE_SIZE, + __phys_to_pfn(hyp_idmap_start), + PAGE_HYP); + if (err) { + kvm_err("Failed to map trampoline @%lx into boot HYP pgd\n", + TRAMPOLINE_VA); + goto out; + } - pgd += pgd_index(addr); - do { - next = pgd_addr_end(addr, end); - if (pgd_none_or_clear_bad(pgd)) - continue; - pud = pud_offset(pgd, addr); - pmd = pmd_offset(pud, addr); + /* Map the same page again into the runtime page tables */ + err = __create_hyp_mappings(hyp_pgd, + TRAMPOLINE_VA, TRAMPOLINE_VA + PAGE_SIZE, + __phys_to_pfn(hyp_idmap_start), + PAGE_HYP); + if (err) { + kvm_err("Failed to map trampoline @%lx into runtime HYP pgd\n", + TRAMPOLINE_VA); + goto out; + } - pud_clear(pud); - clean_pmd_entry(pmd); - pmd_free(NULL, (pmd_t *)((unsigned long)pmd & PAGE_MASK)); - } while (pgd++, addr = next, addr < end); + return 0; +out: + free_hyp_pgds(); + return err; } diff --git a/trunk/arch/arm/kvm/perf.c b/trunk/arch/arm/kvm/perf.c new file mode 100644 index 000000000000..1a3849da0b4b --- /dev/null +++ b/trunk/arch/arm/kvm/perf.c @@ -0,0 +1,68 @@ +/* + * Based on the x86 implementation. + * + * Copyright (C) 2012 ARM Ltd. + * Author: Marc Zyngier + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include + +static int kvm_is_in_guest(void) +{ + return kvm_arm_get_running_vcpu() != NULL; +} + +static int kvm_is_user_mode(void) +{ + struct kvm_vcpu *vcpu; + + vcpu = kvm_arm_get_running_vcpu(); + + if (vcpu) + return !vcpu_mode_priv(vcpu); + + return 0; +} + +static unsigned long kvm_get_guest_ip(void) +{ + struct kvm_vcpu *vcpu; + + vcpu = kvm_arm_get_running_vcpu(); + + if (vcpu) + return *vcpu_pc(vcpu); + + return 0; +} + +static struct perf_guest_info_callbacks kvm_guest_cbs = { + .is_in_guest = kvm_is_in_guest, + .is_user_mode = kvm_is_user_mode, + .get_guest_ip = kvm_get_guest_ip, +}; + +int kvm_perf_init(void) +{ + return perf_register_guest_info_callbacks(&kvm_guest_cbs); +} + +int kvm_perf_teardown(void) +{ + return perf_unregister_guest_info_callbacks(&kvm_guest_cbs); +} diff --git a/trunk/arch/arm/kvm/vgic.c b/trunk/arch/arm/kvm/vgic.c index 0e4cfe123b38..17c5ac7d10ed 100644 --- a/trunk/arch/arm/kvm/vgic.c +++ b/trunk/arch/arm/kvm/vgic.c @@ -1477,7 +1477,7 @@ int kvm_vgic_set_addr(struct kvm *kvm, unsigned long type, u64 addr) if (addr & ~KVM_PHYS_MASK) return -E2BIG; - if (addr & ~PAGE_MASK) + if (addr & (SZ_4K - 1)) return -EINVAL; mutex_lock(&kvm->lock); diff --git a/trunk/arch/arm/mach-at91/at91sam9261.c b/trunk/arch/arm/mach-at91/at91sam9261.c index ac7a341bd0ff..25efb5ac30f1 100644 --- a/trunk/arch/arm/mach-at91/at91sam9261.c +++ b/trunk/arch/arm/mach-at91/at91sam9261.c @@ -169,6 +169,8 @@ static struct clk *periph_clocks[] __initdata = { }; static struct clk_lookup periph_clocks_lookups[] = { + CLKDEV_CON_DEV_ID("hclk", "at91sam9261-lcdfb.0", &hck1), + CLKDEV_CON_DEV_ID("hclk", "at91sam9g10-lcdfb.0", &hck1), CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), diff --git a/trunk/arch/arm/mach-at91/at91sam9261_devices.c b/trunk/arch/arm/mach-at91/at91sam9261_devices.c index 92e0f861084a..629ea5fc95cf 100644 --- a/trunk/arch/arm/mach-at91/at91sam9261_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9261_devices.c @@ -488,7 +488,6 @@ static struct resource lcdc_resources[] = { }; static struct platform_device at91_lcdc_device = { - .name = "atmel_lcdfb", .id = 0, .dev = { .dma_mask = &lcdc_dmamask, @@ -505,6 +504,11 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) return; } + if (cpu_is_at91sam9g10()) + at91_lcdc_device.name = "at91sam9g10-lcdfb"; + else + at91_lcdc_device.name = "at91sam9261-lcdfb"; + #if defined(CONFIG_FB_ATMEL_STN) at91_set_A_periph(AT91_PIN_PB0, 0); /* LCDVSYNC */ at91_set_A_periph(AT91_PIN_PB1, 0); /* LCDHSYNC */ diff --git a/trunk/arch/arm/mach-at91/at91sam9263.c b/trunk/arch/arm/mach-at91/at91sam9263.c index 8e2d9f4a9a45..f44ffd2105a7 100644 --- a/trunk/arch/arm/mach-at91/at91sam9263.c +++ b/trunk/arch/arm/mach-at91/at91sam9263.c @@ -190,6 +190,7 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.1", &ssc1_clk), CLKDEV_CON_DEV_ID("pclk", "fff98000.ssc", &ssc0_clk), CLKDEV_CON_DEV_ID("pclk", "fff9c000.ssc", &ssc1_clk), + CLKDEV_CON_DEV_ID("hclk", "at91sam9263-lcdfb.0", &lcdc_clk), CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.0", &mmc0_clk), CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.1", &mmc1_clk), CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), diff --git a/trunk/arch/arm/mach-at91/at91sam9263_devices.c b/trunk/arch/arm/mach-at91/at91sam9263_devices.c index ed666f5cb01d..858c8aac2daf 100644 --- a/trunk/arch/arm/mach-at91/at91sam9263_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9263_devices.c @@ -848,7 +848,7 @@ static struct resource lcdc_resources[] = { }; static struct platform_device at91_lcdc_device = { - .name = "atmel_lcdfb", + .name = "at91sam9263-lcdfb", .id = 0, .dev = { .dma_mask = &lcdc_dmamask, diff --git a/trunk/arch/arm/mach-at91/at91sam9g45.c b/trunk/arch/arm/mach-at91/at91sam9g45.c index a6c224fc9542..8b7fce067652 100644 --- a/trunk/arch/arm/mach-at91/at91sam9g45.c +++ b/trunk/arch/arm/mach-at91/at91sam9g45.c @@ -228,6 +228,8 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_ID("hclk", &macb_clk), /* One additional fake clock for ohci */ CLKDEV_CON_ID("ohci_clk", &uhphs_clk), + CLKDEV_CON_DEV_ID("hclk", "at91sam9g45-lcdfb.0", &lcdc_clk), + CLKDEV_CON_DEV_ID("hclk", "at91sam9g45es-lcdfb.0", &lcdc_clk), CLKDEV_CON_DEV_ID("ehci_clk", "atmel-ehci", &uhphs_clk), CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk), CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk), diff --git a/trunk/arch/arm/mach-at91/at91sam9g45_devices.c b/trunk/arch/arm/mach-at91/at91sam9g45_devices.c index 827c9f2a70fb..acb703e13331 100644 --- a/trunk/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9g45_devices.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include @@ -981,7 +981,6 @@ static struct resource lcdc_resources[] = { }; static struct platform_device at91_lcdc_device = { - .name = "atmel_lcdfb", .id = 0, .dev = { .dma_mask = &lcdc_dmamask, @@ -997,6 +996,11 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) if (!data) return; + if (cpu_is_at91sam9g45es()) + at91_lcdc_device.name = "at91sam9g45es-lcdfb"; + else + at91_lcdc_device.name = "at91sam9g45-lcdfb"; + at91_set_A_periph(AT91_PIN_PE0, 0); /* LCDDPWR */ at91_set_A_periph(AT91_PIN_PE2, 0); /* LCDCC */ @@ -1900,7 +1904,8 @@ static void __init at91_add_device_tdes(void) {} * -------------------------------------------------------------------- */ #if defined(CONFIG_CRYPTO_DEV_ATMEL_AES) || defined(CONFIG_CRYPTO_DEV_ATMEL_AES_MODULE) -static struct aes_platform_data aes_data; +static struct crypto_platform_data aes_data; +static struct crypto_dma_data alt_atslave; static u64 aes_dmamask = DMA_BIT_MASK(32); static struct resource aes_resources[] = { @@ -1931,23 +1936,20 @@ static struct platform_device at91sam9g45_aes_device = { static void __init at91_add_device_aes(void) { struct at_dma_slave *atslave; - struct aes_dma_data *alt_atslave; - - alt_atslave = kzalloc(sizeof(struct aes_dma_data), GFP_KERNEL); /* DMA TX slave channel configuration */ - atslave = &alt_atslave->txdata; + atslave = &alt_atslave.txdata; atslave->dma_dev = &at_hdmac_device.dev; atslave->cfg = ATC_FIFOCFG_ENOUGHSPACE | ATC_SRC_H2SEL_HW | ATC_SRC_PER(AT_DMA_ID_AES_RX); /* DMA RX slave channel configuration */ - atslave = &alt_atslave->rxdata; + atslave = &alt_atslave.rxdata; atslave->dma_dev = &at_hdmac_device.dev; atslave->cfg = ATC_FIFOCFG_ENOUGHSPACE | ATC_DST_H2SEL_HW | ATC_DST_PER(AT_DMA_ID_AES_TX); - aes_data.dma_slave = alt_atslave; + aes_data.dma_slave = &alt_atslave; platform_device_register(&at91sam9g45_aes_device); } #else diff --git a/trunk/arch/arm/mach-at91/at91sam9rl.c b/trunk/arch/arm/mach-at91/at91sam9rl.c index c39600764236..f77fae5591bc 100644 --- a/trunk/arch/arm/mach-at91/at91sam9rl.c +++ b/trunk/arch/arm/mach-at91/at91sam9rl.c @@ -179,6 +179,7 @@ static struct clk *periph_clocks[] __initdata = { }; static struct clk_lookup periph_clocks_lookups[] = { + CLKDEV_CON_DEV_ID("hclk", "at91sam9rl-lcdfb.0", &lcdc_clk), CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk), CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk), CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), diff --git a/trunk/arch/arm/mach-at91/at91sam9rl_devices.c b/trunk/arch/arm/mach-at91/at91sam9rl_devices.c index ddf223ff35c4..352468f265a9 100644 --- a/trunk/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9rl_devices.c @@ -514,7 +514,7 @@ static struct resource lcdc_resources[] = { }; static struct platform_device at91_lcdc_device = { - .name = "atmel_lcdfb", + .name = "at91sam9rl-lcdfb", .id = 0, .dev = { .dma_mask = &lcdc_dmamask, diff --git a/trunk/arch/arm/mach-at91/cpuidle.c b/trunk/arch/arm/mach-at91/cpuidle.c index 48f1228c611c..69f9e3bbf4e5 100644 --- a/trunk/arch/arm/mach-at91/cpuidle.c +++ b/trunk/arch/arm/mach-at91/cpuidle.c @@ -36,6 +36,8 @@ static int at91_enter_idle(struct cpuidle_device *dev, at91rm9200_standby(); else if (cpu_is_at91sam9g45()) at91sam9g45_standby(); + else if (cpu_is_at91sam9263()) + at91sam9263_standby(); else at91sam9_standby(); diff --git a/trunk/arch/arm/mach-at91/include/mach/cpu.h b/trunk/arch/arm/mach-at91/include/mach/cpu.h index 0f3379fe645f..d3d7b993846b 100644 --- a/trunk/arch/arm/mach-at91/include/mach/cpu.h +++ b/trunk/arch/arm/mach-at91/include/mach/cpu.h @@ -86,7 +86,7 @@ enum at91_soc_type { AT91_SOC_SAMA5D3, /* Unknown type */ - AT91_SOC_NONE + AT91_SOC_UNKNOWN, }; enum at91_soc_subtype { @@ -107,8 +107,11 @@ enum at91_soc_subtype { AT91_SOC_SAMA5D31, AT91_SOC_SAMA5D33, AT91_SOC_SAMA5D34, AT91_SOC_SAMA5D35, + /* No subtype for this SoC */ + AT91_SOC_SUBTYPE_NONE, + /* Unknown subtype */ - AT91_SOC_SUBTYPE_NONE + AT91_SOC_SUBTYPE_UNKNOWN, }; struct at91_socinfo { @@ -122,7 +125,7 @@ const char *at91_get_soc_subtype(struct at91_socinfo *c); static inline int at91_soc_is_detected(void) { - return at91_soc_initdata.type != AT91_SOC_NONE; + return at91_soc_initdata.type != AT91_SOC_UNKNOWN; } #ifdef CONFIG_SOC_AT91RM9200 diff --git a/trunk/arch/arm/mach-at91/pm.c b/trunk/arch/arm/mach-at91/pm.c index 73f1f250403a..530db304ec5e 100644 --- a/trunk/arch/arm/mach-at91/pm.c +++ b/trunk/arch/arm/mach-at91/pm.c @@ -270,6 +270,8 @@ static int at91_pm_enter(suspend_state_t state) at91rm9200_standby(); else if (cpu_is_at91sam9g45()) at91sam9g45_standby(); + else if (cpu_is_at91sam9263()) + at91sam9263_standby(); else at91sam9_standby(); break; diff --git a/trunk/arch/arm/mach-at91/pm.h b/trunk/arch/arm/mach-at91/pm.h index 38f467c6b710..2f5908f0b8c5 100644 --- a/trunk/arch/arm/mach-at91/pm.h +++ b/trunk/arch/arm/mach-at91/pm.h @@ -70,13 +70,31 @@ static inline void at91sam9g45_standby(void) at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1); } -#ifdef CONFIG_SOC_AT91SAM9263 -/* - * FIXME either or both the SDRAM controllers (EB0, EB1) might be in use; - * handle those cases both here and in the Suspend-To-RAM support. +/* We manage both DDRAM/SDRAM controllers, we need more than one value to + * remember. */ -#warning Assuming EB1 SDRAM controller is *NOT* used -#endif +static inline void at91sam9263_standby(void) +{ + u32 lpr0, lpr1; + u32 saved_lpr0, saved_lpr1; + + saved_lpr1 = at91_ramc_read(1, AT91_SDRAMC_LPR); + lpr1 = saved_lpr1 & ~AT91_SDRAMC_LPCB; + lpr1 |= AT91_SDRAMC_LPCB_SELF_REFRESH; + + saved_lpr0 = at91_ramc_read(0, AT91_SDRAMC_LPR); + lpr0 = saved_lpr0 & ~AT91_SDRAMC_LPCB; + lpr0 |= AT91_SDRAMC_LPCB_SELF_REFRESH; + + /* self-refresh mode now */ + at91_ramc_write(0, AT91_SDRAMC_LPR, lpr0); + at91_ramc_write(1, AT91_SDRAMC_LPR, lpr1); + + cpu_do_idle(); + + at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr0); + at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1); +} static inline void at91sam9_standby(void) { diff --git a/trunk/arch/arm/mach-at91/setup.c b/trunk/arch/arm/mach-at91/setup.c index e8491e77b1f7..e2f4bdd146d6 100644 --- a/trunk/arch/arm/mach-at91/setup.c +++ b/trunk/arch/arm/mach-at91/setup.c @@ -105,28 +105,32 @@ static void __init soc_detect(u32 dbgu_base) switch (socid) { case ARCH_ID_AT91RM9200: at91_soc_initdata.type = AT91_SOC_RM9200; - if (at91_soc_initdata.subtype == AT91_SOC_SUBTYPE_NONE) + if (at91_soc_initdata.subtype == AT91_SOC_SUBTYPE_UNKNOWN) at91_soc_initdata.subtype = AT91_SOC_RM9200_BGA; at91_boot_soc = at91rm9200_soc; break; case ARCH_ID_AT91SAM9260: at91_soc_initdata.type = AT91_SOC_SAM9260; + at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE; at91_boot_soc = at91sam9260_soc; break; case ARCH_ID_AT91SAM9261: at91_soc_initdata.type = AT91_SOC_SAM9261; + at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE; at91_boot_soc = at91sam9261_soc; break; case ARCH_ID_AT91SAM9263: at91_soc_initdata.type = AT91_SOC_SAM9263; + at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE; at91_boot_soc = at91sam9263_soc; break; case ARCH_ID_AT91SAM9G20: at91_soc_initdata.type = AT91_SOC_SAM9G20; + at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE; at91_boot_soc = at91sam9260_soc; break; @@ -139,6 +143,7 @@ static void __init soc_detect(u32 dbgu_base) case ARCH_ID_AT91SAM9RL64: at91_soc_initdata.type = AT91_SOC_SAM9RL; + at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE; at91_boot_soc = at91sam9rl_soc; break; @@ -161,6 +166,7 @@ static void __init soc_detect(u32 dbgu_base) /* at91sam9g10 */ if ((socid & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10) { at91_soc_initdata.type = AT91_SOC_SAM9G10; + at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE; at91_boot_soc = at91sam9261_soc; } /* at91sam9xe */ @@ -242,7 +248,7 @@ static const char *soc_name[] = { [AT91_SOC_SAM9X5] = "at91sam9x5", [AT91_SOC_SAM9N12] = "at91sam9n12", [AT91_SOC_SAMA5D3] = "sama5d3", - [AT91_SOC_NONE] = "Unknown" + [AT91_SOC_UNKNOWN] = "Unknown", }; const char *at91_get_soc_type(struct at91_socinfo *c) @@ -268,7 +274,8 @@ static const char *soc_subtype_name[] = { [AT91_SOC_SAMA5D33] = "sama5d33", [AT91_SOC_SAMA5D34] = "sama5d34", [AT91_SOC_SAMA5D35] = "sama5d35", - [AT91_SOC_SUBTYPE_NONE] = "Unknown" + [AT91_SOC_SUBTYPE_NONE] = "None", + [AT91_SOC_SUBTYPE_UNKNOWN] = "Unknown", }; const char *at91_get_soc_subtype(struct at91_socinfo *c) @@ -282,8 +289,8 @@ void __init at91_map_io(void) /* Map peripherals */ iotable_init(&at91_io_desc, 1); - at91_soc_initdata.type = AT91_SOC_NONE; - at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE; + at91_soc_initdata.type = AT91_SOC_UNKNOWN; + at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_UNKNOWN; soc_detect(AT91_BASE_DBGU0); if (!at91_soc_is_detected()) @@ -294,8 +301,9 @@ void __init at91_map_io(void) pr_info("AT91: Detected soc type: %s\n", at91_get_soc_type(&at91_soc_initdata)); - pr_info("AT91: Detected soc subtype: %s\n", - at91_get_soc_subtype(&at91_soc_initdata)); + if (at91_soc_initdata.subtype != AT91_SOC_SUBTYPE_NONE) + pr_info("AT91: Detected soc subtype: %s\n", + at91_get_soc_subtype(&at91_soc_initdata)); if (!at91_soc_is_enabled()) panic("AT91: Soc not enabled"); diff --git a/trunk/arch/arm/mach-bcm/Makefile b/trunk/arch/arm/mach-bcm/Makefile index bbf412261e5e..6adb6aecf48f 100644 --- a/trunk/arch/arm/mach-bcm/Makefile +++ b/trunk/arch/arm/mach-bcm/Makefile @@ -10,4 +10,6 @@ # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -obj-$(CONFIG_ARCH_BCM) := board_bcm.o +obj-$(CONFIG_ARCH_BCM) := board_bcm.o bcm_kona_smc.o bcm_kona_smc_asm.o +plus_sec := $(call as-instr,.arch_extension sec,+sec) +AFLAGS_bcm_kona_smc_asm.o :=-Wa,-march=armv7-a$(plus_sec) diff --git a/trunk/arch/arm/mach-bcm/bcm_kona_smc.c b/trunk/arch/arm/mach-bcm/bcm_kona_smc.c new file mode 100644 index 000000000000..56d9d19b2470 --- /dev/null +++ b/trunk/arch/arm/mach-bcm/bcm_kona_smc.c @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2013 Broadcom 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 version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include + +#include +#include + +#include "bcm_kona_smc.h" + +struct secure_bridge_data { + void __iomem *bounce; /* virtual address */ + u32 __iomem buffer_addr; /* physical address */ + int initialized; +} bridge_data; + +struct bcm_kona_smc_data { + unsigned service_id; + unsigned arg0; + unsigned arg1; + unsigned arg2; + unsigned arg3; +}; + +static const struct of_device_id bcm_kona_smc_ids[] __initconst = { + {.compatible = "bcm,kona-smc"}, + {}, +}; + +/* Map in the bounce area */ +void __init bcm_kona_smc_init(void) +{ + struct device_node *node; + + /* Read buffer addr and size from the device tree node */ + node = of_find_matching_node(NULL, bcm_kona_smc_ids); + BUG_ON(!node); + + /* Don't care about size or flags of the DT node */ + bridge_data.buffer_addr = + be32_to_cpu(*of_get_address(node, 0, NULL, NULL)); + BUG_ON(!bridge_data.buffer_addr); + + bridge_data.bounce = of_iomap(node, 0); + BUG_ON(!bridge_data.bounce); + + bridge_data.initialized = 1; + + pr_info("Secure API initialized!\n"); +} + +/* __bcm_kona_smc() should only run on CPU 0, with pre-emption disabled */ +static void __bcm_kona_smc(void *info) +{ + struct bcm_kona_smc_data *data = info; + u32 *args = bridge_data.bounce; + int rc = 0; + + /* Must run on CPU 0 */ + BUG_ON(smp_processor_id() != 0); + + /* Check map in the bounce area */ + BUG_ON(!bridge_data.initialized); + + /* Copy one 32 bit word into the bounce area */ + args[0] = data->arg0; + args[1] = data->arg1; + args[2] = data->arg2; + args[3] = data->arg3; + + /* Flush caches for input data passed to Secure Monitor */ + if (data->service_id != SSAPI_BRCM_START_VC_CORE) + flush_cache_all(); + + /* Trap into Secure Monitor */ + rc = bcm_kona_smc_asm(data->service_id, bridge_data.buffer_addr); + + if (rc != SEC_ROM_RET_OK) + pr_err("Secure Monitor call failed (0x%x)!\n", rc); +} + +unsigned bcm_kona_smc(unsigned service_id, unsigned arg0, unsigned arg1, + unsigned arg2, unsigned arg3) +{ + struct bcm_kona_smc_data data; + + data.service_id = service_id; + data.arg0 = arg0; + data.arg1 = arg1; + data.arg2 = arg2; + data.arg3 = arg3; + + /* + * Due to a limitation of the secure monitor, we must use the SMP + * infrastructure to forward all secure monitor calls to Core 0. + */ + if (get_cpu() != 0) + smp_call_function_single(0, __bcm_kona_smc, (void *)&data, 1); + else + __bcm_kona_smc(&data); + + put_cpu(); + + return 0; +} diff --git a/trunk/arch/arm/mach-bcm/bcm_kona_smc.h b/trunk/arch/arm/mach-bcm/bcm_kona_smc.h new file mode 100644 index 000000000000..3bedbed1c21b --- /dev/null +++ b/trunk/arch/arm/mach-bcm/bcm_kona_smc.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2013 Broadcom 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 version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef BCM_KONA_SMC_H +#define BCM_KONA_SMC_H + +#include +#define FLAGS (SEC_ROM_ICACHE_ENABLE_MASK | SEC_ROM_DCACHE_ENABLE_MASK | \ + SEC_ROM_IRQ_ENABLE_MASK | SEC_ROM_FIQ_ENABLE_MASK) + +/*! + * Definitions for IRQ & FIQ Mask for ARM + */ + +#define FIQ_IRQ_MASK 0xC0 +#define FIQ_MASK 0x40 +#define IRQ_MASK 0x80 + +/*! + * Secure Mode FLAGs + */ + +/* When set, enables ICache within the secure mode */ +#define SEC_ROM_ICACHE_ENABLE_MASK 0x00000001 + +/* When set, enables DCache within the secure mode */ +#define SEC_ROM_DCACHE_ENABLE_MASK 0x00000002 + +/* When set, enables IRQ within the secure mode */ +#define SEC_ROM_IRQ_ENABLE_MASK 0x00000004 + +/* When set, enables FIQ within the secure mode */ +#define SEC_ROM_FIQ_ENABLE_MASK 0x00000008 + +/* When set, enables Unified L2 cache within the secure mode */ +#define SEC_ROM_UL2_CACHE_ENABLE_MASK 0x00000010 + +/* Broadcom Secure Service API Service IDs */ +#define SSAPI_DORMANT_ENTRY_SERV 0x01000000 +#define SSAPI_PUBLIC_OTP_SERV 0x01000001 +#define SSAPI_ENABLE_L2_CACHE 0x01000002 +#define SSAPI_DISABLE_L2_CACHE 0x01000003 +#define SSAPI_WRITE_SCU_STATUS 0x01000004 +#define SSAPI_WRITE_PWR_GATE 0x01000005 + +/* Broadcom Secure Service API Return Codes */ +#define SEC_ROM_RET_OK 0x00000001 +#define SEC_ROM_RET_FAIL 0x00000009 + +#define SSAPI_RET_FROM_INT_SERV 0x4 +#define SEC_EXIT_NORMAL 0x1 + +#define SSAPI_ROW_AES 0x0E000006 +#define SSAPI_BRCM_START_VC_CORE 0x0E000008 + +#ifndef __ASSEMBLY__ +extern void bcm_kona_smc_init(void); + +extern unsigned bcm_kona_smc(unsigned service_id, + unsigned arg0, + unsigned arg1, + unsigned arg2, + unsigned arg3); + +extern int bcm_kona_smc_asm(u32 service_id, + u32 buffer_addr); + +#endif /* __ASSEMBLY__ */ + +#endif /* BCM_KONA_SMC_H */ diff --git a/trunk/arch/arm/mach-bcm/bcm_kona_smc_asm.S b/trunk/arch/arm/mach-bcm/bcm_kona_smc_asm.S new file mode 100644 index 000000000000..a1608480d60d --- /dev/null +++ b/trunk/arch/arm/mach-bcm/bcm_kona_smc_asm.S @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2013 Broadcom 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 version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include "bcm_kona_smc.h" + +/* + * int bcm_kona_smc_asm(u32 service_id, u32 buffer_addr) + */ + +ENTRY(bcm_kona_smc_asm) + stmfd sp!, {r4-r12, lr} + mov r4, r0 @ service_id + mov r5, #3 @ Keep IRQ and FIQ off in SM + /* + * Since interrupts are disabled in the open mode, we must keep + * interrupts disabled in secure mode by setting R5=0x3. If interrupts + * are enabled in open mode, we can set R5=0x0 to allow interrupts in + * secure mode. If we did this, the secure monitor would return back + * control to the open mode to handle the interrupt prior to completing + * the secure service. If this happened, R12 would not be + * SEC_EXIT_NORMAL and we would need to call SMC again after resetting + * R5 (it gets clobbered by the secure monitor) and setting R4 to + * SSAPI_RET_FROM_INT_SERV to indicate that we want the secure monitor + * to finish up the previous uncompleted secure service. + */ + mov r6, r1 @ buffer_addr + smc #0 + /* Check r12 for SEC_EXIT_NORMAL here if interrupts are enabled */ + ldmfd sp!, {r4-r12, pc} +ENDPROC(bcm_kona_smc_asm) diff --git a/trunk/arch/arm/mach-bcm/board_bcm.c b/trunk/arch/arm/mach-bcm/board_bcm.c index 259593540477..22e8421b1df3 100644 --- a/trunk/arch/arm/mach-bcm/board_bcm.c +++ b/trunk/arch/arm/mach-bcm/board_bcm.c @@ -20,12 +20,35 @@ #include #include +#include +#include "bcm_kona_smc.h" + +static int __init kona_l2_cache_init(void) +{ + if (!IS_ENABLED(CONFIG_CACHE_L2X0)) + return 0; + + bcm_kona_smc(SSAPI_ENABLE_L2_CACHE, 0, 0, 0, 0); + + /* + * The aux_val and aux_mask have no effect since L2 cache is already + * enabled. Pass 0s for aux_val and 1s for aux_mask for default value. + */ + l2x0_of_init(0, ~0); + + return 0; +} + static void __init board_init(void) { of_platform_populate(NULL, of_default_bus_match_table, NULL, &platform_bus); + + bcm_kona_smc_init(); + + kona_l2_cache_init(); } static const char * const bcm11351_dt_compat[] = { "bcm,bcm11351", NULL, }; diff --git a/trunk/arch/arm/mach-davinci/board-da830-evm.c b/trunk/arch/arm/mach-davinci/board-da830-evm.c index 12e6f756361d..1332de8c52c9 100644 --- a/trunk/arch/arm/mach-davinci/board-da830-evm.c +++ b/trunk/arch/arm/mach-davinci/board-da830-evm.c @@ -297,11 +297,7 @@ static const short da830_evm_emif25_pins[] = { -1 }; -#if defined(CONFIG_MMC_DAVINCI) || defined(CONFIG_MMC_DAVINCI_MODULE) -#define HAS_MMC 1 -#else -#define HAS_MMC 0 -#endif +#define HAS_MMC IS_ENABLED(CONFIG_MMC_DAVINCI) #ifdef CONFIG_DA830_UI_NAND static struct mtd_partition da830_evm_nand_partitions[] = { diff --git a/trunk/arch/arm/mach-davinci/board-da850-evm.c b/trunk/arch/arm/mach-davinci/board-da850-evm.c index dcc8710936a5..8a24b6c6339f 100644 --- a/trunk/arch/arm/mach-davinci/board-da850-evm.c +++ b/trunk/arch/arm/mach-davinci/board-da850-evm.c @@ -335,12 +335,7 @@ static const short da850_evm_nor_pins[] = { -1 }; -#if defined(CONFIG_MMC_DAVINCI) || \ - defined(CONFIG_MMC_DAVINCI_MODULE) -#define HAS_MMC 1 -#else -#define HAS_MMC 0 -#endif +#define HAS_MMC IS_ENABLED(CONFIG_MMC_DAVINCI) static inline void da850_evm_setup_nor_nand(void) { @@ -401,7 +396,7 @@ enum da850_evm_ui_exp_pins { DA850_EVM_UI_EXP_PB1, }; -static const char const *da850_evm_ui_exp[] = { +static const char * const da850_evm_ui_exp[] = { [DA850_EVM_UI_EXP_SEL_C] = "sel_c", [DA850_EVM_UI_EXP_SEL_B] = "sel_b", [DA850_EVM_UI_EXP_SEL_A] = "sel_a", @@ -565,7 +560,7 @@ enum da850_evm_bb_exp_pins { DA850_EVM_BB_EXP_USER_SW8 }; -static const char const *da850_evm_bb_exp[] = { +static const char * const da850_evm_bb_exp[] = { [DA850_EVM_BB_EXP_DEEP_SLEEP_EN] = "deep_sleep_en", [DA850_EVM_BB_EXP_SW_RST] = "sw_rst", [DA850_EVM_BB_EXP_TP_23] = "tp_23", @@ -1577,6 +1572,11 @@ static __init void da850_evm_init(void) pr_warn("%s: SATA registration failed: %d\n", __func__, ret); da850_evm_setup_mac_addr(); + + ret = da8xx_register_rproc(); + if (ret) + pr_warn("%s: dsp/rproc registration failed: %d\n", + __func__, ret); } #ifdef CONFIG_SERIAL_8250_CONSOLE @@ -1604,4 +1604,5 @@ MACHINE_START(DAVINCI_DA850_EVM, "DaVinci DA850/OMAP-L138/AM18x EVM") .init_late = davinci_init_late, .dma_zone_size = SZ_128M, .restart = da8xx_restart, + .reserve = da8xx_rproc_reserve_cma, MACHINE_END diff --git a/trunk/arch/arm/mach-davinci/board-dm644x-evm.c b/trunk/arch/arm/mach-davinci/board-dm644x-evm.c index e62108fd7926..a33686a6fbb2 100644 --- a/trunk/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/trunk/arch/arm/mach-davinci/board-dm644x-evm.c @@ -749,26 +749,11 @@ static int davinci_phy_fixup(struct phy_device *phydev) return 0; } -#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \ - defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE) -#define HAS_ATA 1 -#else -#define HAS_ATA 0 -#endif - -#if defined(CONFIG_MTD_PHYSMAP) || \ - defined(CONFIG_MTD_PHYSMAP_MODULE) -#define HAS_NOR 1 -#else -#define HAS_NOR 0 -#endif - -#if defined(CONFIG_MTD_NAND_DAVINCI) || \ - defined(CONFIG_MTD_NAND_DAVINCI_MODULE) -#define HAS_NAND 1 -#else -#define HAS_NAND 0 -#endif +#define HAS_ATA IS_ENABLED(CONFIG_BLK_DEV_PALMCHIP_BK3710) + +#define HAS_NOR IS_ENABLED(CONFIG_MTD_PHYSMAP) + +#define HAS_NAND IS_ENABLED(CONFIG_MTD_NAND_DAVINCI) static __init void davinci_evm_init(void) { diff --git a/trunk/arch/arm/mach-davinci/board-dm646x-evm.c b/trunk/arch/arm/mach-davinci/board-dm646x-evm.c index fc4871ac1c2c..fbb8e5ab1dc1 100644 --- a/trunk/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/trunk/arch/arm/mach-davinci/board-dm646x-evm.c @@ -117,12 +117,7 @@ static struct platform_device davinci_nand_device = { }, }; -#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \ - defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE) -#define HAS_ATA 1 -#else -#define HAS_ATA 0 -#endif +#define HAS_ATA IS_ENABLED(CONFIG_BLK_DEV_PALMCHIP_BK3710) /* CPLD Register 0 bits to control ATA */ #define DM646X_EVM_ATA_RST BIT(0) diff --git a/trunk/arch/arm/mach-davinci/board-neuros-osd2.c b/trunk/arch/arm/mach-davinci/board-neuros-osd2.c index b70e83c03bed..2bc112adf565 100644 --- a/trunk/arch/arm/mach-davinci/board-neuros-osd2.c +++ b/trunk/arch/arm/mach-davinci/board-neuros-osd2.c @@ -166,20 +166,9 @@ static struct davinci_mmc_config davinci_ntosd2_mmc_config = { .wires = 4, }; +#define HAS_ATA IS_ENABLED(CONFIG_BLK_DEV_PALMCHIP_BK3710) -#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \ - defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE) -#define HAS_ATA 1 -#else -#define HAS_ATA 0 -#endif - -#if defined(CONFIG_MTD_NAND_DAVINCI) || \ - defined(CONFIG_MTD_NAND_DAVINCI_MODULE) -#define HAS_NAND 1 -#else -#define HAS_NAND 0 -#endif +#define HAS_NAND IS_ENABLED(CONFIG_MTD_NAND_DAVINCI) static __init void davinci_ntosd2_init(void) { diff --git a/trunk/arch/arm/mach-davinci/board-omapl138-hawk.c b/trunk/arch/arm/mach-davinci/board-omapl138-hawk.c index 328dbd8a37f5..b8c20de10ca2 100644 --- a/trunk/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/trunk/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -310,6 +310,11 @@ static __init void omapl138_hawk_init(void) if (ret) pr_warn("%s: watchdog registration failed: %d\n", __func__, ret); + + ret = da8xx_register_rproc(); + if (ret) + pr_warn("%s: dsp/rproc registration failed: %d\n", + __func__, ret); } #ifdef CONFIG_SERIAL_8250_CONSOLE @@ -337,4 +342,5 @@ MACHINE_START(OMAPL138_HAWKBOARD, "AM18x/OMAP-L138 Hawkboard") .init_late = davinci_init_late, .dma_zone_size = SZ_128M, .restart = da8xx_restart, + .reserve = da8xx_rproc_reserve_cma, MACHINE_END diff --git a/trunk/arch/arm/mach-davinci/da8xx-dt.c b/trunk/arch/arm/mach-davinci/da8xx-dt.c index b1c0a5958275..961aea8bbad5 100644 --- a/trunk/arch/arm/mach-davinci/da8xx-dt.c +++ b/trunk/arch/arm/mach-davinci/da8xx-dt.c @@ -41,6 +41,12 @@ static struct of_dev_auxdata da850_auxdata_lookup[] __initdata = { OF_DEV_AUXDATA("ti,davinci-i2c", 0x01c22000, "i2c_davinci.1", NULL), OF_DEV_AUXDATA("ti,davinci-wdt", 0x01c21000, "watchdog", NULL), OF_DEV_AUXDATA("ti,da830-mmc", 0x01c40000, "da830-mmc.0", NULL), + OF_DEV_AUXDATA("ti,da850-ehrpwm", 0x01f00000, "ehrpwm", NULL), + OF_DEV_AUXDATA("ti,da850-ehrpwm", 0x01f02000, "ehrpwm", NULL), + OF_DEV_AUXDATA("ti,da850-ecap", 0x01f06000, "ecap", NULL), + OF_DEV_AUXDATA("ti,da850-ecap", 0x01f07000, "ecap", NULL), + OF_DEV_AUXDATA("ti,da850-ecap", 0x01f08000, "ecap", NULL), + OF_DEV_AUXDATA("ti,da830-spi", 0x01f0e000, "spi_davinci.1", NULL), {} }; diff --git a/trunk/arch/arm/mach-davinci/devices.c b/trunk/arch/arm/mach-davinci/devices.c index f6927df2dda8..a7068a3aa9d3 100644 --- a/trunk/arch/arm/mach-davinci/devices.c +++ b/trunk/arch/arm/mach-davinci/devices.c @@ -119,7 +119,7 @@ void __init davinci_init_ide(void) platform_device_register(&ide_device); } -#if defined(CONFIG_MMC_DAVINCI) || defined(CONFIG_MMC_DAVINCI_MODULE) +#if IS_ENABLED(CONFIG_MMC_DAVINCI) static u64 mmcsd0_dma_mask = DMA_BIT_MASK(32); diff --git a/trunk/arch/arm/mach-davinci/usb.c b/trunk/arch/arm/mach-davinci/usb.c index 2b4c648f99b6..b0a6b522575f 100644 --- a/trunk/arch/arm/mach-davinci/usb.c +++ b/trunk/arch/arm/mach-davinci/usb.c @@ -18,7 +18,7 @@ #define DA8XX_USB0_BASE 0x01e00000 #define DA8XX_USB1_BASE 0x01e25000 -#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE) +#if IS_ENABLED(CONFIG_USB_MUSB_HDRC) static struct musb_hdrc_eps_bits musb_eps[] = { { "ep1_tx", 8, }, { "ep1_rx", 8, }, diff --git a/trunk/arch/arm/mach-dove/Makefile b/trunk/arch/arm/mach-dove/Makefile index 3f0a858fb597..4d9d2ffc4535 100644 --- a/trunk/arch/arm/mach-dove/Makefile +++ b/trunk/arch/arm/mach-dove/Makefile @@ -1,4 +1,4 @@ -obj-y += common.o addr-map.o irq.o +obj-y += common.o irq.o obj-$(CONFIG_DOVE_LEGACY) += mpp.o obj-$(CONFIG_PCI) += pcie.o obj-$(CONFIG_MACH_DOVE_DB) += dove-db-setup.o diff --git a/trunk/arch/arm/mach-dove/addr-map.c b/trunk/arch/arm/mach-dove/addr-map.c deleted file mode 100644 index 2a06c0163418..000000000000 --- a/trunk/arch/arm/mach-dove/addr-map.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * arch/arm/mach-dove/addr-map.c - * - * Address map functions for Marvell Dove 88AP510 SoC - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "common.h" - -/* - * Generic Address Decode Windows bit settings - */ -#define TARGET_DDR 0x0 -#define TARGET_BOOTROM 0x1 -#define TARGET_CESA 0x3 -#define TARGET_PCIE0 0x4 -#define TARGET_PCIE1 0x8 -#define TARGET_SCRATCHPAD 0xd - -#define ATTR_CESA 0x01 -#define ATTR_BOOTROM 0xfd -#define ATTR_DEV_SPI0_ROM 0xfe -#define ATTR_DEV_SPI1_ROM 0xfb -#define ATTR_PCIE_IO 0xe0 -#define ATTR_PCIE_MEM 0xe8 -#define ATTR_SCRATCHPAD 0x0 - -static inline void __iomem *ddr_map_sc(int i) -{ - return (void __iomem *)(DOVE_MC_VIRT_BASE + 0x100 + ((i) << 4)); -} - -/* - * Description of the windows needed by the platform code - */ -static struct __initdata orion_addr_map_cfg addr_map_cfg = { - .num_wins = 8, - .remappable_wins = 4, - .bridge_virt_base = BRIDGE_VIRT_BASE, -}; - -static const struct __initdata orion_addr_map_info addr_map_info[] = { - /* - * Windows for PCIe IO+MEM space. - */ - { 0, DOVE_PCIE0_IO_PHYS_BASE, DOVE_PCIE0_IO_SIZE, - TARGET_PCIE0, ATTR_PCIE_IO, DOVE_PCIE0_IO_BUS_BASE - }, - { 1, DOVE_PCIE1_IO_PHYS_BASE, DOVE_PCIE1_IO_SIZE, - TARGET_PCIE1, ATTR_PCIE_IO, DOVE_PCIE1_IO_BUS_BASE - }, - { 2, DOVE_PCIE0_MEM_PHYS_BASE, DOVE_PCIE0_MEM_SIZE, - TARGET_PCIE0, ATTR_PCIE_MEM, -1 - }, - { 3, DOVE_PCIE1_MEM_PHYS_BASE, DOVE_PCIE1_MEM_SIZE, - TARGET_PCIE1, ATTR_PCIE_MEM, -1 - }, - /* - * Window for CESA engine. - */ - { 4, DOVE_CESA_PHYS_BASE, DOVE_CESA_SIZE, - TARGET_CESA, ATTR_CESA, -1 - }, - /* - * Window to the BootROM for Standby and Sleep Resume - */ - { 5, DOVE_BOOTROM_PHYS_BASE, DOVE_BOOTROM_SIZE, - TARGET_BOOTROM, ATTR_BOOTROM, -1 - }, - /* - * Window to the PMU Scratch Pad space - */ - { 6, DOVE_SCRATCHPAD_PHYS_BASE, DOVE_SCRATCHPAD_SIZE, - TARGET_SCRATCHPAD, ATTR_SCRATCHPAD, -1 - }, - /* End marker */ - { -1, 0, 0, 0, 0, 0 } -}; - -void __init dove_setup_cpu_mbus(void) -{ - int i; - int cs; - - /* - * Disable, clear and configure windows. - */ - orion_config_wins(&addr_map_cfg, addr_map_info); - - /* - * Setup MBUS dram target info. - */ - orion_mbus_dram_info.mbus_dram_target_id = TARGET_DDR; - - for (i = 0, cs = 0; i < 2; i++) { - u32 map = readl(ddr_map_sc(i)); - - /* - * Chip select enabled? - */ - if (map & 1) { - struct mbus_dram_window *w; - - w = &orion_mbus_dram_info.cs[cs++]; - w->cs_index = i; - w->mbus_attr = 0; /* CS address decoding done inside */ - /* the DDR controller, no need to */ - /* provide attributes */ - w->base = map & 0xff800000; - w->size = 0x100000 << (((map & 0x000f0000) >> 16) - 4); - } - } - orion_mbus_dram_info.num_cs = cs; -} diff --git a/trunk/arch/arm/mach-dove/board-dt.c b/trunk/arch/arm/mach-dove/board-dt.c index fbde1dd67113..0b142803b2e1 100644 --- a/trunk/arch/arm/mach-dove/board-dt.c +++ b/trunk/arch/arm/mach-dove/board-dt.c @@ -64,7 +64,7 @@ static void __init dove_dt_init(void) #ifdef CONFIG_CACHE_TAUROS2 tauros2_init(0); #endif - dove_setup_cpu_mbus(); + dove_setup_cpu_wins(); /* Setup root of clk tree */ dove_of_clk_init(); diff --git a/trunk/arch/arm/mach-dove/common.c b/trunk/arch/arm/mach-dove/common.c index c6b3b2bb50e7..e2b5da031f96 100644 --- a/trunk/arch/arm/mach-dove/common.c +++ b/trunk/arch/arm/mach-dove/common.c @@ -224,6 +224,9 @@ void __init dove_i2c_init(void) void __init dove_init_early(void) { orion_time_set_base(TIMER_VIRT_BASE); + mvebu_mbus_init("marvell,dove-mbus", + BRIDGE_WINS_BASE, BRIDGE_WINS_SZ, + DOVE_MC_WINS_BASE, DOVE_MC_WINS_SZ); } static int __init dove_find_tclk(void) @@ -326,6 +329,40 @@ void __init dove_sdio1_init(void) platform_device_register(&dove_sdio1); } +void __init dove_setup_cpu_wins(void) +{ + /* + * The PCIe windows will no longer be statically allocated + * here once Dove is migrated to the pci-mvebu driver. + */ + mvebu_mbus_add_window_remap_flags("pcie0.0", + DOVE_PCIE0_IO_PHYS_BASE, + DOVE_PCIE0_IO_SIZE, + DOVE_PCIE0_IO_BUS_BASE, + MVEBU_MBUS_PCI_IO); + mvebu_mbus_add_window_remap_flags("pcie1.0", + DOVE_PCIE1_IO_PHYS_BASE, + DOVE_PCIE1_IO_SIZE, + DOVE_PCIE1_IO_BUS_BASE, + MVEBU_MBUS_PCI_IO); + mvebu_mbus_add_window_remap_flags("pcie0.0", + DOVE_PCIE0_MEM_PHYS_BASE, + DOVE_PCIE0_MEM_SIZE, + MVEBU_MBUS_NO_REMAP, + MVEBU_MBUS_PCI_MEM); + mvebu_mbus_add_window_remap_flags("pcie1.0", + DOVE_PCIE1_MEM_PHYS_BASE, + DOVE_PCIE1_MEM_SIZE, + MVEBU_MBUS_NO_REMAP, + MVEBU_MBUS_PCI_MEM); + mvebu_mbus_add_window("cesa", DOVE_CESA_PHYS_BASE, + DOVE_CESA_SIZE); + mvebu_mbus_add_window("bootrom", DOVE_BOOTROM_PHYS_BASE, + DOVE_BOOTROM_SIZE); + mvebu_mbus_add_window("scratchpad", DOVE_SCRATCHPAD_PHYS_BASE, + DOVE_SCRATCHPAD_SIZE); +} + void __init dove_init(void) { pr_info("Dove 88AP510 SoC, TCLK = %d MHz.\n", @@ -334,7 +371,7 @@ void __init dove_init(void) #ifdef CONFIG_CACHE_TAUROS2 tauros2_init(0); #endif - dove_setup_cpu_mbus(); + dove_setup_cpu_wins(); /* Setup root of clk tree */ dove_clk_init(); diff --git a/trunk/arch/arm/mach-dove/common.h b/trunk/arch/arm/mach-dove/common.h index ee59fba4c6d1..e86347928b67 100644 --- a/trunk/arch/arm/mach-dove/common.h +++ b/trunk/arch/arm/mach-dove/common.h @@ -23,7 +23,7 @@ void dove_map_io(void); void dove_init(void); void dove_init_early(void); void dove_init_irq(void); -void dove_setup_cpu_mbus(void); +void dove_setup_cpu_wins(void); void dove_ge00_init(struct mv643xx_eth_platform_data *eth_data); void dove_sata_init(struct mv_sata_platform_data *sata_data); #ifdef CONFIG_PCI diff --git a/trunk/arch/arm/mach-dove/include/mach/dove.h b/trunk/arch/arm/mach-dove/include/mach/dove.h index 661725e3115a..0c4b35f4ee5b 100644 --- a/trunk/arch/arm/mach-dove/include/mach/dove.h +++ b/trunk/arch/arm/mach-dove/include/mach/dove.h @@ -77,6 +77,8 @@ /* North-South Bridge */ #define BRIDGE_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0x20000) #define BRIDGE_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x20000) +#define BRIDGE_WINS_BASE (BRIDGE_PHYS_BASE) +#define BRIDGE_WINS_SZ (0x80) /* Cryptographic Engine */ #define DOVE_CRYPT_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x30000) @@ -168,6 +170,9 @@ #define DOVE_SSP_CLOCK_ENABLE (1 << 1) #define DOVE_SSP_BPB_CLOCK_SRC_SSP (1 << 11) /* Memory Controller */ +#define DOVE_MC_PHYS_BASE (DOVE_NB_REGS_PHYS_BASE + 0x00000) +#define DOVE_MC_WINS_BASE (DOVE_MC_PHYS_BASE + 0x100) +#define DOVE_MC_WINS_SZ (0x8) #define DOVE_MC_VIRT_BASE (DOVE_NB_REGS_VIRT_BASE + 0x00000) /* LCD Controller */ diff --git a/trunk/arch/arm/mach-exynos/Kconfig b/trunk/arch/arm/mach-exynos/Kconfig index f22f69e2d081..d19edff0ea6e 100644 --- a/trunk/arch/arm/mach-exynos/Kconfig +++ b/trunk/arch/arm/mach-exynos/Kconfig @@ -63,6 +63,7 @@ config SOC_EXYNOS5250 bool "SAMSUNG EXYNOS5250" default y depends on ARCH_EXYNOS5 + select PM_GENERIC_DOMAINS if PM select S5P_PM if PM select S5P_SLEEP if PM select S5P_DEV_MFC @@ -83,12 +84,6 @@ config SOC_EXYNOS5440 help Enable EXYNOS5440 SoC support -config EXYNOS4_MCT - bool - default y - help - Use MCT (Multi Core Timer) as kernel timers - config EXYNOS_ATAGS bool "ATAGS based boot for EXYNOS (deprecated)" depends on !ARCH_MULTIPLATFORM @@ -285,8 +280,8 @@ config MACH_UNIVERSAL_C210 select S5P_DEV_ONENAND select S5P_DEV_TV select S5P_GPIO_INT - select S5P_HRT select S5P_SETUP_MIPIPHY + select SAMSUNG_HRT help Machine support for Samsung Mobile Universal S5PC210 Reference Board. @@ -414,10 +409,12 @@ config MACH_EXYNOS4_DT bool "Samsung Exynos4 Machine using device tree" depends on ARCH_EXYNOS4 select ARM_AMBA + select CLKSRC_OF select CPU_EXYNOS4210 select KEYBOARD_SAMSUNG if INPUT_KEYBOARD select PINCTRL select PINCTRL_EXYNOS + select S5P_DEV_MFC select USE_OF help Machine support for Samsung Exynos4 machine with device tree enabled. @@ -430,6 +427,7 @@ config MACH_EXYNOS5_DT default y depends on ARCH_EXYNOS5 select ARM_AMBA + select CLKSRC_OF select USE_OF help Machine support for Samsung EXYNOS5 machine with device tree enabled. diff --git a/trunk/arch/arm/mach-exynos/Makefile b/trunk/arch/arm/mach-exynos/Makefile index 435757e57bb4..b09b027178f3 100644 --- a/trunk/arch/arm/mach-exynos/Makefile +++ b/trunk/arch/arm/mach-exynos/Makefile @@ -13,10 +13,6 @@ obj- := # Core obj-$(CONFIG_ARCH_EXYNOS) += common.o -obj-$(CONFIG_ARCH_EXYNOS4) += clock-exynos4.o -obj-$(CONFIG_CPU_EXYNOS4210) += clock-exynos4210.o -obj-$(CONFIG_SOC_EXYNOS4212) += clock-exynos4212.o -obj-$(CONFIG_SOC_EXYNOS5250) += clock-exynos5.o obj-$(CONFIG_PM) += pm.o obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o @@ -26,10 +22,14 @@ obj-$(CONFIG_ARCH_EXYNOS) += pmu.o obj-$(CONFIG_SMP) += platsmp.o headsmp.o -obj-$(CONFIG_EXYNOS4_MCT) += mct.o - obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o +obj-$(CONFIG_ARCH_EXYNOS) += exynos-smc.o +obj-$(CONFIG_ARCH_EXYNOS) += firmware.o + +plus_sec := $(call as-instr,.arch_extension sec,+sec) +AFLAGS_exynos-smc.o :=-Wa,-march=armv7-a$(plus_sec) + # machine support obj-$(CONFIG_MACH_SMDKC210) += mach-smdkv310.o diff --git a/trunk/arch/arm/mach-exynos/clock-exynos4.c b/trunk/arch/arm/mach-exynos/clock-exynos4.c deleted file mode 100644 index 8a8468d83c8c..000000000000 --- a/trunk/arch/arm/mach-exynos/clock-exynos4.c +++ /dev/null @@ -1,1601 +0,0 @@ -/* - * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * EXYNOS4 - Clock support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "common.h" -#include "clock-exynos4.h" - -#ifdef CONFIG_PM_SLEEP -static struct sleep_save exynos4_clock_save[] = { - SAVE_ITEM(EXYNOS4_CLKDIV_LEFTBUS), - SAVE_ITEM(EXYNOS4_CLKGATE_IP_LEFTBUS), - SAVE_ITEM(EXYNOS4_CLKDIV_RIGHTBUS), - SAVE_ITEM(EXYNOS4_CLKGATE_IP_RIGHTBUS), - SAVE_ITEM(EXYNOS4_CLKSRC_TOP0), - SAVE_ITEM(EXYNOS4_CLKSRC_TOP1), - SAVE_ITEM(EXYNOS4_CLKSRC_CAM), - SAVE_ITEM(EXYNOS4_CLKSRC_TV), - SAVE_ITEM(EXYNOS4_CLKSRC_MFC), - SAVE_ITEM(EXYNOS4_CLKSRC_G3D), - SAVE_ITEM(EXYNOS4_CLKSRC_LCD0), - SAVE_ITEM(EXYNOS4_CLKSRC_MAUDIO), - SAVE_ITEM(EXYNOS4_CLKSRC_FSYS), - SAVE_ITEM(EXYNOS4_CLKSRC_PERIL0), - SAVE_ITEM(EXYNOS4_CLKSRC_PERIL1), - SAVE_ITEM(EXYNOS4_CLKDIV_CAM), - SAVE_ITEM(EXYNOS4_CLKDIV_TV), - SAVE_ITEM(EXYNOS4_CLKDIV_MFC), - SAVE_ITEM(EXYNOS4_CLKDIV_G3D), - SAVE_ITEM(EXYNOS4_CLKDIV_LCD0), - SAVE_ITEM(EXYNOS4_CLKDIV_MAUDIO), - SAVE_ITEM(EXYNOS4_CLKDIV_FSYS0), - SAVE_ITEM(EXYNOS4_CLKDIV_FSYS1), - SAVE_ITEM(EXYNOS4_CLKDIV_FSYS2), - SAVE_ITEM(EXYNOS4_CLKDIV_FSYS3), - SAVE_ITEM(EXYNOS4_CLKDIV_PERIL0), - SAVE_ITEM(EXYNOS4_CLKDIV_PERIL1), - SAVE_ITEM(EXYNOS4_CLKDIV_PERIL2), - SAVE_ITEM(EXYNOS4_CLKDIV_PERIL3), - SAVE_ITEM(EXYNOS4_CLKDIV_PERIL4), - SAVE_ITEM(EXYNOS4_CLKDIV_PERIL5), - SAVE_ITEM(EXYNOS4_CLKDIV_TOP), - SAVE_ITEM(EXYNOS4_CLKSRC_MASK_TOP), - SAVE_ITEM(EXYNOS4_CLKSRC_MASK_CAM), - SAVE_ITEM(EXYNOS4_CLKSRC_MASK_TV), - SAVE_ITEM(EXYNOS4_CLKSRC_MASK_LCD0), - SAVE_ITEM(EXYNOS4_CLKSRC_MASK_MAUDIO), - SAVE_ITEM(EXYNOS4_CLKSRC_MASK_FSYS), - SAVE_ITEM(EXYNOS4_CLKSRC_MASK_PERIL0), - SAVE_ITEM(EXYNOS4_CLKSRC_MASK_PERIL1), - SAVE_ITEM(EXYNOS4_CLKDIV2_RATIO), - SAVE_ITEM(EXYNOS4_CLKGATE_SCLKCAM), - SAVE_ITEM(EXYNOS4_CLKGATE_IP_CAM), - SAVE_ITEM(EXYNOS4_CLKGATE_IP_TV), - SAVE_ITEM(EXYNOS4_CLKGATE_IP_MFC), - SAVE_ITEM(EXYNOS4_CLKGATE_IP_G3D), - SAVE_ITEM(EXYNOS4_CLKGATE_IP_LCD0), - SAVE_ITEM(EXYNOS4_CLKGATE_IP_FSYS), - SAVE_ITEM(EXYNOS4_CLKGATE_IP_GPS), - SAVE_ITEM(EXYNOS4_CLKGATE_IP_PERIL), - SAVE_ITEM(EXYNOS4_CLKGATE_BLOCK), - SAVE_ITEM(EXYNOS4_CLKSRC_MASK_DMC), - SAVE_ITEM(EXYNOS4_CLKSRC_DMC), - SAVE_ITEM(EXYNOS4_CLKDIV_DMC0), - SAVE_ITEM(EXYNOS4_CLKDIV_DMC1), - SAVE_ITEM(EXYNOS4_CLKGATE_IP_DMC), - SAVE_ITEM(EXYNOS4_CLKSRC_CPU), - SAVE_ITEM(EXYNOS4_CLKDIV_CPU), - SAVE_ITEM(EXYNOS4_CLKDIV_CPU + 0x4), - SAVE_ITEM(EXYNOS4_CLKGATE_SCLKCPU), - SAVE_ITEM(EXYNOS4_CLKGATE_IP_CPU), -}; -#endif - -static struct clk exynos4_clk_sclk_hdmi27m = { - .name = "sclk_hdmi27m", - .rate = 27000000, -}; - -static struct clk exynos4_clk_sclk_hdmiphy = { - .name = "sclk_hdmiphy", -}; - -static struct clk exynos4_clk_sclk_usbphy0 = { - .name = "sclk_usbphy0", - .rate = 27000000, -}; - -static struct clk exynos4_clk_sclk_usbphy1 = { - .name = "sclk_usbphy1", -}; - -static struct clk dummy_apb_pclk = { - .name = "apb_pclk", - .id = -1, -}; - -static int exynos4_clksrc_mask_top_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_TOP, clk, enable); -} - -static int exynos4_clksrc_mask_cam_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_CAM, clk, enable); -} - -static int exynos4_clksrc_mask_lcd0_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_LCD0, clk, enable); -} - -int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_FSYS, clk, enable); -} - -static int exynos4_clksrc_mask_peril0_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_PERIL0, clk, enable); -} - -static int exynos4_clksrc_mask_peril1_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_PERIL1, clk, enable); -} - -static int exynos4_clk_ip_mfc_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS4_CLKGATE_IP_MFC, clk, enable); -} - -static int exynos4_clksrc_mask_tv_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_TV, clk, enable); -} - -static int exynos4_clk_ip_cam_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS4_CLKGATE_IP_CAM, clk, enable); -} - -static int exynos4_clk_ip_tv_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS4_CLKGATE_IP_TV, clk, enable); -} - -int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS4_CLKGATE_IP_IMAGE, clk, enable); -} - -static int exynos4_clk_ip_lcd0_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS4_CLKGATE_IP_LCD0, clk, enable); -} - -int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS4210_CLKGATE_IP_LCD1, clk, enable); -} - -int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS4_CLKGATE_IP_FSYS, clk, enable); -} - -static int exynos4_clk_ip_peril_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS4_CLKGATE_IP_PERIL, clk, enable); -} - -static int exynos4_clk_ip_perir_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS4_CLKGATE_IP_PERIR, clk, enable); -} - -int exynos4_clk_ip_dmc_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS4_CLKGATE_IP_DMC, clk, enable); -} - -static int exynos4_clk_hdmiphy_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_HDMI_PHY_CONTROL, clk, enable); -} - -static int exynos4_clk_dac_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_DAC_PHY_CONTROL, clk, enable); -} - -/* Core list of CMU_CPU side */ - -static struct clksrc_clk exynos4_clk_mout_apll = { - .clk = { - .name = "mout_apll", - }, - .sources = &clk_src_apll, - .reg_src = { .reg = EXYNOS4_CLKSRC_CPU, .shift = 0, .size = 1 }, -}; - -static struct clksrc_clk exynos4_clk_sclk_apll = { - .clk = { - .name = "sclk_apll", - .parent = &exynos4_clk_mout_apll.clk, - }, - .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 24, .size = 3 }, -}; - -static struct clksrc_clk exynos4_clk_mout_epll = { - .clk = { - .name = "mout_epll", - }, - .sources = &clk_src_epll, - .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 4, .size = 1 }, -}; - -struct clksrc_clk exynos4_clk_mout_mpll = { - .clk = { - .name = "mout_mpll", - }, - .sources = &clk_src_mpll, - - /* reg_src will be added in each SoCs' clock */ -}; - -static struct clk *exynos4_clkset_moutcore_list[] = { - [0] = &exynos4_clk_mout_apll.clk, - [1] = &exynos4_clk_mout_mpll.clk, -}; - -static struct clksrc_sources exynos4_clkset_moutcore = { - .sources = exynos4_clkset_moutcore_list, - .nr_sources = ARRAY_SIZE(exynos4_clkset_moutcore_list), -}; - -static struct clksrc_clk exynos4_clk_moutcore = { - .clk = { - .name = "moutcore", - }, - .sources = &exynos4_clkset_moutcore, - .reg_src = { .reg = EXYNOS4_CLKSRC_CPU, .shift = 16, .size = 1 }, -}; - -static struct clksrc_clk exynos4_clk_coreclk = { - .clk = { - .name = "core_clk", - .parent = &exynos4_clk_moutcore.clk, - }, - .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 0, .size = 3 }, -}; - -static struct clksrc_clk exynos4_clk_armclk = { - .clk = { - .name = "armclk", - .parent = &exynos4_clk_coreclk.clk, - }, -}; - -static struct clksrc_clk exynos4_clk_aclk_corem0 = { - .clk = { - .name = "aclk_corem0", - .parent = &exynos4_clk_coreclk.clk, - }, - .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 4, .size = 3 }, -}; - -static struct clksrc_clk exynos4_clk_aclk_cores = { - .clk = { - .name = "aclk_cores", - .parent = &exynos4_clk_coreclk.clk, - }, - .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 4, .size = 3 }, -}; - -static struct clksrc_clk exynos4_clk_aclk_corem1 = { - .clk = { - .name = "aclk_corem1", - .parent = &exynos4_clk_coreclk.clk, - }, - .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 8, .size = 3 }, -}; - -static struct clksrc_clk exynos4_clk_periphclk = { - .clk = { - .name = "periphclk", - .parent = &exynos4_clk_coreclk.clk, - }, - .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 12, .size = 3 }, -}; - -/* Core list of CMU_CORE side */ - -static struct clk *exynos4_clkset_corebus_list[] = { - [0] = &exynos4_clk_mout_mpll.clk, - [1] = &exynos4_clk_sclk_apll.clk, -}; - -struct clksrc_sources exynos4_clkset_mout_corebus = { - .sources = exynos4_clkset_corebus_list, - .nr_sources = ARRAY_SIZE(exynos4_clkset_corebus_list), -}; - -static struct clksrc_clk exynos4_clk_mout_corebus = { - .clk = { - .name = "mout_corebus", - }, - .sources = &exynos4_clkset_mout_corebus, - .reg_src = { .reg = EXYNOS4_CLKSRC_DMC, .shift = 4, .size = 1 }, -}; - -static struct clksrc_clk exynos4_clk_sclk_dmc = { - .clk = { - .name = "sclk_dmc", - .parent = &exynos4_clk_mout_corebus.clk, - }, - .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 12, .size = 3 }, -}; - -static struct clksrc_clk exynos4_clk_aclk_cored = { - .clk = { - .name = "aclk_cored", - .parent = &exynos4_clk_sclk_dmc.clk, - }, - .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 16, .size = 3 }, -}; - -static struct clksrc_clk exynos4_clk_aclk_corep = { - .clk = { - .name = "aclk_corep", - .parent = &exynos4_clk_aclk_cored.clk, - }, - .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 20, .size = 3 }, -}; - -static struct clksrc_clk exynos4_clk_aclk_acp = { - .clk = { - .name = "aclk_acp", - .parent = &exynos4_clk_mout_corebus.clk, - }, - .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 0, .size = 3 }, -}; - -static struct clksrc_clk exynos4_clk_pclk_acp = { - .clk = { - .name = "pclk_acp", - .parent = &exynos4_clk_aclk_acp.clk, - }, - .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 4, .size = 3 }, -}; - -/* Core list of CMU_TOP side */ - -struct clk *exynos4_clkset_aclk_top_list[] = { - [0] = &exynos4_clk_mout_mpll.clk, - [1] = &exynos4_clk_sclk_apll.clk, -}; - -static struct clksrc_sources exynos4_clkset_aclk = { - .sources = exynos4_clkset_aclk_top_list, - .nr_sources = ARRAY_SIZE(exynos4_clkset_aclk_top_list), -}; - -static struct clksrc_clk exynos4_clk_aclk_200 = { - .clk = { - .name = "aclk_200", - }, - .sources = &exynos4_clkset_aclk, - .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 12, .size = 1 }, - .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 0, .size = 3 }, -}; - -static struct clksrc_clk exynos4_clk_aclk_100 = { - .clk = { - .name = "aclk_100", - }, - .sources = &exynos4_clkset_aclk, - .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 16, .size = 1 }, - .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 4, .size = 4 }, -}; - -static struct clksrc_clk exynos4_clk_aclk_160 = { - .clk = { - .name = "aclk_160", - }, - .sources = &exynos4_clkset_aclk, - .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 20, .size = 1 }, - .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 8, .size = 3 }, -}; - -struct clksrc_clk exynos4_clk_aclk_133 = { - .clk = { - .name = "aclk_133", - }, - .sources = &exynos4_clkset_aclk, - .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 24, .size = 1 }, - .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 12, .size = 3 }, -}; - -static struct clk *exynos4_clkset_vpllsrc_list[] = { - [0] = &clk_fin_vpll, - [1] = &exynos4_clk_sclk_hdmi27m, -}; - -static struct clksrc_sources exynos4_clkset_vpllsrc = { - .sources = exynos4_clkset_vpllsrc_list, - .nr_sources = ARRAY_SIZE(exynos4_clkset_vpllsrc_list), -}; - -static struct clksrc_clk exynos4_clk_vpllsrc = { - .clk = { - .name = "vpll_src", - .enable = exynos4_clksrc_mask_top_ctrl, - .ctrlbit = (1 << 0), - }, - .sources = &exynos4_clkset_vpllsrc, - .reg_src = { .reg = EXYNOS4_CLKSRC_TOP1, .shift = 0, .size = 1 }, -}; - -static struct clk *exynos4_clkset_sclk_vpll_list[] = { - [0] = &exynos4_clk_vpllsrc.clk, - [1] = &clk_fout_vpll, -}; - -static struct clksrc_sources exynos4_clkset_sclk_vpll = { - .sources = exynos4_clkset_sclk_vpll_list, - .nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_vpll_list), -}; - -static struct clksrc_clk exynos4_clk_sclk_vpll = { - .clk = { - .name = "sclk_vpll", - }, - .sources = &exynos4_clkset_sclk_vpll, - .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 8, .size = 1 }, -}; - -static struct clk exynos4_init_clocks_off[] = { - { - .name = "timers", - .parent = &exynos4_clk_aclk_100.clk, - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1<<24), - }, { - .name = "csis", - .devname = "s5p-mipi-csis.0", - .enable = exynos4_clk_ip_cam_ctrl, - .ctrlbit = (1 << 4), - }, { - .name = "csis", - .devname = "s5p-mipi-csis.1", - .enable = exynos4_clk_ip_cam_ctrl, - .ctrlbit = (1 << 5), - }, { - .name = "jpeg", - .id = 0, - .enable = exynos4_clk_ip_cam_ctrl, - .ctrlbit = (1 << 6), - }, { - .name = "fimc", - .devname = "exynos4-fimc.0", - .enable = exynos4_clk_ip_cam_ctrl, - .ctrlbit = (1 << 0), - }, { - .name = "fimc", - .devname = "exynos4-fimc.1", - .enable = exynos4_clk_ip_cam_ctrl, - .ctrlbit = (1 << 1), - }, { - .name = "fimc", - .devname = "exynos4-fimc.2", - .enable = exynos4_clk_ip_cam_ctrl, - .ctrlbit = (1 << 2), - }, { - .name = "fimc", - .devname = "exynos4-fimc.3", - .enable = exynos4_clk_ip_cam_ctrl, - .ctrlbit = (1 << 3), - }, { - .name = "tsi", - .enable = exynos4_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 4), - }, { - .name = "hsmmc", - .devname = "exynos4-sdhci.0", - .parent = &exynos4_clk_aclk_133.clk, - .enable = exynos4_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 5), - }, { - .name = "hsmmc", - .devname = "exynos4-sdhci.1", - .parent = &exynos4_clk_aclk_133.clk, - .enable = exynos4_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 6), - }, { - .name = "hsmmc", - .devname = "exynos4-sdhci.2", - .parent = &exynos4_clk_aclk_133.clk, - .enable = exynos4_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 7), - }, { - .name = "hsmmc", - .devname = "exynos4-sdhci.3", - .parent = &exynos4_clk_aclk_133.clk, - .enable = exynos4_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 8), - }, { - .name = "biu", - .parent = &exynos4_clk_aclk_133.clk, - .enable = exynos4_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 9), - }, { - .name = "onenand", - .enable = exynos4_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 15), - }, { - .name = "nfcon", - .enable = exynos4_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 16), - }, { - .name = "dac", - .devname = "s5p-sdo", - .enable = exynos4_clk_ip_tv_ctrl, - .ctrlbit = (1 << 2), - }, { - .name = "mixer", - .devname = "s5p-mixer", - .enable = exynos4_clk_ip_tv_ctrl, - .ctrlbit = (1 << 1), - }, { - .name = "vp", - .devname = "s5p-mixer", - .enable = exynos4_clk_ip_tv_ctrl, - .ctrlbit = (1 << 0), - }, { - .name = "hdmi", - .devname = "exynos4-hdmi", - .enable = exynos4_clk_ip_tv_ctrl, - .ctrlbit = (1 << 3), - }, { - .name = "hdmiphy", - .devname = "exynos4-hdmi", - .enable = exynos4_clk_hdmiphy_ctrl, - .ctrlbit = (1 << 0), - }, { - .name = "dacphy", - .devname = "s5p-sdo", - .enable = exynos4_clk_dac_ctrl, - .ctrlbit = (1 << 0), - }, { - .name = "adc", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 15), - }, { - .name = "tmu_apbif", - .enable = exynos4_clk_ip_perir_ctrl, - .ctrlbit = (1 << 17), - }, { - .name = "keypad", - .enable = exynos4_clk_ip_perir_ctrl, - .ctrlbit = (1 << 16), - }, { - .name = "rtc", - .enable = exynos4_clk_ip_perir_ctrl, - .ctrlbit = (1 << 15), - }, { - .name = "watchdog", - .parent = &exynos4_clk_aclk_100.clk, - .enable = exynos4_clk_ip_perir_ctrl, - .ctrlbit = (1 << 14), - }, { - .name = "usbhost", - .enable = exynos4_clk_ip_fsys_ctrl , - .ctrlbit = (1 << 12), - }, { - .name = "otg", - .enable = exynos4_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 13), - }, { - .name = "spi", - .devname = "exynos4210-spi.0", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 16), - }, { - .name = "spi", - .devname = "exynos4210-spi.1", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 17), - }, { - .name = "spi", - .devname = "exynos4210-spi.2", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 18), - }, { - .name = "iis", - .devname = "samsung-i2s.1", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 20), - }, { - .name = "iis", - .devname = "samsung-i2s.2", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 21), - }, { - .name = "pcm", - .devname = "samsung-pcm.1", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 22), - }, { - .name = "pcm", - .devname = "samsung-pcm.2", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 23), - }, { - .name = "slimbus", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 25), - }, { - .name = "spdif", - .devname = "samsung-spdif", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 26), - }, { - .name = "ac97", - .devname = "samsung-ac97", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 27), - }, { - .name = "mfc", - .devname = "s5p-mfc", - .enable = exynos4_clk_ip_mfc_ctrl, - .ctrlbit = (1 << 0), - }, { - .name = "i2c", - .devname = "s3c2440-i2c.0", - .parent = &exynos4_clk_aclk_100.clk, - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 6), - }, { - .name = "i2c", - .devname = "s3c2440-i2c.1", - .parent = &exynos4_clk_aclk_100.clk, - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 7), - }, { - .name = "i2c", - .devname = "s3c2440-i2c.2", - .parent = &exynos4_clk_aclk_100.clk, - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 8), - }, { - .name = "i2c", - .devname = "s3c2440-i2c.3", - .parent = &exynos4_clk_aclk_100.clk, - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 9), - }, { - .name = "i2c", - .devname = "s3c2440-i2c.4", - .parent = &exynos4_clk_aclk_100.clk, - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 10), - }, { - .name = "i2c", - .devname = "s3c2440-i2c.5", - .parent = &exynos4_clk_aclk_100.clk, - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 11), - }, { - .name = "i2c", - .devname = "s3c2440-i2c.6", - .parent = &exynos4_clk_aclk_100.clk, - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 12), - }, { - .name = "i2c", - .devname = "s3c2440-i2c.7", - .parent = &exynos4_clk_aclk_100.clk, - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 13), - }, { - .name = "i2c", - .devname = "s3c2440-hdmiphy-i2c", - .parent = &exynos4_clk_aclk_100.clk, - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 14), - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.0", - .enable = exynos4_clk_ip_mfc_ctrl, - .ctrlbit = (1 << 1), - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.1", - .enable = exynos4_clk_ip_mfc_ctrl, - .ctrlbit = (1 << 2), - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.2", - .enable = exynos4_clk_ip_tv_ctrl, - .ctrlbit = (1 << 4), - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.3", - .enable = exynos4_clk_ip_cam_ctrl, - .ctrlbit = (1 << 11), - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.4", - .enable = exynos4_clk_ip_image_ctrl, - .ctrlbit = (1 << 4), - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.5", - .enable = exynos4_clk_ip_cam_ctrl, - .ctrlbit = (1 << 7), - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.6", - .enable = exynos4_clk_ip_cam_ctrl, - .ctrlbit = (1 << 8), - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.7", - .enable = exynos4_clk_ip_cam_ctrl, - .ctrlbit = (1 << 9), - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.8", - .enable = exynos4_clk_ip_cam_ctrl, - .ctrlbit = (1 << 10), - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.10", - .enable = exynos4_clk_ip_lcd0_ctrl, - .ctrlbit = (1 << 4), - } -}; - -static struct clk exynos4_init_clocks_on[] = { - { - .name = "uart", - .devname = "s5pv210-uart.0", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 0), - }, { - .name = "uart", - .devname = "s5pv210-uart.1", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 1), - }, { - .name = "uart", - .devname = "s5pv210-uart.2", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 2), - }, { - .name = "uart", - .devname = "s5pv210-uart.3", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 3), - }, { - .name = "uart", - .devname = "s5pv210-uart.4", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 4), - }, { - .name = "uart", - .devname = "s5pv210-uart.5", - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1 << 5), - } -}; - -static struct clk exynos4_clk_pdma0 = { - .name = "dma", - .devname = "dma-pl330.0", - .enable = exynos4_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 0), -}; - -static struct clk exynos4_clk_pdma1 = { - .name = "dma", - .devname = "dma-pl330.1", - .enable = exynos4_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 1), -}; - -static struct clk exynos4_clk_mdma1 = { - .name = "dma", - .devname = "dma-pl330.2", - .enable = exynos4_clk_ip_image_ctrl, - .ctrlbit = ((1 << 8) | (1 << 5) | (1 << 2)), -}; - -static struct clk exynos4_clk_fimd0 = { - .name = "fimd", - .devname = "exynos4-fb.0", - .enable = exynos4_clk_ip_lcd0_ctrl, - .ctrlbit = (1 << 0), -}; - -struct clk *exynos4_clkset_group_list[] = { - [0] = &clk_ext_xtal_mux, - [1] = &clk_xusbxti, - [2] = &exynos4_clk_sclk_hdmi27m, - [3] = &exynos4_clk_sclk_usbphy0, - [4] = &exynos4_clk_sclk_usbphy1, - [5] = &exynos4_clk_sclk_hdmiphy, - [6] = &exynos4_clk_mout_mpll.clk, - [7] = &exynos4_clk_mout_epll.clk, - [8] = &exynos4_clk_sclk_vpll.clk, -}; - -struct clksrc_sources exynos4_clkset_group = { - .sources = exynos4_clkset_group_list, - .nr_sources = ARRAY_SIZE(exynos4_clkset_group_list), -}; - -static struct clk *exynos4_clkset_mout_g2d0_list[] = { - [0] = &exynos4_clk_mout_mpll.clk, - [1] = &exynos4_clk_sclk_apll.clk, -}; - -struct clksrc_sources exynos4_clkset_mout_g2d0 = { - .sources = exynos4_clkset_mout_g2d0_list, - .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_g2d0_list), -}; - -static struct clk *exynos4_clkset_mout_g2d1_list[] = { - [0] = &exynos4_clk_mout_epll.clk, - [1] = &exynos4_clk_sclk_vpll.clk, -}; - -struct clksrc_sources exynos4_clkset_mout_g2d1 = { - .sources = exynos4_clkset_mout_g2d1_list, - .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_g2d1_list), -}; - -static struct clk *exynos4_clkset_mout_mfc0_list[] = { - [0] = &exynos4_clk_mout_mpll.clk, - [1] = &exynos4_clk_sclk_apll.clk, -}; - -static struct clksrc_sources exynos4_clkset_mout_mfc0 = { - .sources = exynos4_clkset_mout_mfc0_list, - .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_mfc0_list), -}; - -static struct clksrc_clk exynos4_clk_mout_mfc0 = { - .clk = { - .name = "mout_mfc0", - }, - .sources = &exynos4_clkset_mout_mfc0, - .reg_src = { .reg = EXYNOS4_CLKSRC_MFC, .shift = 0, .size = 1 }, -}; - -static struct clk *exynos4_clkset_mout_mfc1_list[] = { - [0] = &exynos4_clk_mout_epll.clk, - [1] = &exynos4_clk_sclk_vpll.clk, -}; - -static struct clksrc_sources exynos4_clkset_mout_mfc1 = { - .sources = exynos4_clkset_mout_mfc1_list, - .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_mfc1_list), -}; - -static struct clksrc_clk exynos4_clk_mout_mfc1 = { - .clk = { - .name = "mout_mfc1", - }, - .sources = &exynos4_clkset_mout_mfc1, - .reg_src = { .reg = EXYNOS4_CLKSRC_MFC, .shift = 4, .size = 1 }, -}; - -static struct clk *exynos4_clkset_mout_mfc_list[] = { - [0] = &exynos4_clk_mout_mfc0.clk, - [1] = &exynos4_clk_mout_mfc1.clk, -}; - -static struct clksrc_sources exynos4_clkset_mout_mfc = { - .sources = exynos4_clkset_mout_mfc_list, - .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_mfc_list), -}; - -static struct clk *exynos4_clkset_sclk_dac_list[] = { - [0] = &exynos4_clk_sclk_vpll.clk, - [1] = &exynos4_clk_sclk_hdmiphy, -}; - -static struct clksrc_sources exynos4_clkset_sclk_dac = { - .sources = exynos4_clkset_sclk_dac_list, - .nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_dac_list), -}; - -static struct clksrc_clk exynos4_clk_sclk_dac = { - .clk = { - .name = "sclk_dac", - .enable = exynos4_clksrc_mask_tv_ctrl, - .ctrlbit = (1 << 8), - }, - .sources = &exynos4_clkset_sclk_dac, - .reg_src = { .reg = EXYNOS4_CLKSRC_TV, .shift = 8, .size = 1 }, -}; - -static struct clksrc_clk exynos4_clk_sclk_pixel = { - .clk = { - .name = "sclk_pixel", - .parent = &exynos4_clk_sclk_vpll.clk, - }, - .reg_div = { .reg = EXYNOS4_CLKDIV_TV, .shift = 0, .size = 4 }, -}; - -static struct clk *exynos4_clkset_sclk_hdmi_list[] = { - [0] = &exynos4_clk_sclk_pixel.clk, - [1] = &exynos4_clk_sclk_hdmiphy, -}; - -static struct clksrc_sources exynos4_clkset_sclk_hdmi = { - .sources = exynos4_clkset_sclk_hdmi_list, - .nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_hdmi_list), -}; - -static struct clksrc_clk exynos4_clk_sclk_hdmi = { - .clk = { - .name = "sclk_hdmi", - .enable = exynos4_clksrc_mask_tv_ctrl, - .ctrlbit = (1 << 0), - }, - .sources = &exynos4_clkset_sclk_hdmi, - .reg_src = { .reg = EXYNOS4_CLKSRC_TV, .shift = 0, .size = 1 }, -}; - -static struct clk *exynos4_clkset_sclk_mixer_list[] = { - [0] = &exynos4_clk_sclk_dac.clk, - [1] = &exynos4_clk_sclk_hdmi.clk, -}; - -static struct clksrc_sources exynos4_clkset_sclk_mixer = { - .sources = exynos4_clkset_sclk_mixer_list, - .nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_mixer_list), -}; - -static struct clksrc_clk exynos4_clk_sclk_mixer = { - .clk = { - .name = "sclk_mixer", - .enable = exynos4_clksrc_mask_tv_ctrl, - .ctrlbit = (1 << 4), - }, - .sources = &exynos4_clkset_sclk_mixer, - .reg_src = { .reg = EXYNOS4_CLKSRC_TV, .shift = 4, .size = 1 }, -}; - -static struct clksrc_clk *exynos4_sclk_tv[] = { - &exynos4_clk_sclk_dac, - &exynos4_clk_sclk_pixel, - &exynos4_clk_sclk_hdmi, - &exynos4_clk_sclk_mixer, -}; - -static struct clksrc_clk exynos4_clk_dout_mmc0 = { - .clk = { - .name = "dout_mmc0", - }, - .sources = &exynos4_clkset_group, - .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 0, .size = 4 }, - .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 0, .size = 4 }, -}; - -static struct clksrc_clk exynos4_clk_dout_mmc1 = { - .clk = { - .name = "dout_mmc1", - }, - .sources = &exynos4_clkset_group, - .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 4, .size = 4 }, - .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 16, .size = 4 }, -}; - -static struct clksrc_clk exynos4_clk_dout_mmc2 = { - .clk = { - .name = "dout_mmc2", - }, - .sources = &exynos4_clkset_group, - .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 8, .size = 4 }, - .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 0, .size = 4 }, -}; - -static struct clksrc_clk exynos4_clk_dout_mmc3 = { - .clk = { - .name = "dout_mmc3", - }, - .sources = &exynos4_clkset_group, - .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 12, .size = 4 }, - .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 16, .size = 4 }, -}; - -static struct clksrc_clk exynos4_clk_dout_mmc4 = { - .clk = { - .name = "dout_mmc4", - }, - .sources = &exynos4_clkset_group, - .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 16, .size = 4 }, - .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS3, .shift = 0, .size = 4 }, -}; - -static struct clksrc_clk exynos4_clksrcs[] = { - { - .clk = { - .name = "sclk_pwm", - .enable = exynos4_clksrc_mask_peril0_ctrl, - .ctrlbit = (1 << 24), - }, - .sources = &exynos4_clkset_group, - .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 24, .size = 4 }, - .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL3, .shift = 0, .size = 4 }, - }, { - .clk = { - .name = "sclk_csis", - .devname = "s5p-mipi-csis.0", - .enable = exynos4_clksrc_mask_cam_ctrl, - .ctrlbit = (1 << 24), - }, - .sources = &exynos4_clkset_group, - .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 24, .size = 4 }, - .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 24, .size = 4 }, - }, { - .clk = { - .name = "sclk_csis", - .devname = "s5p-mipi-csis.1", - .enable = exynos4_clksrc_mask_cam_ctrl, - .ctrlbit = (1 << 28), - }, - .sources = &exynos4_clkset_group, - .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 28, .size = 4 }, - .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 28, .size = 4 }, - }, { - .clk = { - .name = "sclk_cam0", - .enable = exynos4_clksrc_mask_cam_ctrl, - .ctrlbit = (1 << 16), - }, - .sources = &exynos4_clkset_group, - .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 16, .size = 4 }, - .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 16, .size = 4 }, - }, { - .clk = { - .name = "sclk_cam1", - .enable = exynos4_clksrc_mask_cam_ctrl, - .ctrlbit = (1 << 20), - }, - .sources = &exynos4_clkset_group, - .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 20, .size = 4 }, - .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 20, .size = 4 }, - }, { - .clk = { - .name = "sclk_fimc", - .devname = "exynos4-fimc.0", - .enable = exynos4_clksrc_mask_cam_ctrl, - .ctrlbit = (1 << 0), - }, - .sources = &exynos4_clkset_group, - .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 0, .size = 4 }, - .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 0, .size = 4 }, - }, { - .clk = { - .name = "sclk_fimc", - .devname = "exynos4-fimc.1", - .enable = exynos4_clksrc_mask_cam_ctrl, - .ctrlbit = (1 << 4), - }, - .sources = &exynos4_clkset_group, - .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 4, .size = 4 }, - .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 4, .size = 4 }, - }, { - .clk = { - .name = "sclk_fimc", - .devname = "exynos4-fimc.2", - .enable = exynos4_clksrc_mask_cam_ctrl, - .ctrlbit = (1 << 8), - }, - .sources = &exynos4_clkset_group, - .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 8, .size = 4 }, - .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 8, .size = 4 }, - }, { - .clk = { - .name = "sclk_fimc", - .devname = "exynos4-fimc.3", - .enable = exynos4_clksrc_mask_cam_ctrl, - .ctrlbit = (1 << 12), - }, - .sources = &exynos4_clkset_group, - .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 12, .size = 4 }, - .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 12, .size = 4 }, - }, { - .clk = { - .name = "sclk_fimd", - .devname = "exynos4-fb.0", - .enable = exynos4_clksrc_mask_lcd0_ctrl, - .ctrlbit = (1 << 0), - }, - .sources = &exynos4_clkset_group, - .reg_src = { .reg = EXYNOS4_CLKSRC_LCD0, .shift = 0, .size = 4 }, - .reg_div = { .reg = EXYNOS4_CLKDIV_LCD0, .shift = 0, .size = 4 }, - }, { - .clk = { - .name = "sclk_mfc", - .devname = "s5p-mfc", - }, - .sources = &exynos4_clkset_mout_mfc, - .reg_src = { .reg = EXYNOS4_CLKSRC_MFC, .shift = 8, .size = 1 }, - .reg_div = { .reg = EXYNOS4_CLKDIV_MFC, .shift = 0, .size = 4 }, - }, { - .clk = { - .name = "ciu", - .parent = &exynos4_clk_dout_mmc4.clk, - .enable = exynos4_clksrc_mask_fsys_ctrl, - .ctrlbit = (1 << 16), - }, - .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS3, .shift = 8, .size = 8 }, - } -}; - -static struct clksrc_clk exynos4_clk_sclk_uart0 = { - .clk = { - .name = "uclk1", - .devname = "exynos4210-uart.0", - .enable = exynos4_clksrc_mask_peril0_ctrl, - .ctrlbit = (1 << 0), - }, - .sources = &exynos4_clkset_group, - .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 0, .size = 4 }, - .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 0, .size = 4 }, -}; - -static struct clksrc_clk exynos4_clk_sclk_uart1 = { - .clk = { - .name = "uclk1", - .devname = "exynos4210-uart.1", - .enable = exynos4_clksrc_mask_peril0_ctrl, - .ctrlbit = (1 << 4), - }, - .sources = &exynos4_clkset_group, - .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 4, .size = 4 }, - .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 4, .size = 4 }, -}; - -static struct clksrc_clk exynos4_clk_sclk_uart2 = { - .clk = { - .name = "uclk1", - .devname = "exynos4210-uart.2", - .enable = exynos4_clksrc_mask_peril0_ctrl, - .ctrlbit = (1 << 8), - }, - .sources = &exynos4_clkset_group, - .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 8, .size = 4 }, - .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 8, .size = 4 }, -}; - -static struct clksrc_clk exynos4_clk_sclk_uart3 = { - .clk = { - .name = "uclk1", - .devname = "exynos4210-uart.3", - .enable = exynos4_clksrc_mask_peril0_ctrl, - .ctrlbit = (1 << 12), - }, - .sources = &exynos4_clkset_group, - .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 12, .size = 4 }, - .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 12, .size = 4 }, -}; - -static struct clksrc_clk exynos4_clk_sclk_mmc0 = { - .clk = { - .name = "sclk_mmc", - .devname = "exynos4-sdhci.0", - .parent = &exynos4_clk_dout_mmc0.clk, - .enable = exynos4_clksrc_mask_fsys_ctrl, - .ctrlbit = (1 << 0), - }, - .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 8, .size = 8 }, -}; - -static struct clksrc_clk exynos4_clk_sclk_mmc1 = { - .clk = { - .name = "sclk_mmc", - .devname = "exynos4-sdhci.1", - .parent = &exynos4_clk_dout_mmc1.clk, - .enable = exynos4_clksrc_mask_fsys_ctrl, - .ctrlbit = (1 << 4), - }, - .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 24, .size = 8 }, -}; - -static struct clksrc_clk exynos4_clk_sclk_mmc2 = { - .clk = { - .name = "sclk_mmc", - .devname = "exynos4-sdhci.2", - .parent = &exynos4_clk_dout_mmc2.clk, - .enable = exynos4_clksrc_mask_fsys_ctrl, - .ctrlbit = (1 << 8), - }, - .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 8, .size = 8 }, -}; - -static struct clksrc_clk exynos4_clk_sclk_mmc3 = { - .clk = { - .name = "sclk_mmc", - .devname = "exynos4-sdhci.3", - .parent = &exynos4_clk_dout_mmc3.clk, - .enable = exynos4_clksrc_mask_fsys_ctrl, - .ctrlbit = (1 << 12), - }, - .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 24, .size = 8 }, -}; - -static struct clksrc_clk exynos4_clk_mdout_spi0 = { - .clk = { - .name = "mdout_spi", - .devname = "exynos4210-spi.0", - }, - .sources = &exynos4_clkset_group, - .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 16, .size = 4 }, - .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 0, .size = 4 }, -}; - -static struct clksrc_clk exynos4_clk_mdout_spi1 = { - .clk = { - .name = "mdout_spi", - .devname = "exynos4210-spi.1", - }, - .sources = &exynos4_clkset_group, - .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 20, .size = 4 }, - .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 16, .size = 4 }, -}; - -static struct clksrc_clk exynos4_clk_mdout_spi2 = { - .clk = { - .name = "mdout_spi", - .devname = "exynos4210-spi.2", - }, - .sources = &exynos4_clkset_group, - .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 24, .size = 4 }, - .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL2, .shift = 0, .size = 4 }, -}; - -static struct clksrc_clk exynos4_clk_sclk_spi0 = { - .clk = { - .name = "sclk_spi", - .devname = "exynos4210-spi.0", - .parent = &exynos4_clk_mdout_spi0.clk, - .enable = exynos4_clksrc_mask_peril1_ctrl, - .ctrlbit = (1 << 16), - }, - .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 8, .size = 8 }, -}; - -static struct clksrc_clk exynos4_clk_sclk_spi1 = { - .clk = { - .name = "sclk_spi", - .devname = "exynos4210-spi.1", - .parent = &exynos4_clk_mdout_spi1.clk, - .enable = exynos4_clksrc_mask_peril1_ctrl, - .ctrlbit = (1 << 20), - }, - .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 24, .size = 8 }, -}; - -static struct clksrc_clk exynos4_clk_sclk_spi2 = { - .clk = { - .name = "sclk_spi", - .devname = "exynos4210-spi.2", - .parent = &exynos4_clk_mdout_spi2.clk, - .enable = exynos4_clksrc_mask_peril1_ctrl, - .ctrlbit = (1 << 24), - }, - .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL2, .shift = 8, .size = 8 }, -}; - -/* Clock initialization code */ -static struct clksrc_clk *exynos4_sysclks[] = { - &exynos4_clk_mout_apll, - &exynos4_clk_sclk_apll, - &exynos4_clk_mout_epll, - &exynos4_clk_mout_mpll, - &exynos4_clk_moutcore, - &exynos4_clk_coreclk, - &exynos4_clk_armclk, - &exynos4_clk_aclk_corem0, - &exynos4_clk_aclk_cores, - &exynos4_clk_aclk_corem1, - &exynos4_clk_periphclk, - &exynos4_clk_mout_corebus, - &exynos4_clk_sclk_dmc, - &exynos4_clk_aclk_cored, - &exynos4_clk_aclk_corep, - &exynos4_clk_aclk_acp, - &exynos4_clk_pclk_acp, - &exynos4_clk_vpllsrc, - &exynos4_clk_sclk_vpll, - &exynos4_clk_aclk_200, - &exynos4_clk_aclk_100, - &exynos4_clk_aclk_160, - &exynos4_clk_aclk_133, - &exynos4_clk_dout_mmc0, - &exynos4_clk_dout_mmc1, - &exynos4_clk_dout_mmc2, - &exynos4_clk_dout_mmc3, - &exynos4_clk_dout_mmc4, - &exynos4_clk_mout_mfc0, - &exynos4_clk_mout_mfc1, -}; - -static struct clk *exynos4_clk_cdev[] = { - &exynos4_clk_pdma0, - &exynos4_clk_pdma1, - &exynos4_clk_mdma1, - &exynos4_clk_fimd0, -}; - -static struct clksrc_clk *exynos4_clksrc_cdev[] = { - &exynos4_clk_sclk_uart0, - &exynos4_clk_sclk_uart1, - &exynos4_clk_sclk_uart2, - &exynos4_clk_sclk_uart3, - &exynos4_clk_sclk_mmc0, - &exynos4_clk_sclk_mmc1, - &exynos4_clk_sclk_mmc2, - &exynos4_clk_sclk_mmc3, - &exynos4_clk_sclk_spi0, - &exynos4_clk_sclk_spi1, - &exynos4_clk_sclk_spi2, - &exynos4_clk_mdout_spi0, - &exynos4_clk_mdout_spi1, - &exynos4_clk_mdout_spi2, -}; - -static struct clk_lookup exynos4_clk_lookup[] = { - CLKDEV_INIT("exynos4210-uart.0", "clk_uart_baud0", &exynos4_clk_sclk_uart0.clk), - CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &exynos4_clk_sclk_uart1.clk), - CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &exynos4_clk_sclk_uart2.clk), - CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &exynos4_clk_sclk_uart3.clk), - CLKDEV_INIT("exynos4-sdhci.0", "mmc_busclk.2", &exynos4_clk_sclk_mmc0.clk), - CLKDEV_INIT("exynos4-sdhci.1", "mmc_busclk.2", &exynos4_clk_sclk_mmc1.clk), - CLKDEV_INIT("exynos4-sdhci.2", "mmc_busclk.2", &exynos4_clk_sclk_mmc2.clk), - CLKDEV_INIT("exynos4-sdhci.3", "mmc_busclk.2", &exynos4_clk_sclk_mmc3.clk), - CLKDEV_INIT("exynos4-fb.0", "lcd", &exynos4_clk_fimd0), - CLKDEV_INIT("dma-pl330.0", "apb_pclk", &exynos4_clk_pdma0), - CLKDEV_INIT("dma-pl330.1", "apb_pclk", &exynos4_clk_pdma1), - CLKDEV_INIT("dma-pl330.2", "apb_pclk", &exynos4_clk_mdma1), - CLKDEV_INIT("exynos4210-spi.0", "spi_busclk0", &exynos4_clk_sclk_spi0.clk), - CLKDEV_INIT("exynos4210-spi.1", "spi_busclk0", &exynos4_clk_sclk_spi1.clk), - CLKDEV_INIT("exynos4210-spi.2", "spi_busclk0", &exynos4_clk_sclk_spi2.clk), -}; - -static int xtal_rate; - -static unsigned long exynos4_fout_apll_get_rate(struct clk *clk) -{ - if (soc_is_exynos4210()) - return s5p_get_pll45xx(xtal_rate, __raw_readl(EXYNOS4_APLL_CON0), - pll_4508); - else if (soc_is_exynos4212() || soc_is_exynos4412()) - return s5p_get_pll35xx(xtal_rate, __raw_readl(EXYNOS4_APLL_CON0)); - else - return 0; -} - -static struct clk_ops exynos4_fout_apll_ops = { - .get_rate = exynos4_fout_apll_get_rate, -}; - -static u32 exynos4_vpll_div[][8] = { - { 54000000, 3, 53, 3, 1024, 0, 17, 0 }, - { 108000000, 3, 53, 2, 1024, 0, 17, 0 }, -}; - -static unsigned long exynos4_vpll_get_rate(struct clk *clk) -{ - return clk->rate; -} - -static int exynos4_vpll_set_rate(struct clk *clk, unsigned long rate) -{ - unsigned int vpll_con0, vpll_con1 = 0; - unsigned int i; - - /* Return if nothing changed */ - if (clk->rate == rate) - return 0; - - vpll_con0 = __raw_readl(EXYNOS4_VPLL_CON0); - vpll_con0 &= ~(0x1 << 27 | \ - PLL90XX_MDIV_MASK << PLL46XX_MDIV_SHIFT | \ - PLL90XX_PDIV_MASK << PLL46XX_PDIV_SHIFT | \ - PLL90XX_SDIV_MASK << PLL46XX_SDIV_SHIFT); - - vpll_con1 = __raw_readl(EXYNOS4_VPLL_CON1); - vpll_con1 &= ~(PLL46XX_MRR_MASK << PLL46XX_MRR_SHIFT | \ - PLL46XX_MFR_MASK << PLL46XX_MFR_SHIFT | \ - PLL4650C_KDIV_MASK << PLL46XX_KDIV_SHIFT); - - for (i = 0; i < ARRAY_SIZE(exynos4_vpll_div); i++) { - if (exynos4_vpll_div[i][0] == rate) { - vpll_con0 |= exynos4_vpll_div[i][1] << PLL46XX_PDIV_SHIFT; - vpll_con0 |= exynos4_vpll_div[i][2] << PLL46XX_MDIV_SHIFT; - vpll_con0 |= exynos4_vpll_div[i][3] << PLL46XX_SDIV_SHIFT; - vpll_con1 |= exynos4_vpll_div[i][4] << PLL46XX_KDIV_SHIFT; - vpll_con1 |= exynos4_vpll_div[i][5] << PLL46XX_MFR_SHIFT; - vpll_con1 |= exynos4_vpll_div[i][6] << PLL46XX_MRR_SHIFT; - vpll_con0 |= exynos4_vpll_div[i][7] << 27; - break; - } - } - - if (i == ARRAY_SIZE(exynos4_vpll_div)) { - printk(KERN_ERR "%s: Invalid Clock VPLL Frequency\n", - __func__); - return -EINVAL; - } - - __raw_writel(vpll_con0, EXYNOS4_VPLL_CON0); - __raw_writel(vpll_con1, EXYNOS4_VPLL_CON1); - - /* Wait for VPLL lock */ - while (!(__raw_readl(EXYNOS4_VPLL_CON0) & (1 << PLL46XX_LOCKED_SHIFT))) - continue; - - clk->rate = rate; - return 0; -} - -static struct clk_ops exynos4_vpll_ops = { - .get_rate = exynos4_vpll_get_rate, - .set_rate = exynos4_vpll_set_rate, -}; - -void __init_or_cpufreq exynos4_setup_clocks(void) -{ - struct clk *xtal_clk; - unsigned long apll = 0; - unsigned long mpll = 0; - unsigned long epll = 0; - unsigned long vpll = 0; - unsigned long vpllsrc; - unsigned long xtal; - unsigned long armclk; - unsigned long sclk_dmc; - unsigned long aclk_200; - unsigned long aclk_100; - unsigned long aclk_160; - unsigned long aclk_133; - unsigned int ptr; - - printk(KERN_DEBUG "%s: registering clocks\n", __func__); - - xtal_clk = clk_get(NULL, "xtal"); - BUG_ON(IS_ERR(xtal_clk)); - - xtal = clk_get_rate(xtal_clk); - - xtal_rate = xtal; - - clk_put(xtal_clk); - - printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal); - - if (soc_is_exynos4210()) { - apll = s5p_get_pll45xx(xtal, __raw_readl(EXYNOS4_APLL_CON0), - pll_4508); - mpll = s5p_get_pll45xx(xtal, __raw_readl(EXYNOS4_MPLL_CON0), - pll_4508); - epll = s5p_get_pll46xx(xtal, __raw_readl(EXYNOS4_EPLL_CON0), - __raw_readl(EXYNOS4_EPLL_CON1), pll_4600); - - vpllsrc = clk_get_rate(&exynos4_clk_vpllsrc.clk); - vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(EXYNOS4_VPLL_CON0), - __raw_readl(EXYNOS4_VPLL_CON1), pll_4650c); - } else if (soc_is_exynos4212() || soc_is_exynos4412()) { - apll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS4_APLL_CON0)); - mpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS4_MPLL_CON0)); - epll = s5p_get_pll36xx(xtal, __raw_readl(EXYNOS4_EPLL_CON0), - __raw_readl(EXYNOS4_EPLL_CON1)); - - vpllsrc = clk_get_rate(&exynos4_clk_vpllsrc.clk); - vpll = s5p_get_pll36xx(vpllsrc, __raw_readl(EXYNOS4_VPLL_CON0), - __raw_readl(EXYNOS4_VPLL_CON1)); - } else { - /* nothing */ - } - - clk_fout_apll.ops = &exynos4_fout_apll_ops; - clk_fout_mpll.rate = mpll; - clk_fout_epll.rate = epll; - clk_fout_vpll.ops = &exynos4_vpll_ops; - clk_fout_vpll.rate = vpll; - - printk(KERN_INFO "EXYNOS4: PLL settings, A=%ld, M=%ld, E=%ld V=%ld", - apll, mpll, epll, vpll); - - armclk = clk_get_rate(&exynos4_clk_armclk.clk); - sclk_dmc = clk_get_rate(&exynos4_clk_sclk_dmc.clk); - - aclk_200 = clk_get_rate(&exynos4_clk_aclk_200.clk); - aclk_100 = clk_get_rate(&exynos4_clk_aclk_100.clk); - aclk_160 = clk_get_rate(&exynos4_clk_aclk_160.clk); - aclk_133 = clk_get_rate(&exynos4_clk_aclk_133.clk); - - printk(KERN_INFO "EXYNOS4: ARMCLK=%ld, DMC=%ld, ACLK200=%ld\n" - "ACLK100=%ld, ACLK160=%ld, ACLK133=%ld\n", - armclk, sclk_dmc, aclk_200, - aclk_100, aclk_160, aclk_133); - - clk_f.rate = armclk; - clk_h.rate = sclk_dmc; - clk_p.rate = aclk_100; - - for (ptr = 0; ptr < ARRAY_SIZE(exynos4_clksrcs); ptr++) - s3c_set_clksrc(&exynos4_clksrcs[ptr], true); -} - -static struct clk *exynos4_clks[] __initdata = { - &exynos4_clk_sclk_hdmi27m, - &exynos4_clk_sclk_hdmiphy, - &exynos4_clk_sclk_usbphy0, - &exynos4_clk_sclk_usbphy1, -}; - -#ifdef CONFIG_PM_SLEEP -static int exynos4_clock_suspend(void) -{ - s3c_pm_do_save(exynos4_clock_save, ARRAY_SIZE(exynos4_clock_save)); - return 0; -} - -static void exynos4_clock_resume(void) -{ - s3c_pm_do_restore_core(exynos4_clock_save, ARRAY_SIZE(exynos4_clock_save)); -} - -#else -#define exynos4_clock_suspend NULL -#define exynos4_clock_resume NULL -#endif - -static struct syscore_ops exynos4_clock_syscore_ops = { - .suspend = exynos4_clock_suspend, - .resume = exynos4_clock_resume, -}; - -void __init exynos4_register_clocks(void) -{ - int ptr; - - s3c24xx_register_clocks(exynos4_clks, ARRAY_SIZE(exynos4_clks)); - - for (ptr = 0; ptr < ARRAY_SIZE(exynos4_sysclks); ptr++) - s3c_register_clksrc(exynos4_sysclks[ptr], 1); - - for (ptr = 0; ptr < ARRAY_SIZE(exynos4_sclk_tv); ptr++) - s3c_register_clksrc(exynos4_sclk_tv[ptr], 1); - - for (ptr = 0; ptr < ARRAY_SIZE(exynos4_clksrc_cdev); ptr++) - s3c_register_clksrc(exynos4_clksrc_cdev[ptr], 1); - - s3c_register_clksrc(exynos4_clksrcs, ARRAY_SIZE(exynos4_clksrcs)); - s3c_register_clocks(exynos4_init_clocks_on, ARRAY_SIZE(exynos4_init_clocks_on)); - - s3c24xx_register_clocks(exynos4_clk_cdev, ARRAY_SIZE(exynos4_clk_cdev)); - for (ptr = 0; ptr < ARRAY_SIZE(exynos4_clk_cdev); ptr++) - s3c_disable_clocks(exynos4_clk_cdev[ptr], 1); - - s3c_register_clocks(exynos4_init_clocks_off, ARRAY_SIZE(exynos4_init_clocks_off)); - s3c_disable_clocks(exynos4_init_clocks_off, ARRAY_SIZE(exynos4_init_clocks_off)); - clkdev_add_table(exynos4_clk_lookup, ARRAY_SIZE(exynos4_clk_lookup)); - - register_syscore_ops(&exynos4_clock_syscore_ops); - s3c24xx_register_clock(&dummy_apb_pclk); - - s3c_pwmclk_init(); -} diff --git a/trunk/arch/arm/mach-exynos/clock-exynos4.h b/trunk/arch/arm/mach-exynos/clock-exynos4.h deleted file mode 100644 index bd12d5f8b63d..000000000000 --- a/trunk/arch/arm/mach-exynos/clock-exynos4.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Header file for exynos4 clock support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifndef __ASM_ARCH_CLOCK_H -#define __ASM_ARCH_CLOCK_H __FILE__ - -#include - -extern struct clksrc_clk exynos4_clk_aclk_133; -extern struct clksrc_clk exynos4_clk_mout_mpll; - -extern struct clksrc_sources exynos4_clkset_mout_corebus; -extern struct clksrc_sources exynos4_clkset_group; - -extern struct clk *exynos4_clkset_aclk_top_list[]; -extern struct clk *exynos4_clkset_group_list[]; - -extern struct clksrc_sources exynos4_clkset_mout_g2d0; -extern struct clksrc_sources exynos4_clkset_mout_g2d1; - -extern int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable); -extern int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable); -extern int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable); -extern int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable); -extern int exynos4_clk_ip_dmc_ctrl(struct clk *clk, int enable); - -#endif /* __ASM_ARCH_CLOCK_H */ diff --git a/trunk/arch/arm/mach-exynos/clock-exynos4210.c b/trunk/arch/arm/mach-exynos/clock-exynos4210.c deleted file mode 100644 index 19af9f783c56..000000000000 --- a/trunk/arch/arm/mach-exynos/clock-exynos4210.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * EXYNOS4210 - Clock support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "common.h" -#include "clock-exynos4.h" - -#ifdef CONFIG_PM_SLEEP -static struct sleep_save exynos4210_clock_save[] = { - SAVE_ITEM(EXYNOS4_CLKSRC_IMAGE), - SAVE_ITEM(EXYNOS4_CLKDIV_IMAGE), - SAVE_ITEM(EXYNOS4210_CLKSRC_LCD1), - SAVE_ITEM(EXYNOS4210_CLKDIV_LCD1), - SAVE_ITEM(EXYNOS4210_CLKSRC_MASK_LCD1), - SAVE_ITEM(EXYNOS4210_CLKGATE_IP_IMAGE), - SAVE_ITEM(EXYNOS4210_CLKGATE_IP_LCD1), - SAVE_ITEM(EXYNOS4210_CLKGATE_IP_PERIR), -}; -#endif - -static struct clksrc_clk *sysclks[] = { - /* nothing here yet */ -}; - -static struct clksrc_clk exynos4210_clk_mout_g2d0 = { - .clk = { - .name = "mout_g2d0", - }, - .sources = &exynos4_clkset_mout_g2d0, - .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 0, .size = 1 }, -}; - -static struct clksrc_clk exynos4210_clk_mout_g2d1 = { - .clk = { - .name = "mout_g2d1", - }, - .sources = &exynos4_clkset_mout_g2d1, - .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 4, .size = 1 }, -}; - -static struct clk *exynos4210_clkset_mout_g2d_list[] = { - [0] = &exynos4210_clk_mout_g2d0.clk, - [1] = &exynos4210_clk_mout_g2d1.clk, -}; - -static struct clksrc_sources exynos4210_clkset_mout_g2d = { - .sources = exynos4210_clkset_mout_g2d_list, - .nr_sources = ARRAY_SIZE(exynos4210_clkset_mout_g2d_list), -}; - -static int exynos4_clksrc_mask_lcd1_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS4210_CLKSRC_MASK_LCD1, clk, enable); -} - -static struct clksrc_clk clksrcs[] = { - { - .clk = { - .name = "sclk_sata", - .id = -1, - .enable = exynos4_clksrc_mask_fsys_ctrl, - .ctrlbit = (1 << 24), - }, - .sources = &exynos4_clkset_mout_corebus, - .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 24, .size = 1 }, - .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS0, .shift = 20, .size = 4 }, - }, { - .clk = { - .name = "sclk_fimd", - .devname = "exynos4-fb.1", - .enable = exynos4_clksrc_mask_lcd1_ctrl, - .ctrlbit = (1 << 0), - }, - .sources = &exynos4_clkset_group, - .reg_src = { .reg = EXYNOS4210_CLKSRC_LCD1, .shift = 0, .size = 4 }, - .reg_div = { .reg = EXYNOS4210_CLKDIV_LCD1, .shift = 0, .size = 4 }, - }, { - .clk = { - .name = "sclk_fimg2d", - }, - .sources = &exynos4210_clkset_mout_g2d, - .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 8, .size = 1 }, - .reg_div = { .reg = EXYNOS4_CLKDIV_IMAGE, .shift = 0, .size = 4 }, - }, -}; - -static struct clk init_clocks_off[] = { - { - .name = "sataphy", - .id = -1, - .parent = &exynos4_clk_aclk_133.clk, - .enable = exynos4_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 3), - }, { - .name = "sata", - .id = -1, - .parent = &exynos4_clk_aclk_133.clk, - .enable = exynos4_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 10), - }, { - .name = "fimd", - .devname = "exynos4-fb.1", - .enable = exynos4_clk_ip_lcd1_ctrl, - .ctrlbit = (1 << 0), - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.9", - .enable = exynos4_clk_ip_image_ctrl, - .ctrlbit = (1 << 3), - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.11", - .enable = exynos4_clk_ip_lcd1_ctrl, - .ctrlbit = (1 << 4), - }, { - .name = "fimg2d", - .enable = exynos4_clk_ip_image_ctrl, - .ctrlbit = (1 << 0), - }, -}; - -#ifdef CONFIG_PM_SLEEP -static int exynos4210_clock_suspend(void) -{ - s3c_pm_do_save(exynos4210_clock_save, ARRAY_SIZE(exynos4210_clock_save)); - - return 0; -} - -static void exynos4210_clock_resume(void) -{ - s3c_pm_do_restore_core(exynos4210_clock_save, ARRAY_SIZE(exynos4210_clock_save)); -} - -#else -#define exynos4210_clock_suspend NULL -#define exynos4210_clock_resume NULL -#endif - -static struct syscore_ops exynos4210_clock_syscore_ops = { - .suspend = exynos4210_clock_suspend, - .resume = exynos4210_clock_resume, -}; - -void __init exynos4210_register_clocks(void) -{ - int ptr; - - exynos4_clk_mout_mpll.reg_src.reg = EXYNOS4_CLKSRC_CPU; - exynos4_clk_mout_mpll.reg_src.shift = 8; - exynos4_clk_mout_mpll.reg_src.size = 1; - - for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++) - s3c_register_clksrc(sysclks[ptr], 1); - - s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); - - s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); - s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); - - register_syscore_ops(&exynos4210_clock_syscore_ops); -} diff --git a/trunk/arch/arm/mach-exynos/clock-exynos4212.c b/trunk/arch/arm/mach-exynos/clock-exynos4212.c deleted file mode 100644 index 529476f8ec71..000000000000 --- a/trunk/arch/arm/mach-exynos/clock-exynos4212.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * EXYNOS4212 - Clock support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "common.h" -#include "clock-exynos4.h" - -#ifdef CONFIG_PM_SLEEP -static struct sleep_save exynos4212_clock_save[] = { - SAVE_ITEM(EXYNOS4_CLKSRC_IMAGE), - SAVE_ITEM(EXYNOS4_CLKDIV_IMAGE), - SAVE_ITEM(EXYNOS4212_CLKGATE_IP_IMAGE), - SAVE_ITEM(EXYNOS4212_CLKGATE_IP_PERIR), -}; -#endif - -static int exynos4212_clk_ip_isp0_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS4_CLKGATE_IP_ISP0, clk, enable); -} - -static int exynos4212_clk_ip_isp1_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS4_CLKGATE_IP_ISP1, clk, enable); -} - -static struct clk *clk_src_mpll_user_list[] = { - [0] = &clk_fin_mpll, - [1] = &exynos4_clk_mout_mpll.clk, -}; - -static struct clksrc_sources clk_src_mpll_user = { - .sources = clk_src_mpll_user_list, - .nr_sources = ARRAY_SIZE(clk_src_mpll_user_list), -}; - -static struct clksrc_clk clk_mout_mpll_user = { - .clk = { - .name = "mout_mpll_user", - }, - .sources = &clk_src_mpll_user, - .reg_src = { .reg = EXYNOS4_CLKSRC_CPU, .shift = 24, .size = 1 }, -}; - -static struct clksrc_clk exynos4x12_clk_mout_g2d0 = { - .clk = { - .name = "mout_g2d0", - }, - .sources = &exynos4_clkset_mout_g2d0, - .reg_src = { .reg = EXYNOS4_CLKSRC_DMC, .shift = 20, .size = 1 }, -}; - -static struct clksrc_clk exynos4x12_clk_mout_g2d1 = { - .clk = { - .name = "mout_g2d1", - }, - .sources = &exynos4_clkset_mout_g2d1, - .reg_src = { .reg = EXYNOS4_CLKSRC_DMC, .shift = 24, .size = 1 }, -}; - -static struct clk *exynos4x12_clkset_mout_g2d_list[] = { - [0] = &exynos4x12_clk_mout_g2d0.clk, - [1] = &exynos4x12_clk_mout_g2d1.clk, -}; - -static struct clksrc_sources exynos4x12_clkset_mout_g2d = { - .sources = exynos4x12_clkset_mout_g2d_list, - .nr_sources = ARRAY_SIZE(exynos4x12_clkset_mout_g2d_list), -}; - -static struct clksrc_clk *sysclks[] = { - &clk_mout_mpll_user, -}; - -static struct clksrc_clk clksrcs[] = { - { - .clk = { - .name = "sclk_fimg2d", - }, - .sources = &exynos4x12_clkset_mout_g2d, - .reg_src = { .reg = EXYNOS4_CLKSRC_DMC, .shift = 28, .size = 1 }, - .reg_div = { .reg = EXYNOS4_CLKDIV_DMC1, .shift = 0, .size = 4 }, - }, -}; - -static struct clk init_clocks_off[] = { - { - .name = "sysmmu", - .devname = "exynos-sysmmu.9", - .enable = exynos4_clk_ip_dmc_ctrl, - .ctrlbit = (1 << 24), - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.12", - .enable = exynos4212_clk_ip_isp0_ctrl, - .ctrlbit = (7 << 8), - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.13", - .enable = exynos4212_clk_ip_isp1_ctrl, - .ctrlbit = (1 << 4), - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.14", - .enable = exynos4212_clk_ip_isp0_ctrl, - .ctrlbit = (1 << 11), - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.15", - .enable = exynos4212_clk_ip_isp0_ctrl, - .ctrlbit = (1 << 12), - }, { - .name = "flite", - .devname = "exynos-fimc-lite.0", - .enable = exynos4212_clk_ip_isp0_ctrl, - .ctrlbit = (1 << 4), - }, { - .name = "flite", - .devname = "exynos-fimc-lite.1", - .enable = exynos4212_clk_ip_isp0_ctrl, - .ctrlbit = (1 << 3), - }, { - .name = "fimg2d", - .enable = exynos4_clk_ip_dmc_ctrl, - .ctrlbit = (1 << 23), - }, -}; - -#ifdef CONFIG_PM_SLEEP -static int exynos4212_clock_suspend(void) -{ - s3c_pm_do_save(exynos4212_clock_save, ARRAY_SIZE(exynos4212_clock_save)); - - return 0; -} - -static void exynos4212_clock_resume(void) -{ - s3c_pm_do_restore_core(exynos4212_clock_save, ARRAY_SIZE(exynos4212_clock_save)); -} - -#else -#define exynos4212_clock_suspend NULL -#define exynos4212_clock_resume NULL -#endif - -static struct syscore_ops exynos4212_clock_syscore_ops = { - .suspend = exynos4212_clock_suspend, - .resume = exynos4212_clock_resume, -}; - -void __init exynos4212_register_clocks(void) -{ - int ptr; - - /* usbphy1 is removed */ - exynos4_clkset_group_list[4] = NULL; - - /* mout_mpll_user is used */ - exynos4_clkset_group_list[6] = &clk_mout_mpll_user.clk; - exynos4_clkset_aclk_top_list[0] = &clk_mout_mpll_user.clk; - - exynos4_clk_mout_mpll.reg_src.reg = EXYNOS4_CLKSRC_DMC; - exynos4_clk_mout_mpll.reg_src.shift = 12; - exynos4_clk_mout_mpll.reg_src.size = 1; - - for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++) - s3c_register_clksrc(sysclks[ptr], 1); - - s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); - - s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); - s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); - - register_syscore_ops(&exynos4212_clock_syscore_ops); -} diff --git a/trunk/arch/arm/mach-exynos/clock-exynos5.c b/trunk/arch/arm/mach-exynos/clock-exynos5.c deleted file mode 100644 index b0ea31fc9fb8..000000000000 --- a/trunk/arch/arm/mach-exynos/clock-exynos5.c +++ /dev/null @@ -1,1645 +0,0 @@ -/* - * Copyright (c) 2012 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Clock support for EXYNOS5 SoCs - * - * 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 -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "common.h" - -#ifdef CONFIG_PM_SLEEP -static struct sleep_save exynos5_clock_save[] = { - SAVE_ITEM(EXYNOS5_CLKSRC_MASK_TOP), - SAVE_ITEM(EXYNOS5_CLKSRC_MASK_GSCL), - SAVE_ITEM(EXYNOS5_CLKSRC_MASK_DISP1_0), - SAVE_ITEM(EXYNOS5_CLKSRC_MASK_FSYS), - SAVE_ITEM(EXYNOS5_CLKSRC_MASK_MAUDIO), - SAVE_ITEM(EXYNOS5_CLKSRC_MASK_PERIC0), - SAVE_ITEM(EXYNOS5_CLKSRC_MASK_PERIC1), - SAVE_ITEM(EXYNOS5_CLKGATE_IP_GSCL), - SAVE_ITEM(EXYNOS5_CLKGATE_IP_DISP1), - SAVE_ITEM(EXYNOS5_CLKGATE_IP_MFC), - SAVE_ITEM(EXYNOS5_CLKGATE_IP_G3D), - SAVE_ITEM(EXYNOS5_CLKGATE_IP_GEN), - SAVE_ITEM(EXYNOS5_CLKGATE_IP_FSYS), - SAVE_ITEM(EXYNOS5_CLKGATE_IP_PERIC), - SAVE_ITEM(EXYNOS5_CLKGATE_IP_PERIS), - SAVE_ITEM(EXYNOS5_CLKGATE_BLOCK), - SAVE_ITEM(EXYNOS5_CLKDIV_TOP0), - SAVE_ITEM(EXYNOS5_CLKDIV_TOP1), - SAVE_ITEM(EXYNOS5_CLKDIV_GSCL), - SAVE_ITEM(EXYNOS5_CLKDIV_DISP1_0), - SAVE_ITEM(EXYNOS5_CLKDIV_GEN), - SAVE_ITEM(EXYNOS5_CLKDIV_MAUDIO), - SAVE_ITEM(EXYNOS5_CLKDIV_FSYS0), - SAVE_ITEM(EXYNOS5_CLKDIV_FSYS1), - SAVE_ITEM(EXYNOS5_CLKDIV_FSYS2), - SAVE_ITEM(EXYNOS5_CLKDIV_FSYS3), - SAVE_ITEM(EXYNOS5_CLKDIV_PERIC0), - SAVE_ITEM(EXYNOS5_CLKDIV_PERIC1), - SAVE_ITEM(EXYNOS5_CLKDIV_PERIC2), - SAVE_ITEM(EXYNOS5_CLKDIV_PERIC3), - SAVE_ITEM(EXYNOS5_CLKDIV_PERIC4), - SAVE_ITEM(EXYNOS5_CLKDIV_PERIC5), - SAVE_ITEM(EXYNOS5_SCLK_DIV_ISP), - SAVE_ITEM(EXYNOS5_CLKSRC_TOP0), - SAVE_ITEM(EXYNOS5_CLKSRC_TOP1), - SAVE_ITEM(EXYNOS5_CLKSRC_TOP2), - SAVE_ITEM(EXYNOS5_CLKSRC_TOP3), - SAVE_ITEM(EXYNOS5_CLKSRC_GSCL), - SAVE_ITEM(EXYNOS5_CLKSRC_DISP1_0), - SAVE_ITEM(EXYNOS5_CLKSRC_MAUDIO), - SAVE_ITEM(EXYNOS5_CLKSRC_FSYS), - SAVE_ITEM(EXYNOS5_CLKSRC_PERIC0), - SAVE_ITEM(EXYNOS5_CLKSRC_PERIC1), - SAVE_ITEM(EXYNOS5_SCLK_SRC_ISP), - SAVE_ITEM(EXYNOS5_EPLL_CON0), - SAVE_ITEM(EXYNOS5_EPLL_CON1), - SAVE_ITEM(EXYNOS5_EPLL_CON2), - SAVE_ITEM(EXYNOS5_VPLL_CON0), - SAVE_ITEM(EXYNOS5_VPLL_CON1), - SAVE_ITEM(EXYNOS5_VPLL_CON2), - SAVE_ITEM(EXYNOS5_PWR_CTRL1), - SAVE_ITEM(EXYNOS5_PWR_CTRL2), -}; -#endif - -static struct clk exynos5_clk_sclk_dptxphy = { - .name = "sclk_dptx", -}; - -static struct clk exynos5_clk_sclk_hdmi24m = { - .name = "sclk_hdmi24m", - .rate = 24000000, -}; - -static struct clk exynos5_clk_sclk_hdmi27m = { - .name = "sclk_hdmi27m", - .rate = 27000000, -}; - -static struct clk exynos5_clk_sclk_hdmiphy = { - .name = "sclk_hdmiphy", -}; - -static struct clk exynos5_clk_sclk_usbphy = { - .name = "sclk_usbphy", - .rate = 48000000, -}; - -static int exynos5_clksrc_mask_top_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_TOP, clk, enable); -} - -static int exynos5_clksrc_mask_disp1_0_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_DISP1_0, clk, enable); -} - -static int exynos5_clksrc_mask_fsys_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_FSYS, clk, enable); -} - -static int exynos5_clksrc_mask_gscl_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_GSCL, clk, enable); -} - -static int exynos5_clksrc_mask_peric0_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_PERIC0, clk, enable); -} - -static int exynos5_clksrc_mask_peric1_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_PERIC1, clk, enable); -} - -static int exynos5_clk_ip_acp_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS5_CLKGATE_IP_ACP, clk, enable); -} - -static int exynos5_clk_ip_core_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS5_CLKGATE_IP_CORE, clk, enable); -} - -static int exynos5_clk_ip_disp1_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS5_CLKGATE_IP_DISP1, clk, enable); -} - -static int exynos5_clk_ip_fsys_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS5_CLKGATE_IP_FSYS, clk, enable); -} - -static int exynos5_clk_block_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS5_CLKGATE_BLOCK, clk, enable); -} - -static int exynos5_clk_ip_gen_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS5_CLKGATE_IP_GEN, clk, enable); -} - -static int exynos5_clk_ip_mfc_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS5_CLKGATE_IP_MFC, clk, enable); -} - -static int exynos5_clk_ip_peric_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS5_CLKGATE_IP_PERIC, clk, enable); -} - -static int exynos5_clk_ip_peris_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS5_CLKGATE_IP_PERIS, clk, enable); -} - -static int exynos5_clk_ip_gscl_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS5_CLKGATE_IP_GSCL, clk, enable); -} - -static int exynos5_clk_ip_isp0_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS5_CLKGATE_IP_ISP0, clk, enable); -} - -static int exynos5_clk_ip_isp1_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(EXYNOS5_CLKGATE_IP_ISP1, clk, enable); -} - -static int exynos5_clk_hdmiphy_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_HDMI_PHY_CONTROL, clk, enable); -} - -/* Core list of CMU_CPU side */ - -static struct clksrc_clk exynos5_clk_mout_apll = { - .clk = { - .name = "mout_apll", - }, - .sources = &clk_src_apll, - .reg_src = { .reg = EXYNOS5_CLKSRC_CPU, .shift = 0, .size = 1 }, -}; - -static struct clksrc_clk exynos5_clk_sclk_apll = { - .clk = { - .name = "sclk_apll", - .parent = &exynos5_clk_mout_apll.clk, - }, - .reg_div = { .reg = EXYNOS5_CLKDIV_CPU0, .shift = 24, .size = 3 }, -}; - -static struct clksrc_clk exynos5_clk_mout_bpll_fout = { - .clk = { - .name = "mout_bpll_fout", - }, - .sources = &clk_src_bpll_fout, - .reg_src = { .reg = EXYNOS5_PLL_DIV2_SEL, .shift = 0, .size = 1 }, -}; - -static struct clk *exynos5_clk_src_bpll_list[] = { - [0] = &clk_fin_bpll, - [1] = &exynos5_clk_mout_bpll_fout.clk, -}; - -static struct clksrc_sources exynos5_clk_src_bpll = { - .sources = exynos5_clk_src_bpll_list, - .nr_sources = ARRAY_SIZE(exynos5_clk_src_bpll_list), -}; - -static struct clksrc_clk exynos5_clk_mout_bpll = { - .clk = { - .name = "mout_bpll", - }, - .sources = &exynos5_clk_src_bpll, - .reg_src = { .reg = EXYNOS5_CLKSRC_CDREX, .shift = 0, .size = 1 }, -}; - -static struct clk *exynos5_clk_src_bpll_user_list[] = { - [0] = &clk_fin_mpll, - [1] = &exynos5_clk_mout_bpll.clk, -}; - -static struct clksrc_sources exynos5_clk_src_bpll_user = { - .sources = exynos5_clk_src_bpll_user_list, - .nr_sources = ARRAY_SIZE(exynos5_clk_src_bpll_user_list), -}; - -static struct clksrc_clk exynos5_clk_mout_bpll_user = { - .clk = { - .name = "mout_bpll_user", - }, - .sources = &exynos5_clk_src_bpll_user, - .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 24, .size = 1 }, -}; - -static struct clksrc_clk exynos5_clk_mout_cpll = { - .clk = { - .name = "mout_cpll", - }, - .sources = &clk_src_cpll, - .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 8, .size = 1 }, -}; - -static struct clksrc_clk exynos5_clk_mout_epll = { - .clk = { - .name = "mout_epll", - }, - .sources = &clk_src_epll, - .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 12, .size = 1 }, -}; - -static struct clksrc_clk exynos5_clk_mout_mpll_fout = { - .clk = { - .name = "mout_mpll_fout", - }, - .sources = &clk_src_mpll_fout, - .reg_src = { .reg = EXYNOS5_PLL_DIV2_SEL, .shift = 4, .size = 1 }, -}; - -static struct clk *exynos5_clk_src_mpll_list[] = { - [0] = &clk_fin_mpll, - [1] = &exynos5_clk_mout_mpll_fout.clk, -}; - -static struct clksrc_sources exynos5_clk_src_mpll = { - .sources = exynos5_clk_src_mpll_list, - .nr_sources = ARRAY_SIZE(exynos5_clk_src_mpll_list), -}; - -static struct clksrc_clk exynos5_clk_mout_mpll = { - .clk = { - .name = "mout_mpll", - }, - .sources = &exynos5_clk_src_mpll, - .reg_src = { .reg = EXYNOS5_CLKSRC_CORE1, .shift = 8, .size = 1 }, -}; - -static struct clk *exynos_clkset_vpllsrc_list[] = { - [0] = &clk_fin_vpll, - [1] = &exynos5_clk_sclk_hdmi27m, -}; - -static struct clksrc_sources exynos5_clkset_vpllsrc = { - .sources = exynos_clkset_vpllsrc_list, - .nr_sources = ARRAY_SIZE(exynos_clkset_vpllsrc_list), -}; - -static struct clksrc_clk exynos5_clk_vpllsrc = { - .clk = { - .name = "vpll_src", - .enable = exynos5_clksrc_mask_top_ctrl, - .ctrlbit = (1 << 0), - }, - .sources = &exynos5_clkset_vpllsrc, - .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 0, .size = 1 }, -}; - -static struct clk *exynos5_clkset_sclk_vpll_list[] = { - [0] = &exynos5_clk_vpllsrc.clk, - [1] = &clk_fout_vpll, -}; - -static struct clksrc_sources exynos5_clkset_sclk_vpll = { - .sources = exynos5_clkset_sclk_vpll_list, - .nr_sources = ARRAY_SIZE(exynos5_clkset_sclk_vpll_list), -}; - -static struct clksrc_clk exynos5_clk_sclk_vpll = { - .clk = { - .name = "sclk_vpll", - }, - .sources = &exynos5_clkset_sclk_vpll, - .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 16, .size = 1 }, -}; - -static struct clksrc_clk exynos5_clk_sclk_pixel = { - .clk = { - .name = "sclk_pixel", - .parent = &exynos5_clk_sclk_vpll.clk, - }, - .reg_div = { .reg = EXYNOS5_CLKDIV_DISP1_0, .shift = 28, .size = 4 }, -}; - -static struct clk *exynos5_clkset_sclk_hdmi_list[] = { - [0] = &exynos5_clk_sclk_pixel.clk, - [1] = &exynos5_clk_sclk_hdmiphy, -}; - -static struct clksrc_sources exynos5_clkset_sclk_hdmi = { - .sources = exynos5_clkset_sclk_hdmi_list, - .nr_sources = ARRAY_SIZE(exynos5_clkset_sclk_hdmi_list), -}; - -static struct clksrc_clk exynos5_clk_sclk_hdmi = { - .clk = { - .name = "sclk_hdmi", - .enable = exynos5_clksrc_mask_disp1_0_ctrl, - .ctrlbit = (1 << 20), - }, - .sources = &exynos5_clkset_sclk_hdmi, - .reg_src = { .reg = EXYNOS5_CLKSRC_DISP1_0, .shift = 20, .size = 1 }, -}; - -static struct clksrc_clk *exynos5_sclk_tv[] = { - &exynos5_clk_sclk_pixel, - &exynos5_clk_sclk_hdmi, -}; - -static struct clk *exynos5_clk_src_mpll_user_list[] = { - [0] = &clk_fin_mpll, - [1] = &exynos5_clk_mout_mpll.clk, -}; - -static struct clksrc_sources exynos5_clk_src_mpll_user = { - .sources = exynos5_clk_src_mpll_user_list, - .nr_sources = ARRAY_SIZE(exynos5_clk_src_mpll_user_list), -}; - -static struct clksrc_clk exynos5_clk_mout_mpll_user = { - .clk = { - .name = "mout_mpll_user", - }, - .sources = &exynos5_clk_src_mpll_user, - .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 20, .size = 1 }, -}; - -static struct clk *exynos5_clkset_mout_cpu_list[] = { - [0] = &exynos5_clk_mout_apll.clk, - [1] = &exynos5_clk_mout_mpll.clk, -}; - -static struct clksrc_sources exynos5_clkset_mout_cpu = { - .sources = exynos5_clkset_mout_cpu_list, - .nr_sources = ARRAY_SIZE(exynos5_clkset_mout_cpu_list), -}; - -static struct clksrc_clk exynos5_clk_mout_cpu = { - .clk = { - .name = "mout_cpu", - }, - .sources = &exynos5_clkset_mout_cpu, - .reg_src = { .reg = EXYNOS5_CLKSRC_CPU, .shift = 16, .size = 1 }, -}; - -static struct clksrc_clk exynos5_clk_dout_armclk = { - .clk = { - .name = "dout_armclk", - .parent = &exynos5_clk_mout_cpu.clk, - }, - .reg_div = { .reg = EXYNOS5_CLKDIV_CPU0, .shift = 0, .size = 3 }, -}; - -static struct clksrc_clk exynos5_clk_dout_arm2clk = { - .clk = { - .name = "dout_arm2clk", - .parent = &exynos5_clk_dout_armclk.clk, - }, - .reg_div = { .reg = EXYNOS5_CLKDIV_CPU0, .shift = 28, .size = 3 }, -}; - -static struct clk exynos5_clk_armclk = { - .name = "armclk", - .parent = &exynos5_clk_dout_arm2clk.clk, -}; - -/* Core list of CMU_CDREX side */ - -static struct clk *exynos5_clkset_cdrex_list[] = { - [0] = &exynos5_clk_mout_mpll.clk, - [1] = &exynos5_clk_mout_bpll.clk, -}; - -static struct clksrc_sources exynos5_clkset_cdrex = { - .sources = exynos5_clkset_cdrex_list, - .nr_sources = ARRAY_SIZE(exynos5_clkset_cdrex_list), -}; - -static struct clksrc_clk exynos5_clk_cdrex = { - .clk = { - .name = "clk_cdrex", - }, - .sources = &exynos5_clkset_cdrex, - .reg_src = { .reg = EXYNOS5_CLKSRC_CDREX, .shift = 4, .size = 1 }, - .reg_div = { .reg = EXYNOS5_CLKDIV_CDREX, .shift = 16, .size = 3 }, -}; - -static struct clksrc_clk exynos5_clk_aclk_acp = { - .clk = { - .name = "aclk_acp", - .parent = &exynos5_clk_mout_mpll.clk, - }, - .reg_div = { .reg = EXYNOS5_CLKDIV_ACP, .shift = 0, .size = 3 }, -}; - -static struct clksrc_clk exynos5_clk_pclk_acp = { - .clk = { - .name = "pclk_acp", - .parent = &exynos5_clk_aclk_acp.clk, - }, - .reg_div = { .reg = EXYNOS5_CLKDIV_ACP, .shift = 4, .size = 3 }, -}; - -/* Core list of CMU_TOP side */ - -static struct clk *exynos5_clkset_aclk_top_list[] = { - [0] = &exynos5_clk_mout_mpll_user.clk, - [1] = &exynos5_clk_mout_bpll_user.clk, -}; - -static struct clksrc_sources exynos5_clkset_aclk = { - .sources = exynos5_clkset_aclk_top_list, - .nr_sources = ARRAY_SIZE(exynos5_clkset_aclk_top_list), -}; - -static struct clksrc_clk exynos5_clk_aclk_400 = { - .clk = { - .name = "aclk_400", - }, - .sources = &exynos5_clkset_aclk, - .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 20, .size = 1 }, - .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 24, .size = 3 }, -}; - -static struct clk *exynos5_clkset_aclk_333_166_list[] = { - [0] = &exynos5_clk_mout_cpll.clk, - [1] = &exynos5_clk_mout_mpll_user.clk, -}; - -static struct clksrc_sources exynos5_clkset_aclk_333_166 = { - .sources = exynos5_clkset_aclk_333_166_list, - .nr_sources = ARRAY_SIZE(exynos5_clkset_aclk_333_166_list), -}; - -static struct clksrc_clk exynos5_clk_aclk_333 = { - .clk = { - .name = "aclk_333", - }, - .sources = &exynos5_clkset_aclk_333_166, - .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 16, .size = 1 }, - .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 20, .size = 3 }, -}; - -static struct clksrc_clk exynos5_clk_aclk_166 = { - .clk = { - .name = "aclk_166", - }, - .sources = &exynos5_clkset_aclk_333_166, - .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 8, .size = 1 }, - .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 8, .size = 3 }, -}; - -static struct clksrc_clk exynos5_clk_aclk_266 = { - .clk = { - .name = "aclk_266", - .parent = &exynos5_clk_mout_mpll_user.clk, - }, - .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 16, .size = 3 }, -}; - -static struct clksrc_clk exynos5_clk_aclk_200 = { - .clk = { - .name = "aclk_200", - }, - .sources = &exynos5_clkset_aclk, - .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 12, .size = 1 }, - .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 12, .size = 3 }, -}; - -static struct clksrc_clk exynos5_clk_aclk_66_pre = { - .clk = { - .name = "aclk_66_pre", - .parent = &exynos5_clk_mout_mpll_user.clk, - }, - .reg_div = { .reg = EXYNOS5_CLKDIV_TOP1, .shift = 24, .size = 3 }, -}; - -static struct clksrc_clk exynos5_clk_aclk_66 = { - .clk = { - .name = "aclk_66", - .parent = &exynos5_clk_aclk_66_pre.clk, - }, - .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 0, .size = 3 }, -}; - -static struct clksrc_clk exynos5_clk_mout_aclk_300_gscl_mid = { - .clk = { - .name = "mout_aclk_300_gscl_mid", - }, - .sources = &exynos5_clkset_aclk, - .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 24, .size = 1 }, -}; - -static struct clk *exynos5_clkset_aclk_300_mid1_list[] = { - [0] = &exynos5_clk_sclk_vpll.clk, - [1] = &exynos5_clk_mout_cpll.clk, -}; - -static struct clksrc_sources exynos5_clkset_aclk_300_gscl_mid1 = { - .sources = exynos5_clkset_aclk_300_mid1_list, - .nr_sources = ARRAY_SIZE(exynos5_clkset_aclk_300_mid1_list), -}; - -static struct clksrc_clk exynos5_clk_mout_aclk_300_gscl_mid1 = { - .clk = { - .name = "mout_aclk_300_gscl_mid1", - }, - .sources = &exynos5_clkset_aclk_300_gscl_mid1, - .reg_src = { .reg = EXYNOS5_CLKSRC_TOP1, .shift = 12, .size = 1 }, -}; - -static struct clk *exynos5_clkset_aclk_300_gscl_list[] = { - [0] = &exynos5_clk_mout_aclk_300_gscl_mid.clk, - [1] = &exynos5_clk_mout_aclk_300_gscl_mid1.clk, -}; - -static struct clksrc_sources exynos5_clkset_aclk_300_gscl = { - .sources = exynos5_clkset_aclk_300_gscl_list, - .nr_sources = ARRAY_SIZE(exynos5_clkset_aclk_300_gscl_list), -}; - -static struct clksrc_clk exynos5_clk_mout_aclk_300_gscl = { - .clk = { - .name = "mout_aclk_300_gscl", - }, - .sources = &exynos5_clkset_aclk_300_gscl, - .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 25, .size = 1 }, -}; - -static struct clk *exynos5_clk_src_gscl_300_list[] = { - [0] = &clk_ext_xtal_mux, - [1] = &exynos5_clk_mout_aclk_300_gscl.clk, -}; - -static struct clksrc_sources exynos5_clk_src_gscl_300 = { - .sources = exynos5_clk_src_gscl_300_list, - .nr_sources = ARRAY_SIZE(exynos5_clk_src_gscl_300_list), -}; - -static struct clksrc_clk exynos5_clk_aclk_300_gscl = { - .clk = { - .name = "aclk_300_gscl", - }, - .sources = &exynos5_clk_src_gscl_300, - .reg_src = { .reg = EXYNOS5_CLKSRC_TOP3, .shift = 10, .size = 1 }, -}; - -static struct clk exynos5_init_clocks_off[] = { - { - .name = "timers", - .parent = &exynos5_clk_aclk_66.clk, - .enable = exynos5_clk_ip_peric_ctrl, - .ctrlbit = (1 << 24), - }, { - .name = "tmu_apbif", - .parent = &exynos5_clk_aclk_66.clk, - .enable = exynos5_clk_ip_peris_ctrl, - .ctrlbit = (1 << 21), - }, { - .name = "rtc", - .parent = &exynos5_clk_aclk_66.clk, - .enable = exynos5_clk_ip_peris_ctrl, - .ctrlbit = (1 << 20), - }, { - .name = "watchdog", - .parent = &exynos5_clk_aclk_66.clk, - .enable = exynos5_clk_ip_peris_ctrl, - .ctrlbit = (1 << 19), - }, { - .name = "biu", /* bus interface unit clock */ - .devname = "dw_mmc.0", - .parent = &exynos5_clk_aclk_200.clk, - .enable = exynos5_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 12), - }, { - .name = "biu", - .devname = "dw_mmc.1", - .parent = &exynos5_clk_aclk_200.clk, - .enable = exynos5_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 13), - }, { - .name = "biu", - .devname = "dw_mmc.2", - .parent = &exynos5_clk_aclk_200.clk, - .enable = exynos5_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 14), - }, { - .name = "biu", - .devname = "dw_mmc.3", - .parent = &exynos5_clk_aclk_200.clk, - .enable = exynos5_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 15), - }, { - .name = "sata", - .devname = "exynos5-sata", - .parent = &exynos5_clk_aclk_200.clk, - .enable = exynos5_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 6), - }, { - .name = "sata-phy", - .devname = "exynos5-sata-phy", - .parent = &exynos5_clk_aclk_200.clk, - .enable = exynos5_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 24), - }, { - .name = "i2c", - .devname = "exynos5-sata-phy-i2c", - .parent = &exynos5_clk_aclk_200.clk, - .enable = exynos5_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 25), - }, { - .name = "mfc", - .devname = "s5p-mfc-v6", - .enable = exynos5_clk_ip_mfc_ctrl, - .ctrlbit = (1 << 0), - }, { - .name = "hdmi", - .devname = "exynos5-hdmi", - .enable = exynos5_clk_ip_disp1_ctrl, - .ctrlbit = (1 << 6), - }, { - .name = "hdmiphy", - .devname = "exynos5-hdmi", - .enable = exynos5_clk_hdmiphy_ctrl, - .ctrlbit = (1 << 0), - }, { - .name = "mixer", - .devname = "exynos5-mixer", - .enable = exynos5_clk_ip_disp1_ctrl, - .ctrlbit = (1 << 5), - }, { - .name = "dp", - .devname = "exynos-dp", - .enable = exynos5_clk_ip_disp1_ctrl, - .ctrlbit = (1 << 4), - }, { - .name = "jpeg", - .enable = exynos5_clk_ip_gen_ctrl, - .ctrlbit = (1 << 2), - }, { - .name = "dsim0", - .enable = exynos5_clk_ip_disp1_ctrl, - .ctrlbit = (1 << 3), - }, { - .name = "iis", - .devname = "samsung-i2s.1", - .enable = exynos5_clk_ip_peric_ctrl, - .ctrlbit = (1 << 20), - }, { - .name = "iis", - .devname = "samsung-i2s.2", - .enable = exynos5_clk_ip_peric_ctrl, - .ctrlbit = (1 << 21), - }, { - .name = "pcm", - .devname = "samsung-pcm.1", - .enable = exynos5_clk_ip_peric_ctrl, - .ctrlbit = (1 << 22), - }, { - .name = "pcm", - .devname = "samsung-pcm.2", - .enable = exynos5_clk_ip_peric_ctrl, - .ctrlbit = (1 << 23), - }, { - .name = "spdif", - .devname = "samsung-spdif", - .enable = exynos5_clk_ip_peric_ctrl, - .ctrlbit = (1 << 26), - }, { - .name = "ac97", - .devname = "samsung-ac97", - .enable = exynos5_clk_ip_peric_ctrl, - .ctrlbit = (1 << 27), - }, { - .name = "usbhost", - .enable = exynos5_clk_ip_fsys_ctrl , - .ctrlbit = (1 << 18), - }, { - .name = "usbotg", - .enable = exynos5_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 7), - }, { - .name = "nfcon", - .enable = exynos5_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 22), - }, { - .name = "iop", - .enable = exynos5_clk_ip_fsys_ctrl, - .ctrlbit = ((1 << 30) | (1 << 26) | (1 << 23)), - }, { - .name = "core_iop", - .enable = exynos5_clk_ip_core_ctrl, - .ctrlbit = ((1 << 21) | (1 << 3)), - }, { - .name = "mcu_iop", - .enable = exynos5_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 0), - }, { - .name = "i2c", - .devname = "s3c2440-i2c.0", - .parent = &exynos5_clk_aclk_66.clk, - .enable = exynos5_clk_ip_peric_ctrl, - .ctrlbit = (1 << 6), - }, { - .name = "i2c", - .devname = "s3c2440-i2c.1", - .parent = &exynos5_clk_aclk_66.clk, - .enable = exynos5_clk_ip_peric_ctrl, - .ctrlbit = (1 << 7), - }, { - .name = "i2c", - .devname = "s3c2440-i2c.2", - .parent = &exynos5_clk_aclk_66.clk, - .enable = exynos5_clk_ip_peric_ctrl, - .ctrlbit = (1 << 8), - }, { - .name = "i2c", - .devname = "s3c2440-i2c.3", - .parent = &exynos5_clk_aclk_66.clk, - .enable = exynos5_clk_ip_peric_ctrl, - .ctrlbit = (1 << 9), - }, { - .name = "i2c", - .devname = "s3c2440-i2c.4", - .parent = &exynos5_clk_aclk_66.clk, - .enable = exynos5_clk_ip_peric_ctrl, - .ctrlbit = (1 << 10), - }, { - .name = "i2c", - .devname = "s3c2440-i2c.5", - .parent = &exynos5_clk_aclk_66.clk, - .enable = exynos5_clk_ip_peric_ctrl, - .ctrlbit = (1 << 11), - }, { - .name = "i2c", - .devname = "s3c2440-i2c.6", - .parent = &exynos5_clk_aclk_66.clk, - .enable = exynos5_clk_ip_peric_ctrl, - .ctrlbit = (1 << 12), - }, { - .name = "i2c", - .devname = "s3c2440-i2c.7", - .parent = &exynos5_clk_aclk_66.clk, - .enable = exynos5_clk_ip_peric_ctrl, - .ctrlbit = (1 << 13), - }, { - .name = "i2c", - .devname = "s3c2440-hdmiphy-i2c", - .parent = &exynos5_clk_aclk_66.clk, - .enable = exynos5_clk_ip_peric_ctrl, - .ctrlbit = (1 << 14), - }, { - .name = "spi", - .devname = "exynos4210-spi.0", - .parent = &exynos5_clk_aclk_66.clk, - .enable = exynos5_clk_ip_peric_ctrl, - .ctrlbit = (1 << 16), - }, { - .name = "spi", - .devname = "exynos4210-spi.1", - .parent = &exynos5_clk_aclk_66.clk, - .enable = exynos5_clk_ip_peric_ctrl, - .ctrlbit = (1 << 17), - }, { - .name = "spi", - .devname = "exynos4210-spi.2", - .parent = &exynos5_clk_aclk_66.clk, - .enable = exynos5_clk_ip_peric_ctrl, - .ctrlbit = (1 << 18), - }, { - .name = "gscl", - .devname = "exynos-gsc.0", - .enable = exynos5_clk_ip_gscl_ctrl, - .ctrlbit = (1 << 0), - }, { - .name = "gscl", - .devname = "exynos-gsc.1", - .enable = exynos5_clk_ip_gscl_ctrl, - .ctrlbit = (1 << 1), - }, { - .name = "gscl", - .devname = "exynos-gsc.2", - .enable = exynos5_clk_ip_gscl_ctrl, - .ctrlbit = (1 << 2), - }, { - .name = "gscl", - .devname = "exynos-gsc.3", - .enable = exynos5_clk_ip_gscl_ctrl, - .ctrlbit = (1 << 3), - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.1", - .enable = &exynos5_clk_ip_mfc_ctrl, - .ctrlbit = (1 << 1), - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.0", - .enable = &exynos5_clk_ip_mfc_ctrl, - .ctrlbit = (1 << 2), - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.2", - .enable = &exynos5_clk_ip_disp1_ctrl, - .ctrlbit = (1 << 9) - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.3", - .enable = &exynos5_clk_ip_gen_ctrl, - .ctrlbit = (1 << 7), - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.4", - .enable = &exynos5_clk_ip_gen_ctrl, - .ctrlbit = (1 << 6) - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.5", - .enable = &exynos5_clk_ip_gscl_ctrl, - .ctrlbit = (1 << 7), - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.6", - .enable = &exynos5_clk_ip_gscl_ctrl, - .ctrlbit = (1 << 8), - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.7", - .enable = &exynos5_clk_ip_gscl_ctrl, - .ctrlbit = (1 << 9), - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.8", - .enable = &exynos5_clk_ip_gscl_ctrl, - .ctrlbit = (1 << 10), - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.9", - .enable = &exynos5_clk_ip_isp0_ctrl, - .ctrlbit = (0x3F << 8), - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.10", - .enable = &exynos5_clk_ip_isp1_ctrl, - .ctrlbit = (0xF << 4), - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.11", - .enable = &exynos5_clk_ip_disp1_ctrl, - .ctrlbit = (1 << 8) - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.12", - .enable = &exynos5_clk_ip_gscl_ctrl, - .ctrlbit = (1 << 11), - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.13", - .enable = &exynos5_clk_ip_gscl_ctrl, - .ctrlbit = (1 << 12), - }, { - .name = "sysmmu", - .devname = "exynos-sysmmu.14", - .enable = &exynos5_clk_ip_acp_ctrl, - .ctrlbit = (1 << 7) - } -}; - -static struct clk exynos5_init_clocks_on[] = { - { - .name = "uart", - .devname = "s5pv210-uart.0", - .enable = exynos5_clk_ip_peric_ctrl, - .ctrlbit = (1 << 0), - }, { - .name = "uart", - .devname = "s5pv210-uart.1", - .enable = exynos5_clk_ip_peric_ctrl, - .ctrlbit = (1 << 1), - }, { - .name = "uart", - .devname = "s5pv210-uart.2", - .enable = exynos5_clk_ip_peric_ctrl, - .ctrlbit = (1 << 2), - }, { - .name = "uart", - .devname = "s5pv210-uart.3", - .enable = exynos5_clk_ip_peric_ctrl, - .ctrlbit = (1 << 3), - }, { - .name = "uart", - .devname = "s5pv210-uart.4", - .enable = exynos5_clk_ip_peric_ctrl, - .ctrlbit = (1 << 4), - }, { - .name = "uart", - .devname = "s5pv210-uart.5", - .enable = exynos5_clk_ip_peric_ctrl, - .ctrlbit = (1 << 5), - } -}; - -static struct clk exynos5_clk_pdma0 = { - .name = "dma", - .devname = "dma-pl330.0", - .enable = exynos5_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 1), -}; - -static struct clk exynos5_clk_pdma1 = { - .name = "dma", - .devname = "dma-pl330.1", - .enable = exynos5_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 2), -}; - -static struct clk exynos5_clk_mdma1 = { - .name = "dma", - .devname = "dma-pl330.2", - .enable = exynos5_clk_ip_gen_ctrl, - .ctrlbit = (1 << 4), -}; - -static struct clk exynos5_clk_fimd1 = { - .name = "fimd", - .devname = "exynos5-fb.1", - .enable = exynos5_clk_ip_disp1_ctrl, - .ctrlbit = (1 << 0), -}; - -static struct clk *exynos5_clkset_group_list[] = { - [0] = &clk_ext_xtal_mux, - [1] = NULL, - [2] = &exynos5_clk_sclk_hdmi24m, - [3] = &exynos5_clk_sclk_dptxphy, - [4] = &exynos5_clk_sclk_usbphy, - [5] = &exynos5_clk_sclk_hdmiphy, - [6] = &exynos5_clk_mout_mpll_user.clk, - [7] = &exynos5_clk_mout_epll.clk, - [8] = &exynos5_clk_sclk_vpll.clk, - [9] = &exynos5_clk_mout_cpll.clk, -}; - -static struct clksrc_sources exynos5_clkset_group = { - .sources = exynos5_clkset_group_list, - .nr_sources = ARRAY_SIZE(exynos5_clkset_group_list), -}; - -/* Possible clock sources for aclk_266_gscl_sub Mux */ -static struct clk *clk_src_gscl_266_list[] = { - [0] = &clk_ext_xtal_mux, - [1] = &exynos5_clk_aclk_266.clk, -}; - -static struct clksrc_sources clk_src_gscl_266 = { - .sources = clk_src_gscl_266_list, - .nr_sources = ARRAY_SIZE(clk_src_gscl_266_list), -}; - -static struct clksrc_clk exynos5_clk_dout_mmc0 = { - .clk = { - .name = "dout_mmc0", - }, - .sources = &exynos5_clkset_group, - .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 0, .size = 4 }, - .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 0, .size = 4 }, -}; - -static struct clksrc_clk exynos5_clk_dout_mmc1 = { - .clk = { - .name = "dout_mmc1", - }, - .sources = &exynos5_clkset_group, - .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 4, .size = 4 }, - .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 16, .size = 4 }, -}; - -static struct clksrc_clk exynos5_clk_dout_mmc2 = { - .clk = { - .name = "dout_mmc2", - }, - .sources = &exynos5_clkset_group, - .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 8, .size = 4 }, - .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 0, .size = 4 }, -}; - -static struct clksrc_clk exynos5_clk_dout_mmc3 = { - .clk = { - .name = "dout_mmc3", - }, - .sources = &exynos5_clkset_group, - .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 12, .size = 4 }, - .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 16, .size = 4 }, -}; - -static struct clksrc_clk exynos5_clk_dout_mmc4 = { - .clk = { - .name = "dout_mmc4", - }, - .sources = &exynos5_clkset_group, - .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 16, .size = 4 }, - .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS3, .shift = 0, .size = 4 }, -}; - -static struct clksrc_clk exynos5_clk_sclk_uart0 = { - .clk = { - .name = "uclk1", - .devname = "exynos4210-uart.0", - .enable = exynos5_clksrc_mask_peric0_ctrl, - .ctrlbit = (1 << 0), - }, - .sources = &exynos5_clkset_group, - .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 0, .size = 4 }, - .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 0, .size = 4 }, -}; - -static struct clksrc_clk exynos5_clk_sclk_uart1 = { - .clk = { - .name = "uclk1", - .devname = "exynos4210-uart.1", - .enable = exynos5_clksrc_mask_peric0_ctrl, - .ctrlbit = (1 << 4), - }, - .sources = &exynos5_clkset_group, - .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 4, .size = 4 }, - .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 4, .size = 4 }, -}; - -static struct clksrc_clk exynos5_clk_sclk_uart2 = { - .clk = { - .name = "uclk1", - .devname = "exynos4210-uart.2", - .enable = exynos5_clksrc_mask_peric0_ctrl, - .ctrlbit = (1 << 8), - }, - .sources = &exynos5_clkset_group, - .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 8, .size = 4 }, - .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 8, .size = 4 }, -}; - -static struct clksrc_clk exynos5_clk_sclk_uart3 = { - .clk = { - .name = "uclk1", - .devname = "exynos4210-uart.3", - .enable = exynos5_clksrc_mask_peric0_ctrl, - .ctrlbit = (1 << 12), - }, - .sources = &exynos5_clkset_group, - .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 12, .size = 4 }, - .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 12, .size = 4 }, -}; - -static struct clksrc_clk exynos5_clk_sclk_mmc0 = { - .clk = { - .name = "ciu", /* card interface unit clock */ - .devname = "dw_mmc.0", - .parent = &exynos5_clk_dout_mmc0.clk, - .enable = exynos5_clksrc_mask_fsys_ctrl, - .ctrlbit = (1 << 0), - }, - .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 8, .size = 8 }, -}; - -static struct clksrc_clk exynos5_clk_sclk_mmc1 = { - .clk = { - .name = "ciu", - .devname = "dw_mmc.1", - .parent = &exynos5_clk_dout_mmc1.clk, - .enable = exynos5_clksrc_mask_fsys_ctrl, - .ctrlbit = (1 << 4), - }, - .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 24, .size = 8 }, -}; - -static struct clksrc_clk exynos5_clk_sclk_mmc2 = { - .clk = { - .name = "ciu", - .devname = "dw_mmc.2", - .parent = &exynos5_clk_dout_mmc2.clk, - .enable = exynos5_clksrc_mask_fsys_ctrl, - .ctrlbit = (1 << 8), - }, - .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 8, .size = 8 }, -}; - -static struct clksrc_clk exynos5_clk_sclk_mmc3 = { - .clk = { - .name = "ciu", - .devname = "dw_mmc.3", - .parent = &exynos5_clk_dout_mmc3.clk, - .enable = exynos5_clksrc_mask_fsys_ctrl, - .ctrlbit = (1 << 12), - }, - .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 24, .size = 8 }, -}; - -static struct clksrc_clk exynos5_clk_mdout_spi0 = { - .clk = { - .name = "mdout_spi", - .devname = "exynos4210-spi.0", - }, - .sources = &exynos5_clkset_group, - .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC1, .shift = 16, .size = 4 }, - .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC1, .shift = 0, .size = 4 }, -}; - -static struct clksrc_clk exynos5_clk_mdout_spi1 = { - .clk = { - .name = "mdout_spi", - .devname = "exynos4210-spi.1", - }, - .sources = &exynos5_clkset_group, - .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC1, .shift = 20, .size = 4 }, - .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC1, .shift = 16, .size = 4 }, -}; - -static struct clksrc_clk exynos5_clk_mdout_spi2 = { - .clk = { - .name = "mdout_spi", - .devname = "exynos4210-spi.2", - }, - .sources = &exynos5_clkset_group, - .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC1, .shift = 24, .size = 4 }, - .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC2, .shift = 0, .size = 4 }, -}; - -static struct clksrc_clk exynos5_clk_sclk_spi0 = { - .clk = { - .name = "sclk_spi", - .devname = "exynos4210-spi.0", - .parent = &exynos5_clk_mdout_spi0.clk, - .enable = exynos5_clksrc_mask_peric1_ctrl, - .ctrlbit = (1 << 16), - }, - .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC1, .shift = 8, .size = 8 }, -}; - -static struct clksrc_clk exynos5_clk_sclk_spi1 = { - .clk = { - .name = "sclk_spi", - .devname = "exynos4210-spi.1", - .parent = &exynos5_clk_mdout_spi1.clk, - .enable = exynos5_clksrc_mask_peric1_ctrl, - .ctrlbit = (1 << 20), - }, - .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC1, .shift = 24, .size = 8 }, -}; - -static struct clksrc_clk exynos5_clk_sclk_spi2 = { - .clk = { - .name = "sclk_spi", - .devname = "exynos4210-spi.2", - .parent = &exynos5_clk_mdout_spi2.clk, - .enable = exynos5_clksrc_mask_peric1_ctrl, - .ctrlbit = (1 << 24), - }, - .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC2, .shift = 8, .size = 8 }, -}; - -static struct clksrc_clk exynos5_clk_sclk_fimd1 = { - .clk = { - .name = "sclk_fimd", - .devname = "exynos5-fb.1", - .enable = exynos5_clksrc_mask_disp1_0_ctrl, - .ctrlbit = (1 << 0), - }, - .sources = &exynos5_clkset_group, - .reg_src = { .reg = EXYNOS5_CLKSRC_DISP1_0, .shift = 0, .size = 4 }, - .reg_div = { .reg = EXYNOS5_CLKDIV_DISP1_0, .shift = 0, .size = 4 }, -}; - -static struct clksrc_clk exynos5_clksrcs[] = { - { - .clk = { - .name = "aclk_266_gscl", - }, - .sources = &clk_src_gscl_266, - .reg_src = { .reg = EXYNOS5_CLKSRC_TOP3, .shift = 8, .size = 1 }, - }, { - .clk = { - .name = "sclk_g3d", - .devname = "mali-t604.0", - .enable = exynos5_clk_block_ctrl, - .ctrlbit = (1 << 1), - }, - .sources = &exynos5_clkset_aclk, - .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 20, .size = 1 }, - .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 24, .size = 3 }, - }, { - .clk = { - .name = "sclk_sata", - .devname = "exynos5-sata", - .enable = exynos5_clksrc_mask_fsys_ctrl, - .ctrlbit = (1 << 24), - }, - .sources = &exynos5_clkset_aclk, - .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 24, .size = 1 }, - .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS0, .shift = 20, .size = 4 }, - }, { - .clk = { - .name = "sclk_gscl_wrap", - .devname = "s5p-mipi-csis.0", - .enable = exynos5_clksrc_mask_gscl_ctrl, - .ctrlbit = (1 << 24), - }, - .sources = &exynos5_clkset_group, - .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 24, .size = 4 }, - .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 24, .size = 4 }, - }, { - .clk = { - .name = "sclk_gscl_wrap", - .devname = "s5p-mipi-csis.1", - .enable = exynos5_clksrc_mask_gscl_ctrl, - .ctrlbit = (1 << 28), - }, - .sources = &exynos5_clkset_group, - .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 28, .size = 4 }, - .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 28, .size = 4 }, - }, { - .clk = { - .name = "sclk_cam0", - .enable = exynos5_clksrc_mask_gscl_ctrl, - .ctrlbit = (1 << 16), - }, - .sources = &exynos5_clkset_group, - .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 16, .size = 4 }, - .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 16, .size = 4 }, - }, { - .clk = { - .name = "sclk_cam1", - .enable = exynos5_clksrc_mask_gscl_ctrl, - .ctrlbit = (1 << 20), - }, - .sources = &exynos5_clkset_group, - .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 20, .size = 4 }, - .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 20, .size = 4 }, - }, { - .clk = { - .name = "sclk_jpeg", - .parent = &exynos5_clk_mout_cpll.clk, - }, - .reg_div = { .reg = EXYNOS5_CLKDIV_GEN, .shift = 4, .size = 3 }, - }, -}; - -/* Clock initialization code */ -static struct clksrc_clk *exynos5_sysclks[] = { - &exynos5_clk_mout_apll, - &exynos5_clk_sclk_apll, - &exynos5_clk_mout_bpll, - &exynos5_clk_mout_bpll_fout, - &exynos5_clk_mout_bpll_user, - &exynos5_clk_mout_cpll, - &exynos5_clk_mout_epll, - &exynos5_clk_mout_mpll, - &exynos5_clk_mout_mpll_fout, - &exynos5_clk_mout_mpll_user, - &exynos5_clk_vpllsrc, - &exynos5_clk_sclk_vpll, - &exynos5_clk_mout_cpu, - &exynos5_clk_dout_armclk, - &exynos5_clk_dout_arm2clk, - &exynos5_clk_cdrex, - &exynos5_clk_aclk_400, - &exynos5_clk_aclk_333, - &exynos5_clk_aclk_266, - &exynos5_clk_aclk_200, - &exynos5_clk_aclk_166, - &exynos5_clk_aclk_300_gscl, - &exynos5_clk_mout_aclk_300_gscl, - &exynos5_clk_mout_aclk_300_gscl_mid, - &exynos5_clk_mout_aclk_300_gscl_mid1, - &exynos5_clk_aclk_66_pre, - &exynos5_clk_aclk_66, - &exynos5_clk_dout_mmc0, - &exynos5_clk_dout_mmc1, - &exynos5_clk_dout_mmc2, - &exynos5_clk_dout_mmc3, - &exynos5_clk_dout_mmc4, - &exynos5_clk_aclk_acp, - &exynos5_clk_pclk_acp, - &exynos5_clk_sclk_spi0, - &exynos5_clk_sclk_spi1, - &exynos5_clk_sclk_spi2, - &exynos5_clk_mdout_spi0, - &exynos5_clk_mdout_spi1, - &exynos5_clk_mdout_spi2, - &exynos5_clk_sclk_fimd1, -}; - -static struct clk *exynos5_clk_cdev[] = { - &exynos5_clk_pdma0, - &exynos5_clk_pdma1, - &exynos5_clk_mdma1, - &exynos5_clk_fimd1, -}; - -static struct clksrc_clk *exynos5_clksrc_cdev[] = { - &exynos5_clk_sclk_uart0, - &exynos5_clk_sclk_uart1, - &exynos5_clk_sclk_uart2, - &exynos5_clk_sclk_uart3, - &exynos5_clk_sclk_mmc0, - &exynos5_clk_sclk_mmc1, - &exynos5_clk_sclk_mmc2, - &exynos5_clk_sclk_mmc3, -}; - -static struct clk_lookup exynos5_clk_lookup[] = { - CLKDEV_INIT("exynos4210-uart.0", "clk_uart_baud0", &exynos5_clk_sclk_uart0.clk), - CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &exynos5_clk_sclk_uart1.clk), - CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &exynos5_clk_sclk_uart2.clk), - CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &exynos5_clk_sclk_uart3.clk), - CLKDEV_INIT("exynos4-sdhci.0", "mmc_busclk.2", &exynos5_clk_sclk_mmc0.clk), - CLKDEV_INIT("exynos4-sdhci.1", "mmc_busclk.2", &exynos5_clk_sclk_mmc1.clk), - CLKDEV_INIT("exynos4-sdhci.2", "mmc_busclk.2", &exynos5_clk_sclk_mmc2.clk), - CLKDEV_INIT("exynos4-sdhci.3", "mmc_busclk.2", &exynos5_clk_sclk_mmc3.clk), - CLKDEV_INIT("exynos4210-spi.0", "spi_busclk0", &exynos5_clk_sclk_spi0.clk), - CLKDEV_INIT("exynos4210-spi.1", "spi_busclk0", &exynos5_clk_sclk_spi1.clk), - CLKDEV_INIT("exynos4210-spi.2", "spi_busclk0", &exynos5_clk_sclk_spi2.clk), - CLKDEV_INIT("dma-pl330.0", "apb_pclk", &exynos5_clk_pdma0), - CLKDEV_INIT("dma-pl330.1", "apb_pclk", &exynos5_clk_pdma1), - CLKDEV_INIT("dma-pl330.2", "apb_pclk", &exynos5_clk_mdma1), - CLKDEV_INIT("exynos5-fb.1", "lcd", &exynos5_clk_fimd1), -}; - -static unsigned long exynos5_epll_get_rate(struct clk *clk) -{ - return clk->rate; -} - -static struct clk *exynos5_clks[] __initdata = { - &exynos5_clk_sclk_hdmi27m, - &exynos5_clk_sclk_hdmiphy, - &clk_fout_bpll, - &clk_fout_bpll_div2, - &clk_fout_cpll, - &clk_fout_mpll_div2, - &exynos5_clk_armclk, -}; - -static u32 epll_div[][6] = { - { 192000000, 0, 48, 3, 1, 0 }, - { 180000000, 0, 45, 3, 1, 0 }, - { 73728000, 1, 73, 3, 3, 47710 }, - { 67737600, 1, 90, 4, 3, 20762 }, - { 49152000, 0, 49, 3, 3, 9961 }, - { 45158400, 0, 45, 3, 3, 10381 }, - { 180633600, 0, 45, 3, 1, 10381 }, -}; - -static int exynos5_epll_set_rate(struct clk *clk, unsigned long rate) -{ - unsigned int epll_con, epll_con_k; - unsigned int i; - unsigned int tmp; - unsigned int epll_rate; - unsigned int locktime; - unsigned int lockcnt; - - /* Return if nothing changed */ - if (clk->rate == rate) - return 0; - - if (clk->parent) - epll_rate = clk_get_rate(clk->parent); - else - epll_rate = clk_ext_xtal_mux.rate; - - if (epll_rate != 24000000) { - pr_err("Invalid Clock : recommended clock is 24MHz.\n"); - return -EINVAL; - } - - epll_con = __raw_readl(EXYNOS5_EPLL_CON0); - epll_con &= ~(0x1 << 27 | \ - PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT | \ - PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT | \ - PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT); - - for (i = 0; i < ARRAY_SIZE(epll_div); i++) { - if (epll_div[i][0] == rate) { - epll_con_k = epll_div[i][5] << 0; - epll_con |= epll_div[i][1] << 27; - epll_con |= epll_div[i][2] << PLL46XX_MDIV_SHIFT; - epll_con |= epll_div[i][3] << PLL46XX_PDIV_SHIFT; - epll_con |= epll_div[i][4] << PLL46XX_SDIV_SHIFT; - break; - } - } - - if (i == ARRAY_SIZE(epll_div)) { - printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", - __func__); - return -EINVAL; - } - - epll_rate /= 1000000; - - /* 3000 max_cycls : specification data */ - locktime = 3000 / epll_rate * epll_div[i][3]; - lockcnt = locktime * 10000 / (10000 / epll_rate); - - __raw_writel(lockcnt, EXYNOS5_EPLL_LOCK); - - __raw_writel(epll_con, EXYNOS5_EPLL_CON0); - __raw_writel(epll_con_k, EXYNOS5_EPLL_CON1); - - do { - tmp = __raw_readl(EXYNOS5_EPLL_CON0); - } while (!(tmp & 0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT)); - - clk->rate = rate; - - return 0; -} - -static struct clk_ops exynos5_epll_ops = { - .get_rate = exynos5_epll_get_rate, - .set_rate = exynos5_epll_set_rate, -}; - -static int xtal_rate; - -static unsigned long exynos5_fout_apll_get_rate(struct clk *clk) -{ - return s5p_get_pll35xx(xtal_rate, __raw_readl(EXYNOS5_APLL_CON0)); -} - -static struct clk_ops exynos5_fout_apll_ops = { - .get_rate = exynos5_fout_apll_get_rate, -}; - -#ifdef CONFIG_PM -static int exynos5_clock_suspend(void) -{ - s3c_pm_do_save(exynos5_clock_save, ARRAY_SIZE(exynos5_clock_save)); - - return 0; -} - -static void exynos5_clock_resume(void) -{ - s3c_pm_do_restore_core(exynos5_clock_save, ARRAY_SIZE(exynos5_clock_save)); -} -#else -#define exynos5_clock_suspend NULL -#define exynos5_clock_resume NULL -#endif - -static struct syscore_ops exynos5_clock_syscore_ops = { - .suspend = exynos5_clock_suspend, - .resume = exynos5_clock_resume, -}; - -void __init_or_cpufreq exynos5_setup_clocks(void) -{ - struct clk *xtal_clk; - unsigned long apll; - unsigned long bpll; - unsigned long cpll; - unsigned long mpll; - unsigned long epll; - unsigned long vpll; - unsigned long vpllsrc; - unsigned long xtal; - unsigned long armclk; - unsigned long mout_cdrex; - unsigned long aclk_400; - unsigned long aclk_333; - unsigned long aclk_266; - unsigned long aclk_200; - unsigned long aclk_166; - unsigned long aclk_66; - unsigned int ptr; - - printk(KERN_DEBUG "%s: registering clocks\n", __func__); - - xtal_clk = clk_get(NULL, "xtal"); - BUG_ON(IS_ERR(xtal_clk)); - - xtal = clk_get_rate(xtal_clk); - - xtal_rate = xtal; - - clk_put(xtal_clk); - - printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal); - - apll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_APLL_CON0)); - bpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_BPLL_CON0)); - cpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_CPLL_CON0)); - mpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_MPLL_CON0)); - epll = s5p_get_pll36xx(xtal, __raw_readl(EXYNOS5_EPLL_CON0), - __raw_readl(EXYNOS5_EPLL_CON1)); - - vpllsrc = clk_get_rate(&exynos5_clk_vpllsrc.clk); - vpll = s5p_get_pll36xx(vpllsrc, __raw_readl(EXYNOS5_VPLL_CON0), - __raw_readl(EXYNOS5_VPLL_CON1)); - - clk_fout_apll.ops = &exynos5_fout_apll_ops; - clk_fout_bpll.rate = bpll; - clk_fout_bpll_div2.rate = bpll >> 1; - clk_fout_cpll.rate = cpll; - clk_fout_mpll.rate = mpll; - clk_fout_mpll_div2.rate = mpll >> 1; - clk_fout_epll.rate = epll; - clk_fout_vpll.rate = vpll; - - printk(KERN_INFO "EXYNOS5: PLL settings, A=%ld, B=%ld, C=%ld\n" - "M=%ld, E=%ld V=%ld", - apll, bpll, cpll, mpll, epll, vpll); - - armclk = clk_get_rate(&exynos5_clk_armclk); - mout_cdrex = clk_get_rate(&exynos5_clk_cdrex.clk); - - aclk_400 = clk_get_rate(&exynos5_clk_aclk_400.clk); - aclk_333 = clk_get_rate(&exynos5_clk_aclk_333.clk); - aclk_266 = clk_get_rate(&exynos5_clk_aclk_266.clk); - aclk_200 = clk_get_rate(&exynos5_clk_aclk_200.clk); - aclk_166 = clk_get_rate(&exynos5_clk_aclk_166.clk); - aclk_66 = clk_get_rate(&exynos5_clk_aclk_66.clk); - - printk(KERN_INFO "EXYNOS5: ARMCLK=%ld, CDREX=%ld, ACLK400=%ld\n" - "ACLK333=%ld, ACLK266=%ld, ACLK200=%ld\n" - "ACLK166=%ld, ACLK66=%ld\n", - armclk, mout_cdrex, aclk_400, - aclk_333, aclk_266, aclk_200, - aclk_166, aclk_66); - - - clk_fout_epll.ops = &exynos5_epll_ops; - - if (clk_set_parent(&exynos5_clk_mout_epll.clk, &clk_fout_epll)) - printk(KERN_ERR "Unable to set parent %s of clock %s.\n", - clk_fout_epll.name, exynos5_clk_mout_epll.clk.name); - - clk_set_rate(&exynos5_clk_sclk_apll.clk, 100000000); - clk_set_rate(&exynos5_clk_aclk_266.clk, 300000000); - - clk_set_rate(&exynos5_clk_aclk_acp.clk, 267000000); - clk_set_rate(&exynos5_clk_pclk_acp.clk, 134000000); - - for (ptr = 0; ptr < ARRAY_SIZE(exynos5_clksrcs); ptr++) - s3c_set_clksrc(&exynos5_clksrcs[ptr], true); -} - -void __init exynos5_register_clocks(void) -{ - int ptr; - - s3c24xx_register_clocks(exynos5_clks, ARRAY_SIZE(exynos5_clks)); - - for (ptr = 0; ptr < ARRAY_SIZE(exynos5_sysclks); ptr++) - s3c_register_clksrc(exynos5_sysclks[ptr], 1); - - for (ptr = 0; ptr < ARRAY_SIZE(exynos5_sclk_tv); ptr++) - s3c_register_clksrc(exynos5_sclk_tv[ptr], 1); - - for (ptr = 0; ptr < ARRAY_SIZE(exynos5_clksrc_cdev); ptr++) - s3c_register_clksrc(exynos5_clksrc_cdev[ptr], 1); - - s3c_register_clksrc(exynos5_clksrcs, ARRAY_SIZE(exynos5_clksrcs)); - s3c_register_clocks(exynos5_init_clocks_on, ARRAY_SIZE(exynos5_init_clocks_on)); - - s3c24xx_register_clocks(exynos5_clk_cdev, ARRAY_SIZE(exynos5_clk_cdev)); - for (ptr = 0; ptr < ARRAY_SIZE(exynos5_clk_cdev); ptr++) - s3c_disable_clocks(exynos5_clk_cdev[ptr], 1); - - s3c_register_clocks(exynos5_init_clocks_off, ARRAY_SIZE(exynos5_init_clocks_off)); - s3c_disable_clocks(exynos5_init_clocks_off, ARRAY_SIZE(exynos5_init_clocks_off)); - clkdev_add_table(exynos5_clk_lookup, ARRAY_SIZE(exynos5_clk_lookup)); - - register_syscore_ops(&exynos5_clock_syscore_ops); - s3c_pwmclk_init(); -} diff --git a/trunk/arch/arm/mach-exynos/common.c b/trunk/arch/arm/mach-exynos/common.c index 15718da30c45..745e304ad0de 100644 --- a/trunk/arch/arm/mach-exynos/common.c +++ b/trunk/arch/arm/mach-exynos/common.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include @@ -37,9 +39,9 @@ #include #include #include +#include #include -#include #include #include #include @@ -65,17 +67,16 @@ static const char name_exynos5440[] = "EXYNOS5440"; static void exynos4_map_io(void); static void exynos5_map_io(void); static void exynos5440_map_io(void); -static void exynos4_init_clocks(int xtal); -static void exynos5_init_clocks(int xtal); static void exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no); static int exynos_init(void); +unsigned long xxti_f = 0, xusbxti_f = 0; + static struct cpu_table cpu_ids[] __initdata = { { .idcode = EXYNOS4210_CPU_ID, .idmask = EXYNOS4_CPU_MASK, .map_io = exynos4_map_io, - .init_clocks = exynos4_init_clocks, .init_uarts = exynos4_init_uarts, .init = exynos_init, .name = name_exynos4210, @@ -83,7 +84,6 @@ static struct cpu_table cpu_ids[] __initdata = { .idcode = EXYNOS4212_CPU_ID, .idmask = EXYNOS4_CPU_MASK, .map_io = exynos4_map_io, - .init_clocks = exynos4_init_clocks, .init_uarts = exynos4_init_uarts, .init = exynos_init, .name = name_exynos4212, @@ -91,7 +91,6 @@ static struct cpu_table cpu_ids[] __initdata = { .idcode = EXYNOS4412_CPU_ID, .idmask = EXYNOS4_CPU_MASK, .map_io = exynos4_map_io, - .init_clocks = exynos4_init_clocks, .init_uarts = exynos4_init_uarts, .init = exynos_init, .name = name_exynos4412, @@ -99,7 +98,6 @@ static struct cpu_table cpu_ids[] __initdata = { .idcode = EXYNOS5250_SOC_ID, .idmask = EXYNOS5_SOC_MASK, .map_io = exynos5_map_io, - .init_clocks = exynos5_init_clocks, .init = exynos_init, .name = name_exynos5250, }, { @@ -122,17 +120,6 @@ static struct map_desc exynos_iodesc[] __initdata = { }, }; -#ifdef CONFIG_ARCH_EXYNOS5 -static struct map_desc exynos5440_iodesc[] __initdata = { - { - .virtual = (unsigned long)S5P_VA_CHIPID, - .pfn = __phys_to_pfn(EXYNOS5440_PA_CHIPID), - .length = SZ_4K, - .type = MT_DEVICE, - }, -}; -#endif - static struct map_desc exynos4_iodesc[] __initdata = { { .virtual = (unsigned long)S3C_VA_SYS, @@ -235,6 +222,33 @@ static struct map_desc exynos4_iodesc1[] __initdata = { }, }; +static struct map_desc exynos4210_iodesc[] __initdata = { + { + .virtual = (unsigned long)S5P_VA_SYSRAM_NS, + .pfn = __phys_to_pfn(EXYNOS4210_PA_SYSRAM_NS), + .length = SZ_4K, + .type = MT_DEVICE, + }, +}; + +static struct map_desc exynos4x12_iodesc[] __initdata = { + { + .virtual = (unsigned long)S5P_VA_SYSRAM_NS, + .pfn = __phys_to_pfn(EXYNOS4x12_PA_SYSRAM_NS), + .length = SZ_4K, + .type = MT_DEVICE, + }, +}; + +static struct map_desc exynos5250_iodesc[] __initdata = { + { + .virtual = (unsigned long)S5P_VA_SYSRAM_NS, + .pfn = __phys_to_pfn(EXYNOS5250_PA_SYSRAM_NS), + .length = SZ_4K, + .type = MT_DEVICE, + }, +}; + static struct map_desc exynos5_iodesc[] __initdata = { { .virtual = (unsigned long)S3C_VA_SYS, @@ -256,11 +270,6 @@ static struct map_desc exynos5_iodesc[] __initdata = { .pfn = __phys_to_pfn(EXYNOS5_PA_SROMC), .length = SZ_4K, .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S5P_VA_SYSTIMER, - .pfn = __phys_to_pfn(EXYNOS5_PA_SYSTIMER), - .length = SZ_4K, - .type = MT_DEVICE, }, { .virtual = (unsigned long)S5P_VA_SYSRAM, .pfn = __phys_to_pfn(EXYNOS5_PA_SYSRAM), @@ -328,6 +337,31 @@ void __init exynos_init_late(void) exynos_pm_late_initcall(); } +#ifdef CONFIG_OF +int __init exynos_fdt_map_chipid(unsigned long node, const char *uname, + int depth, void *data) +{ + struct map_desc iodesc; + __be32 *reg; + unsigned long len; + + if (!of_flat_dt_is_compatible(node, "samsung,exynos4210-chipid") && + !of_flat_dt_is_compatible(node, "samsung,exynos5440-clock")) + return 0; + + reg = of_get_flat_dt_prop(node, "reg", &len); + if (reg == NULL || len != (sizeof(unsigned long) * 2)) + return 0; + + iodesc.pfn = __phys_to_pfn(be32_to_cpu(reg[0])); + iodesc.length = be32_to_cpu(reg[1]) - 1; + iodesc.virtual = (unsigned long)S5P_VA_CHIPID; + iodesc.type = MT_DEVICE; + iotable_init(&iodesc, 1); + return 1; +} +#endif + /* * exynos_map_io * @@ -336,19 +370,12 @@ void __init exynos_init_late(void) void __init exynos_init_io(struct map_desc *mach_desc, int size) { - struct map_desc *iodesc = exynos_iodesc; - int iodesc_sz = ARRAY_SIZE(exynos_iodesc); -#if defined(CONFIG_OF) && defined(CONFIG_ARCH_EXYNOS5) - unsigned long root = of_get_flat_dt_root(); - - /* initialize the io descriptors we need for initialization */ - if (of_flat_dt_is_compatible(root, "samsung,exynos5440")) { - iodesc = exynos5440_iodesc; - iodesc_sz = ARRAY_SIZE(exynos5440_iodesc); - } +#ifdef CONFIG_OF + if (initial_boot_params) + of_scan_flat_dt(exynos_fdt_map_chipid, NULL); + else #endif - - iotable_init(iodesc, iodesc_sz); + iotable_init(exynos_iodesc, ARRAY_SIZE(exynos_iodesc)); if (mach_desc) iotable_init(mach_desc, size); @@ -368,6 +395,11 @@ static void __init exynos4_map_io(void) else iotable_init(exynos4_iodesc1, ARRAY_SIZE(exynos4_iodesc1)); + if (soc_is_exynos4210()) + iotable_init(exynos4210_iodesc, ARRAY_SIZE(exynos4210_iodesc)); + if (soc_is_exynos4212() || soc_is_exynos4412()) + iotable_init(exynos4x12_iodesc, ARRAY_SIZE(exynos4x12_iodesc)); + /* initialize device information early */ exynos4_default_sdhci0(); exynos4_default_sdhci1(); @@ -400,22 +432,9 @@ static void __init exynos4_map_io(void) static void __init exynos5_map_io(void) { iotable_init(exynos5_iodesc, ARRAY_SIZE(exynos5_iodesc)); -} - -static void __init exynos4_init_clocks(int xtal) -{ - printk(KERN_DEBUG "%s: initializing clocks\n", __func__); - s3c24xx_register_baseclocks(xtal); - s5p_register_clocks(xtal); - - if (soc_is_exynos4210()) - exynos4210_register_clocks(); - else if (soc_is_exynos4212() || soc_is_exynos4412()) - exynos4212_register_clocks(); - - exynos4_register_clocks(); - exynos4_setup_clocks(); + if (soc_is_exynos5250()) + iotable_init(exynos5250_iodesc, ARRAY_SIZE(exynos5250_iodesc)); } static void __init exynos5440_map_io(void) @@ -423,24 +442,36 @@ static void __init exynos5440_map_io(void) iotable_init(exynos5440_iodesc0, ARRAY_SIZE(exynos5440_iodesc0)); } -static void __init exynos5_init_clocks(int xtal) +void __init exynos_init_time(void) { - printk(KERN_DEBUG "%s: initializing clocks\n", __func__); - - /* EXYNOS5440 can support only common clock framework */ - - if (soc_is_exynos5440()) - return; - -#ifdef CONFIG_SOC_EXYNOS5250 - s3c24xx_register_baseclocks(xtal); - s5p_register_clocks(xtal); - - exynos5_register_clocks(); - exynos5_setup_clocks(); + if (of_have_populated_dt()) { +#ifdef CONFIG_OF + of_clk_init(NULL); + clocksource_of_init(); #endif + } else { + /* todo: remove after migrating legacy E4 platforms to dt */ +#ifdef CONFIG_ARCH_EXYNOS4 + exynos4_clk_init(NULL, !soc_is_exynos4210(), S5P_VA_CMU, readl(S5P_VA_CHIPID + 8) & 1); + exynos4_clk_register_fixed_ext(xxti_f, xusbxti_f); +#endif + mct_init(S5P_VA_SYSTIMER, EXYNOS4_IRQ_MCT_G0, EXYNOS4_IRQ_MCT_L0, EXYNOS4_IRQ_MCT_L1); + } } +static unsigned int max_combiner_nr(void) +{ + if (soc_is_exynos5250()) + return EXYNOS5_MAX_COMBINER_NR; + else if (soc_is_exynos4412()) + return EXYNOS4412_MAX_COMBINER_NR; + else if (soc_is_exynos4212()) + return EXYNOS4212_MAX_COMBINER_NR; + else + return EXYNOS4210_MAX_COMBINER_NR; +} + + void __init exynos4_init_irq(void) { unsigned int gic_bank_offset; @@ -455,14 +486,8 @@ void __init exynos4_init_irq(void) #endif if (!of_have_populated_dt()) - combiner_init(S5P_VA_COMBINER_BASE, NULL); - - /* - * The parameters of s5p_init_irq() are for VIC init. - * Theses parameters should be NULL and 0 because EXYNOS4 - * uses GIC instead of VIC. - */ - s5p_init_irq(NULL, 0); + combiner_init(S5P_VA_COMBINER_BASE, NULL, + max_combiner_nr(), COMBINER_IRQ(0, 0)); gic_arch_extn.irq_set_wake = s3c_irq_wake; } @@ -472,14 +497,6 @@ void __init exynos5_init_irq(void) #ifdef CONFIG_OF irqchip_init(); #endif - /* - * The parameters of s5p_init_irq() are for VIC init. - * Theses parameters should be NULL and 0 because EXYNOS4 - * uses GIC instead of VIC. - */ - if (!of_machine_is_compatible("samsung,exynos5440")) - s5p_init_irq(NULL, 0); - gic_arch_extn.irq_set_wake = s3c_irq_wake; } @@ -824,6 +841,7 @@ static int __init exynos_init_irq_eint(void) static const struct of_device_id exynos_pinctrl_ids[] = { { .compatible = "samsung,exynos4210-pinctrl", }, { .compatible = "samsung,exynos4x12-pinctrl", }, + { .compatible = "samsung,exynos5250-pinctrl", }, }; struct device_node *pctrl_np, *wkup_np; const char *wkup_compat = "samsung,exynos4210-wakeup-eint"; @@ -877,3 +895,30 @@ static int __init exynos_init_irq_eint(void) return 0; } arch_initcall(exynos_init_irq_eint); + +static struct resource exynos4_pmu_resource[] = { + DEFINE_RES_IRQ(EXYNOS4_IRQ_PMU), + DEFINE_RES_IRQ(EXYNOS4_IRQ_PMU_CPU1), +#if defined(CONFIG_SOC_EXYNOS4412) + DEFINE_RES_IRQ(EXYNOS4_IRQ_PMU_CPU2), + DEFINE_RES_IRQ(EXYNOS4_IRQ_PMU_CPU3), +#endif +}; + +static struct platform_device exynos4_device_pmu = { + .name = "arm-pmu", + .num_resources = ARRAY_SIZE(exynos4_pmu_resource), + .resource = exynos4_pmu_resource, +}; + +static int __init exynos_armpmu_init(void) +{ + if (!of_have_populated_dt()) { + if (soc_is_exynos4210() || soc_is_exynos4212()) + exynos4_device_pmu.num_resources = 2; + platform_device_register(&exynos4_device_pmu); + } + + return 0; +} +arch_initcall(exynos_armpmu_init); diff --git a/trunk/arch/arm/mach-exynos/common.h b/trunk/arch/arm/mach-exynos/common.h index 9339bb8954be..60dd35cc01a6 100644 --- a/trunk/arch/arm/mach-exynos/common.h +++ b/trunk/arch/arm/mach-exynos/common.h @@ -12,7 +12,11 @@ #ifndef __ARCH_ARM_MACH_EXYNOS_COMMON_H #define __ARCH_ARM_MACH_EXYNOS_COMMON_H -extern void exynos4_timer_init(void); +#include + +void mct_init(void __iomem *base, int irq_g0, int irq_l0, int irq_l1); +void exynos_init_time(void); +extern unsigned long xxti_f, xusbxti_f; struct map_desc; void exynos_init_io(struct map_desc *mach_desc, int size); @@ -22,6 +26,12 @@ void exynos4_restart(char mode, const char *cmd); void exynos5_restart(char mode, const char *cmd); void exynos_init_late(void); +/* ToDo: remove these after migrating legacy exynos4 platforms to dt */ +void exynos4_clk_init(struct device_node *np, int is_exynos4210, void __iomem *reg_base, unsigned long xom); +void exynos4_clk_register_fixed_ext(unsigned long, unsigned long); + +void exynos_firmware_init(void); + #ifdef CONFIG_PM_GENERIC_DOMAINS int exynos_pm_late_initcall(void); #else @@ -61,7 +71,8 @@ void exynos4212_register_clocks(void); #endif struct device_node; -void combiner_init(void __iomem *combiner_base, struct device_node *np); +void combiner_init(void __iomem *combiner_base, struct device_node *np, + unsigned int max_nr, int irq_base); extern struct smp_operations exynos_smp_ops; diff --git a/trunk/arch/arm/mach-exynos/exynos-smc.S b/trunk/arch/arm/mach-exynos/exynos-smc.S new file mode 100644 index 000000000000..2e27aa3813fd --- /dev/null +++ b/trunk/arch/arm/mach-exynos/exynos-smc.S @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2012 Samsung Electronics. + * + * Copied from omap-smc.S Copyright (C) 2010 Texas Instruments, Inc. + * + * This program is free software,you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include + +/* + * Function signature: void exynos_smc(u32 cmd, u32 arg1, u32 arg2, u32 arg3) + */ + +ENTRY(exynos_smc) + stmfd sp!, {r4-r11, lr} + dsb + smc #0 + ldmfd sp!, {r4-r11, pc} +ENDPROC(exynos_smc) diff --git a/trunk/arch/arm/mach-exynos/firmware.c b/trunk/arch/arm/mach-exynos/firmware.c new file mode 100644 index 000000000000..ed11f100d479 --- /dev/null +++ b/trunk/arch/arm/mach-exynos/firmware.c @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2012 Samsung Electronics. + * Kyungmin Park + * Tomasz Figa + * + * 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 +#include +#include +#include +#include + +#include + +#include + +#include "smc.h" + +static int exynos_do_idle(void) +{ + exynos_smc(SMC_CMD_SLEEP, 0, 0, 0); + return 0; +} + +static int exynos_cpu_boot(int cpu) +{ + exynos_smc(SMC_CMD_CPU1BOOT, cpu, 0, 0); + return 0; +} + +static int exynos_set_cpu_boot_addr(int cpu, unsigned long boot_addr) +{ + void __iomem *boot_reg = S5P_VA_SYSRAM_NS + 0x1c + 4*cpu; + + __raw_writel(boot_addr, boot_reg); + return 0; +} + +static const struct firmware_ops exynos_firmware_ops = { + .do_idle = exynos_do_idle, + .set_cpu_boot_addr = exynos_set_cpu_boot_addr, + .cpu_boot = exynos_cpu_boot, +}; + +void __init exynos_firmware_init(void) +{ + if (of_have_populated_dt()) { + struct device_node *nd; + const __be32 *addr; + + nd = of_find_compatible_node(NULL, NULL, + "samsung,secure-firmware"); + if (!nd) + return; + + addr = of_get_address(nd, 0, NULL, NULL); + if (!addr) { + pr_err("%s: No address specified.\n", __func__); + return; + } + } + + pr_info("Running under secure firmware.\n"); + + register_firmware_ops(&exynos_firmware_ops); +} diff --git a/trunk/arch/arm/mach-exynos/hotplug.c b/trunk/arch/arm/mach-exynos/hotplug.c index c3f825b27947..af90cfa2f826 100644 --- a/trunk/arch/arm/mach-exynos/hotplug.c +++ b/trunk/arch/arm/mach-exynos/hotplug.c @@ -28,7 +28,6 @@ static inline void cpu_enter_lowpower_a9(void) { unsigned int v; - flush_cache_all(); asm volatile( " mcr p15, 0, %1, c7, c5, 0\n" " mcr p15, 0, %1, c7, c10, 4\n" diff --git a/trunk/arch/arm/mach-exynos/include/mach/irqs.h b/trunk/arch/arm/mach-exynos/include/mach/irqs.h index 8bd5dde5fc78..c72f59d91fce 100644 --- a/trunk/arch/arm/mach-exynos/include/mach/irqs.h +++ b/trunk/arch/arm/mach-exynos/include/mach/irqs.h @@ -30,8 +30,6 @@ /* For EXYNOS4 and EXYNOS5 */ -#define EXYNOS_IRQ_MCT_LOCALTIMER IRQ_PPI(12) - #define EXYNOS_IRQ_EINT16_31 IRQ_SPI(32) /* For EXYNOS4 SoCs */ @@ -128,7 +126,7 @@ #define EXYNOS4_IRQ_ADC1 IRQ_SPI(107) #define EXYNOS4_IRQ_PEN1 IRQ_SPI(108) #define EXYNOS4_IRQ_KEYPAD IRQ_SPI(109) -#define EXYNOS4_IRQ_PMU IRQ_SPI(110) +#define EXYNOS4_IRQ_POWER_PMU IRQ_SPI(110) #define EXYNOS4_IRQ_GPS IRQ_SPI(111) #define EXYNOS4_IRQ_INTFEEDCTRL_SSS IRQ_SPI(112) #define EXYNOS4_IRQ_SLIMBUS IRQ_SPI(113) @@ -136,6 +134,11 @@ #define EXYNOS4_IRQ_TSI IRQ_SPI(115) #define EXYNOS4_IRQ_SATA IRQ_SPI(116) +#define EXYNOS4_IRQ_PMU COMBINER_IRQ(2, 2) +#define EXYNOS4_IRQ_PMU_CPU1 COMBINER_IRQ(3, 2) +#define EXYNOS4_IRQ_PMU_CPU2 COMBINER_IRQ(18, 2) +#define EXYNOS4_IRQ_PMU_CPU3 COMBINER_IRQ(19, 2) + #define EXYNOS4_IRQ_TMU_TRIG0 COMBINER_IRQ(2, 4) #define EXYNOS4_IRQ_TMU_TRIG1 COMBINER_IRQ(3, 4) @@ -168,7 +171,10 @@ #define EXYNOS4_IRQ_FIMD0_VSYNC COMBINER_IRQ(11, 1) #define EXYNOS4_IRQ_FIMD0_SYSTEM COMBINER_IRQ(11, 2) -#define EXYNOS4_MAX_COMBINER_NR 16 +#define EXYNOS4210_MAX_COMBINER_NR 16 +#define EXYNOS4212_MAX_COMBINER_NR 18 +#define EXYNOS4412_MAX_COMBINER_NR 20 +#define EXYNOS4_MAX_COMBINER_NR EXYNOS4412_MAX_COMBINER_NR #define EXYNOS4_IRQ_GPIO1_NR_GROUPS 16 #define EXYNOS4_IRQ_GPIO2_NR_GROUPS 9 @@ -233,7 +239,6 @@ #define IRQ_TC EXYNOS4_IRQ_PEN0 #define IRQ_KEYPAD EXYNOS4_IRQ_KEYPAD -#define IRQ_PMU EXYNOS4_IRQ_PMU #define IRQ_FIMD0_FIFO EXYNOS4_IRQ_FIMD0_FIFO #define IRQ_FIMD0_VSYNC EXYNOS4_IRQ_FIMD0_VSYNC @@ -323,8 +328,6 @@ #define EXYNOS5_IRQ_CEC IRQ_SPI(114) #define EXYNOS5_IRQ_SATA IRQ_SPI(115) -#define EXYNOS5_IRQ_MCT_L0 IRQ_SPI(120) -#define EXYNOS5_IRQ_MCT_L1 IRQ_SPI(121) #define EXYNOS5_IRQ_MMC44 IRQ_SPI(123) #define EXYNOS5_IRQ_MDMA1 IRQ_SPI(124) #define EXYNOS5_IRQ_FIMC_LITE0 IRQ_SPI(125) @@ -419,8 +422,6 @@ #define EXYNOS5_IRQ_PMU_CPU1 COMBINER_IRQ(22, 4) #define EXYNOS5_IRQ_EINT0 COMBINER_IRQ(23, 0) -#define EXYNOS5_IRQ_MCT_G0 COMBINER_IRQ(23, 3) -#define EXYNOS5_IRQ_MCT_G1 COMBINER_IRQ(23, 4) #define EXYNOS5_IRQ_EINT1 COMBINER_IRQ(24, 0) #define EXYNOS5_IRQ_SYSMMU_LITE1_0 COMBINER_IRQ(24, 1) diff --git a/trunk/arch/arm/mach-exynos/include/mach/map.h b/trunk/arch/arm/mach-exynos/include/mach/map.h index 1df6abbf53b8..92b29bb583cb 100644 --- a/trunk/arch/arm/mach-exynos/include/mach/map.h +++ b/trunk/arch/arm/mach-exynos/include/mach/map.h @@ -26,6 +26,9 @@ #define EXYNOS4_PA_SYSRAM0 0x02025000 #define EXYNOS4_PA_SYSRAM1 0x02020000 #define EXYNOS5_PA_SYSRAM 0x02020000 +#define EXYNOS4210_PA_SYSRAM_NS 0x0203F000 +#define EXYNOS4x12_PA_SYSRAM_NS 0x0204F000 +#define EXYNOS5250_PA_SYSRAM_NS 0x0204F000 #define EXYNOS4_PA_FIMC0 0x11800000 #define EXYNOS4_PA_FIMC1 0x11810000 @@ -53,7 +56,6 @@ #define EXYNOS4_PA_ONENAND_DMA 0x0C600000 #define EXYNOS_PA_CHIPID 0x10000000 -#define EXYNOS5440_PA_CHIPID 0x00160000 #define EXYNOS4_PA_SYSCON 0x10010000 #define EXYNOS5_PA_SYSCON 0x10050100 @@ -65,7 +67,6 @@ #define EXYNOS5_PA_CMU 0x10010000 #define EXYNOS4_PA_SYSTIMER 0x10050000 -#define EXYNOS5_PA_SYSTIMER 0x101C0000 #define EXYNOS4_PA_WATCHDOG 0x10060000 #define EXYNOS5_PA_WATCHDOG 0x101D0000 diff --git a/trunk/arch/arm/mach-exynos/include/mach/regs-mct.h b/trunk/arch/arm/mach-exynos/include/mach/regs-mct.h deleted file mode 100644 index 80dd02ad6d61..000000000000 --- a/trunk/arch/arm/mach-exynos/include/mach/regs-mct.h +++ /dev/null @@ -1,53 +0,0 @@ -/* arch/arm/mach-exynos4/include/mach/regs-mct.h - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * EXYNOS4 MCT configutation - * - * 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. -*/ - -#ifndef __ASM_ARCH_REGS_MCT_H -#define __ASM_ARCH_REGS_MCT_H __FILE__ - -#include - -#define EXYNOS4_MCTREG(x) (S5P_VA_SYSTIMER + (x)) - -#define EXYNOS4_MCT_G_CNT_L EXYNOS4_MCTREG(0x100) -#define EXYNOS4_MCT_G_CNT_U EXYNOS4_MCTREG(0x104) -#define EXYNOS4_MCT_G_CNT_WSTAT EXYNOS4_MCTREG(0x110) - -#define EXYNOS4_MCT_G_COMP0_L EXYNOS4_MCTREG(0x200) -#define EXYNOS4_MCT_G_COMP0_U EXYNOS4_MCTREG(0x204) -#define EXYNOS4_MCT_G_COMP0_ADD_INCR EXYNOS4_MCTREG(0x208) - -#define EXYNOS4_MCT_G_TCON EXYNOS4_MCTREG(0x240) - -#define EXYNOS4_MCT_G_INT_CSTAT EXYNOS4_MCTREG(0x244) -#define EXYNOS4_MCT_G_INT_ENB EXYNOS4_MCTREG(0x248) -#define EXYNOS4_MCT_G_WSTAT EXYNOS4_MCTREG(0x24C) - -#define _EXYNOS4_MCT_L_BASE EXYNOS4_MCTREG(0x300) -#define EXYNOS4_MCT_L_BASE(x) (_EXYNOS4_MCT_L_BASE + (0x100 * x)) -#define EXYNOS4_MCT_L_MASK (0xffffff00) - -#define MCT_L_TCNTB_OFFSET (0x00) -#define MCT_L_ICNTB_OFFSET (0x08) -#define MCT_L_TCON_OFFSET (0x20) -#define MCT_L_INT_CSTAT_OFFSET (0x30) -#define MCT_L_INT_ENB_OFFSET (0x34) -#define MCT_L_WSTAT_OFFSET (0x40) - -#define MCT_G_TCON_START (1 << 8) -#define MCT_G_TCON_COMP0_AUTO_INC (1 << 1) -#define MCT_G_TCON_COMP0_ENABLE (1 << 0) - -#define MCT_L_TCON_INTERVAL_MODE (1 << 2) -#define MCT_L_TCON_INT_START (1 << 1) -#define MCT_L_TCON_TIMER_START (1 << 0) - -#endif /* __ASM_ARCH_REGS_MCT_H */ diff --git a/trunk/arch/arm/mach-exynos/include/mach/regs-pmu.h b/trunk/arch/arm/mach-exynos/include/mach/regs-pmu.h index 3f30aa1ae354..57344b7e98ce 100644 --- a/trunk/arch/arm/mach-exynos/include/mach/regs-pmu.h +++ b/trunk/arch/arm/mach-exynos/include/mach/regs-pmu.h @@ -344,6 +344,7 @@ #define EXYNOS5_FSYS_ARM_OPTION S5P_PMUREG(0x2208) #define EXYNOS5_ISP_ARM_OPTION S5P_PMUREG(0x2288) #define EXYNOS5_ARM_COMMON_OPTION S5P_PMUREG(0x2408) +#define EXYNOS5_ARM_L2_OPTION S5P_PMUREG(0x2608) #define EXYNOS5_TOP_PWR_OPTION S5P_PMUREG(0x2C48) #define EXYNOS5_TOP_PWR_SYSMEM_OPTION S5P_PMUREG(0x2CC8) #define EXYNOS5_JPEG_MEM_OPTION S5P_PMUREG(0x2F48) diff --git a/trunk/arch/arm/mach-exynos/mach-armlex4210.c b/trunk/arch/arm/mach-exynos/mach-armlex4210.c index 2126f3503a3f..5f0f55701374 100644 --- a/trunk/arch/arm/mach-exynos/mach-armlex4210.c +++ b/trunk/arch/arm/mach-exynos/mach-armlex4210.c @@ -178,7 +178,6 @@ static void __init armlex4210_smsc911x_init(void) static void __init armlex4210_map_io(void) { exynos_init_io(NULL, 0); - s3c24xx_init_clocks(24000000); s3c24xx_init_uarts(armlex4210_uartcfgs, ARRAY_SIZE(armlex4210_uartcfgs)); } @@ -203,6 +202,6 @@ MACHINE_START(ARMLEX4210, "ARMLEX4210") .map_io = armlex4210_map_io, .init_machine = armlex4210_machine_init, .init_late = exynos_init_late, - .init_time = exynos4_timer_init, + .init_time = exynos_init_time, .restart = exynos4_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-exynos/mach-exynos4-dt.c b/trunk/arch/arm/mach-exynos/mach-exynos4-dt.c index 3358088c822a..b9ed834a7eee 100644 --- a/trunk/arch/arm/mach-exynos/mach-exynos4-dt.c +++ b/trunk/arch/arm/mach-exynos/mach-exynos4-dt.c @@ -11,121 +11,26 @@ * published by the Free Software Foundation. */ +#include #include +#include #include +#include +#include #include -#include - -#include -#include +#include #include "common.h" -/* - * The following lookup table is used to override device names when devices - * are registered from device tree. This is temporarily added to enable - * device tree support addition for the Exynos4 architecture. - * - * For drivers that require platform data to be provided from the machine - * file, a platform data pointer can also be supplied along with the - * devices names. Usually, the platform data elements that cannot be parsed - * from the device tree by the drivers (example: function pointers) are - * supplied. But it should be noted that this is a temporary mechanism and - * at some point, the drivers should be capable of parsing all the platform - * data from the device tree. - */ -static const struct of_dev_auxdata exynos4_auxdata_lookup[] __initconst = { - OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS4_PA_UART0, - "exynos4210-uart.0", NULL), - OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS4_PA_UART1, - "exynos4210-uart.1", NULL), - OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS4_PA_UART2, - "exynos4210-uart.2", NULL), - OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS4_PA_UART3, - "exynos4210-uart.3", NULL), - OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(0), - "exynos4-sdhci.0", NULL), - OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(1), - "exynos4-sdhci.1", NULL), - OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(2), - "exynos4-sdhci.2", NULL), - OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(3), - "exynos4-sdhci.3", NULL), - OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(0), - "s3c2440-i2c.0", NULL), - OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(1), - "s3c2440-i2c.1", NULL), - OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(2), - "s3c2440-i2c.2", NULL), - OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(3), - "s3c2440-i2c.3", NULL), - OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(4), - "s3c2440-i2c.4", NULL), - OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(5), - "s3c2440-i2c.5", NULL), - OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(6), - "s3c2440-i2c.6", NULL), - OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(7), - "s3c2440-i2c.7", NULL), - OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS4_PA_SPI0, - "exynos4210-spi.0", NULL), - OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS4_PA_SPI1, - "exynos4210-spi.1", NULL), - OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS4_PA_SPI2, - "exynos4210-spi.2", NULL), - OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA0, "dma-pl330.0", NULL), - OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA1, "dma-pl330.1", NULL), - OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_MDMA1, "dma-pl330.2", NULL), - OF_DEV_AUXDATA("samsung,exynos4210-tmu", EXYNOS4_PA_TMU, - "exynos-tmu", NULL), - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x13620000, - "exynos-sysmmu.0", NULL), /* MFC_L */ - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x13630000, - "exynos-sysmmu.1", NULL), /* MFC_R */ - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x13E20000, - "exynos-sysmmu.2", NULL), /* TV */ - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x11A60000, - "exynos-sysmmu.3", NULL), /* JPEG */ - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x12A30000, - "exynos-sysmmu.4", NULL), /* ROTATOR */ - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x11A20000, - "exynos-sysmmu.5", NULL), /* FIMC0 */ - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x11A30000, - "exynos-sysmmu.6", NULL), /* FIMC1 */ - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x11A40000, - "exynos-sysmmu.7", NULL), /* FIMC2 */ - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x11A50000, - "exynos-sysmmu.8", NULL), /* FIMC3 */ - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x12A20000, - "exynos-sysmmu.9", NULL), /* G2D(4210) */ - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x10A40000, - "exynos-sysmmu.9", NULL), /* G2D(4x12) */ - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x11E20000, - "exynos-sysmmu.10", NULL), /* FIMD0 */ - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x12220000, - "exynos-sysmmu.11", NULL), /* FIMD1(4210) */ - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x12260000, - "exynos-sysmmu.12", NULL), /* IS0(4x12) */ - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x122B0000, - "exynos-sysmmu.13", NULL), /* IS1(4x12) */ - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x123B0000, - "exynos-sysmmu.14", NULL), /* FIMC-LITE0(4x12) */ - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x123C0000, - "exynos-sysmmu.15", NULL), /* FIMC-LITE1(4x12) */ - {}, -}; - static void __init exynos4_dt_map_io(void) { exynos_init_io(NULL, 0); - s3c24xx_init_clocks(24000000); } static void __init exynos4_dt_machine_init(void) { - of_platform_populate(NULL, of_default_bus_match_table, - exynos4_auxdata_lookup, NULL); + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } static char const *exynos4_dt_compat[] __initdata = { @@ -135,14 +40,28 @@ static char const *exynos4_dt_compat[] __initdata = { NULL }; +static void __init exynos4_reserve(void) +{ +#ifdef CONFIG_S5P_DEV_MFC + struct s5p_mfc_dt_meminfo mfc_mem; + + /* Reserve memory for MFC only if it's available */ + mfc_mem.compatible = "samsung,mfc-v5"; + if (of_scan_flat_dt(s5p_fdt_find_mfc_mem, &mfc_mem)) + s5p_mfc_reserve_mem(mfc_mem.roff, mfc_mem.rsize, mfc_mem.loff, + mfc_mem.lsize); +#endif +} DT_MACHINE_START(EXYNOS4210_DT, "Samsung Exynos4 (Flattened Device Tree)") /* Maintainer: Thomas Abraham */ .smp = smp_ops(exynos_smp_ops), .init_irq = exynos4_init_irq, .map_io = exynos4_dt_map_io, + .init_early = exynos_firmware_init, .init_machine = exynos4_dt_machine_init, .init_late = exynos_init_late, - .init_time = exynos4_timer_init, + .init_time = exynos_init_time, .dt_compat = exynos4_dt_compat, .restart = exynos4_restart, + .reserve = exynos4_reserve, MACHINE_END diff --git a/trunk/arch/arm/mach-exynos/mach-exynos5-dt.c b/trunk/arch/arm/mach-exynos/mach-exynos5-dt.c index acaeb14db54b..753b94f3fca7 100644 --- a/trunk/arch/arm/mach-exynos/mach-exynos5-dt.c +++ b/trunk/arch/arm/mach-exynos/mach-exynos5-dt.c @@ -11,151 +11,21 @@ #include #include -#include #include #include +#include #include -#include #include #include -#include #include #include "common.h" -/* - * The following lookup table is used to override device names when devices - * are registered from device tree. This is temporarily added to enable - * device tree support addition for the EXYNOS5 architecture. - * - * For drivers that require platform data to be provided from the machine - * file, a platform data pointer can also be supplied along with the - * devices names. Usually, the platform data elements that cannot be parsed - * from the device tree by the drivers (example: function pointers) are - * supplied. But it should be noted that this is a temporary mechanism and - * at some point, the drivers should be capable of parsing all the platform - * data from the device tree. - */ -static const struct of_dev_auxdata exynos5250_auxdata_lookup[] __initconst = { - OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART0, - "exynos4210-uart.0", NULL), - OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART1, - "exynos4210-uart.1", NULL), - OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART2, - "exynos4210-uart.2", NULL), - OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART3, - "exynos4210-uart.3", NULL), - OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(0), - "s3c2440-i2c.0", NULL), - OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(1), - "s3c2440-i2c.1", NULL), - OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(2), - "s3c2440-i2c.2", NULL), - OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(3), - "s3c2440-i2c.3", NULL), - OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(4), - "s3c2440-i2c.4", NULL), - OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(5), - "s3c2440-i2c.5", NULL), - OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(6), - "s3c2440-i2c.6", NULL), - OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(7), - "s3c2440-i2c.7", NULL), - OF_DEV_AUXDATA("samsung,s3c2440-hdmiphy-i2c", EXYNOS5_PA_IIC(8), - "s3c2440-hdmiphy-i2c", NULL), - OF_DEV_AUXDATA("samsung,exynos5250-dw-mshc", EXYNOS5_PA_DWMCI0, - "dw_mmc.0", NULL), - OF_DEV_AUXDATA("samsung,exynos5250-dw-mshc", EXYNOS5_PA_DWMCI1, - "dw_mmc.1", NULL), - OF_DEV_AUXDATA("samsung,exynos5250-dw-mshc", EXYNOS5_PA_DWMCI2, - "dw_mmc.2", NULL), - OF_DEV_AUXDATA("samsung,exynos5250-dw-mshc", EXYNOS5_PA_DWMCI3, - "dw_mmc.3", NULL), - OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS5_PA_SPI0, - "exynos4210-spi.0", NULL), - OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS5_PA_SPI1, - "exynos4210-spi.1", NULL), - OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS5_PA_SPI2, - "exynos4210-spi.2", NULL), - OF_DEV_AUXDATA("samsung,exynos5-sata-ahci", 0x122F0000, - "exynos5-sata", NULL), - OF_DEV_AUXDATA("samsung,exynos5-sata-phy", 0x12170000, - "exynos5-sata-phy", NULL), - OF_DEV_AUXDATA("samsung,exynos5-sata-phy-i2c", 0x121D0000, - "exynos5-sata-phy-i2c", NULL), - OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA0, "dma-pl330.0", NULL), - OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA1, "dma-pl330.1", NULL), - OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_MDMA1, "dma-pl330.2", NULL), - OF_DEV_AUXDATA("samsung,exynos5-gsc", EXYNOS5_PA_GSC0, - "exynos-gsc.0", NULL), - OF_DEV_AUXDATA("samsung,exynos5-gsc", EXYNOS5_PA_GSC1, - "exynos-gsc.1", NULL), - OF_DEV_AUXDATA("samsung,exynos5-gsc", EXYNOS5_PA_GSC2, - "exynos-gsc.2", NULL), - OF_DEV_AUXDATA("samsung,exynos5-gsc", EXYNOS5_PA_GSC3, - "exynos-gsc.3", NULL), - OF_DEV_AUXDATA("samsung,exynos5-hdmi", 0x14530000, - "exynos5-hdmi", NULL), - OF_DEV_AUXDATA("samsung,exynos5-mixer", 0x14450000, - "exynos5-mixer", NULL), - OF_DEV_AUXDATA("samsung,mfc-v6", 0x11000000, "s5p-mfc-v6", NULL), - OF_DEV_AUXDATA("samsung,exynos5250-tmu", 0x10060000, - "exynos-tmu", NULL), - OF_DEV_AUXDATA("samsung,i2s-v5", 0x03830000, - "samsung-i2s.0", NULL), - OF_DEV_AUXDATA("samsung,i2s-v5", 0x12D60000, - "samsung-i2s.1", NULL), - OF_DEV_AUXDATA("samsung,i2s-v5", 0x12D70000, - "samsung-i2s.2", NULL), - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x11210000, - "exynos-sysmmu.0", "mfc"), /* MFC_L */ - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x11200000, - "exynos-sysmmu.1", "mfc"), /* MFC_R */ - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x14650000, - "exynos-sysmmu.2", NULL), /* TV */ - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x11F20000, - "exynos-sysmmu.3", "jpeg"), /* JPEG */ - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x11D40000, - "exynos-sysmmu.4", NULL), /* ROTATOR */ - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x13E80000, - "exynos-sysmmu.5", "gscl"), /* GSCL0 */ - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x13E90000, - "exynos-sysmmu.6", "gscl"), /* GSCL1 */ - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x13EA0000, - "exynos-sysmmu.7", "gscl"), /* GSCL2 */ - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x13EB0000, - "exynos-sysmmu.8", "gscl"), /* GSCL3 */ - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x13260000, - "exynos-sysmmu.9", NULL), /* FIMC-IS0 */ - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x132C0000, - "exynos-sysmmu.10", NULL), /* FIMC-IS1 */ - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x14640000, - "exynos-sysmmu.11", NULL), /* FIMD1 */ - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x13C40000, - "exynos-sysmmu.12", NULL), /* FIMC-LITE0 */ - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x13C50000, - "exynos-sysmmu.13", NULL), /* FIMC-LITE1 */ - OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x10A60000, - "exynos-sysmmu.14", NULL), /* G2D */ - {}, -}; - -static const struct of_dev_auxdata exynos5440_auxdata_lookup[] __initconst = { - OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5440_PA_UART0, - "exynos4210-uart.0", NULL), - {}, -}; - static void __init exynos5_dt_map_io(void) { - unsigned long root = of_get_flat_dt_root(); - exynos_init_io(NULL, 0); - - if (of_flat_dt_is_compatible(root, "samsung,exynos5250")) - s3c24xx_init_clocks(24000000); } static void __init exynos5_dt_machine_init(void) @@ -182,12 +52,7 @@ static void __init exynos5_dt_machine_init(void) } } - if (of_machine_is_compatible("samsung,exynos5250")) - of_platform_populate(NULL, of_default_bus_match_table, - exynos5250_auxdata_lookup, NULL); - else if (of_machine_is_compatible("samsung,exynos5440")) - of_platform_populate(NULL, of_default_bus_match_table, - exynos5440_auxdata_lookup, NULL); + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } static char const *exynos5_dt_compat[] __initdata = { @@ -216,7 +81,7 @@ DT_MACHINE_START(EXYNOS5_DT, "SAMSUNG EXYNOS5 (Flattened Device Tree)") .map_io = exynos5_dt_map_io, .init_machine = exynos5_dt_machine_init, .init_late = exynos_init_late, - .init_time = exynos4_timer_init, + .init_time = exynos_init_time, .dt_compat = exynos5_dt_compat, .restart = exynos5_restart, .reserve = exynos5_reserve, diff --git a/trunk/arch/arm/mach-exynos/mach-nuri.c b/trunk/arch/arm/mach-exynos/mach-nuri.c index ab920e34bd0a..5c8b2878dbbd 100644 --- a/trunk/arch/arm/mach-exynos/mach-nuri.c +++ b/trunk/arch/arm/mach-exynos/mach-nuri.c @@ -1252,7 +1252,7 @@ static void __init nuri_camera_init(void) } m5mols_board_info.irq = s5p_register_gpio_interrupt(GPIO_CAM_8M_ISP_INT); - if (!IS_ERR_VALUE(m5mols_board_info.irq)) + if (m5mols_board_info.irq >= 0) s3c_gpio_cfgpin(GPIO_CAM_8M_ISP_INT, S3C_GPIO_SFN(0xF)); else pr_err("%s: Failed to configure 8M_ISP_INT GPIO\n", __func__); @@ -1331,8 +1331,9 @@ static struct platform_device *nuri_devices[] __initdata = { static void __init nuri_map_io(void) { exynos_init_io(NULL, 0); - s3c24xx_init_clocks(clk_xusbxti.rate); s3c24xx_init_uarts(nuri_uartcfgs, ARRAY_SIZE(nuri_uartcfgs)); + xxti_f = 0; + xusbxti_f = 24000000; } static void __init nuri_reserve(void) @@ -1381,7 +1382,7 @@ MACHINE_START(NURI, "NURI") .map_io = nuri_map_io, .init_machine = nuri_machine_init, .init_late = exynos_init_late, - .init_time = exynos4_timer_init, + .init_time = exynos_init_time, .reserve = &nuri_reserve, .restart = exynos4_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-exynos/mach-origen.c b/trunk/arch/arm/mach-exynos/mach-origen.c index ec42024dd13f..27f03ed5d067 100644 --- a/trunk/arch/arm/mach-exynos/mach-origen.c +++ b/trunk/arch/arm/mach-exynos/mach-origen.c @@ -755,8 +755,9 @@ static void s5p_tv_setup(void) static void __init origen_map_io(void) { exynos_init_io(NULL, 0); - s3c24xx_init_clocks(clk_xusbxti.rate); s3c24xx_init_uarts(origen_uartcfgs, ARRAY_SIZE(origen_uartcfgs)); + xxti_f = 0; + xusbxti_f = 24000000; } static void __init origen_power_init(void) @@ -816,7 +817,7 @@ MACHINE_START(ORIGEN, "ORIGEN") .map_io = origen_map_io, .init_machine = origen_machine_init, .init_late = exynos_init_late, - .init_time = exynos4_timer_init, + .init_time = exynos_init_time, .reserve = &origen_reserve, .restart = exynos4_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-exynos/mach-smdk4x12.c b/trunk/arch/arm/mach-exynos/mach-smdk4x12.c index 5df91236dbb4..2c8af9617920 100644 --- a/trunk/arch/arm/mach-exynos/mach-smdk4x12.c +++ b/trunk/arch/arm/mach-exynos/mach-smdk4x12.c @@ -323,7 +323,6 @@ static struct platform_device *smdk4x12_devices[] __initdata = { static void __init smdk4x12_map_io(void) { exynos_init_io(NULL, 0); - s3c24xx_init_clocks(clk_xusbxti.rate); s3c24xx_init_uarts(smdk4x12_uartcfgs, ARRAY_SIZE(smdk4x12_uartcfgs)); } @@ -377,7 +376,7 @@ MACHINE_START(SMDK4212, "SMDK4212") .init_irq = exynos4_init_irq, .map_io = smdk4x12_map_io, .init_machine = smdk4x12_machine_init, - .init_time = exynos4_timer_init, + .init_time = exynos_init_time, .restart = exynos4_restart, .reserve = &smdk4x12_reserve, MACHINE_END @@ -391,7 +390,7 @@ MACHINE_START(SMDK4412, "SMDK4412") .map_io = smdk4x12_map_io, .init_machine = smdk4x12_machine_init, .init_late = exynos_init_late, - .init_time = exynos4_timer_init, + .init_time = exynos_init_time, .restart = exynos4_restart, .reserve = &smdk4x12_reserve, MACHINE_END diff --git a/trunk/arch/arm/mach-exynos/mach-smdkv310.c b/trunk/arch/arm/mach-exynos/mach-smdkv310.c index 9680e1291065..d95b8cf85253 100644 --- a/trunk/arch/arm/mach-exynos/mach-smdkv310.c +++ b/trunk/arch/arm/mach-exynos/mach-smdkv310.c @@ -372,8 +372,9 @@ static void s5p_tv_setup(void) static void __init smdkv310_map_io(void) { exynos_init_io(NULL, 0); - s3c24xx_init_clocks(clk_xusbxti.rate); s3c24xx_init_uarts(smdkv310_uartcfgs, ARRAY_SIZE(smdkv310_uartcfgs)); + xxti_f = 12000000; + xusbxti_f = 24000000; } static void __init smdkv310_reserve(void) @@ -424,7 +425,7 @@ MACHINE_START(SMDKV310, "SMDKV310") .init_irq = exynos4_init_irq, .map_io = smdkv310_map_io, .init_machine = smdkv310_machine_init, - .init_time = exynos4_timer_init, + .init_time = exynos_init_time, .reserve = &smdkv310_reserve, .restart = exynos4_restart, MACHINE_END @@ -437,7 +438,7 @@ MACHINE_START(SMDKC210, "SMDKC210") .map_io = smdkv310_map_io, .init_machine = smdkv310_machine_init, .init_late = exynos_init_late, - .init_time = exynos4_timer_init, + .init_time = exynos_init_time, .reserve = &smdkv310_reserve, .restart = exynos4_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-exynos/mach-universal_c210.c b/trunk/arch/arm/mach-exynos/mach-universal_c210.c index d28c7fbaba2d..327d50d4681d 100644 --- a/trunk/arch/arm/mach-exynos/mach-universal_c210.c +++ b/trunk/arch/arm/mach-exynos/mach-universal_c210.c @@ -41,7 +41,7 @@ #include #include #include -#include +#include #include #include @@ -1093,9 +1093,10 @@ static struct platform_device *universal_devices[] __initdata = { static void __init universal_map_io(void) { exynos_init_io(NULL, 0); - s3c24xx_init_clocks(clk_xusbxti.rate); s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs)); - s5p_set_timer_source(S5P_PWM2, S5P_PWM4); + samsung_set_timer_source(SAMSUNG_PWM2, SAMSUNG_PWM4); + xxti_f = 0; + xusbxti_f = 24000000; } static void s5p_tv_setup(void) @@ -1153,7 +1154,7 @@ MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210") .map_io = universal_map_io, .init_machine = universal_machine_init, .init_late = exynos_init_late, - .init_time = s5p_timer_init, + .init_time = samsung_timer_init, .reserve = &universal_reserve, .restart = exynos4_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-exynos/platsmp.c b/trunk/arch/arm/mach-exynos/platsmp.c index 95e04bd5813f..a0e8ff7758a4 100644 --- a/trunk/arch/arm/mach-exynos/platsmp.c +++ b/trunk/arch/arm/mach-exynos/platsmp.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -137,10 +138,21 @@ static int __cpuinit exynos_boot_secondary(unsigned int cpu, struct task_struct timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { + unsigned long boot_addr; + smp_rmb(); - __raw_writel(virt_to_phys(exynos4_secondary_startup), - cpu_boot_reg(phys_cpu)); + boot_addr = virt_to_phys(exynos4_secondary_startup); + + /* + * Try to set boot address using firmware first + * and fall back to boot register if it fails. + */ + if (call_firmware_op(set_cpu_boot_addr, phys_cpu, boot_addr)) + __raw_writel(boot_addr, cpu_boot_reg(phys_cpu)); + + call_firmware_op(cpu_boot, phys_cpu); + arch_send_wakeup_ipi_mask(cpumask_of(cpu)); if (pen_release == -1) @@ -196,10 +208,20 @@ static void __init exynos_smp_prepare_cpus(unsigned int max_cpus) * system-wide flags register. The boot monitor waits * until it receives a soft interrupt, and then the * secondary CPU branches to this address. + * + * Try using firmware operation first and fall back to + * boot register if it fails. */ - for (i = 1; i < max_cpus; ++i) - __raw_writel(virt_to_phys(exynos4_secondary_startup), - cpu_boot_reg(cpu_logical_map(i))); + for (i = 1; i < max_cpus; ++i) { + unsigned long phys_cpu; + unsigned long boot_addr; + + phys_cpu = cpu_logical_map(i); + boot_addr = virt_to_phys(exynos4_secondary_startup); + + if (call_firmware_op(set_cpu_boot_addr, phys_cpu, boot_addr)) + __raw_writel(boot_addr, cpu_boot_reg(phys_cpu)); + } } struct smp_operations exynos_smp_ops __initdata = { diff --git a/trunk/arch/arm/mach-exynos/pmu.c b/trunk/arch/arm/mach-exynos/pmu.c index daebc1abc966..97d688526258 100644 --- a/trunk/arch/arm/mach-exynos/pmu.c +++ b/trunk/arch/arm/mach-exynos/pmu.c @@ -228,6 +228,7 @@ static struct exynos_pmu_conf exynos5250_pmu_config[] = { { EXYNOS5_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, { EXYNOS5_ARM_COMMON_SYS_PWR_REG, { 0x0, 0x0, 0x2} }, { EXYNOS5_ARM_L2_SYS_PWR_REG, { 0x3, 0x3, 0x3} }, + { EXYNOS5_ARM_L2_OPTION, { 0x10, 0x10, 0x0 } }, { EXYNOS5_CMU_ACLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, { EXYNOS5_CMU_SCLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, { EXYNOS5_CMU_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, @@ -353,11 +354,9 @@ static void exynos5_init_pmu(void) /* * SKIP_DEACTIVATE_ACEACP_IN_PWDN_BITFIELD Enable - * MANUAL_L2RSTDISABLE_CONTROL_BITFIELD Enable */ tmp = __raw_readl(EXYNOS5_ARM_COMMON_OPTION); - tmp |= (EXYNOS5_MANUAL_L2RSTDISABLE_CONTROL | - EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN); + tmp |= EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN; __raw_writel(tmp, EXYNOS5_ARM_COMMON_OPTION); /* diff --git a/trunk/arch/arm/mach-exynos/smc.h b/trunk/arch/arm/mach-exynos/smc.h new file mode 100644 index 000000000000..13a1dc8ecbf2 --- /dev/null +++ b/trunk/arch/arm/mach-exynos/smc.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2012 Samsung Electronics. + * + * EXYNOS - SMC Call + * + * 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. + */ + +#ifndef __ASM_ARCH_EXYNOS_SMC_H +#define __ASM_ARCH_EXYNOS_SMC_H + +#define SMC_CMD_INIT (-1) +#define SMC_CMD_INFO (-2) +/* For Power Management */ +#define SMC_CMD_SLEEP (-3) +#define SMC_CMD_CPU1BOOT (-4) +#define SMC_CMD_CPU0AFTR (-5) +/* For CP15 Access */ +#define SMC_CMD_C15RESUME (-11) +/* For L2 Cache Access */ +#define SMC_CMD_L2X0CTRL (-21) +#define SMC_CMD_L2X0SETUP1 (-22) +#define SMC_CMD_L2X0SETUP2 (-23) +#define SMC_CMD_L2X0INVALL (-24) +#define SMC_CMD_L2X0DEBUG (-25) + +extern void exynos_smc(u32 cmd, u32 arg1, u32 arg2, u32 arg3); + +#endif diff --git a/trunk/arch/arm/mach-highbank/highbank.c b/trunk/arch/arm/mach-highbank/highbank.c index 76c1170b3528..e7df2dd43a40 100644 --- a/trunk/arch/arm/mach-highbank/highbank.c +++ b/trunk/arch/arm/mach-highbank/highbank.c @@ -15,6 +15,7 @@ */ #include #include +#include #include #include #include @@ -28,12 +29,9 @@ #include #include -#include #include #include #include -#include -#include #include #include #include @@ -90,36 +88,16 @@ static void __init highbank_init_irq(void) #endif } -static struct clk_lookup lookup = { - .dev_id = "sp804", - .con_id = NULL, -}; - static void __init highbank_timer_init(void) { - int irq; struct device_node *np; - void __iomem *timer_base; /* Map system registers */ np = of_find_compatible_node(NULL, NULL, "calxeda,hb-sregs"); sregs_base = of_iomap(np, 0); WARN_ON(!sregs_base); - np = of_find_compatible_node(NULL, NULL, "arm,sp804"); - timer_base = of_iomap(np, 0); - WARN_ON(!timer_base); - irq = irq_of_parse_and_map(np, 0); - of_clk_init(NULL); - lookup.clk = of_clk_get(np, 0); - clkdev_add(&lookup); - - sp804_clocksource_and_sched_clock_init(timer_base + 0x20, "timer1"); - sp804_clockevents_init(timer_base, irq, "timer0"); - - arch_timer_of_register(); - arch_timer_sched_clock_init(); clocksource_of_init(); } diff --git a/trunk/arch/arm/mach-highbank/hotplug.c b/trunk/arch/arm/mach-highbank/hotplug.c index 890cae23c12a..a019e4e86e51 100644 --- a/trunk/arch/arm/mach-highbank/hotplug.c +++ b/trunk/arch/arm/mach-highbank/hotplug.c @@ -14,7 +14,6 @@ * this program. If not, see . */ #include - #include #include "core.h" diff --git a/trunk/arch/arm/mach-imx/Kconfig b/trunk/arch/arm/mach-imx/Kconfig index d58ad4ff8d34..ba44328464f3 100644 --- a/trunk/arch/arm/mach-imx/Kconfig +++ b/trunk/arch/arm/mach-imx/Kconfig @@ -5,6 +5,7 @@ config ARCH_MXC select AUTO_ZRELADDR if !ZBOOT_ROM select CLKDEV_LOOKUP select CLKSRC_MMIO + select GENERIC_ALLOCATOR select GENERIC_CLOCKEVENTS select GENERIC_IRQ_CHIP select MULTI_IRQ_HANDLER @@ -61,9 +62,8 @@ config MXC_ULPI config ARCH_HAS_RNGA bool -config IRAM_ALLOC +config HAVE_IMX_ANATOP bool - select GENERIC_ALLOCATOR config HAVE_IMX_GPC bool @@ -73,6 +73,7 @@ config HAVE_IMX_MMDC config HAVE_IMX_SRC def_bool y if SMP + select ARCH_HAS_RESET_CONTROLLER config IMX_HAVE_IOMUX_V1 bool @@ -115,6 +116,8 @@ config SOC_IMX25 config SOC_IMX27 bool + select ARCH_HAS_CPUFREQ + select ARCH_HAS_OPP select COMMON_CLK select CPU_ARM926T select IMX_HAVE_IOMUX_V1 @@ -142,6 +145,7 @@ config SOC_IMX35 config SOC_IMX5 bool select ARCH_HAS_CPUFREQ + select ARCH_HAS_OPP select ARCH_MXC_IOMUX_V3 select COMMON_CLK select CPU_V7 @@ -466,8 +470,6 @@ config MACH_MX31ADS_WM1133_EV1 depends on MACH_MX31ADS depends on MFD_WM8350_I2C depends on REGULATOR_WM8350 = y - select MFD_WM8350_CONFIG_MODE_0 - select MFD_WM8352_CONFIG_MODE_0 help Include support for the Wolfson Microelectronics 1133-EV1 PMU and audio module for the MX31ADS platform. @@ -785,7 +787,7 @@ config SOC_IMX53 This enables support for Freescale i.MX53 processor. config SOC_IMX6Q - bool "i.MX6 Quad support" + bool "i.MX6 Quad/DualLite support" select ARCH_HAS_CPUFREQ select ARCH_HAS_OPP select ARM_CPU_SUSPEND if PM @@ -798,6 +800,7 @@ config SOC_IMX6Q select HAVE_ARM_SCU if SMP select HAVE_ARM_TWD if LOCAL_TIMERS select HAVE_CAN_FLEXCAN if CAN + select HAVE_IMX_ANATOP select HAVE_IMX_GPC select HAVE_IMX_MMDC select HAVE_IMX_SRC diff --git a/trunk/arch/arm/mach-imx/Makefile b/trunk/arch/arm/mach-imx/Makefile index fbe60a145344..70ae7c490ac0 100644 --- a/trunk/arch/arm/mach-imx/Makefile +++ b/trunk/arch/arm/mach-imx/Makefile @@ -23,7 +23,6 @@ obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o obj-$(CONFIG_MXC_TZIC) += tzic.o obj-$(CONFIG_MXC_AVIC) += avic.o -obj-$(CONFIG_IRAM_ALLOC) += iram_alloc.o obj-$(CONFIG_MXC_ULPI) += ulpi.o obj-$(CONFIG_MXC_USE_EPIT) += epit.o obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o @@ -91,6 +90,7 @@ obj-$(CONFIG_MACH_EUKREA_CPUIMX35SD) += mach-cpuimx35.o obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD) += eukrea_mbimxsd35-baseboard.o obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o +obj-$(CONFIG_HAVE_IMX_ANATOP) += anatop.o obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o obj-$(CONFIG_HAVE_IMX_SRC) += src.o diff --git a/trunk/arch/arm/mach-imx/anatop.c b/trunk/arch/arm/mach-imx/anatop.c new file mode 100644 index 000000000000..0cfa07dd9aa4 --- /dev/null +++ b/trunk/arch/arm/mach-imx/anatop.c @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2013 Freescale Semiconductor, Inc. + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include +#include +#include +#include +#include +#include +#include "common.h" + +#define REG_SET 0x4 +#define REG_CLR 0x8 + +#define ANADIG_REG_2P5 0x130 +#define ANADIG_REG_CORE 0x140 +#define ANADIG_ANA_MISC0 0x150 +#define ANADIG_USB1_CHRG_DETECT 0x1b0 +#define ANADIG_USB2_CHRG_DETECT 0x210 +#define ANADIG_DIGPROG 0x260 + +#define BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG 0x40000 +#define BM_ANADIG_REG_CORE_FET_ODRIVE 0x20000000 +#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG 0x1000 +#define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B 0x80000 +#define BM_ANADIG_USB_CHRG_DETECT_EN_B 0x100000 + +static struct regmap *anatop; + +static void imx_anatop_enable_weak2p5(bool enable) +{ + u32 reg, val; + + regmap_read(anatop, ANADIG_ANA_MISC0, &val); + + /* can only be enabled when stop_mode_config is clear. */ + reg = ANADIG_REG_2P5; + reg += (enable && (val & BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG) == 0) ? + REG_SET : REG_CLR; + regmap_write(anatop, reg, BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG); +} + +static void imx_anatop_enable_fet_odrive(bool enable) +{ + regmap_write(anatop, ANADIG_REG_CORE + (enable ? REG_SET : REG_CLR), + BM_ANADIG_REG_CORE_FET_ODRIVE); +} + +void imx_anatop_pre_suspend(void) +{ + imx_anatop_enable_weak2p5(true); + imx_anatop_enable_fet_odrive(true); +} + +void imx_anatop_post_resume(void) +{ + imx_anatop_enable_fet_odrive(false); + imx_anatop_enable_weak2p5(false); +} + +void imx_anatop_usb_chrg_detect_disable(void) +{ + regmap_write(anatop, ANADIG_USB1_CHRG_DETECT, + BM_ANADIG_USB_CHRG_DETECT_EN_B + | BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B); + regmap_write(anatop, ANADIG_USB2_CHRG_DETECT, + BM_ANADIG_USB_CHRG_DETECT_EN_B | + BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B); +} + +u32 imx_anatop_get_digprog(void) +{ + struct device_node *np; + void __iomem *anatop_base; + static u32 digprog; + + if (digprog) + return digprog; + + np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop"); + anatop_base = of_iomap(np, 0); + WARN_ON(!anatop_base); + digprog = readl_relaxed(anatop_base + ANADIG_DIGPROG); + + return digprog; +} + +void __init imx_anatop_init(void) +{ + anatop = syscon_regmap_lookup_by_compatible("fsl,imx6q-anatop"); + if (IS_ERR(anatop)) { + pr_err("%s: failed to find imx6q-anatop regmap!\n", __func__); + return; + } +} diff --git a/trunk/arch/arm/mach-imx/clk-imx51-imx53.c b/trunk/arch/arm/mach-imx/clk-imx51-imx53.c index 2bc623b414c1..6fc486b6a3c6 100644 --- a/trunk/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/trunk/arch/arm/mach-imx/clk-imx51-imx53.c @@ -45,16 +45,40 @@ static const char *mx53_ipu_di1_sel[] = { "di_pred", "osc", "ckih1", "tve_di", " static const char *mx53_ldb_di1_sel[] = { "pll3_sw", "pll4_sw", }; static const char *mx51_tve_ext_sel[] = { "osc", "ckih1", }; static const char *mx53_tve_ext_sel[] = { "pll4_sw", "ckih1", }; -static const char *tve_sel[] = { "tve_pred", "tve_ext_sel", }; +static const char *mx51_tve_sel[] = { "tve_pred", "tve_ext_sel", }; static const char *ipu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", }; +static const char *gpu3d_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb" }; +static const char *gpu2d_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb" }; static const char *vpu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", }; static const char *mx53_can_sel[] = { "ipg", "ckih1", "ckih2", "lp_apm", }; +static const char *mx53_cko1_sel[] = { + "cpu_podf", "pll1_sw", "pll2_sw", "pll3_sw", + "emi_slow_podf", "pll4_sw", "nfc_podf", "dummy", + "di_pred", "dummy", "dummy", "ahb", + "ipg", "per_root", "ckil", "dummy",}; +static const char *mx53_cko2_sel[] = { + "dummy"/* dptc_core */, "dummy"/* dptc_perich */, + "dummy", "esdhc_a_podf", + "usboh3_podf", "dummy"/* wrck_clk_root */, + "ecspi_podf", "dummy"/* pll1_ref_clk */, + "esdhc_b_podf", "dummy"/* ddr_clk_root */, + "dummy"/* arm_axi_clk_root */, "dummy"/* usb_phy_out */, + "vpu_sel", "ipu_sel", + "osc", "ckih1", + "dummy", "esdhc_c_sel", + "ssi1_root_podf", "ssi2_root_podf", + "dummy", "dummy", + "dummy"/* lpsr_clk_root */, "dummy"/* pgc_clk_root */, + "dummy"/* tve_out */, "usb_phy_sel", + "tve_sel", "lp_apm", + "uart_root", "dummy"/* spdif0_clk_root */, + "dummy", "dummy", }; enum imx5_clks { dummy, ckil, osc, ckih1, ckih2, ahb, ipg, axi_a, axi_b, uart_pred, uart_root, esdhc_a_pred, esdhc_b_pred, esdhc_c_s, esdhc_d_s, emi_sel, emi_slow_podf, nfc_podf, ecspi_pred, ecspi_podf, usboh3_pred, - usboh3_podf, usb_phy_pred, usb_phy_podf, cpu_podf, di_pred, tve_di, + usboh3_podf, usb_phy_pred, usb_phy_podf, cpu_podf, di_pred, tve_di_unused, tve_s, uart1_ipg_gate, uart1_per_gate, uart2_ipg_gate, uart2_per_gate, uart3_ipg_gate, uart3_per_gate, i2c1_gate, i2c2_gate, gpt_ipg_gate, pwm1_ipg_gate, pwm1_hf_gate, pwm2_ipg_gate, pwm2_hf_gate, @@ -83,7 +107,10 @@ enum imx5_clks { ssi2_root_gate, ssi3_root_gate, ssi_ext1_gate, ssi_ext2_gate, epit1_ipg_gate, epit1_hf_gate, epit2_ipg_gate, epit2_hf_gate, can_sel, can1_serial_gate, can1_ipg_gate, - owire_gate, + owire_gate, gpu3d_s, gpu2d_s, gpu3d_gate, gpu2d_gate, garb_gate, + cko1_sel, cko1_podf, cko1, + cko2_sel, cko2_podf, cko2, + srtc_gate, pata_gate, clk_max }; @@ -160,8 +187,6 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil, usb_phy_sel_str, ARRAY_SIZE(usb_phy_sel_str)); clk[cpu_podf] = imx_clk_divider("cpu_podf", "pll1_sw", MXC_CCM_CACRR, 0, 3); clk[di_pred] = imx_clk_divider("di_pred", "pll3_sw", MXC_CCM_CDCDR, 6, 3); - clk[tve_di] = imx_clk_fixed("tve_di", 65000000); /* FIXME */ - clk[tve_s] = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1, tve_sel, ARRAY_SIZE(tve_sel)); clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", MXC_CCM_CCGR0, 30); clk[uart1_ipg_gate] = imx_clk_gate2("uart1_ipg_gate", "ipg", MXC_CCM_CCGR1, 6); clk[uart1_per_gate] = imx_clk_gate2("uart1_per_gate", "uart_root", MXC_CCM_CCGR1, 8); @@ -200,6 +225,11 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil, clk[nfc_gate] = imx_clk_gate2("nfc_gate", "nfc_podf", MXC_CCM_CCGR5, 20); clk[ipu_di0_gate] = imx_clk_gate2("ipu_di0_gate", "ipu_di0_sel", MXC_CCM_CCGR6, 10); clk[ipu_di1_gate] = imx_clk_gate2("ipu_di1_gate", "ipu_di1_sel", MXC_CCM_CCGR6, 12); + clk[gpu3d_s] = imx_clk_mux("gpu3d_sel", MXC_CCM_CBCMR, 4, 2, gpu3d_sel, ARRAY_SIZE(gpu3d_sel)); + clk[gpu2d_s] = imx_clk_mux("gpu2d_sel", MXC_CCM_CBCMR, 16, 2, gpu2d_sel, ARRAY_SIZE(gpu2d_sel)); + clk[gpu3d_gate] = imx_clk_gate2("gpu3d_gate", "gpu3d_sel", MXC_CCM_CCGR5, 2); + clk[garb_gate] = imx_clk_gate2("garb_gate", "axi_a", MXC_CCM_CCGR5, 4); + clk[gpu2d_gate] = imx_clk_gate2("gpu2d_gate", "gpu2d_sel", MXC_CCM_CCGR6, 14); clk[vpu_s] = imx_clk_mux("vpu_sel", MXC_CCM_CBCMR, 14, 2, vpu_sel, ARRAY_SIZE(vpu_sel)); clk[vpu_gate] = imx_clk_gate2("vpu_gate", "vpu_sel", MXC_CCM_CCGR5, 6); clk[vpu_reference_gate] = imx_clk_gate2("vpu_reference_gate", "osc", MXC_CCM_CCGR5, 8); @@ -235,6 +265,8 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil, clk[epit2_ipg_gate] = imx_clk_gate2("epit2_ipg_gate", "ipg", MXC_CCM_CCGR2, 6); clk[epit2_hf_gate] = imx_clk_gate2("epit2_hf_gate", "per_root", MXC_CCM_CCGR2, 8); clk[owire_gate] = imx_clk_gate2("owire_gate", "per_root", MXC_CCM_CCGR2, 22); + clk[srtc_gate] = imx_clk_gate2("srtc_gate", "per_root", MXC_CCM_CCGR4, 28); + clk[pata_gate] = imx_clk_gate2("pata_gate", "ipg", MXC_CCM_CCGR4, 0); for (i = 0; i < ARRAY_SIZE(clk); i++) if (IS_ERR(clk[i])) @@ -286,7 +318,6 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil, clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.0"); clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.1"); clk_register_clkdev(clk[dummy], NULL, "imx-keypad"); - clk_register_clkdev(clk[tve_gate], NULL, "imx-tve.0"); clk_register_clkdev(clk[ipu_di1_gate], "di1", "imx-tve.0"); clk_register_clkdev(clk[gpc_dvfs], "gpc_dvfs", NULL); clk_register_clkdev(clk[epit1_ipg_gate], "ipg", "imx-epit.0"); @@ -331,8 +362,10 @@ int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, mx51_ipu_di0_sel, ARRAY_SIZE(mx51_ipu_di0_sel)); clk[ipu_di1_sel] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3, mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel)); - clk[tve_ext_sel] = imx_clk_mux("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, - mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel)); + clk[tve_ext_sel] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, + mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel), CLK_SET_RATE_PARENT); + clk[tve_s] = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1, + mx51_tve_sel, ARRAY_SIZE(mx51_tve_sel)); clk[tve_gate] = imx_clk_gate2("tve_gate", "tve_sel", MXC_CCM_CCGR2, 30); clk[tve_pred] = imx_clk_divider("tve_pred", "pll3_sw", MXC_CCM_CDCDR, 28, 3); clk[esdhc1_per_gate] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2); @@ -420,23 +453,23 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, clk[pll3_sw] = imx_clk_pllv2("pll3_sw", "osc", MX53_DPLL3_BASE); clk[pll4_sw] = imx_clk_pllv2("pll4_sw", "osc", MX53_DPLL4_BASE); - clk[ldb_di1_sel] = imx_clk_mux("ldb_di1_sel", MXC_CCM_CSCMR2, 9, 1, - mx53_ldb_di1_sel, ARRAY_SIZE(mx53_ldb_di1_sel)); clk[ldb_di1_div_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); - clk[ldb_di1_div] = imx_clk_divider("ldb_di1_div", "ldb_di1_div_3_5", MXC_CCM_CSCMR2, 11, 1); + clk[ldb_di1_div] = imx_clk_divider_flags("ldb_di1_div", "ldb_di1_div_3_5", MXC_CCM_CSCMR2, 11, 1, 0); + clk[ldb_di1_sel] = imx_clk_mux_flags("ldb_di1_sel", MXC_CCM_CSCMR2, 9, 1, + mx53_ldb_di1_sel, ARRAY_SIZE(mx53_ldb_di1_sel), CLK_SET_RATE_PARENT); clk[di_pll4_podf] = imx_clk_divider("di_pll4_podf", "pll4_sw", MXC_CCM_CDCDR, 16, 3); - clk[ldb_di0_sel] = imx_clk_mux("ldb_di0_sel", MXC_CCM_CSCMR2, 8, 1, - mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel)); clk[ldb_di0_div_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); - clk[ldb_di0_div] = imx_clk_divider("ldb_di0_div", "ldb_di0_div_3_5", MXC_CCM_CSCMR2, 10, 1); + clk[ldb_di0_div] = imx_clk_divider_flags("ldb_di0_div", "ldb_di0_div_3_5", MXC_CCM_CSCMR2, 10, 1, 0); + clk[ldb_di0_sel] = imx_clk_mux_flags("ldb_di0_sel", MXC_CCM_CSCMR2, 8, 1, + mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel), CLK_SET_RATE_PARENT); clk[ldb_di0_gate] = imx_clk_gate2("ldb_di0_gate", "ldb_di0_div", MXC_CCM_CCGR6, 28); clk[ldb_di1_gate] = imx_clk_gate2("ldb_di1_gate", "ldb_di1_div", MXC_CCM_CCGR6, 30); clk[ipu_di0_sel] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3, mx53_ipu_di0_sel, ARRAY_SIZE(mx53_ipu_di0_sel)); clk[ipu_di1_sel] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3, mx53_ipu_di1_sel, ARRAY_SIZE(mx53_ipu_di1_sel)); - clk[tve_ext_sel] = imx_clk_mux("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, - mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel)); + clk[tve_ext_sel] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, + mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel), CLK_SET_RATE_PARENT); clk[tve_gate] = imx_clk_gate2("tve_gate", "tve_pred", MXC_CCM_CCGR2, 30); clk[tve_pred] = imx_clk_divider("tve_pred", "tve_ext_sel", MXC_CCM_CDCDR, 28, 3); clk[esdhc1_per_gate] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2); @@ -453,6 +486,16 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, clk[can2_ipg_gate] = imx_clk_gate2("can2_ipg_gate", "ipg", MXC_CCM_CCGR4, 6); clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22); + clk[cko1_sel] = imx_clk_mux("cko1_sel", MXC_CCM_CCOSR, 0, 4, + mx53_cko1_sel, ARRAY_SIZE(mx53_cko1_sel)); + clk[cko1_podf] = imx_clk_divider("cko1_podf", "cko1_sel", MXC_CCM_CCOSR, 4, 3); + clk[cko1] = imx_clk_gate2("cko1", "cko1_podf", MXC_CCM_CCOSR, 7); + + clk[cko2_sel] = imx_clk_mux("cko2_sel", MXC_CCM_CCOSR, 16, 5, + mx53_cko2_sel, ARRAY_SIZE(mx53_cko2_sel)); + clk[cko2_podf] = imx_clk_divider("cko2_podf", "cko2_sel", MXC_CCM_CCOSR, 21, 3); + clk[cko2] = imx_clk_gate2("cko2", "cko2_podf", MXC_CCM_CCOSR, 24); + for (i = 0; i < ARRAY_SIZE(clk); i++) if (IS_ERR(clk[i])) pr_err("i.MX53 clk %d: register failed with %ld\n", diff --git a/trunk/arch/arm/mach-imx/clk-imx6q.c b/trunk/arch/arm/mach-imx/clk-imx6q.c index d38e54f5b6d7..151259003086 100644 --- a/trunk/arch/arm/mach-imx/clk-imx6q.c +++ b/trunk/arch/arm/mach-imx/clk-imx6q.c @@ -1,5 +1,5 @@ /* - * Copyright 2011 Freescale Semiconductor, Inc. + * Copyright 2011-2013 Freescale Semiconductor, Inc. * Copyright 2011 Linaro Ltd. * * The code contained herein is licensed under the GNU General Public @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -22,6 +23,12 @@ #include "clk.h" #include "common.h" +#include "hardware.h" + +#define CCR 0x0 +#define BM_CCR_WB_COUNT (0x7 << 16) +#define BM_CCR_RBC_BYPASS_COUNT (0x3f << 21) +#define BM_CCR_RBC_EN (0x1 << 27) #define CCGR0 0x68 #define CCGR1 0x6c @@ -67,6 +74,67 @@ void imx6q_set_chicken_bit(void) writel_relaxed(val, ccm_base + CGPR); } +static void imx6q_enable_rbc(bool enable) +{ + u32 val; + static bool last_rbc_mode; + + if (last_rbc_mode == enable) + return; + /* + * need to mask all interrupts in GPC before + * operating RBC configurations + */ + imx_gpc_mask_all(); + + /* configure RBC enable bit */ + val = readl_relaxed(ccm_base + CCR); + val &= ~BM_CCR_RBC_EN; + val |= enable ? BM_CCR_RBC_EN : 0; + writel_relaxed(val, ccm_base + CCR); + + /* configure RBC count */ + val = readl_relaxed(ccm_base + CCR); + val &= ~BM_CCR_RBC_BYPASS_COUNT; + val |= enable ? BM_CCR_RBC_BYPASS_COUNT : 0; + writel(val, ccm_base + CCR); + + /* + * need to delay at least 2 cycles of CKIL(32K) + * due to hardware design requirement, which is + * ~61us, here we use 65us for safe + */ + udelay(65); + + /* restore GPC interrupt mask settings */ + imx_gpc_restore_all(); + + last_rbc_mode = enable; +} + +static void imx6q_enable_wb(bool enable) +{ + u32 val; + static bool last_wb_mode; + + if (last_wb_mode == enable) + return; + + /* configure well bias enable bit */ + val = readl_relaxed(ccm_base + CLPCR); + val &= ~BM_CLPCR_WB_PER_AT_LPM; + val |= enable ? BM_CLPCR_WB_PER_AT_LPM : 0; + writel_relaxed(val, ccm_base + CLPCR); + + /* configure well bias count */ + val = readl_relaxed(ccm_base + CCR); + val &= ~BM_CCR_WB_COUNT; + val |= enable ? BM_CCR_WB_COUNT : 0; + writel_relaxed(val, ccm_base + CCR); + + last_wb_mode = enable; +} + int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) { u32 val = readl_relaxed(ccm_base + CLPCR); @@ -74,6 +142,8 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) val &= ~BM_CLPCR_LPM; switch (mode) { case WAIT_CLOCKED: + imx6q_enable_wb(false); + imx6q_enable_rbc(false); break; case WAIT_UNCLOCKED: val |= 0x1 << BP_CLPCR_LPM; @@ -92,6 +162,8 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) val |= 0x3 << BP_CLPCR_STBY_COUNT; val |= BM_CLPCR_VSTBY; val |= BM_CLPCR_SBYOS; + imx6q_enable_wb(true); + imx6q_enable_rbc(true); break; default: return -EINVAL; @@ -109,29 +181,29 @@ static const char *periph_clk2_sels[] = { "pll3_usb_otg", "osc", }; static const char *periph_sels[] = { "periph_pre", "periph_clk2", }; static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", }; static const char *axi_sels[] = { "periph", "pll2_pfd2_396m", "pll3_pfd1_540m", }; -static const char *audio_sels[] = { "pll4_audio", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", }; +static const char *audio_sels[] = { "pll4_post_div", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", }; static const char *gpu_axi_sels[] = { "axi", "ahb", }; static const char *gpu2d_core_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", }; static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", }; static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd9_720m", }; static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", }; static const char *ldb_di_sels[] = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_usb_otg", }; -static const char *ipu_di_pre_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", }; +static const char *ipu_di_pre_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", }; static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; static const char *ipu1_di1_sels[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; static const char *ipu2_di0_sels[] = { "ipu2_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; static const char *ipu2_di1_sels[] = { "ipu2_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; static const char *hsi_tx_sels[] = { "pll3_120m", "pll2_pfd2_396m", }; static const char *pcie_axi_sels[] = { "axi", "ahb", }; -static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_audio", }; +static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_post_div", }; static const char *usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", }; static const char *enfc_sels[] = { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", }; static const char *emi_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd2_396m", "pll2_pfd0_352m", }; static const char *vdo_axi_sels[] = { "axi", "ahb", }; static const char *vpu_axi_sels[] = { "axi", "pll2_pfd2_396m", "pll2_pfd0_352m", }; -static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video", +static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div", "dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0", - "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_audio", }; + "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_post_div", }; enum mx6q_clks { dummy, ckil, ckih, osc, pll2_pfd0_352m, pll2_pfd1_594m, pll2_pfd2_396m, @@ -165,7 +237,7 @@ enum mx6q_clks { pll4_audio, pll5_video, pll8_mlb, pll7_usb_host, pll6_enet, ssi1_ipg, ssi2_ipg, ssi3_ipg, rom, usbphy1, usbphy2, ldb_di0_div_3_5, ldb_di1_div_3_5, sata_ref, sata_ref_100m, pcie_ref, pcie_ref_125m, enet_ref, usbphy1_gate, - usbphy2_gate, clk_max + usbphy2_gate, pll4_post_div, pll5_post_div, pll5_video_div, clk_max }; static struct clk *clk[clk_max]; @@ -182,6 +254,21 @@ static struct clk_div_table clk_enet_ref_table[] = { { .val = 3, .div = 4, }, }; +static struct clk_div_table post_div_table[] = { + { .val = 2, .div = 1, }, + { .val = 1, .div = 2, }, + { .val = 0, .div = 4, }, + { } +}; + +static struct clk_div_table video_div_table[] = { + { .val = 0, .div = 1, }, + { .val = 1, .div = 2, }, + { .val = 2, .div = 1, }, + { .val = 3, .div = 4, }, + { } +}; + int __init mx6q_clocks_init(void) { struct device_node *np; @@ -208,6 +295,14 @@ int __init mx6q_clocks_init(void) base = of_iomap(np, 0); WARN_ON(!base); + /* Audio/video PLL post dividers do not work on i.MX6q revision 1.0 */ + if (cpu_is_imx6q() && imx6q_revision() == IMX_CHIP_REVISION_1_0) { + post_div_table[1].div = 1; + post_div_table[2].div = 1; + video_div_table[1].div = 1; + video_div_table[2].div = 1; + }; + /* type name parent_name base div_mask */ clk[pll1_sys] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f); clk[pll2_bus] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1); @@ -260,6 +355,10 @@ int __init mx6q_clocks_init(void) clk[pll3_60m] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8); clk[twd] = imx_clk_fixed_factor("twd", "arm", 1, 2); + clk[pll4_post_div] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio", CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock); + clk[pll5_post_div] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video", CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock); + clk[pll5_video_div] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock); + np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ccm"); base = of_iomap(np, 0); WARN_ON(!base); @@ -283,8 +382,8 @@ int __init mx6q_clocks_init(void) clk[gpu3d_shader_sel] = imx_clk_mux("gpu3d_shader_sel", base + 0x18, 8, 2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels)); clk[ipu1_sel] = imx_clk_mux("ipu1_sel", base + 0x3c, 9, 2, ipu_sels, ARRAY_SIZE(ipu_sels)); clk[ipu2_sel] = imx_clk_mux("ipu2_sel", base + 0x3c, 14, 2, ipu_sels, ARRAY_SIZE(ipu_sels)); - clk[ldb_di0_sel] = imx_clk_mux("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels)); - clk[ldb_di1_sel] = imx_clk_mux("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels)); + clk[ldb_di0_sel] = imx_clk_mux_flags("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT); + clk[ldb_di1_sel] = imx_clk_mux_flags("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT); clk[ipu1_di0_pre_sel] = imx_clk_mux("ipu1_di0_pre_sel", base + 0x34, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels)); clk[ipu1_di1_pre_sel] = imx_clk_mux("ipu1_di1_pre_sel", base + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels)); clk[ipu2_di0_pre_sel] = imx_clk_mux("ipu2_di0_pre_sel", base + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels)); @@ -332,9 +431,9 @@ int __init mx6q_clocks_init(void) clk[ipu1_podf] = imx_clk_divider("ipu1_podf", "ipu1_sel", base + 0x3c, 11, 3); clk[ipu2_podf] = imx_clk_divider("ipu2_podf", "ipu2_sel", base + 0x3c, 16, 3); clk[ldb_di0_div_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); - clk[ldb_di0_podf] = imx_clk_divider("ldb_di0_podf", "ldb_di0_div_3_5", base + 0x20, 10, 1); + clk[ldb_di0_podf] = imx_clk_divider_flags("ldb_di0_podf", "ldb_di0_div_3_5", base + 0x20, 10, 1, 0); clk[ldb_di1_div_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); - clk[ldb_di1_podf] = imx_clk_divider("ldb_di1_podf", "ldb_di1_div_3_5", base + 0x20, 11, 1); + clk[ldb_di1_podf] = imx_clk_divider_flags("ldb_di1_podf", "ldb_di1_div_3_5", base + 0x20, 11, 1, 0); clk[ipu1_di0_pre] = imx_clk_divider("ipu1_di0_pre", "ipu1_di0_pre_sel", base + 0x34, 3, 3); clk[ipu1_di1_pre] = imx_clk_divider("ipu1_di1_pre", "ipu1_di1_pre_sel", base + 0x34, 12, 3); clk[ipu2_di0_pre] = imx_clk_divider("ipu2_di0_pre", "ipu2_di0_pre_sel", base + 0x38, 3, 3); @@ -448,6 +547,11 @@ int __init mx6q_clocks_init(void) clk_register_clkdev(clk[cko1], "cko1", NULL); clk_register_clkdev(clk[arm], NULL, "cpu0"); + if (imx6q_revision() != IMX_CHIP_REVISION_1_0) { + clk_set_parent(clk[ldb_di0_sel], clk[pll5_video_div]); + clk_set_parent(clk[ldb_di1_sel], clk[pll5_video_div]); + } + /* * The gpmi needs 100MHz frequency in the EDO/Sync mode, * We can not get the 100MHz from the pll2_pfd0_352m. diff --git a/trunk/arch/arm/mach-imx/clk.h b/trunk/arch/arm/mach-imx/clk.h index 9d1f3b99d1d3..d9d9d9c66dff 100644 --- a/trunk/arch/arm/mach-imx/clk.h +++ b/trunk/arch/arm/mach-imx/clk.h @@ -59,6 +59,14 @@ static inline struct clk *imx_clk_divider(const char *name, const char *parent, reg, shift, width, 0, &imx_ccm_lock); } +static inline struct clk *imx_clk_divider_flags(const char *name, + const char *parent, void __iomem *reg, u8 shift, u8 width, + unsigned long flags) +{ + return clk_register_divider(NULL, name, parent, flags, + reg, shift, width, 0, &imx_ccm_lock); +} + static inline struct clk *imx_clk_gate(const char *name, const char *parent, void __iomem *reg, u8 shift) { @@ -73,6 +81,15 @@ static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg, width, 0, &imx_ccm_lock); } +static inline struct clk *imx_clk_mux_flags(const char *name, + void __iomem *reg, u8 shift, u8 width, const char **parents, + int num_parents, unsigned long flags) +{ + return clk_register_mux(NULL, name, parents, num_parents, + flags, reg, shift, width, 0, + &imx_ccm_lock); +} + static inline struct clk *imx_clk_fixed_factor(const char *name, const char *parent, unsigned int mult, unsigned int div) { diff --git a/trunk/arch/arm/mach-imx/common.h b/trunk/arch/arm/mach-imx/common.h index 9fea2522d7a3..c08ae3f99cee 100644 --- a/trunk/arch/arm/mach-imx/common.h +++ b/trunk/arch/arm/mach-imx/common.h @@ -1,5 +1,5 @@ /* - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved. */ /* @@ -12,6 +12,7 @@ #define __ASM_ARCH_MXC_COMMON_H__ struct platform_device; +struct pt_regs; struct clk; enum mxc_cpu_pwr_mode; @@ -74,6 +75,7 @@ extern void mxc_set_cpu_type(unsigned int type); extern void mxc_restart(char, const char *); extern void mxc_arch_reset_init(void __iomem *); extern int mx53_revision(void); +extern int imx6q_revision(void); extern int mx53_display_revision(void); extern void imx_set_aips(void __iomem *); extern int mxc_device_init(void); @@ -128,6 +130,13 @@ extern void imx_src_prepare_restart(void); extern void imx_gpc_init(void); extern void imx_gpc_pre_suspend(void); extern void imx_gpc_post_resume(void); +extern void imx_gpc_mask_all(void); +extern void imx_gpc_restore_all(void); +extern void imx_anatop_init(void); +extern void imx_anatop_pre_suspend(void); +extern void imx_anatop_post_resume(void); +extern void imx_anatop_usb_chrg_detect_disable(void); +extern u32 imx_anatop_get_digprog(void); extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); extern void imx6q_set_chicken_bit(void); diff --git a/trunk/arch/arm/mach-imx/devices/devices.c b/trunk/arch/arm/mach-imx/devices/devices.c index 1b37482407f9..1b4366a0e7c0 100644 --- a/trunk/arch/arm/mach-imx/devices/devices.c +++ b/trunk/arch/arm/mach-imx/devices/devices.c @@ -37,7 +37,7 @@ int __init mxc_device_init(void) int ret; ret = device_register(&mxc_aips_bus); - if (IS_ERR_VALUE(ret)) + if (ret < 0) goto done; ret = device_register(&mxc_ahb_bus); diff --git a/trunk/arch/arm/mach-imx/gpc.c b/trunk/arch/arm/mach-imx/gpc.c index 02b61cdf39b9..44a65e9ff1fc 100644 --- a/trunk/arch/arm/mach-imx/gpc.c +++ b/trunk/arch/arm/mach-imx/gpc.c @@ -1,5 +1,5 @@ /* - * Copyright 2011 Freescale Semiconductor, Inc. + * Copyright 2011-2013 Freescale Semiconductor, Inc. * Copyright 2011 Linaro Ltd. * * The code contained herein is licensed under the GNU General Public @@ -69,6 +69,27 @@ static int imx_gpc_irq_set_wake(struct irq_data *d, unsigned int on) return 0; } +void imx_gpc_mask_all(void) +{ + void __iomem *reg_imr1 = gpc_base + GPC_IMR1; + int i; + + for (i = 0; i < IMR_NUM; i++) { + gpc_saved_imrs[i] = readl_relaxed(reg_imr1 + i * 4); + writel_relaxed(~0, reg_imr1 + i * 4); + } + +} + +void imx_gpc_restore_all(void) +{ + void __iomem *reg_imr1 = gpc_base + GPC_IMR1; + int i; + + for (i = 0; i < IMR_NUM; i++) + writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4); +} + static void imx_gpc_irq_unmask(struct irq_data *d) { void __iomem *reg; diff --git a/trunk/arch/arm/mach-imx/headsmp.S b/trunk/arch/arm/mach-imx/headsmp.S index a58c8b0527cc..67b9c48dcafe 100644 --- a/trunk/arch/arm/mach-imx/headsmp.S +++ b/trunk/arch/arm/mach-imx/headsmp.S @@ -24,7 +24,7 @@ ENTRY(v7_secondary_startup) ENDPROC(v7_secondary_startup) #endif -#ifdef CONFIG_PM +#ifdef CONFIG_ARM_CPU_SUSPEND /* * The following code must assume it is running from physical address * where absolute virtual addresses to the data section have to be diff --git a/trunk/arch/arm/mach-imx/hotplug.c b/trunk/arch/arm/mach-imx/hotplug.c index 361a253e2b63..3daf1ed90579 100644 --- a/trunk/arch/arm/mach-imx/hotplug.c +++ b/trunk/arch/arm/mach-imx/hotplug.c @@ -11,8 +11,9 @@ */ #include -#include +#include #include +#include #include "common.h" @@ -20,7 +21,6 @@ static inline void cpu_enter_lowpower(void) { unsigned int v; - flush_cache_all(); asm volatile( "mcr p15, 0, %1, c7, c5, 0\n" " mcr p15, 0, %1, c7, c10, 4\n" diff --git a/trunk/arch/arm/mach-imx/iram_alloc.c b/trunk/arch/arm/mach-imx/iram_alloc.c deleted file mode 100644 index e05cf407db65..000000000000 --- a/trunk/arch/arm/mach-imx/iram_alloc.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * 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., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include "linux/platform_data/imx-iram.h" - -static unsigned long iram_phys_base; -static void __iomem *iram_virt_base; -static struct gen_pool *iram_pool; - -static inline void __iomem *iram_phys_to_virt(unsigned long p) -{ - return iram_virt_base + (p - iram_phys_base); -} - -void __iomem *iram_alloc(unsigned int size, unsigned long *dma_addr) -{ - if (!iram_pool) - return NULL; - - *dma_addr = gen_pool_alloc(iram_pool, size); - pr_debug("iram alloc - %dB@0x%lX\n", size, *dma_addr); - if (!*dma_addr) - return NULL; - return iram_phys_to_virt(*dma_addr); -} -EXPORT_SYMBOL(iram_alloc); - -void iram_free(unsigned long addr, unsigned int size) -{ - if (!iram_pool) - return; - - gen_pool_free(iram_pool, addr, size); -} -EXPORT_SYMBOL(iram_free); - -int __init iram_init(unsigned long base, unsigned long size) -{ - iram_phys_base = base; - - iram_pool = gen_pool_create(PAGE_SHIFT, -1); - if (!iram_pool) - return -ENOMEM; - - gen_pool_add(iram_pool, base, size, -1); - iram_virt_base = ioremap(iram_phys_base, size); - if (!iram_virt_base) - return -EIO; - - pr_debug("i.MX IRAM pool: %ld KB@0x%p\n", size / 1024, iram_virt_base); - return 0; -} diff --git a/trunk/arch/arm/mach-imx/mach-imx6q.c b/trunk/arch/arm/mach-imx/mach-imx6q.c index 99502eeefdf7..5536fd81379a 100644 --- a/trunk/arch/arm/mach-imx/mach-imx6q.c +++ b/trunk/arch/arm/mach-imx/mach-imx6q.c @@ -1,5 +1,5 @@ /* - * Copyright 2011 Freescale Semiconductor, Inc. + * Copyright 2011-2013 Freescale Semiconductor, Inc. * Copyright 2011 Linaro Ltd. * * The code contained herein is licensed under the GNU General Public @@ -38,38 +38,32 @@ #include "cpuidle.h" #include "hardware.h" -#define IMX6Q_ANALOG_DIGPROG 0x260 +static u32 chip_revision; -static int imx6q_revision(void) +int imx6q_revision(void) { - struct device_node *np; - void __iomem *base; - static u32 rev; - - if (!rev) { - np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop"); - if (!np) - return IMX_CHIP_REVISION_UNKNOWN; - base = of_iomap(np, 0); - if (!base) { - of_node_put(np); - return IMX_CHIP_REVISION_UNKNOWN; - } - rev = readl_relaxed(base + IMX6Q_ANALOG_DIGPROG); - iounmap(base); - of_node_put(np); - } + return chip_revision; +} + +static void __init imx6q_init_revision(void) +{ + u32 rev = imx_anatop_get_digprog(); switch (rev & 0xff) { case 0: - return IMX_CHIP_REVISION_1_0; + chip_revision = IMX_CHIP_REVISION_1_0; + break; case 1: - return IMX_CHIP_REVISION_1_1; + chip_revision = IMX_CHIP_REVISION_1_1; + break; case 2: - return IMX_CHIP_REVISION_1_2; + chip_revision = IMX_CHIP_REVISION_1_2; + break; default: - return IMX_CHIP_REVISION_UNKNOWN; + chip_revision = IMX_CHIP_REVISION_UNKNOWN; } + + mxc_set_cpu_type(rev >> 16 & 0xff); } static void imx6q_restart(char mode, const char *cmd) @@ -164,29 +158,7 @@ static void __init imx6q_1588_init(void) } static void __init imx6q_usb_init(void) { - struct regmap *anatop; - -#define HW_ANADIG_USB1_CHRG_DETECT 0x000001b0 -#define HW_ANADIG_USB2_CHRG_DETECT 0x00000210 - -#define BM_ANADIG_USB_CHRG_DETECT_EN_B 0x00100000 -#define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B 0x00080000 - - anatop = syscon_regmap_lookup_by_compatible("fsl,imx6q-anatop"); - if (!IS_ERR(anatop)) { - /* - * The external charger detector needs to be disabled, - * or the signal at DP will be poor - */ - regmap_write(anatop, HW_ANADIG_USB1_CHRG_DETECT, - BM_ANADIG_USB_CHRG_DETECT_EN_B - | BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B); - regmap_write(anatop, HW_ANADIG_USB2_CHRG_DETECT, - BM_ANADIG_USB_CHRG_DETECT_EN_B | - BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B); - } else { - pr_warn("failed to find fsl,imx6q-anatop regmap\n"); - } + imx_anatop_usb_chrg_detect_disable(); } static void __init imx6q_init_machine(void) @@ -196,6 +168,7 @@ static void __init imx6q_init_machine(void) of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + imx_anatop_init(); imx6q_pm_init(); imx6q_usb_init(); imx6q_1588_init(); @@ -282,6 +255,7 @@ static void __init imx6q_map_io(void) static void __init imx6q_init_irq(void) { + imx6q_init_revision(); l2x0_of_init(0, ~0UL); imx_src_init(); imx_gpc_init(); @@ -292,15 +266,17 @@ static void __init imx6q_timer_init(void) { mx6q_clocks_init(); clocksource_of_init(); - imx_print_silicon_rev("i.MX6Q", imx6q_revision()); + imx_print_silicon_rev(cpu_is_imx6dl() ? "i.MX6DL" : "i.MX6Q", + imx6q_revision()); } static const char *imx6q_dt_compat[] __initdata = { + "fsl,imx6dl", "fsl,imx6q", NULL, }; -DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad (Device Tree)") +DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad/DualLite (Device Tree)") .smp = smp_ops(imx_smp_ops), .map_io = imx6q_map_io, .init_irq = imx6q_init_irq, diff --git a/trunk/arch/arm/mach-imx/mm-imx1.c b/trunk/arch/arm/mach-imx/mm-imx1.c index 7a146671e65a..3c609c52d3eb 100644 --- a/trunk/arch/arm/mach-imx/mm-imx1.c +++ b/trunk/arch/arm/mach-imx/mm-imx1.c @@ -51,6 +51,8 @@ void __init mx1_init_irq(void) void __init imx1_soc_init(void) { + mxc_device_init(); + mxc_register_gpio("imx1-gpio", 0, MX1_GPIO1_BASE_ADDR, SZ_256, MX1_GPIO_INT_PORTA, 0); mxc_register_gpio("imx1-gpio", 1, MX1_GPIO2_BASE_ADDR, SZ_256, diff --git a/trunk/arch/arm/mach-imx/mxc.h b/trunk/arch/arm/mach-imx/mxc.h index 7dce17a9fe6c..8629e5be7ecd 100644 --- a/trunk/arch/arm/mach-imx/mxc.h +++ b/trunk/arch/arm/mach-imx/mxc.h @@ -34,6 +34,8 @@ #define MXC_CPU_MX35 35 #define MXC_CPU_MX51 51 #define MXC_CPU_MX53 53 +#define MXC_CPU_IMX6DL 0x61 +#define MXC_CPU_IMX6Q 0x63 #define IMX_CHIP_REVISION_1_0 0x10 #define IMX_CHIP_REVISION_1_1 0x11 @@ -150,6 +152,15 @@ extern unsigned int __mxc_cpu_type; #endif #ifndef __ASSEMBLY__ +static inline bool cpu_is_imx6dl(void) +{ + return __mxc_cpu_type == MXC_CPU_IMX6DL; +} + +static inline bool cpu_is_imx6q(void) +{ + return __mxc_cpu_type == MXC_CPU_IMX6Q; +} struct cpu_op { u32 cpu_rate; diff --git a/trunk/arch/arm/mach-imx/platsmp.c b/trunk/arch/arm/mach-imx/platsmp.c index 77e9a25ed0f6..4a69305db65e 100644 --- a/trunk/arch/arm/mach-imx/platsmp.c +++ b/trunk/arch/arm/mach-imx/platsmp.c @@ -68,8 +68,8 @@ static void __init imx_smp_init_cpus(void) ncores = scu_get_core_count(scu_base); - for (i = 0; i < ncores; i++) - set_cpu_possible(i, true); + for (i = ncores; i < NR_CPUS; i++) + set_cpu_possible(i, false); } void imx_smp_prepare(void) diff --git a/trunk/arch/arm/mach-imx/pm-imx6q.c b/trunk/arch/arm/mach-imx/pm-imx6q.c index 5faba7a3c95f..204942749e21 100644 --- a/trunk/arch/arm/mach-imx/pm-imx6q.c +++ b/trunk/arch/arm/mach-imx/pm-imx6q.c @@ -1,5 +1,5 @@ /* - * Copyright 2011 Freescale Semiconductor, Inc. + * Copyright 2011-2013 Freescale Semiconductor, Inc. * Copyright 2011 Linaro Ltd. * * The code contained herein is licensed under the GNU General Public @@ -34,10 +34,12 @@ static int imx6q_pm_enter(suspend_state_t state) case PM_SUSPEND_MEM: imx6q_set_lpm(STOP_POWER_OFF); imx_gpc_pre_suspend(); + imx_anatop_pre_suspend(); imx_set_cpu_jump(0, v7_cpu_resume); /* Zzz ... */ cpu_suspend(0, imx6q_suspend_finish); imx_smp_prepare(); + imx_anatop_post_resume(); imx_gpc_post_resume(); imx6q_set_lpm(WAIT_CLOCKED); break; diff --git a/trunk/arch/arm/mach-imx/src.c b/trunk/arch/arm/mach-imx/src.c index 97d086889481..10a6b1a8c5ac 100644 --- a/trunk/arch/arm/mach-imx/src.c +++ b/trunk/arch/arm/mach-imx/src.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include "common.h" @@ -21,10 +22,65 @@ #define SRC_SCR 0x000 #define SRC_GPR1 0x020 #define BP_SRC_SCR_WARM_RESET_ENABLE 0 +#define BP_SRC_SCR_SW_GPU_RST 1 +#define BP_SRC_SCR_SW_VPU_RST 2 +#define BP_SRC_SCR_SW_IPU1_RST 3 +#define BP_SRC_SCR_SW_OPEN_VG_RST 4 +#define BP_SRC_SCR_SW_IPU2_RST 12 #define BP_SRC_SCR_CORE1_RST 14 #define BP_SRC_SCR_CORE1_ENABLE 22 static void __iomem *src_base; +static DEFINE_SPINLOCK(scr_lock); + +static const int sw_reset_bits[5] = { + BP_SRC_SCR_SW_GPU_RST, + BP_SRC_SCR_SW_VPU_RST, + BP_SRC_SCR_SW_IPU1_RST, + BP_SRC_SCR_SW_OPEN_VG_RST, + BP_SRC_SCR_SW_IPU2_RST +}; + +static int imx_src_reset_module(struct reset_controller_dev *rcdev, + unsigned long sw_reset_idx) +{ + unsigned long timeout; + unsigned long flags; + int bit; + u32 val; + + if (!src_base) + return -ENODEV; + + if (sw_reset_idx >= ARRAY_SIZE(sw_reset_bits)) + return -EINVAL; + + bit = 1 << sw_reset_bits[sw_reset_idx]; + + spin_lock_irqsave(&scr_lock, flags); + val = readl_relaxed(src_base + SRC_SCR); + val |= bit; + writel_relaxed(val, src_base + SRC_SCR); + spin_unlock_irqrestore(&scr_lock, flags); + + timeout = jiffies + msecs_to_jiffies(1000); + while (readl(src_base + SRC_SCR) & bit) { + if (time_after(jiffies, timeout)) + return -ETIME; + cpu_relax(); + } + + return 0; +} + +static struct reset_control_ops imx_src_ops = { + .reset = imx_src_reset_module, +}; + +static struct reset_controller_dev imx_reset_controller = { + .ops = &imx_src_ops, + .nr_resets = ARRAY_SIZE(sw_reset_bits), +}; void imx_enable_cpu(int cpu, bool enable) { @@ -32,9 +88,11 @@ void imx_enable_cpu(int cpu, bool enable) cpu = cpu_logical_map(cpu); mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1); + spin_lock(&scr_lock); val = readl_relaxed(src_base + SRC_SCR); val = enable ? val | mask : val & ~mask; writel_relaxed(val, src_base + SRC_SCR); + spin_unlock(&scr_lock); } void imx_set_cpu_jump(int cpu, void *jump_addr) @@ -61,9 +119,11 @@ void imx_src_prepare_restart(void) u32 val; /* clear enable bits of secondary cores */ + spin_lock(&scr_lock); val = readl_relaxed(src_base + SRC_SCR); val &= ~(0x7 << BP_SRC_SCR_CORE1_ENABLE); writel_relaxed(val, src_base + SRC_SCR); + spin_unlock(&scr_lock); /* clear persistent entry register of primary core */ writel_relaxed(0, src_base + SRC_GPR1); @@ -80,11 +140,17 @@ void __init imx_src_init(void) src_base = of_iomap(np, 0); WARN_ON(!src_base); + imx_reset_controller.of_node = np; + if (IS_ENABLED(CONFIG_RESET_CONTROLLER)) + reset_controller_register(&imx_reset_controller); + /* * force warm reset sources to generate cold reset * for a more reliable restart */ + spin_lock(&scr_lock); val = readl_relaxed(src_base + SRC_SCR); val &= ~(1 << BP_SRC_SCR_WARM_RESET_ENABLE); writel_relaxed(val, src_base + SRC_SCR); + spin_unlock(&scr_lock); } diff --git a/trunk/arch/arm/mach-integrator/integrator_ap.c b/trunk/arch/arm/mach-integrator/integrator_ap.c index ea961445e0e9..b23c8e4f28e8 100644 --- a/trunk/arch/arm/mach-integrator/integrator_ap.c +++ b/trunk/arch/arm/mach-integrator/integrator_ap.c @@ -536,16 +536,14 @@ static void __init ap_init_of(void) 'A' + (ap_sc_id & 0x0f)); soc_dev = soc_device_register(soc_dev_attr); - if (IS_ERR_OR_NULL(soc_dev)) { + if (IS_ERR(soc_dev)) { kfree(soc_dev_attr->revision); kfree(soc_dev_attr); return; } parent = soc_device_to_device(soc_dev); - - if (!IS_ERR_OR_NULL(parent)) - integrator_init_sysfs(parent, ap_sc_id); + integrator_init_sysfs(parent, ap_sc_id); of_platform_populate(root, of_default_bus_match_table, ap_auxdata_lookup, parent); diff --git a/trunk/arch/arm/mach-integrator/integrator_cp.c b/trunk/arch/arm/mach-integrator/integrator_cp.c index 2b0db82a5381..8c60fcb08a98 100644 --- a/trunk/arch/arm/mach-integrator/integrator_cp.c +++ b/trunk/arch/arm/mach-integrator/integrator_cp.c @@ -250,39 +250,6 @@ static void __init intcp_init_early(void) } #ifdef CONFIG_OF - -static void __init cp_of_timer_init(void) -{ - struct device_node *node; - const char *path; - void __iomem *base; - int err; - int irq; - - err = of_property_read_string(of_aliases, - "arm,timer-primary", &path); - if (WARN_ON(err)) - return; - node = of_find_node_by_path(path); - base = of_iomap(node, 0); - if (WARN_ON(!base)) - return; - writel(0, base + TIMER_CTRL); - sp804_clocksource_init(base, node->name); - - err = of_property_read_string(of_aliases, - "arm,timer-secondary", &path); - if (WARN_ON(err)) - return; - node = of_find_node_by_path(path); - base = of_iomap(node, 0); - if (WARN_ON(!base)) - return; - irq = irq_of_parse_and_map(node, 0); - writel(0, base + TIMER_CTRL); - sp804_clockevents_init(base, irq, node->name); -} - static const struct of_device_id fpga_irq_of_match[] __initconst = { { .compatible = "arm,versatile-fpga-irq", .data = fpga_irq_of_init, }, { /* Sentinel */ } @@ -360,17 +327,14 @@ static void __init intcp_init_of(void) 'A' + (intcp_sc_id & 0x0f)); soc_dev = soc_device_register(soc_dev_attr); - if (IS_ERR_OR_NULL(soc_dev)) { + if (IS_ERR(soc_dev)) { kfree(soc_dev_attr->revision); kfree(soc_dev_attr); return; } parent = soc_device_to_device(soc_dev); - - if (!IS_ERR_OR_NULL(parent)) - integrator_init_sysfs(parent, intcp_sc_id); - + integrator_init_sysfs(parent, intcp_sc_id); of_platform_populate(root, of_default_bus_match_table, intcp_auxdata_lookup, parent); } @@ -386,7 +350,6 @@ DT_MACHINE_START(INTEGRATOR_CP_DT, "ARM Integrator/CP (Device Tree)") .init_early = intcp_init_early, .init_irq = intcp_init_irq_of, .handle_irq = fpga_handle_irq, - .init_time = cp_of_timer_init, .init_machine = intcp_init_of, .restart = integrator_restart, .dt_compat = intcp_dt_board_compat, diff --git a/trunk/arch/arm/mach-kirkwood/Kconfig b/trunk/arch/arm/mach-kirkwood/Kconfig index 7b6a64bc5f40..7509a89af967 100644 --- a/trunk/arch/arm/mach-kirkwood/Kconfig +++ b/trunk/arch/arm/mach-kirkwood/Kconfig @@ -2,23 +2,41 @@ if ARCH_KIRKWOOD menu "Marvell Kirkwood Implementations" +config MACH_D2NET_V2 + bool "LaCie d2 Network v2 NAS Board" + help + Say 'Y' here if you want your kernel to support the + LaCie d2 Network v2 NAS. + config MACH_DB88F6281_BP bool "Marvell DB-88F6281-BP Development Board" help Say 'Y' here if you want your kernel to support the Marvell DB-88F6281-BP Development Board. -config MACH_RD88F6192_NAS - bool "Marvell RD-88F6192-NAS Reference Board" +config MACH_DOCKSTAR + bool "Seagate FreeAgent DockStar" help Say 'Y' here if you want your kernel to support the - Marvell RD-88F6192-NAS Reference Board. + Seagate FreeAgent DockStar. -config MACH_RD88F6281 - bool "Marvell RD-88F6281 Reference Board" +config MACH_ESATA_SHEEVAPLUG + bool "Marvell eSATA SheevaPlug Reference Board" help Say 'Y' here if you want your kernel to support the - Marvell RD-88F6281 Reference Board. + Marvell eSATA SheevaPlug Reference Board. + +config MACH_GURUPLUG + bool "Marvell GuruPlug Reference Board" + help + Say 'Y' here if you want your kernel to support the + Marvell GuruPlug Reference Board. + +config MACH_INETSPACE_V2 + bool "LaCie Internet Space v2 NAS Board" + help + Say 'Y' here if you want your kernel to support the + LaCie Internet Space v2 NAS. config MACH_MV88F6281GTW_GE bool "Marvell 88F6281 GTW GE Board" @@ -26,23 +44,93 @@ config MACH_MV88F6281GTW_GE Say 'Y' here if you want your kernel to support the Marvell 88F6281 GTW GE Board. +config MACH_NET2BIG_V2 + bool "LaCie 2Big Network v2 NAS Board" + help + Say 'Y' here if you want your kernel to support the + LaCie 2Big Network v2 NAS. + +config MACH_NET5BIG_V2 + bool "LaCie 5Big Network v2 NAS Board" + help + Say 'Y' here if you want your kernel to support the + LaCie 5Big Network v2 NAS. + +config MACH_NETSPACE_MAX_V2 + bool "LaCie Network Space Max v2 NAS Board" + help + Say 'Y' here if you want your kernel to support the + LaCie Network Space Max v2 NAS. + +config MACH_NETSPACE_V2 + bool "LaCie Network Space v2 NAS Board" + help + Say 'Y' here if you want your kernel to support the + LaCie Network Space v2 NAS. + +config MACH_OPENRD + bool + +config MACH_OPENRD_BASE + bool "Marvell OpenRD Base Board" + select MACH_OPENRD + help + Say 'Y' here if you want your kernel to support the + Marvell OpenRD Base Board. + +config MACH_OPENRD_CLIENT + bool "Marvell OpenRD Client Board" + select MACH_OPENRD + help + Say 'Y' here if you want your kernel to support the + Marvell OpenRD Client Board. + +config MACH_OPENRD_ULTIMATE + bool "Marvell OpenRD Ultimate Board" + select MACH_OPENRD + help + Say 'Y' here if you want your kernel to support the + Marvell OpenRD Ultimate Board. + +config MACH_RD88F6192_NAS + bool "Marvell RD-88F6192-NAS Reference Board" + help + Say 'Y' here if you want your kernel to support the + Marvell RD-88F6192-NAS Reference Board. + +config MACH_RD88F6281 + bool "Marvell RD-88F6281 Reference Board" + help + Say 'Y' here if you want your kernel to support the + Marvell RD-88F6281 Reference Board. + config MACH_SHEEVAPLUG bool "Marvell SheevaPlug Reference Board" help Say 'Y' here if you want your kernel to support the Marvell SheevaPlug Reference Board. -config MACH_ESATA_SHEEVAPLUG - bool "Marvell eSATA SheevaPlug Reference Board" +config MACH_T5325 + bool "HP t5325 Thin Client" help Say 'Y' here if you want your kernel to support the - Marvell eSATA SheevaPlug Reference Board. + HP t5325 Thin Client. -config MACH_GURUPLUG - bool "Marvell GuruPlug Reference Board" +config MACH_TS219 + bool "QNAP TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and TS-219P+ Turbo NAS" help Say 'Y' here if you want your kernel to support the - Marvell GuruPlug Reference Board. + QNAP TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and + TS-219P+ Turbo NAS devices. + +config MACH_TS41X + bool "QNAP TS-410, TS-410U, TS-419P, TS-419P+ and TS-419U Turbo NAS" + help + Say 'Y' here if you want your kernel to support the + QNAP TS-410, TS-410U, TS-419P, TS-419P+ and TS-419U Turbo + NAS devices. + +comment "Device tree entries" config ARCH_KIRKWOOD_DT bool "Marvell Kirkwood Flattened Device Tree" @@ -58,12 +146,27 @@ config ARCH_KIRKWOOD_DT Say 'Y' here if you want your kernel to support the Marvell Kirkwood using flattened device tree. -config MACH_GURUPLUG_DT - bool "Marvell GuruPlug Reference Board (Flattened Device Tree)" +config MACH_CLOUDBOX_DT + bool "LaCie CloudBox NAS (Flattened Device Tree)" + select ARCH_KIRKWOOD_DT + help + Say 'Y' here if you want your kernel to support the LaCie + CloudBox NAS, using Flattened Device Tree. + +config MACH_DLINK_KIRKWOOD_DT + bool "D-Link Kirkwood-based NAS (Flattened Device Tree)" select ARCH_KIRKWOOD_DT help Say 'Y' here if you want your kernel to support the - Marvell GuruPlug Reference Board (Flattened Device Tree). + Kirkwood-based D-Link NASes such as DNS-320 & DNS-325, + using Flattened Device Tree. + +config MACH_DOCKSTAR_DT + bool "Seagate FreeAgent Dockstar (Flattened Device Tree)" + select ARCH_KIRKWOOD_DT + help + Say 'Y' here if you want your kernel to support the + Seagate FreeAgent Dockstar (Flattened Device Tree). config MACH_DREAMPLUG_DT bool "Marvell DreamPlug (Flattened Device Tree)" @@ -72,19 +175,19 @@ config MACH_DREAMPLUG_DT Say 'Y' here if you want your kernel to support the Marvell DreamPlug (Flattened Device Tree). -config MACH_ICONNECT_DT - bool "Iomega Iconnect (Flattened Device Tree)" +config MACH_GOFLEXNET_DT + bool "Seagate GoFlex Net (Flattened Device Tree)" select ARCH_KIRKWOOD_DT help - Say 'Y' here to enable Iomega Iconnect support. + Say 'Y' here if you want your kernel to support the + Seagate GoFlex Net (Flattened Device Tree). -config MACH_DLINK_KIRKWOOD_DT - bool "D-Link Kirkwood-based NAS (Flattened Device Tree)" +config MACH_GURUPLUG_DT + bool "Marvell GuruPlug Reference Board (Flattened Device Tree)" select ARCH_KIRKWOOD_DT help Say 'Y' here if you want your kernel to support the - Kirkwood-based D-Link NASes such as DNS-320 & DNS-325, - using Flattened Device Tree. + Marvell GuruPlug Reference Board (Flattened Device Tree). config MACH_IB62X0_DT bool "RaidSonic IB-NAS6210, IB-NAS6220 (Flattened Device Tree)" @@ -94,41 +197,18 @@ config MACH_IB62X0_DT RaidSonic IB-NAS6210 & IB-NAS6220 devices, using Flattened Device Tree. -config MACH_TS219_DT - bool "Device Tree for QNAP TS-11X, TS-21X NAS" - select ARCH_KIRKWOOD_DT - select ARM_APPENDED_DTB - select ARM_ATAG_DTB_COMPAT - help - Say 'Y' here if you want your kernel to support the QNAP - TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and - TS-219P+ Turbo NAS devices using Fattened Device Tree. - There are two different Device Tree descriptions, depending - on if the device is based on an if the board uses the MV6281 - or MV6282. If you have the wrong one, the buttons will not - work. - -config MACH_DOCKSTAR_DT - bool "Seagate FreeAgent Dockstar (Flattened Device Tree)" - select ARCH_KIRKWOOD_DT - help - Say 'Y' here if you want your kernel to support the - Seagate FreeAgent Dockstar (Flattened Device Tree). - -config MACH_GOFLEXNET_DT - bool "Seagate GoFlex Net (Flattened Device Tree)" +config MACH_ICONNECT_DT + bool "Iomega Iconnect (Flattened Device Tree)" select ARCH_KIRKWOOD_DT help - Say 'Y' here if you want your kernel to support the - Seagate GoFlex Net (Flattened Device Tree). + Say 'Y' here to enable Iomega Iconnect support. -config MACH_LSXL_DT - bool "Buffalo Linkstation LS-XHL, LS-CHLv2 (Flattened Device Tree)" +config MACH_INETSPACE_V2_DT + bool "LaCie Internet Space v2 NAS (Flattened Device Tree)" select ARCH_KIRKWOOD_DT help - Say 'Y' here if you want your kernel to support the - Buffalo Linkstation LS-XHL & LS-CHLv2 devices, using - Flattened Device Tree. + Say 'Y' here if you want your kernel to support the LaCie + Internet Space v2 NAS, using Flattened Device Tree. config MACH_IOMEGA_IX2_200_DT bool "Iomega StorCenter ix2-200 (Flattened Device Tree)" @@ -144,12 +224,13 @@ config MACH_KM_KIRKWOOD_DT Say 'Y' here if you want your kernel to support the Keymile Kirkwood Reference Desgin, using Flattened Device Tree. -config MACH_INETSPACE_V2_DT - bool "LaCie Internet Space v2 NAS (Flattened Device Tree)" +config MACH_LSXL_DT + bool "Buffalo Linkstation LS-XHL, LS-CHLv2 (Flattened Device Tree)" select ARCH_KIRKWOOD_DT help - Say 'Y' here if you want your kernel to support the LaCie - Internet Space v2 NAS, using Flattened Device Tree. + Say 'Y' here if you want your kernel to support the + Buffalo Linkstation LS-XHL & LS-CHLv2 devices, using + Flattened Device Tree. config MACH_MPLCEC4_DT bool "MPL CEC4 (Flattened Device Tree)" @@ -158,12 +239,12 @@ config MACH_MPLCEC4_DT Say 'Y' here if you want your kernel to support the MPL CEC4 (Flattened Device Tree). -config MACH_NETSPACE_V2_DT - bool "LaCie Network Space v2 NAS (Flattened Device Tree)" +config MACH_NETSPACE_LITE_V2_DT + bool "LaCie Network Space Lite v2 NAS (Flattened Device Tree)" select ARCH_KIRKWOOD_DT help Say 'Y' here if you want your kernel to support the LaCie - Network Space v2 NAS, using Flattened Device Tree. + Network Space Lite v2 NAS, using Flattened Device Tree. config MACH_NETSPACE_MAX_V2_DT bool "LaCie Network Space Max v2 NAS (Flattened Device Tree)" @@ -172,128 +253,69 @@ config MACH_NETSPACE_MAX_V2_DT Say 'Y' here if you want your kernel to support the LaCie Network Space Max v2 NAS, using Flattened Device Tree. -config MACH_NETSPACE_LITE_V2_DT - bool "LaCie Network Space Lite v2 NAS (Flattened Device Tree)" - select ARCH_KIRKWOOD_DT - help - Say 'Y' here if you want your kernel to support the LaCie - Network Space Lite v2 NAS, using Flattened Device Tree. - config MACH_NETSPACE_MINI_V2_DT bool "LaCie Network Space Mini v2 NAS (Flattened Device Tree)" select ARCH_KIRKWOOD_DT help Say 'Y' here if you want your kernel to support the LaCie - Network Space Mini v2 NAS (aka SafeBox), using Flattened - Device Tree. + Network Space Mini v2 NAS using Flattened Device Tree. -config MACH_OPENBLOCKS_A6_DT - bool "Plat'Home OpenBlocks A6 (Flattened Device Tree)" - select ARCH_KIRKWOOD_DT - help - Say 'Y' here if you want your kernel to support the - Plat'Home OpenBlocks A6 (Flattened Device Tree). + This board is embedded in a product named CloudBox, which + provides automatic backup on a 100GB cloud storage. This + should not confused with a more recent LaCie NAS also named + CloudBox. For this last, the disk capacity is 1TB or above. -config MACH_TOPKICK_DT - bool "USI Topkick (Flattened Device Tree)" +config MACH_NETSPACE_V2_DT + bool "LaCie Network Space v2 NAS (Flattened Device Tree)" select ARCH_KIRKWOOD_DT help - Say 'Y' here if you want your kernel to support the - USI Topkick, using Flattened Device Tree - -config MACH_TS219 - bool "QNAP TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and TS-219P+ Turbo NAS" - help - Say 'Y' here if you want your kernel to support the - QNAP TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and - TS-219P+ Turbo NAS devices. - -config MACH_TS41X - bool "QNAP TS-410, TS-410U, TS-419P, TS-419P+ and TS-419U Turbo NAS" - help - Say 'Y' here if you want your kernel to support the - QNAP TS-410, TS-410U, TS-419P, TS-419P+ and TS-419U Turbo - NAS devices. - -config MACH_DOCKSTAR - bool "Seagate FreeAgent DockStar" - help - Say 'Y' here if you want your kernel to support the - Seagate FreeAgent DockStar. - -config MACH_OPENRD - bool - -config MACH_OPENRD_BASE - bool "Marvell OpenRD Base Board" - select MACH_OPENRD - help - Say 'Y' here if you want your kernel to support the - Marvell OpenRD Base Board. - -config MACH_OPENRD_CLIENT - bool "Marvell OpenRD Client Board" - select MACH_OPENRD - help - Say 'Y' here if you want your kernel to support the - Marvell OpenRD Client Board. - -config MACH_OPENRD_ULTIMATE - bool "Marvell OpenRD Ultimate Board" - select MACH_OPENRD - help - Say 'Y' here if you want your kernel to support the - Marvell OpenRD Ultimate Board. - -config MACH_NETSPACE_V2 - bool "LaCie Network Space v2 NAS Board" - help - Say 'Y' here if you want your kernel to support the - LaCie Network Space v2 NAS. - -config MACH_INETSPACE_V2 - bool "LaCie Internet Space v2 NAS Board" - help - Say 'Y' here if you want your kernel to support the - LaCie Internet Space v2 NAS. - -config MACH_NETSPACE_MAX_V2 - bool "LaCie Network Space Max v2 NAS Board" - help - Say 'Y' here if you want your kernel to support the - LaCie Network Space Max v2 NAS. + Say 'Y' here if you want your kernel to support the LaCie + Network Space v2 NAS, using Flattened Device Tree. -config MACH_D2NET_V2 - bool "LaCie d2 Network v2 NAS Board" +config MACH_NSA310_DT + bool "ZyXEL NSA-310 (Flattened Device Tree)" + select ARCH_KIRKWOOD_DT + select ARM_ATAG_DTB_COMPAT help Say 'Y' here if you want your kernel to support the - LaCie d2 Network v2 NAS. + ZyXEL NSA-310 board (Flattened Device Tree). -config MACH_NET2BIG_V2 - bool "LaCie 2Big Network v2 NAS Board" +config MACH_OPENBLOCKS_A6_DT + bool "Plat'Home OpenBlocks A6 (Flattened Device Tree)" + select ARCH_KIRKWOOD_DT help Say 'Y' here if you want your kernel to support the - LaCie 2Big Network v2 NAS. + Plat'Home OpenBlocks A6 (Flattened Device Tree). -config MACH_NET5BIG_V2 - bool "LaCie 5Big Network v2 NAS Board" +config MACH_READYNAS_DT + bool "NETGEAR ReadyNAS Duo v2 (Flattened Device Tree)" + select ARCH_KIRKWOOD_DT + select ARM_APPENDED_DTB + select ARM_ATAG_DTB_COMPAT help Say 'Y' here if you want your kernel to support the - LaCie 5Big Network v2 NAS. + NETGEAR ReadyNAS Duo v2 using Fattened Device Tree. -config MACH_T5325 - bool "HP t5325 Thin Client" +config MACH_TOPKICK_DT + bool "USI Topkick (Flattened Device Tree)" + select ARCH_KIRKWOOD_DT help Say 'Y' here if you want your kernel to support the - HP t5325 Thin Client. + USI Topkick, using Flattened Device Tree -config MACH_NSA310_DT - bool "ZyXEL NSA-310 (Flattened Device Tree)" +config MACH_TS219_DT + bool "Device Tree for QNAP TS-11X, TS-21X NAS" select ARCH_KIRKWOOD_DT + select ARM_APPENDED_DTB select ARM_ATAG_DTB_COMPAT help - Say 'Y' here if you want your kernel to support the - ZyXEL NSA-310 board (Flattened Device Tree). + Say 'Y' here if you want your kernel to support the QNAP + TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and + TS-219P+ Turbo NAS devices using Fattened Device Tree. + There are two different Device Tree descriptions, depending + on if the device is based on an if the board uses the MV6281 + or MV6282. If you have the wrong one, the buttons will not + work. endmenu diff --git a/trunk/arch/arm/mach-kirkwood/Makefile b/trunk/arch/arm/mach-kirkwood/Makefile index 4cc4bee4d0cf..e1f3735d3415 100644 --- a/trunk/arch/arm/mach-kirkwood/Makefile +++ b/trunk/arch/arm/mach-kirkwood/Makefile @@ -1,42 +1,44 @@ -obj-y += common.o addr-map.o irq.o pcie.o mpp.o +obj-y += common.o irq.o pcie.o mpp.o +obj-$(CONFIG_MACH_D2NET_V2) += d2net_v2-setup.o lacie_v2-common.o obj-$(CONFIG_MACH_DB88F6281_BP) += db88f6281-bp-setup.o -obj-$(CONFIG_MACH_RD88F6192_NAS) += rd88f6192-nas-setup.o -obj-$(CONFIG_MACH_RD88F6281) += rd88f6281-setup.o -obj-$(CONFIG_MACH_MV88F6281GTW_GE) += mv88f6281gtw_ge-setup.o -obj-$(CONFIG_MACH_SHEEVAPLUG) += sheevaplug-setup.o +obj-$(CONFIG_MACH_DOCKSTAR) += dockstar-setup.o obj-$(CONFIG_MACH_ESATA_SHEEVAPLUG) += sheevaplug-setup.o obj-$(CONFIG_MACH_GURUPLUG) += guruplug-setup.o -obj-$(CONFIG_MACH_DOCKSTAR) += dockstar-setup.o -obj-$(CONFIG_MACH_TS219) += ts219-setup.o tsx1x-common.o -obj-$(CONFIG_MACH_TS41X) += ts41x-setup.o tsx1x-common.o -obj-$(CONFIG_MACH_OPENRD) += openrd-setup.o -obj-$(CONFIG_MACH_NETSPACE_V2) += netspace_v2-setup.o lacie_v2-common.o obj-$(CONFIG_MACH_INETSPACE_V2) += netspace_v2-setup.o lacie_v2-common.o -obj-$(CONFIG_MACH_NETSPACE_MAX_V2) += netspace_v2-setup.o lacie_v2-common.o -obj-$(CONFIG_MACH_D2NET_V2) += d2net_v2-setup.o lacie_v2-common.o +obj-$(CONFIG_MACH_MV88F6281GTW_GE) += mv88f6281gtw_ge-setup.o obj-$(CONFIG_MACH_NET2BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o obj-$(CONFIG_MACH_NET5BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o +obj-$(CONFIG_MACH_NETSPACE_MAX_V2) += netspace_v2-setup.o lacie_v2-common.o +obj-$(CONFIG_MACH_NETSPACE_V2) += netspace_v2-setup.o lacie_v2-common.o +obj-$(CONFIG_MACH_OPENRD) += openrd-setup.o +obj-$(CONFIG_MACH_RD88F6192_NAS) += rd88f6192-nas-setup.o +obj-$(CONFIG_MACH_RD88F6281) += rd88f6281-setup.o +obj-$(CONFIG_MACH_SHEEVAPLUG) += sheevaplug-setup.o obj-$(CONFIG_MACH_T5325) += t5325-setup.o +obj-$(CONFIG_MACH_TS219) += ts219-setup.o tsx1x-common.o +obj-$(CONFIG_MACH_TS41X) += ts41x-setup.o tsx1x-common.o obj-$(CONFIG_ARCH_KIRKWOOD_DT) += board-dt.o -obj-$(CONFIG_MACH_DREAMPLUG_DT) += board-dreamplug.o -obj-$(CONFIG_MACH_GURUPLUG_DT) += board-guruplug.o -obj-$(CONFIG_MACH_ICONNECT_DT) += board-iconnect.o +obj-$(CONFIG_MACH_CLOUDBOX_DT) += board-ns2.o obj-$(CONFIG_MACH_DLINK_KIRKWOOD_DT) += board-dnskw.o -obj-$(CONFIG_MACH_IB62X0_DT) += board-ib62x0.o -obj-$(CONFIG_MACH_TS219_DT) += board-ts219.o tsx1x-common.o obj-$(CONFIG_MACH_DOCKSTAR_DT) += board-dockstar.o +obj-$(CONFIG_MACH_DREAMPLUG_DT) += board-dreamplug.o obj-$(CONFIG_MACH_GOFLEXNET_DT) += board-goflexnet.o -obj-$(CONFIG_MACH_LSXL_DT) += board-lsxl.o +obj-$(CONFIG_MACH_GURUPLUG_DT) += board-guruplug.o +obj-$(CONFIG_MACH_IB62X0_DT) += board-ib62x0.o +obj-$(CONFIG_MACH_ICONNECT_DT) += board-iconnect.o +obj-$(CONFIG_MACH_INETSPACE_V2_DT) += board-ns2.o obj-$(CONFIG_MACH_IOMEGA_IX2_200_DT) += board-iomega_ix2_200.o obj-$(CONFIG_MACH_KM_KIRKWOOD_DT) += board-km_kirkwood.o -obj-$(CONFIG_MACH_INETSPACE_V2_DT) += board-ns2.o +obj-$(CONFIG_MACH_LSXL_DT) += board-lsxl.o obj-$(CONFIG_MACH_MPLCEC4_DT) += board-mplcec4.o -obj-$(CONFIG_MACH_NETSPACE_V2_DT) += board-ns2.o -obj-$(CONFIG_MACH_NETSPACE_MAX_V2_DT) += board-ns2.o obj-$(CONFIG_MACH_NETSPACE_LITE_V2_DT) += board-ns2.o +obj-$(CONFIG_MACH_NETSPACE_MAX_V2_DT) += board-ns2.o obj-$(CONFIG_MACH_NETSPACE_MINI_V2_DT) += board-ns2.o +obj-$(CONFIG_MACH_NETSPACE_V2_DT) += board-ns2.o obj-$(CONFIG_MACH_NSA310_DT) += board-nsa310.o obj-$(CONFIG_MACH_OPENBLOCKS_A6_DT) += board-openblocks_a6.o +obj-$(CONFIG_MACH_READYNAS_DT) += board-readynas.o obj-$(CONFIG_MACH_TOPKICK_DT) += board-usi_topkick.o +obj-$(CONFIG_MACH_TS219_DT) += board-ts219.o tsx1x-common.o diff --git a/trunk/arch/arm/mach-kirkwood/addr-map.c b/trunk/arch/arm/mach-kirkwood/addr-map.c deleted file mode 100644 index 8f0d162a1e1d..000000000000 --- a/trunk/arch/arm/mach-kirkwood/addr-map.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * arch/arm/mach-kirkwood/addr-map.c - * - * Address map functions for Marvell Kirkwood SoCs - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include -#include -#include -#include -#include -#include -#include "common.h" - -/* - * Generic Address Decode Windows bit settings - */ -#define TARGET_DEV_BUS 1 -#define TARGET_SRAM 3 -#define TARGET_PCIE 4 -#define ATTR_DEV_SPI_ROM 0x1e -#define ATTR_DEV_BOOT 0x1d -#define ATTR_DEV_NAND 0x2f -#define ATTR_DEV_CS3 0x37 -#define ATTR_DEV_CS2 0x3b -#define ATTR_DEV_CS1 0x3d -#define ATTR_DEV_CS0 0x3e -#define ATTR_PCIE_IO 0xe0 -#define ATTR_PCIE_MEM 0xe8 -#define ATTR_PCIE1_IO 0xd0 -#define ATTR_PCIE1_MEM 0xd8 -#define ATTR_SRAM 0x01 - -/* - * Description of the windows needed by the platform code - */ -static struct __initdata orion_addr_map_cfg addr_map_cfg = { - .num_wins = 8, - .remappable_wins = 4, - .bridge_virt_base = BRIDGE_VIRT_BASE, -}; - -static const struct __initdata orion_addr_map_info addr_map_info[] = { - /* - * Windows for PCIe IO+MEM space. - */ - { 0, KIRKWOOD_PCIE_IO_PHYS_BASE, KIRKWOOD_PCIE_IO_SIZE, - TARGET_PCIE, ATTR_PCIE_IO, KIRKWOOD_PCIE_IO_BUS_BASE - }, - { 1, KIRKWOOD_PCIE_MEM_PHYS_BASE, KIRKWOOD_PCIE_MEM_SIZE, - TARGET_PCIE, ATTR_PCIE_MEM, KIRKWOOD_PCIE_MEM_BUS_BASE - }, - { 2, KIRKWOOD_PCIE1_IO_PHYS_BASE, KIRKWOOD_PCIE1_IO_SIZE, - TARGET_PCIE, ATTR_PCIE1_IO, KIRKWOOD_PCIE1_IO_BUS_BASE - }, - { 3, KIRKWOOD_PCIE1_MEM_PHYS_BASE, KIRKWOOD_PCIE1_MEM_SIZE, - TARGET_PCIE, ATTR_PCIE1_MEM, KIRKWOOD_PCIE1_MEM_BUS_BASE - }, - /* - * Window for NAND controller. - */ - { 4, KIRKWOOD_NAND_MEM_PHYS_BASE, KIRKWOOD_NAND_MEM_SIZE, - TARGET_DEV_BUS, ATTR_DEV_NAND, -1 - }, - /* - * Window for SRAM. - */ - { 5, KIRKWOOD_SRAM_PHYS_BASE, KIRKWOOD_SRAM_SIZE, - TARGET_SRAM, ATTR_SRAM, -1 - }, - /* End marker */ - { -1, 0, 0, 0, 0, 0 } -}; - -void __init kirkwood_setup_cpu_mbus(void) -{ - /* - * Disable, clear and configure windows. - */ - orion_config_wins(&addr_map_cfg, addr_map_info); - - /* - * Setup MBUS dram target info. - */ - orion_setup_cpu_mbus_target(&addr_map_cfg, - (void __iomem *) DDR_WINDOW_CPU_BASE); -} diff --git a/trunk/arch/arm/mach-kirkwood/board-dt.c b/trunk/arch/arm/mach-kirkwood/board-dt.c index d367aa6b47bb..e9647b80cb59 100644 --- a/trunk/arch/arm/mach-kirkwood/board-dt.c +++ b/trunk/arch/arm/mach-kirkwood/board-dt.c @@ -93,7 +93,7 @@ static void __init kirkwood_dt_init(void) */ writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG); - kirkwood_setup_cpu_mbus(); + kirkwood_setup_wins(); kirkwood_l2_init(); @@ -139,16 +139,20 @@ static void __init kirkwood_dt_init(void) if (of_machine_is_compatible("keymile,km_kirkwood")) km_kirkwood_init(); - if (of_machine_is_compatible("lacie,inetspace_v2") || - of_machine_is_compatible("lacie,netspace_v2") || - of_machine_is_compatible("lacie,netspace_max_v2") || + if (of_machine_is_compatible("lacie,cloudbox") || + of_machine_is_compatible("lacie,inetspace_v2") || of_machine_is_compatible("lacie,netspace_lite_v2") || - of_machine_is_compatible("lacie,netspace_mini_v2")) + of_machine_is_compatible("lacie,netspace_max_v2") || + of_machine_is_compatible("lacie,netspace_mini_v2") || + of_machine_is_compatible("lacie,netspace_v2")) ns2_init(); if (of_machine_is_compatible("mpl,cec4")) mplcec4_init(); + if (of_machine_is_compatible("netgear,readynas-duo-v2")) + netgear_readynas_init(); + if (of_machine_is_compatible("plathome,openblocks-a6")) openblocks_a6_init(); @@ -171,12 +175,14 @@ static const char * const kirkwood_dt_board_compat[] = { "buffalo,lsxl", "iom,ix2-200", "keymile,km_kirkwood", + "lacie,cloudbox", "lacie,inetspace_v2", - "lacie,netspace_max_v2", - "lacie,netspace_v2", "lacie,netspace_lite_v2", + "lacie,netspace_max_v2", "lacie,netspace_mini_v2", + "lacie,netspace_v2", "mpl,cec4", + "netgear,readynas-duo-v2", "plathome,openblocks-a6", "usi,topkick", "zyxel,nsa310", diff --git a/trunk/arch/arm/mach-kirkwood/board-ns2.c b/trunk/arch/arm/mach-kirkwood/board-ns2.c index f2ea3b7ad726..f8f660525ace 100644 --- a/trunk/arch/arm/mach-kirkwood/board-ns2.c +++ b/trunk/arch/arm/mach-kirkwood/board-ns2.c @@ -27,7 +27,8 @@ void __init ns2_init(void) /* * Basic setup. Needs to be called early. */ - if (of_machine_is_compatible("lacie,netspace_lite_v2") || + if (of_machine_is_compatible("lacie,cloudbox") || + of_machine_is_compatible("lacie,netspace_lite_v2") || of_machine_is_compatible("lacie,netspace_mini_v2")) ns2_ge00_data.phy_addr = MV643XX_ETH_PHY_ADDR(0); kirkwood_ge00_init(&ns2_ge00_data); diff --git a/trunk/arch/arm/mach-kirkwood/board-readynas.c b/trunk/arch/arm/mach-kirkwood/board-readynas.c new file mode 100644 index 000000000000..fb42c20e273f --- /dev/null +++ b/trunk/arch/arm/mach-kirkwood/board-readynas.c @@ -0,0 +1,28 @@ +/* + * NETGEAR ReadyNAS Duo v2 Board setup for drivers not already + * converted to DT. + * + * Copyright (C) 2013, Arnaud EBALARD + * + * 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 +#include +#include +#include +#include +#include "common.h" + +static struct mv643xx_eth_platform_data netgear_readynas_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(0), +}; + +void __init netgear_readynas_init(void) +{ + kirkwood_ge00_init(&netgear_readynas_ge00_data); + kirkwood_pcie_init(KW_PCIE0); +} diff --git a/trunk/arch/arm/mach-kirkwood/common.c b/trunk/arch/arm/mach-kirkwood/common.c index 49792a0cd2d3..c2cae69e6d2b 100644 --- a/trunk/arch/arm/mach-kirkwood/common.c +++ b/trunk/arch/arm/mach-kirkwood/common.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include "common.h" @@ -535,6 +534,9 @@ void __init kirkwood_init_early(void) * the allocations won't fail. */ init_dma_coherent_pool_size(SZ_1M); + mvebu_mbus_init("marvell,kirkwood-mbus", + BRIDGE_WINS_BASE, BRIDGE_WINS_SZ, + DDR_WINDOW_CPU_BASE, DDR_WINDOW_CPU_SZ); } int kirkwood_tclk; @@ -650,6 +652,38 @@ char * __init kirkwood_id(void) } } +void __init kirkwood_setup_wins(void) +{ + /* + * The PCIe windows will no longer be statically allocated + * here once Kirkwood is migrated to the pci-mvebu driver. + */ + mvebu_mbus_add_window_remap_flags("pcie0.0", + KIRKWOOD_PCIE_IO_PHYS_BASE, + KIRKWOOD_PCIE_IO_SIZE, + KIRKWOOD_PCIE_IO_BUS_BASE, + MVEBU_MBUS_PCI_IO); + mvebu_mbus_add_window_remap_flags("pcie0.0", + KIRKWOOD_PCIE_MEM_PHYS_BASE, + KIRKWOOD_PCIE_MEM_SIZE, + MVEBU_MBUS_NO_REMAP, + MVEBU_MBUS_PCI_MEM); + mvebu_mbus_add_window_remap_flags("pcie1.0", + KIRKWOOD_PCIE1_IO_PHYS_BASE, + KIRKWOOD_PCIE1_IO_SIZE, + KIRKWOOD_PCIE1_IO_BUS_BASE, + MVEBU_MBUS_PCI_IO); + mvebu_mbus_add_window_remap_flags("pcie1.0", + KIRKWOOD_PCIE1_MEM_PHYS_BASE, + KIRKWOOD_PCIE1_MEM_SIZE, + MVEBU_MBUS_NO_REMAP, + MVEBU_MBUS_PCI_MEM); + mvebu_mbus_add_window("nand", KIRKWOOD_NAND_MEM_PHYS_BASE, + KIRKWOOD_NAND_MEM_SIZE); + mvebu_mbus_add_window("sram", KIRKWOOD_SRAM_PHYS_BASE, + KIRKWOOD_SRAM_SIZE); +} + void __init kirkwood_l2_init(void) { #ifdef CONFIG_CACHE_FEROCEON_L2 @@ -675,7 +709,7 @@ void __init kirkwood_init(void) */ writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG); - kirkwood_setup_cpu_mbus(); + kirkwood_setup_wins(); kirkwood_l2_init(); diff --git a/trunk/arch/arm/mach-kirkwood/common.h b/trunk/arch/arm/mach-kirkwood/common.h index 5ed70565c843..21da3b1ebd7b 100644 --- a/trunk/arch/arm/mach-kirkwood/common.h +++ b/trunk/arch/arm/mach-kirkwood/common.h @@ -30,7 +30,7 @@ void kirkwood_init(void); void kirkwood_init_early(void); void kirkwood_init_irq(void); -void kirkwood_setup_cpu_mbus(void); +void kirkwood_setup_wins(void); void kirkwood_enable_pcie(void); void kirkwood_pcie_id(u32 *dev, u32 *rev); @@ -141,12 +141,24 @@ void openblocks_a6_init(void); static inline void openblocks_a6_init(void) {}; #endif +#ifdef CONFIG_MACH_READYNAS_DT +void netgear_readynas_init(void); +#else +static inline void netgear_readynas_init(void) {}; +#endif + #ifdef CONFIG_MACH_TOPKICK_DT void usi_topkick_init(void); #else static inline void usi_topkick_init(void) {}; #endif +#ifdef CONFIG_MACH_CLOUDBOX_DT +void cloudbox_init(void); +#else +static inline void cloudbox_init(void) {}; +#endif + /* early init functions not converted to fdt yet */ char *kirkwood_id(void); void kirkwood_l2_init(void); diff --git a/trunk/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/trunk/arch/arm/mach-kirkwood/include/mach/kirkwood.h index a05563a31c95..92976cef3910 100644 --- a/trunk/arch/arm/mach-kirkwood/include/mach/kirkwood.h +++ b/trunk/arch/arm/mach-kirkwood/include/mach/kirkwood.h @@ -60,8 +60,9 @@ * Register Map */ #define DDR_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x00000) -#define DDR_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x00000) -#define DDR_WINDOW_CPU_BASE (DDR_VIRT_BASE + 0x1500) +#define DDR_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x00000) +#define DDR_WINDOW_CPU_BASE (DDR_PHYS_BASE + 0x1500) +#define DDR_WINDOW_CPU_SZ (0x20) #define DDR_OPERATION_BASE (DDR_PHYS_BASE + 0x1418) #define DEV_BUS_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x10000) @@ -80,6 +81,8 @@ #define BRIDGE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x20000) #define BRIDGE_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x20000) +#define BRIDGE_WINS_BASE (BRIDGE_PHYS_BASE) +#define BRIDGE_WINS_SZ (0x80) #define CRYPTO_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x30000) diff --git a/trunk/arch/arm/mach-kirkwood/pcie.c b/trunk/arch/arm/mach-kirkwood/pcie.c index d96ad4c09972..7f43e6c2f8c0 100644 --- a/trunk/arch/arm/mach-kirkwood/pcie.c +++ b/trunk/arch/arm/mach-kirkwood/pcie.c @@ -17,7 +17,6 @@ #include #include #include -#include #include "common.h" static void kirkwood_enable_pcie_clk(const char *port) diff --git a/trunk/arch/arm/mach-mmp/aspenite.c b/trunk/arch/arm/mach-mmp/aspenite.c index 76901f4ce611..5b660ec09ef5 100644 --- a/trunk/arch/arm/mach-mmp/aspenite.c +++ b/trunk/arch/arm/mach-mmp/aspenite.c @@ -9,6 +9,7 @@ * publishhed by the Free Software Foundation. */ #include +#include #include #include #include @@ -110,6 +111,10 @@ static unsigned long common_pin_config[] __initdata = { GPIO121_KP_MKIN4, }; +static struct pxa_gpio_platform_data pxa168_gpio_pdata = { + .irq_base = MMP_GPIO_TO_IRQ(0), +}; + static struct smc91x_platdata smc91x_info = { .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, }; @@ -242,6 +247,8 @@ static void __init common_init(void) pxa168_add_nand(&aspenite_nand_info); pxa168_add_fb(&aspenite_lcd_info); pxa168_add_keypad(&aspenite_keypad_info); + platform_device_add_data(&pxa168_device_gpio, &pxa168_gpio_pdata, + sizeof(struct pxa_gpio_platform_data)); platform_device_register(&pxa168_device_gpio); /* off-chip devices */ diff --git a/trunk/arch/arm/mach-mmp/avengers_lite.c b/trunk/arch/arm/mach-mmp/avengers_lite.c index 1f94957b56ae..a451a0f4d512 100644 --- a/trunk/arch/arm/mach-mmp/avengers_lite.c +++ b/trunk/arch/arm/mach-mmp/avengers_lite.c @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -32,12 +33,18 @@ static unsigned long avengers_lite_pin_config_V16F[] __initdata = { GPIO89_UART2_RXD, }; +static struct pxa_gpio_platform_data pxa168_gpio_pdata = { + .irq_base = MMP_GPIO_TO_IRQ(0), +}; + static void __init avengers_lite_init(void) { mfp_config(ARRAY_AND_SIZE(avengers_lite_pin_config_V16F)); /* on-chip devices */ pxa168_add_uart(2); + platform_device_add_data(&pxa168_device_gpio, &pxa168_gpio_pdata, + sizeof(struct pxa_gpio_platform_data)); platform_device_register(&pxa168_device_gpio); } diff --git a/trunk/arch/arm/mach-mmp/brownstone.c b/trunk/arch/arm/mach-mmp/brownstone.c index 2358011c7d8e..ac25544b8cdb 100644 --- a/trunk/arch/arm/mach-mmp/brownstone.c +++ b/trunk/arch/arm/mach-mmp/brownstone.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -104,6 +105,10 @@ static unsigned long brownstone_pin_config[] __initdata = { GPIO89_GPIO, }; +static struct pxa_gpio_platform_data mmp2_gpio_pdata = { + .irq_base = MMP_GPIO_TO_IRQ(0), +}; + static struct regulator_consumer_supply max8649_supply[] = { REGULATOR_SUPPLY("vcc_core", NULL), }; @@ -202,6 +207,8 @@ static void __init brownstone_init(void) /* on-chip devices */ mmp2_add_uart(1); mmp2_add_uart(3); + platform_device_add_data(&mmp2_device_gpio, &mmp2_gpio_pdata, + sizeof(struct pxa_gpio_platform_data)); platform_device_register(&mmp2_device_gpio); mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(brownstone_twsi1_info)); mmp2_add_sdhost(0, &mmp2_sdh_platdata_mmc0); /* SD/MMC */ diff --git a/trunk/arch/arm/mach-mmp/clock-mmp2.c b/trunk/arch/arm/mach-mmp/clock-mmp2.c index 21d22002cd19..53d77cbd6000 100644 --- a/trunk/arch/arm/mach-mmp/clock-mmp2.c +++ b/trunk/arch/arm/mach-mmp/clock-mmp2.c @@ -98,7 +98,7 @@ static struct clk_lookup mmp2_clkregs[] = { INIT_CLKREG(&clk_twsi5, "pxa2xx-i2c.4", NULL), INIT_CLKREG(&clk_twsi6, "pxa2xx-i2c.5", NULL), INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL), - INIT_CLKREG(&clk_gpio, "pxa-gpio", NULL), + INIT_CLKREG(&clk_gpio, "mmp2-gpio", NULL), INIT_CLKREG(&clk_sdh0, "sdhci-pxav3.0", "PXA-SDHCLK"), INIT_CLKREG(&clk_sdh1, "sdhci-pxav3.1", "PXA-SDHCLK"), INIT_CLKREG(&clk_sdh2, "sdhci-pxav3.2", "PXA-SDHCLK"), diff --git a/trunk/arch/arm/mach-mmp/clock-pxa168.c b/trunk/arch/arm/mach-mmp/clock-pxa168.c index 5e6c18ccebd4..c572f219ae26 100644 --- a/trunk/arch/arm/mach-mmp/clock-pxa168.c +++ b/trunk/arch/arm/mach-mmp/clock-pxa168.c @@ -78,7 +78,7 @@ static struct clk_lookup pxa168_clkregs[] = { INIT_CLKREG(&clk_ssp5, "pxa168-ssp.4", NULL), INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL), INIT_CLKREG(&clk_lcd, "pxa168-fb", NULL), - INIT_CLKREG(&clk_gpio, "pxa-gpio", NULL), + INIT_CLKREG(&clk_gpio, "mmp-gpio", NULL), INIT_CLKREG(&clk_keypad, "pxa27x-keypad", NULL), INIT_CLKREG(&clk_eth, "pxa168-eth", "MFUCLK"), INIT_CLKREG(&clk_usb, NULL, "PXA168-USBCLK"), diff --git a/trunk/arch/arm/mach-mmp/clock-pxa910.c b/trunk/arch/arm/mach-mmp/clock-pxa910.c index 933ea71d0b56..379e1df61c70 100644 --- a/trunk/arch/arm/mach-mmp/clock-pxa910.c +++ b/trunk/arch/arm/mach-mmp/clock-pxa910.c @@ -56,7 +56,7 @@ static struct clk_lookup pxa910_clkregs[] = { INIT_CLKREG(&clk_pwm3, "pxa910-pwm.2", NULL), INIT_CLKREG(&clk_pwm4, "pxa910-pwm.3", NULL), INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL), - INIT_CLKREG(&clk_gpio, "pxa-gpio", NULL), + INIT_CLKREG(&clk_gpio, "mmp-gpio", NULL), INIT_CLKREG(&clk_u2o, NULL, "U2OCLK"), INIT_CLKREG(&clk_rtc, "sa1100-rtc", NULL), }; diff --git a/trunk/arch/arm/mach-mmp/flint.c b/trunk/arch/arm/mach-mmp/flint.c index 754c352dd02b..6291c33d83e2 100644 --- a/trunk/arch/arm/mach-mmp/flint.c +++ b/trunk/arch/arm/mach-mmp/flint.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -77,6 +78,10 @@ static unsigned long flint_pin_config[] __initdata = { GPIO160_ND_RDY1, }; +static struct pxa_gpio_platform_data mmp2_gpio_pdata = { + .irq_base = MMP_GPIO_TO_IRQ(0), +}; + static struct smc91x_platdata flint_smc91x_info = { .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, }; @@ -111,6 +116,8 @@ static void __init flint_init(void) /* on-chip devices */ mmp2_add_uart(1); mmp2_add_uart(2); + platform_device_add_data(&mmp2_device_gpio, &mmp2_gpio_pdata, + sizeof(struct pxa_gpio_platform_data)); platform_device_register(&mmp2_device_gpio); /* off-chip devices */ diff --git a/trunk/arch/arm/mach-mmp/gplugd.c b/trunk/arch/arm/mach-mmp/gplugd.c index f62b68d926f4..d81b2475e67e 100644 --- a/trunk/arch/arm/mach-mmp/gplugd.c +++ b/trunk/arch/arm/mach-mmp/gplugd.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -128,6 +129,10 @@ static unsigned long gplugd_pin_config[] __initdata = { GPIO116_I2S_TXD }; +static struct pxa_gpio_platform_data pxa168_gpio_pdata = { + .irq_base = MMP_GPIO_TO_IRQ(0), +}; + static struct i2c_board_info gplugd_i2c_board_info[] = { { .type = "isl1208", @@ -186,6 +191,8 @@ static void __init gplugd_init(void) pxa168_add_uart(3); pxa168_add_ssp(1); pxa168_add_twsi(0, NULL, ARRAY_AND_SIZE(gplugd_i2c_board_info)); + platform_device_add_data(&pxa168_device_gpio, &pxa168_gpio_pdata, + sizeof(struct pxa_gpio_platform_data)); platform_device_register(&pxa168_device_gpio); pxa168_add_eth(&gplugd_eth_platform_data); diff --git a/trunk/arch/arm/mach-mmp/include/mach/debug-macro.S b/trunk/arch/arm/mach-mmp/include/mach/debug-macro.S deleted file mode 100644 index 5c3cc29688ab..000000000000 --- a/trunk/arch/arm/mach-mmp/include/mach/debug-macro.S +++ /dev/null @@ -1,30 +0,0 @@ -/* arch/arm/mach-mmp/include/mach/debug-macro.S - * - * Debugging macro include header - * - * Copied from arch/arm/mach-pxa/include/mach/debug.S - * - * 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. - */ - -#if defined(CONFIG_DEBUG_MMP_UART2) -#define MMP_UART_OFFSET 0x00017000 -#elif defined(CONFIG_DEBUG_MMP_UART3) -#define MMP_UART_OFFSET 0x00018000 -#else -#error "Select uart for DEBUG_LL" -#endif - -#include - - .macro addruart, rp, rv, tmp - ldr \rp, =APB_PHYS_BASE @ physical - ldr \rv, =APB_VIRT_BASE @ virtual - orr \rp, \rp, #MMP_UART_OFFSET - orr \rv, \rv, #MMP_UART_OFFSET - .endm - -#define UART_SHIFT 2 -#include diff --git a/trunk/arch/arm/mach-mmp/jasper.c b/trunk/arch/arm/mach-mmp/jasper.c index 66634fd0ecb0..0e9e5c05b37c 100644 --- a/trunk/arch/arm/mach-mmp/jasper.c +++ b/trunk/arch/arm/mach-mmp/jasper.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -99,6 +100,10 @@ static unsigned long jasper_pin_config[] __initdata = { GPIO151_MMC3_CLK, }; +static struct pxa_gpio_platform_data mmp2_gpio_pdata = { + .irq_base = MMP_GPIO_TO_IRQ(0), +}; + static struct regulator_consumer_supply max8649_supply[] = { REGULATOR_SUPPLY("vcc_core", NULL), }; @@ -165,6 +170,9 @@ static void __init jasper_init(void) mmp2_add_uart(1); mmp2_add_uart(3); mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(jasper_twsi1_info)); + platform_device_add_data(&mmp2_device_gpio, &mmp2_gpio_pdata, + sizeof(struct pxa_gpio_platform_data)); + platform_device_register(&mmp2_device_gpio); mmp2_add_sdhost(0, &mmp2_sdh_platdata_mmc0); /* SD/MMC */ regulator_has_full_constraints(); diff --git a/trunk/arch/arm/mach-mmp/mmp-dt.c b/trunk/arch/arm/mach-mmp/mmp-dt.c index d063efa0a4f1..b37915dc4470 100644 --- a/trunk/arch/arm/mach-mmp/mmp-dt.c +++ b/trunk/arch/arm/mach-mmp/mmp-dt.c @@ -28,7 +28,7 @@ static const struct of_dev_auxdata pxa168_auxdata_lookup[] __initconst = { OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4026000, "pxa2xx-uart.2", NULL), OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4011000, "pxa2xx-i2c.0", NULL), OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4025000, "pxa2xx-i2c.1", NULL), - OF_DEV_AUXDATA("mrvl,mmp-gpio", 0xd4019000, "pxa-gpio", NULL), + OF_DEV_AUXDATA("marvell,mmp-gpio", 0xd4019000, "mmp-gpio", NULL), OF_DEV_AUXDATA("mrvl,mmp-rtc", 0xd4010000, "sa1100-rtc", NULL), {} }; @@ -39,7 +39,7 @@ static const struct of_dev_auxdata pxa910_auxdata_lookup[] __initconst = { OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4036000, "pxa2xx-uart.2", NULL), OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4011000, "pxa2xx-i2c.0", NULL), OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4037000, "pxa2xx-i2c.1", NULL), - OF_DEV_AUXDATA("mrvl,mmp-gpio", 0xd4019000, "pxa-gpio", NULL), + OF_DEV_AUXDATA("marvell,mmp-gpio", 0xd4019000, "mmp-gpio", NULL), OF_DEV_AUXDATA("mrvl,mmp-rtc", 0xd4010000, "sa1100-rtc", NULL), {} }; diff --git a/trunk/arch/arm/mach-mmp/mmp2-dt.c b/trunk/arch/arm/mach-mmp/mmp2-dt.c index fad431aa6e09..4ac256720f7d 100644 --- a/trunk/arch/arm/mach-mmp/mmp2-dt.c +++ b/trunk/arch/arm/mach-mmp/mmp2-dt.c @@ -31,7 +31,7 @@ static const struct of_dev_auxdata mmp2_auxdata_lookup[] __initconst = { OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4016000, "pxa2xx-uart.3", NULL), OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4011000, "pxa2xx-i2c.0", NULL), OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4025000, "pxa2xx-i2c.1", NULL), - OF_DEV_AUXDATA("mrvl,mmp-gpio", 0xd4019000, "pxa-gpio", NULL), + OF_DEV_AUXDATA("marvell,mmp-gpio", 0xd4019000, "mmp2-gpio", NULL), OF_DEV_AUXDATA("mrvl,mmp-rtc", 0xd4010000, "sa1100-rtc", NULL), {} }; diff --git a/trunk/arch/arm/mach-mmp/mmp2.c b/trunk/arch/arm/mach-mmp/mmp2.c index d94d114eef7b..c7592f168bbd 100644 --- a/trunk/arch/arm/mach-mmp/mmp2.c +++ b/trunk/arch/arm/mach-mmp/mmp2.c @@ -164,7 +164,7 @@ struct resource mmp2_resource_gpio[] = { }; struct platform_device mmp2_device_gpio = { - .name = "pxa-gpio", + .name = "mmp2-gpio", .id = -1, .num_resources = ARRAY_SIZE(mmp2_resource_gpio), .resource = mmp2_resource_gpio, diff --git a/trunk/arch/arm/mach-mmp/pxa168.c b/trunk/arch/arm/mach-mmp/pxa168.c index 9bc7b86a86a7..a30dcf3b7d9e 100644 --- a/trunk/arch/arm/mach-mmp/pxa168.c +++ b/trunk/arch/arm/mach-mmp/pxa168.c @@ -125,7 +125,7 @@ struct resource pxa168_resource_gpio[] = { }; struct platform_device pxa168_device_gpio = { - .name = "pxa-gpio", + .name = "mmp-gpio", .id = -1, .num_resources = ARRAY_SIZE(pxa168_resource_gpio), .resource = pxa168_resource_gpio, diff --git a/trunk/arch/arm/mach-mmp/pxa910.c b/trunk/arch/arm/mach-mmp/pxa910.c index 36cb321a3d70..ce6393acad86 100644 --- a/trunk/arch/arm/mach-mmp/pxa910.c +++ b/trunk/arch/arm/mach-mmp/pxa910.c @@ -152,7 +152,7 @@ struct resource pxa910_resource_gpio[] = { }; struct platform_device pxa910_device_gpio = { - .name = "pxa-gpio", + .name = "mmp-gpio", .id = -1, .num_resources = ARRAY_SIZE(pxa910_resource_gpio), .resource = pxa910_resource_gpio, diff --git a/trunk/arch/arm/mach-mmp/tavorevb.c b/trunk/arch/arm/mach-mmp/tavorevb.c index 4c127d23955d..cdfc9bfee1a4 100644 --- a/trunk/arch/arm/mach-mmp/tavorevb.c +++ b/trunk/arch/arm/mach-mmp/tavorevb.c @@ -8,6 +8,7 @@ * publishhed by the Free Software Foundation. */ #include +#include #include #include #include @@ -60,6 +61,10 @@ static unsigned long tavorevb_pin_config[] __initdata = { DF_RDY0_DF_RDY0, }; +static struct pxa_gpio_platform_data pxa910_gpio_pdata = { + .irq_base = MMP_GPIO_TO_IRQ(0), +}; + static struct smc91x_platdata tavorevb_smc91x_info = { .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, }; @@ -93,6 +98,8 @@ static void __init tavorevb_init(void) /* on-chip devices */ pxa910_add_uart(1); + platform_device_add_data(&pxa910_device_gpio, &pxa910_gpio_pdata, + sizeof(struct pxa_gpio_platform_data)); platform_device_register(&pxa910_device_gpio); /* off-chip devices */ diff --git a/trunk/arch/arm/mach-mmp/teton_bga.c b/trunk/arch/arm/mach-mmp/teton_bga.c index 8609967975ed..e4d95b4c6bb2 100644 --- a/trunk/arch/arm/mach-mmp/teton_bga.c +++ b/trunk/arch/arm/mach-mmp/teton_bga.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -49,6 +50,10 @@ static unsigned long teton_bga_pin_config[] __initdata = { GPIO78_GPIO, }; +static struct pxa_gpio_platform_data pxa168_gpio_pdata = { + .irq_base = MMP_GPIO_TO_IRQ(0), +}; + static unsigned int teton_bga_matrix_key_map[] = { KEY(0, 6, KEY_ESC), KEY(0, 7, KEY_ENTER), @@ -79,6 +84,8 @@ static void __init teton_bga_init(void) pxa168_add_uart(1); pxa168_add_keypad(&teton_bga_keypad_info); pxa168_add_twsi(0, NULL, ARRAY_AND_SIZE(teton_bga_i2c_info)); + platform_device_add_data(&pxa168_device_gpio, &pxa168_gpio_pdata, + sizeof(struct pxa_gpio_platform_data)); platform_device_register(&pxa168_device_gpio); } diff --git a/trunk/arch/arm/mach-mmp/ttc_dkb.c b/trunk/arch/arm/mach-mmp/ttc_dkb.c index 6528a5fa6a26..8483906d4308 100644 --- a/trunk/arch/arm/mach-mmp/ttc_dkb.c +++ b/trunk/arch/arm/mach-mmp/ttc_dkb.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -75,6 +76,10 @@ static unsigned long ttc_dkb_pin_config[] __initdata = { DF_RDY0_DF_RDY0, }; +static struct pxa_gpio_platform_data pxa910_gpio_pdata = { + .irq_base = MMP_GPIO_TO_IRQ(0), +}; + static struct mtd_partition ttc_dkb_onenand_partitions[] = { { .name = "bootloader", @@ -278,6 +283,8 @@ static void __init ttc_dkb_init(void) /* off-chip devices */ pxa910_add_twsi(0, NULL, ARRAY_AND_SIZE(ttc_dkb_i2c_info)); + platform_device_add_data(&pxa910_device_gpio, &pxa910_gpio_pdata, + sizeof(struct pxa_gpio_platform_data)); platform_add_devices(ARRAY_AND_SIZE(ttc_dkb_devices)); #ifdef CONFIG_USB_MV_UDC diff --git a/trunk/arch/arm/mach-msm/hotplug.c b/trunk/arch/arm/mach-msm/hotplug.c index 750446feb444..326a87261f9a 100644 --- a/trunk/arch/arm/mach-msm/hotplug.c +++ b/trunk/arch/arm/mach-msm/hotplug.c @@ -10,16 +10,12 @@ #include #include -#include #include #include "common.h" static inline void cpu_enter_lowpower(void) { - /* Just flush the cache. Changing the coherency is not yet - * available on msm. */ - flush_cache_all(); } static inline void cpu_leave_lowpower(void) diff --git a/trunk/arch/arm/mach-msm/last_radio_log.c b/trunk/arch/arm/mach-msm/last_radio_log.c index 7777767ee89a..9c392a29fc7e 100644 --- a/trunk/arch/arm/mach-msm/last_radio_log.c +++ b/trunk/arch/arm/mach-msm/last_radio_log.c @@ -66,6 +66,6 @@ void msm_init_last_radio_log(struct module *owner) pr_err("%s: last radio log is %d bytes long\n", __func__, radio_log_size); last_radio_log_fops.owner = owner; - entry->size = radio_log_size; + proc_set_size(entry, radio_log_size); } EXPORT_SYMBOL(msm_init_last_radio_log); diff --git a/trunk/arch/arm/mach-mv78xx0/Makefile b/trunk/arch/arm/mach-mv78xx0/Makefile index 67a13f9bfe64..7cd04634d302 100644 --- a/trunk/arch/arm/mach-mv78xx0/Makefile +++ b/trunk/arch/arm/mach-mv78xx0/Makefile @@ -1,4 +1,4 @@ -obj-y += common.o addr-map.o mpp.o irq.o pcie.o +obj-y += common.o mpp.o irq.o pcie.o obj-$(CONFIG_MACH_DB78X00_BP) += db78x00-bp-setup.o obj-$(CONFIG_MACH_RD78X00_MASA) += rd78x00-masa-setup.o obj-$(CONFIG_MACH_TERASTATION_WXL) += buffalo-wxl-setup.o diff --git a/trunk/arch/arm/mach-mv78xx0/addr-map.c b/trunk/arch/arm/mach-mv78xx0/addr-map.c deleted file mode 100644 index 26e9876b50e9..000000000000 --- a/trunk/arch/arm/mach-mv78xx0/addr-map.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * arch/arm/mach-mv78xx0/addr-map.c - * - * Address map functions for Marvell MV78xx0 SoCs - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include -#include -#include -#include -#include -#include -#include "common.h" - -/* - * Generic Address Decode Windows bit settings - */ -#define TARGET_DEV_BUS 1 -#define TARGET_PCIE0 4 -#define TARGET_PCIE1 8 -#define TARGET_PCIE(i) ((i) ? TARGET_PCIE1 : TARGET_PCIE0) -#define ATTR_DEV_SPI_ROM 0x1f -#define ATTR_DEV_BOOT 0x2f -#define ATTR_DEV_CS3 0x37 -#define ATTR_DEV_CS2 0x3b -#define ATTR_DEV_CS1 0x3d -#define ATTR_DEV_CS0 0x3e -#define ATTR_PCIE_IO(l) (0xf0 & ~(0x10 << (l))) -#define ATTR_PCIE_MEM(l) (0xf8 & ~(0x10 << (l))) - -/* - * CPU Address Decode Windows registers - */ -#define WIN0_OFF(n) (BRIDGE_VIRT_BASE + 0x0000 + ((n) << 4)) -#define WIN8_OFF(n) (BRIDGE_VIRT_BASE + 0x0900 + (((n) - 8) << 4)) - -static void __init __iomem *win_cfg_base(const struct orion_addr_map_cfg *cfg, int win) -{ - /* - * Find the control register base address for this window. - * - * BRIDGE_VIRT_BASE points to the right (CPU0's or CPU1's) - * MBUS bridge depending on which CPU core we're running on, - * so we don't need to take that into account here. - */ - - return (win < 8) ? WIN0_OFF(win) : WIN8_OFF(win); -} - -/* - * Description of the windows needed by the platform code - */ -static struct orion_addr_map_cfg addr_map_cfg __initdata = { - .num_wins = 14, - .remappable_wins = 8, - .win_cfg_base = win_cfg_base, -}; - -void __init mv78xx0_setup_cpu_mbus(void) -{ - /* - * Disable, clear and configure windows. - */ - orion_config_wins(&addr_map_cfg, NULL); - - /* - * Setup MBUS dram target info. - */ - if (mv78xx0_core_index() == 0) - orion_setup_cpu_mbus_target(&addr_map_cfg, - (void __iomem *) DDR_WINDOW_CPU0_BASE); - else - orion_setup_cpu_mbus_target(&addr_map_cfg, - (void __iomem *) DDR_WINDOW_CPU1_BASE); -} - -void __init mv78xx0_setup_pcie_io_win(int window, u32 base, u32 size, - int maj, int min) -{ - orion_setup_cpu_win(&addr_map_cfg, window, base, size, - TARGET_PCIE(maj), ATTR_PCIE_IO(min), 0); -} - -void __init mv78xx0_setup_pcie_mem_win(int window, u32 base, u32 size, - int maj, int min) -{ - orion_setup_cpu_win(&addr_map_cfg, window, base, size, - TARGET_PCIE(maj), ATTR_PCIE_MEM(min), -1); -} diff --git a/trunk/arch/arm/mach-mv78xx0/common.c b/trunk/arch/arm/mach-mv78xx0/common.c index 0efa14498ebc..749a7f8c4992 100644 --- a/trunk/arch/arm/mach-mv78xx0/common.c +++ b/trunk/arch/arm/mach-mv78xx0/common.c @@ -334,6 +334,14 @@ void __init mv78xx0_uart3_init(void) void __init mv78xx0_init_early(void) { orion_time_set_base(TIMER_VIRT_BASE); + if (mv78xx0_core_index() == 0) + mvebu_mbus_init("marvell,mv78xx0-mbus", + BRIDGE_WINS_CPU0_BASE, BRIDGE_WINS_SZ, + DDR_WINDOW_CPU0_BASE, DDR_WINDOW_CPU_SZ); + else + mvebu_mbus_init("marvell,mv78xx0-mbus", + BRIDGE_WINS_CPU1_BASE, BRIDGE_WINS_SZ, + DDR_WINDOW_CPU1_BASE, DDR_WINDOW_CPU_SZ); } void __init_refok mv78xx0_timer_init(void) @@ -397,8 +405,6 @@ void __init mv78xx0_init(void) printk("HCLK = %dMHz, ", (hclk + 499999) / 1000000); printk("TCLK = %dMHz\n", (get_tclk() + 499999) / 1000000); - mv78xx0_setup_cpu_mbus(); - #ifdef CONFIG_CACHE_FEROCEON_L2 feroceon_l2_init(is_l2_writethrough()); #endif diff --git a/trunk/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h b/trunk/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h index 46200a183cf2..723748d8ba7d 100644 --- a/trunk/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h +++ b/trunk/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h @@ -60,13 +60,18 @@ */ #define BRIDGE_VIRT_BASE (MV78XX0_CORE_REGS_VIRT_BASE) #define BRIDGE_PHYS_BASE (MV78XX0_CORE_REGS_PHYS_BASE) +#define BRIDGE_WINS_CPU0_BASE (MV78XX0_CORE0_REGS_PHYS_BASE) +#define BRIDGE_WINS_CPU1_BASE (MV78XX0_CORE1_REGS_PHYS_BASE) +#define BRIDGE_WINS_SZ (0xA000) /* * Register Map */ #define DDR_VIRT_BASE (MV78XX0_REGS_VIRT_BASE + 0x00000) -#define DDR_WINDOW_CPU0_BASE (DDR_VIRT_BASE + 0x1500) -#define DDR_WINDOW_CPU1_BASE (DDR_VIRT_BASE + 0x1570) +#define DDR_PHYS_BASE (MV78XX0_REGS_PHYS_BASE + 0x00000) +#define DDR_WINDOW_CPU0_BASE (DDR_PHYS_BASE + 0x1500) +#define DDR_WINDOW_CPU1_BASE (DDR_PHYS_BASE + 0x1570) +#define DDR_WINDOW_CPU_SZ (0x20) #define DEV_BUS_PHYS_BASE (MV78XX0_REGS_PHYS_BASE + 0x10000) #define DEV_BUS_VIRT_BASE (MV78XX0_REGS_VIRT_BASE + 0x10000) diff --git a/trunk/arch/arm/mach-mv78xx0/pcie.c b/trunk/arch/arm/mach-mv78xx0/pcie.c index ee8c0b51df2c..dc26a654c496 100644 --- a/trunk/arch/arm/mach-mv78xx0/pcie.c +++ b/trunk/arch/arm/mach-mv78xx0/pcie.c @@ -10,11 +10,11 @@ #include #include +#include #include