diff --git a/[refs] b/[refs] index fda0b9b738c4..93410cf50266 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 96b70641b937e99c1579cb6ebbcdb7b0af98cdd0 +refs/heads/master: 5e67cc4041304a0dc77e6cfbb355d69eefb883d0 diff --git a/trunk/.mailmap b/trunk/.mailmap index 9b0d0267a3c3..658003aa9446 100644 --- a/trunk/.mailmap +++ b/trunk/.mailmap @@ -111,5 +111,8 @@ Uwe Kleine-König Uwe Kleine-König Uwe Kleine-König Valdis Kletnieks +Viresh Kumar Takashi YOSHII Yusuke Goda +Gustavo Padovan +Gustavo Padovan diff --git a/trunk/Documentation/ABI/testing/sysfs-block-rssd b/trunk/Documentation/ABI/testing/sysfs-block-rssd index d535757799fe..679ce3543122 100644 --- a/trunk/Documentation/ABI/testing/sysfs-block-rssd +++ b/trunk/Documentation/ABI/testing/sysfs-block-rssd @@ -6,13 +6,21 @@ Description: This is a read-only file. Dumps below driver information and hardware registers. - S ACTive - Command Issue - - Allocated - Completed - PORT IRQ STAT - HOST IRQ STAT + - Allocated + - Commands in Q What: /sys/block/rssd*/status Date: April 2012 KernelVersion: 3.4 Contact: Asai Thambi S P -Description: This is a read-only file. Indicates the status of the device. +Description: This is a read-only file. Indicates the status of the device. + +What: /sys/block/rssd*/flags +Date: May 2012 +KernelVersion: 3.5 +Contact: Asai Thambi S P +Description: This is a read-only file. Dumps the flags in port and driver + data structure diff --git a/trunk/Documentation/ABI/testing/sysfs-bus-fcoe b/trunk/Documentation/ABI/testing/sysfs-bus-fcoe new file mode 100644 index 000000000000..469d09c02f6b --- /dev/null +++ b/trunk/Documentation/ABI/testing/sysfs-bus-fcoe @@ -0,0 +1,77 @@ +What: /sys/bus/fcoe/ctlr_X +Date: March 2012 +KernelVersion: TBD +Contact: Robert Love , devel@open-fcoe.org +Description: 'FCoE Controller' instances on the fcoe bus +Attributes: + + fcf_dev_loss_tmo: Device loss timeout peroid (see below). Changing + this value will change the dev_loss_tmo for all + FCFs discovered by this controller. + + lesb_link_fail: Link Error Status Block (LESB) link failure count. + + lesb_vlink_fail: Link Error Status Block (LESB) virtual link + failure count. + + lesb_miss_fka: Link Error Status Block (LESB) missed FCoE + Initialization Protocol (FIP) Keep-Alives (FKA). + + lesb_symb_err: Link Error Status Block (LESB) symbolic error count. + + lesb_err_block: Link Error Status Block (LESB) block error count. + + lesb_fcs_error: Link Error Status Block (LESB) Fibre Channel + Serivces error count. + +Notes: ctlr_X (global increment starting at 0) + +What: /sys/bus/fcoe/fcf_X +Date: March 2012 +KernelVersion: TBD +Contact: Robert Love , devel@open-fcoe.org +Description: 'FCoE FCF' instances on the fcoe bus. A FCF is a Fibre Channel + Forwarder, which is a FCoE switch that can accept FCoE + (Ethernet) packets, unpack them, and forward the embedded + Fibre Channel frames into a FC fabric. It can also take + outbound FC frames and pack them in Ethernet packets to + be sent to their destination on the Ethernet segment. +Attributes: + + fabric_name: Identifies the fabric that the FCF services. + + switch_name: Identifies the FCF. + + priority: The switch's priority amongst other FCFs on the same + fabric. + + selected: 1 indicates that the switch has been selected for use; + 0 indicates that the swich will not be used. + + fc_map: The Fibre Channel MAP + + vfid: The Virtual Fabric ID + + mac: The FCF's MAC address + + fka_peroid: The FIP Keep-Alive peroid + + fabric_state: The internal kernel state + "Unknown" - Initialization value + "Disconnected" - No link to the FCF/fabric + "Connected" - Host is connected to the FCF + "Deleted" - FCF is being removed from the system + + dev_loss_tmo: The device loss timeout peroid for this FCF. + +Notes: A device loss infrastructre similar to the FC Transport's + is present in fcoe_sysfs. It is nice to have so that a + link flapping adapter doesn't continually advance the count + used to identify the discovered FCF. FCFs will exist in a + "Disconnected" state until either the timer expires and the + FCF becomes "Deleted" or the FCF is rediscovered and becomes + "Connected." + + +Users: The first user of this interface will be the fcoeadm application, + which is commonly packaged in the fcoe-utils package. diff --git a/trunk/Documentation/ABI/testing/sysfs-bus-i2c-devices-lm3533 b/trunk/Documentation/ABI/testing/sysfs-bus-i2c-devices-lm3533 new file mode 100644 index 000000000000..1b62230b33b9 --- /dev/null +++ b/trunk/Documentation/ABI/testing/sysfs-bus-i2c-devices-lm3533 @@ -0,0 +1,15 @@ +What: /sys/bus/i2c/devices/.../output_hvled[n] +Date: April 2012 +KernelVersion: 3.5 +Contact: Johan Hovold +Description: + Set the controlling backlight device for high-voltage current + sink HVLED[n] (n = 1, 2) (0, 1). + +What: /sys/bus/i2c/devices/.../output_lvled[n] +Date: April 2012 +KernelVersion: 3.5 +Contact: Johan Hovold +Description: + Set the controlling led device for low-voltage current sink + LVLED[n] (n = 1..5) (0..3). diff --git a/trunk/Documentation/ABI/testing/sysfs-bus-iio b/trunk/Documentation/ABI/testing/sysfs-bus-iio index 5bc8a476c15e..cfedf63cce15 100644 --- a/trunk/Documentation/ABI/testing/sysfs-bus-iio +++ b/trunk/Documentation/ABI/testing/sysfs-bus-iio @@ -219,6 +219,7 @@ What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_scale What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_supply_scale What: /sys/bus/iio/devices/iio:deviceX/in_voltage_scale What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_scale +What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_scale What: /sys/bus/iio/devices/iio:deviceX/in_accel_scale What: /sys/bus/iio/devices/iio:deviceX/in_accel_peak_scale What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_scale @@ -273,6 +274,7 @@ What: /sys/bus/iio/devices/iio:deviceX/in_accel_scale_available What: /sys/.../iio:deviceX/in_voltageX_scale_available What: /sys/.../iio:deviceX/in_voltage-voltage_scale_available What: /sys/.../iio:deviceX/out_voltageX_scale_available +What: /sys/.../iio:deviceX/out_altvoltageX_scale_available What: /sys/.../iio:deviceX/in_capacitance_scale_available KernelVersion: 2.635 Contact: linux-iio@vger.kernel.org @@ -298,14 +300,19 @@ Description: gives the 3dB frequency of the filter in Hz. What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_raw +What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_raw KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: Raw (unscaled, no bias etc.) output voltage for channel Y. The number must always be specified and unique if the output corresponds to a single channel. + While DAC like devices typically use out_voltage, + a continuous frequency generating device, such as + a DDS or PLL should use out_altvoltage. What: /sys/bus/iio/devices/iio:deviceX/out_voltageY&Z_raw +What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY&Z_raw KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: @@ -316,6 +323,8 @@ Description: What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_powerdown_mode What: /sys/bus/iio/devices/iio:deviceX/out_voltage_powerdown_mode +What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_powerdown_mode +What: /sys/bus/iio/devices/iio:deviceX/out_altvoltage_powerdown_mode KernelVersion: 2.6.38 Contact: linux-iio@vger.kernel.org Description: @@ -330,6 +339,8 @@ Description: What: /sys/.../iio:deviceX/out_votlageY_powerdown_mode_available What: /sys/.../iio:deviceX/out_voltage_powerdown_mode_available +What: /sys/.../iio:deviceX/out_altvotlageY_powerdown_mode_available +What: /sys/.../iio:deviceX/out_altvoltage_powerdown_mode_available KernelVersion: 2.6.38 Contact: linux-iio@vger.kernel.org Description: @@ -338,6 +349,8 @@ Description: What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_powerdown What: /sys/bus/iio/devices/iio:deviceX/out_voltage_powerdown +What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_powerdown +What: /sys/bus/iio/devices/iio:deviceX/out_altvoltage_powerdown KernelVersion: 2.6.38 Contact: linux-iio@vger.kernel.org Description: @@ -346,6 +359,24 @@ Description: normal operation. Y may be suppressed if all outputs are controlled together. +What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_frequency +KernelVersion: 3.4.0 +Contact: linux-iio@vger.kernel.org +Description: + Output frequency for channel Y in Hz. The number must always be + specified and unique if the output corresponds to a single + channel. + +What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_phase +KernelVersion: 3.4.0 +Contact: linux-iio@vger.kernel.org +Description: + Phase in radians of one frequency/clock output Y + (out_altvoltageY) relative to another frequency/clock output + (out_altvoltageZ) of the device X. The number must always be + specified and unique if the output corresponds to a single + channel. + What: /sys/bus/iio/devices/iio:deviceX/events KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org diff --git a/trunk/Documentation/ABI/testing/sysfs-bus-rbd b/trunk/Documentation/ABI/testing/sysfs-bus-rbd index dbedafb095e2..bcd88eb7ebcd 100644 --- a/trunk/Documentation/ABI/testing/sysfs-bus-rbd +++ b/trunk/Documentation/ABI/testing/sysfs-bus-rbd @@ -65,11 +65,11 @@ snap_* Entries under /sys/bus/rbd/devices//snap_ ------------------------------------------------------------- -id +snap_id The rados internal snapshot id assigned for this snapshot -size +snap_size The size of the image when this snapshot was taken. diff --git a/trunk/Documentation/ABI/testing/sysfs-class-backlight-driver-lm3533 b/trunk/Documentation/ABI/testing/sysfs-class-backlight-driver-lm3533 new file mode 100644 index 000000000000..77cf7ac949af --- /dev/null +++ b/trunk/Documentation/ABI/testing/sysfs-class-backlight-driver-lm3533 @@ -0,0 +1,48 @@ +What: /sys/class/backlight//als_channel +Date: May 2012 +KernelVersion: 3.5 +Contact: Johan Hovold +Description: + Get the ALS output channel used as input in + ALS-current-control mode (0, 1), where + + 0 - out_current0 (backlight 0) + 1 - out_current1 (backlight 1) + +What: /sys/class/backlight//als_en +Date: May 2012 +KernelVersion: 3.5 +Contact: Johan Hovold +Description: + Enable ALS-current-control mode (0, 1). + +What: /sys/class/backlight//id +Date: April 2012 +KernelVersion: 3.5 +Contact: Johan Hovold +Description: + Get the id of this backlight (0, 1). + +What: /sys/class/backlight//linear +Date: April 2012 +KernelVersion: 3.5 +Contact: Johan Hovold +Description: + Set the brightness-mapping mode (0, 1), where + + 0 - exponential mode + 1 - linear mode + +What: /sys/class/backlight//pwm +Date: April 2012 +KernelVersion: 3.5 +Contact: Johan Hovold +Description: + Set the PWM-input control mask (5 bits), where + + bit 5 - PWM-input enabled in Zone 4 + bit 4 - PWM-input enabled in Zone 3 + bit 3 - PWM-input enabled in Zone 2 + bit 2 - PWM-input enabled in Zone 1 + bit 1 - PWM-input enabled in Zone 0 + bit 0 - PWM-input enabled diff --git a/trunk/Documentation/ABI/testing/sysfs-class-led-driver-lm3533 b/trunk/Documentation/ABI/testing/sysfs-class-led-driver-lm3533 new file mode 100644 index 000000000000..620ebb3b9baa --- /dev/null +++ b/trunk/Documentation/ABI/testing/sysfs-class-led-driver-lm3533 @@ -0,0 +1,65 @@ +What: /sys/class/leds//als_channel +Date: May 2012 +KernelVersion: 3.5 +Contact: Johan Hovold +Description: + Set the ALS output channel to use as input in + ALS-current-control mode (1, 2), where + + 1 - out_current1 + 2 - out_current2 + +What: /sys/class/leds//als_en +Date: May 2012 +KernelVersion: 3.5 +Contact: Johan Hovold +Description: + Enable ALS-current-control mode (0, 1). + +What: /sys/class/leds//falltime +What: /sys/class/leds//risetime +Date: April 2012 +KernelVersion: 3.5 +Contact: Johan Hovold +Description: + Set the pattern generator fall and rise times (0..7), where + + 0 - 2048 us + 1 - 262 ms + 2 - 524 ms + 3 - 1.049 s + 4 - 2.097 s + 5 - 4.194 s + 6 - 8.389 s + 7 - 16.78 s + +What: /sys/class/leds//id +Date: April 2012 +KernelVersion: 3.5 +Contact: Johan Hovold +Description: + Get the id of this led (0..3). + +What: /sys/class/leds//linear +Date: April 2012 +KernelVersion: 3.5 +Contact: Johan Hovold +Description: + Set the brightness-mapping mode (0, 1), where + + 0 - exponential mode + 1 - linear mode + +What: /sys/class/leds//pwm +Date: April 2012 +KernelVersion: 3.5 +Contact: Johan Hovold +Description: + Set the PWM-input control mask (5 bits), where + + bit 5 - PWM-input enabled in Zone 4 + bit 4 - PWM-input enabled in Zone 3 + bit 3 - PWM-input enabled in Zone 2 + bit 2 - PWM-input enabled in Zone 1 + bit 1 - PWM-input enabled in Zone 0 + bit 0 - PWM-input enabled diff --git a/trunk/Documentation/ABI/testing/sysfs-class-mtd b/trunk/Documentation/ABI/testing/sysfs-class-mtd index 4d55a1888981..db1ad7e34fc3 100644 --- a/trunk/Documentation/ABI/testing/sysfs-class-mtd +++ b/trunk/Documentation/ABI/testing/sysfs-class-mtd @@ -123,3 +123,54 @@ Description: half page, or a quarter page). In the case of ECC NOR, it is the ECC block size. + +What: /sys/class/mtd/mtdX/ecc_strength +Date: April 2012 +KernelVersion: 3.4 +Contact: linux-mtd@lists.infradead.org +Description: + Maximum number of bit errors that the device is capable of + correcting within each region covering an ecc step. This will + always be a non-negative integer. Note that some devices will + have multiple ecc steps within each writesize region. + + In the case of devices lacking any ECC capability, it is 0. + +What: /sys/class/mtd/mtdX/bitflip_threshold +Date: April 2012 +KernelVersion: 3.4 +Contact: linux-mtd@lists.infradead.org +Description: + This allows the user to examine and adjust the criteria by which + mtd returns -EUCLEAN from mtd_read(). If the maximum number of + bit errors that were corrected on any single region comprising + an ecc step (as reported by the driver) equals or exceeds this + value, -EUCLEAN is returned. Otherwise, absent an error, 0 is + returned. Higher layers (e.g., UBI) use this return code as an + indication that an erase block may be degrading and should be + scrutinized as a candidate for being marked as bad. + + The initial value may be specified by the flash device driver. + If not, then the default value is ecc_strength. + + The introduction of this feature brings a subtle change to the + meaning of the -EUCLEAN return code. Previously, it was + interpreted to mean simply "one or more bit errors were + corrected". Its new interpretation can be phrased as "a + dangerously high number of bit errors were corrected on one or + more regions comprising an ecc step". The precise definition of + "dangerously high" can be adjusted by the user with + bitflip_threshold. Users are discouraged from doing this, + however, unless they know what they are doing and have intimate + knowledge of the properties of their device. Broadly speaking, + bitflip_threshold should be low enough to detect genuine erase + block degradation, but high enough to avoid the consequences of + a persistent return value of -EUCLEAN on devices where sticky + bitflips occur. Note that if bitflip_threshold exceeds + ecc_strength, -EUCLEAN is never returned by mtd_read(). + Conversely, if bitflip_threshold is zero, -EUCLEAN is always + returned, absent a hard error. + + This is generally applicable only to NAND flash devices with ECC + capability. It is ignored on devices lacking ECC capability; + i.e., devices for which ecc_strength is zero. diff --git a/trunk/Documentation/CodingStyle b/trunk/Documentation/CodingStyle index c58b236bbe04..cb9258b8fd35 100644 --- a/trunk/Documentation/CodingStyle +++ b/trunk/Documentation/CodingStyle @@ -671,8 +671,9 @@ ones already enabled by DEBUG. Chapter 14: Allocating memory The kernel provides the following general purpose memory allocators: -kmalloc(), kzalloc(), kcalloc(), vmalloc(), and vzalloc(). Please refer to -the API documentation for further information about them. +kmalloc(), kzalloc(), kmalloc_array(), kcalloc(), vmalloc(), and +vzalloc(). Please refer to the API documentation for further information +about them. The preferred form for passing a size of a struct is the following: @@ -686,6 +687,17 @@ Casting the return value which is a void pointer is redundant. The conversion from void pointer to any other pointer type is guaranteed by the C programming language. +The preferred form for allocating an array is the following: + + p = kmalloc_array(n, sizeof(...), ...); + +The preferred form for allocating a zeroed array is the following: + + p = kcalloc(n, sizeof(...), ...); + +Both forms check for overflow on the allocation size n * sizeof(...), +and return NULL if that occurred. + Chapter 15: The inline disease diff --git a/trunk/Documentation/DocBook/media/v4l/pixfmt.xml b/trunk/Documentation/DocBook/media/v4l/pixfmt.xml index f5ac15ed0549..e58934c92895 100644 --- a/trunk/Documentation/DocBook/media/v4l/pixfmt.xml +++ b/trunk/Documentation/DocBook/media/v4l/pixfmt.xml @@ -986,13 +986,13 @@ http://www.thedirks.org/winnov/ V4L2_PIX_FMT_Y4 'Y04 ' - Old 4-bit greyscale format. Only the least significant 4 bits of each byte are used, + Old 4-bit greyscale format. Only the most significant 4 bits of each byte are used, the other bits are set to 0. V4L2_PIX_FMT_Y6 'Y06 ' - Old 6-bit greyscale format. Only the least significant 6 bits of each byte are used, + Old 6-bit greyscale format. Only the most significant 6 bits of each byte are used, the other bits are set to 0. diff --git a/trunk/Documentation/DocBook/media/v4l/v4l2.xml b/trunk/Documentation/DocBook/media/v4l/v4l2.xml index 015c561754b7..008c2d73a484 100644 --- a/trunk/Documentation/DocBook/media/v4l/v4l2.xml +++ b/trunk/Documentation/DocBook/media/v4l/v4l2.xml @@ -560,6 +560,7 @@ and discussions on the V4L mailing list. &sub-g-tuner; &sub-log-status; &sub-overlay; + &sub-prepare-buf; &sub-qbuf; &sub-querybuf; &sub-querycap; @@ -567,7 +568,6 @@ and discussions on the V4L mailing list. &sub-query-dv-preset; &sub-query-dv-timings; &sub-querystd; - &sub-prepare-buf; &sub-reqbufs; &sub-s-hw-freq-seek; &sub-streamon; diff --git a/trunk/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml b/trunk/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml index 765549ff8a71..a2474ecb574a 100644 --- a/trunk/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml +++ b/trunk/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml @@ -108,10 +108,9 @@ information. /> - __u32 + struct v4l2_format format - Filled in by the application, preserved by the driver. - See . + Filled in by the application, preserved by the driver. __u32 diff --git a/trunk/Documentation/DocBook/media/v4l/vidioc-dqevent.xml b/trunk/Documentation/DocBook/media/v4l/vidioc-dqevent.xml index e8714aa16433..98a856f9ec30 100644 --- a/trunk/Documentation/DocBook/media/v4l/vidioc-dqevent.xml +++ b/trunk/Documentation/DocBook/media/v4l/vidioc-dqevent.xml @@ -89,7 +89,7 @@ &v4l2-event-frame-sync; - frame + frame_sync Event data for event V4L2_EVENT_FRAME_SYNC. diff --git a/trunk/Documentation/DocBook/mtdnand.tmpl b/trunk/Documentation/DocBook/mtdnand.tmpl index 0c674be0d3c6..e0aedb7a7827 100644 --- a/trunk/Documentation/DocBook/mtdnand.tmpl +++ b/trunk/Documentation/DocBook/mtdnand.tmpl @@ -1119,8 +1119,6 @@ in this page These constants are defined in nand.h. They are ored together to describe the chip functionality. -/* Chip can not auto increment pages */ -#define NAND_NO_AUTOINCR 0x00000001 /* Buswitdh is 16 bit */ #define NAND_BUSWIDTH_16 0x00000002 /* Device supports partial programming without padding */ diff --git a/trunk/Documentation/SubmittingPatches b/trunk/Documentation/SubmittingPatches index 4468ce24427c..c379a2a6949f 100644 --- a/trunk/Documentation/SubmittingPatches +++ b/trunk/Documentation/SubmittingPatches @@ -150,7 +150,8 @@ be able to justify all violations that remain in your patch. Look through the MAINTAINERS file and the source code, and determine if your change applies to a specific subsystem of the kernel, with -an assigned maintainer. If so, e-mail that person. +an assigned maintainer. If so, e-mail that person. The script +scripts/get_maintainer.pl can be very useful at this step. If no maintainer is listed, or the maintainer does not respond, send your patch to the primary Linux kernel developer's mailing list, diff --git a/trunk/Documentation/arm/OMAP/DSS b/trunk/Documentation/arm/OMAP/DSS index 888ae7b83ae4..a564ceea9e98 100644 --- a/trunk/Documentation/arm/OMAP/DSS +++ b/trunk/Documentation/arm/OMAP/DSS @@ -47,6 +47,51 @@ flexible way to enable non-common multi-display configuration. In addition to modelling the hardware overlays, omapdss supports virtual overlays and overlay managers. These can be used when updating a display with CPU or system DMA. +omapdss driver support for audio +-------------------------------- +There exist several display technologies and standards that support audio as +well. Hence, it is relevant to update the DSS device driver to provide an audio +interface that may be used by an audio driver or any other driver interested in +the functionality. + +The audio_enable function is intended to prepare the relevant +IP for playback (e.g., enabling an audio FIFO, taking in/out of reset +some IP, enabling companion chips, etc). It is intended to be called before +audio_start. The audio_disable function performs the reverse operation and is +intended to be called after audio_stop. + +While a given DSS device driver may support audio, it is possible that for +certain configurations audio is not supported (e.g., an HDMI display using a +VESA video timing). The audio_supported function is intended to query whether +the current configuration of the display supports audio. + +The audio_config function is intended to configure all the relevant audio +parameters of the display. In order to make the function independent of any +specific DSS device driver, a struct omap_dss_audio is defined. Its purpose +is to contain all the required parameters for audio configuration. At the +moment, such structure contains pointers to IEC-60958 channel status word +and CEA-861 audio infoframe structures. This should be enough to support +HDMI and DisplayPort, as both are based on CEA-861 and IEC-60958. + +The audio_enable/disable, audio_config and audio_supported functions could be +implemented as functions that may sleep. Hence, they should not be called +while holding a spinlock or a readlock. + +The audio_start/audio_stop function is intended to effectively start/stop audio +playback after the configuration has taken place. These functions are designed +to be used in an atomic context. Hence, audio_start should return quickly and be +called only after all the needed resources for audio playback (audio FIFOs, +DMA channels, companion chips, etc) have been enabled to begin data transfers. +audio_stop is designed to only stop the audio transfers. The resources used +for playback are released using audio_disable. + +The enum omap_dss_audio_state may be used to help the implementations of +the interface to keep track of the audio state. The initial state is _DISABLED; +then, the state transitions to _CONFIGURED, and then, when it is ready to +play audio, to _ENABLED. The state _PLAYING is used when the audio is being +rendered. + + Panel and controller drivers ---------------------------- @@ -156,6 +201,7 @@ timings Display timings (pixclock,xres/hfp/hbp/hsw,yres/vfp/vbp/vsw) "pal" and "ntsc" panel_name tear_elim Tearing elimination 0=off, 1=on +output_type Output type (video encoder only): "composite" or "svideo" There are also some debugfs files at /omapdss/ which show information about clocks and registers. diff --git a/trunk/Documentation/arm/SPEAr/overview.txt b/trunk/Documentation/arm/SPEAr/overview.txt index 28a9af953b9d..65610bf52ebf 100644 --- a/trunk/Documentation/arm/SPEAr/overview.txt +++ b/trunk/Documentation/arm/SPEAr/overview.txt @@ -8,9 +8,8 @@ Introduction weblink : http://www.st.com/spear The ST Microelectronics SPEAr range of ARM9/CortexA9 System-on-Chip CPUs are - supported by the 'spear' platform of ARM Linux. Currently SPEAr300, - SPEAr310, SPEAr320 and SPEAr600 SOCs are supported. Support for the SPEAr13XX - series is in progress. + supported by the 'spear' platform of ARM Linux. Currently SPEAr1310, + SPEAr1340, SPEAr300, SPEAr310, SPEAr320 and SPEAr600 SOCs are supported. Hierarchy in SPEAr is as follows: @@ -26,36 +25,39 @@ Introduction - SPEAr600 (SOC) - SPEAr600 Evaluation Board - SPEAr13XX (13XX SOC series, based on ARM CORTEXA9) - - SPEAr1300 (SOC) + - SPEAr1310 (SOC) + - SPEAr1310 Evaluation Board + - SPEAr1340 (SOC) + - SPEAr1340 Evaluation Board Configuration ------------- A generic configuration is provided for each machine, and can be used as the default by - make spear600_defconfig - make spear300_defconfig - make spear310_defconfig - make spear320_defconfig + make spear13xx_defconfig + make spear3xx_defconfig + make spear6xx_defconfig Layout ------ - The common files for multiple machine families (SPEAr3XX, SPEAr6XX and - SPEAr13XX) are located in the platform code contained in arch/arm/plat-spear + The common files for multiple machine families (SPEAr3xx, SPEAr6xx and + SPEAr13xx) are located in the platform code contained in arch/arm/plat-spear with headers in plat/. Each machine series have a directory with name arch/arm/mach-spear followed by series name. Like mach-spear3xx, mach-spear6xx and mach-spear13xx. - Common file for machines of spear3xx family is mach-spear3xx/spear3xx.c and for - spear6xx is mach-spear6xx/spear6xx.c. mach-spear* also contain soc/machine - specific files, like spear300.c, spear310.c, spear320.c and spear600.c. - mach-spear* doesn't contains board specific files as they fully support - Flattened Device Tree. + Common file for machines of spear3xx family is mach-spear3xx/spear3xx.c, for + spear6xx is mach-spear6xx/spear6xx.c and for spear13xx family is + mach-spear13xx/spear13xx.c. mach-spear* also contain soc/machine specific + files, like spear1310.c, spear1340.c spear300.c, spear310.c, spear320.c and + spear600.c. mach-spear* doesn't contains board specific files as they fully + support Flattened Device Tree. Document Author --------------- - Viresh Kumar , (c) 2010-2012 ST Microelectronics + Viresh Kumar , (c) 2010-2012 ST Microelectronics diff --git a/trunk/Documentation/cgroups/memory.txt b/trunk/Documentation/cgroups/memory.txt index 9b1067afb224..dd88540bb995 100644 --- a/trunk/Documentation/cgroups/memory.txt +++ b/trunk/Documentation/cgroups/memory.txt @@ -184,12 +184,14 @@ behind this approach is that a cgroup that aggressively uses a shared page will eventually get charged for it (once it is uncharged from the cgroup that brought it in -- this will happen on memory pressure). +But see section 8.2: when moving a task to another cgroup, its pages may +be recharged to the new cgroup, if move_charge_at_immigrate has been chosen. + Exception: If CONFIG_CGROUP_CGROUP_MEM_RES_CTLR_SWAP is not used. When you do swapoff and make swapped-out pages of shmem(tmpfs) to be backed into memory in force, charges for pages are accounted against the caller of swapoff rather than the users of shmem. - 2.4 Swap Extension (CONFIG_CGROUP_MEM_RES_CTLR_SWAP) Swap Extension allows you to record charge for swap. A swapped-in page is @@ -374,14 +376,15 @@ cgroup might have some charge associated with it, even though all tasks have migrated away from it. (because we charge against pages, not against tasks.) -Such charges are freed or moved to their parent. At moving, both of RSS -and CACHES are moved to parent. -rmdir() may return -EBUSY if freeing/moving fails. See 5.1 also. +We move the stats to root (if use_hierarchy==0) or parent (if +use_hierarchy==1), and no change on the charge except uncharging +from the child. Charges recorded in swap information is not updated at removal of cgroup. Recorded information is discarded and a cgroup which uses swap (swapcache) will be charged as a new owner of it. +About use_hierarchy, see Section 6. 5. Misc. interfaces. @@ -394,13 +397,15 @@ will be charged as a new owner of it. Almost all pages tracked by this memory cgroup will be unmapped and freed. Some pages cannot be freed because they are locked or in-use. Such pages are - moved to parent and this cgroup will be empty. This may return -EBUSY if - VM is too busy to free/move all pages immediately. + moved to parent(if use_hierarchy==1) or root (if use_hierarchy==0) and this + cgroup will be empty. Typical use case of this interface is that calling this before rmdir(). Because rmdir() moves all pages to parent, some out-of-use page caches can be moved to the parent. If you want to avoid that, force_empty will be useful. + About use_hierarchy, see Section 6. + 5.2 stat file memory.stat file includes following statistics @@ -430,17 +435,10 @@ hierarchical_memory_limit - # of bytes of memory limit with regard to hierarchy hierarchical_memsw_limit - # of bytes of memory+swap limit with regard to hierarchy under which memory cgroup is. -total_cache - sum of all children's "cache" -total_rss - sum of all children's "rss" -total_mapped_file - sum of all children's "cache" -total_pgpgin - sum of all children's "pgpgin" -total_pgpgout - sum of all children's "pgpgout" -total_swap - sum of all children's "swap" -total_inactive_anon - sum of all children's "inactive_anon" -total_active_anon - sum of all children's "active_anon" -total_inactive_file - sum of all children's "inactive_file" -total_active_file - sum of all children's "active_file" -total_unevictable - sum of all children's "unevictable" +total_ - # hierarchical version of , which in + addition to the cgroup's own value includes the + sum of all hierarchical children's values of + , i.e. total_cache # The following additional stats are dependent on CONFIG_DEBUG_VM. @@ -622,8 +620,7 @@ memory cgroup. bit | what type of charges would be moved ? -----+------------------------------------------------------------------------ 0 | A charge of an anonymous page(or swap of it) used by the target task. - | Those pages and swaps must be used only by the target task. You must - | enable Swap Extension(see 2.4) to enable move of swap charges. + | You must enable Swap Extension(see 2.4) to enable move of swap charges. -----+------------------------------------------------------------------------ 1 | A charge of file pages(normal file, tmpfs file(e.g. ipc shared memory) | and swaps of tmpfs file) mmapped by the target task. Unlike the case of @@ -636,8 +633,6 @@ memory cgroup. 8.3 TODO -- Implement madvise(2) to let users decide the vma to be moved or not to be - moved. - All of moving charge operations are done under cgroup_mutex. It's not good behavior to hold the mutex too long, so we may need some trick. diff --git a/trunk/Documentation/cgroups/resource_counter.txt b/trunk/Documentation/cgroups/resource_counter.txt index f3c4ec3626a2..0c4a344e78fa 100644 --- a/trunk/Documentation/cgroups/resource_counter.txt +++ b/trunk/Documentation/cgroups/resource_counter.txt @@ -92,6 +92,14 @@ to work with it. The _locked routines imply that the res_counter->lock is taken. + f. void res_counter_uncharge_until + (struct res_counter *rc, struct res_counter *top, + unsinged long val) + + Almost same as res_cunter_uncharge() but propagation of uncharge + stops when rc == top. This is useful when kill a res_coutner in + child cgroup. + 2.1 Other accounting routines There are more routines that may help you with common needs, like diff --git a/trunk/Documentation/cris/README b/trunk/Documentation/cris/README index d9b086869a60..8dbdb1a44429 100644 --- a/trunk/Documentation/cris/README +++ b/trunk/Documentation/cris/README @@ -1,38 +1,34 @@ -Linux 2.4 on the CRIS architecture -================================== -$Id: README,v 1.7 2001/04/19 12:38:32 bjornw Exp $ +Linux on the CRIS architecture +============================== -This is a port of Linux 2.4 to Axis Communications ETRAX 100LX embedded -network CPU. For more information about CRIS and ETRAX please see further -below. +This is a port of Linux to Axis Communications ETRAX 100LX, +ETRAX FS and ARTPEC-3 embedded network CPUs. + +For more information about CRIS and ETRAX please see further below. In order to compile this you need a version of gcc with support for the -ETRAX chip family. Please see this link for more information on how to +ETRAX chip family. Please see this link for more information on how to download the compiler and other tools useful when building and booting software for the ETRAX platform: -http://developer.axis.com/doc/software/devboard_lx/install-howto.html - - +http://developer.axis.com/wiki/doku.php?id=axis:install-howto-2_20 What is CRIS ? -------------- CRIS is an acronym for 'Code Reduced Instruction Set'. It is the CPU architecture in Axis Communication AB's range of embedded network CPU's, -called ETRAX. The latest CPU is called ETRAX 100LX, where LX stands for -'Linux' because the chip was designed to be a good host for the Linux -operating system. +called ETRAX. The ETRAX 100LX chip -------------------- -For reference, please see the press-release: +For reference, please see the following link: -http://www.axis.com/news/us/001101_etrax.htm +http://www.axis.com/products/dev_etrax_100lx/index.htm -The ETRAX 100LX is a 100 MIPS processor with 8kB cache, MMU, and a very broad -range of built-in interfaces, all with modern scatter/gather DMA. +The ETRAX 100LX is a 100 MIPS processor with 8kB cache, MMU, and a very broad +range of built-in interfaces, all with modern scatter/gather DMA. Memory interfaces: @@ -51,20 +47,28 @@ I/O interfaces: * SCSI * two parallel-ports * two generic 8-bit ports - - (not all interfaces are available at the same time due to chip pin + + (not all interfaces are available at the same time due to chip pin multiplexing) -The previous version of the ETRAX, the ETRAX 100, sits in almost all of -Axis shipping thin-servers like the Axis 2100 web camera or the ETRAX 100 -developer-board. It lacks an MMU so the Linux we run on that is a version -of uClinux (Linux 2.0 without MM-support) ported to the CRIS architecture. -The new Linux 2.4 port has full MM and needs a CPU with an MMU, so it will -not run on the ETRAX 100. +ETRAX 100LX is CRISv10 architecture. + + +The ETRAX FS and ARTPEC-3 chips +------------------------------- -A version of the Axis developer-board with ETRAX 100LX (running Linux -2.4) is now available. For more information please see developer.axis.com. +The ETRAX FS is a 200MHz 32-bit RISC processor with on-chip 16kB +I-cache and 16kB D-cache and with a wide range of device interfaces +including multiple high speed serial ports and an integrated USB 1.1 PHY. +The ARTPEC-3 is a variant of the ETRAX FS with additional IO-units +used by the Axis Communications network cameras. + +See below link for more information: + +http://www.axis.com/products/dev_etrax_fs/index.htm + +ETRAX FS and ARTPEC-3 are both CRISv32 architectures. Bootlog ------- @@ -182,10 +186,6 @@ SwapFree: 0 kB -rwxr-xr-x 1 342 100 16252 Jan 01 00:00 telnetd -(All programs are statically linked to the libc at this point - we have not ported the - shared libraries yet) - - diff --git a/trunk/Documentation/device-mapper/thin-provisioning.txt b/trunk/Documentation/device-mapper/thin-provisioning.txt index 3370bc4d7b98..f5cfc62b7ad3 100644 --- a/trunk/Documentation/device-mapper/thin-provisioning.txt +++ b/trunk/Documentation/device-mapper/thin-provisioning.txt @@ -287,6 +287,17 @@ iii) Messages the current transaction id is when you change it with this compare-and-swap message. + reserve_metadata_snap + + Reserve a copy of the data mapping btree for use by userland. + This allows userland to inspect the mappings as they were when + this message was executed. Use the pool's status command to + get the root block associated with the metadata snapshot. + + release_metadata_snap + + Release a previously reserved copy of the data mapping btree. + 'thin' target ------------- diff --git a/trunk/Documentation/devicetree/bindings/arm/fsl.txt b/trunk/Documentation/devicetree/bindings/arm/fsl.txt index bfbc771a65f8..ac9e7516756e 100644 --- a/trunk/Documentation/devicetree/bindings/arm/fsl.txt +++ b/trunk/Documentation/devicetree/bindings/arm/fsl.txt @@ -1,6 +1,14 @@ Freescale i.MX Platforms Device Tree Bindings ----------------------------------------------- +i.MX23 Evaluation Kit +Required root node properties: + - compatible = "fsl,imx23-evk", "fsl,imx23"; + +i.MX28 Evaluation Kit +Required root node properties: + - compatible = "fsl,imx28-evk", "fsl,imx28"; + i.MX51 Babbage Board Required root node properties: - compatible = "fsl,imx51-babbage", "fsl,imx51"; @@ -29,6 +37,10 @@ i.MX6 Quad SABRE Lite Board Required root node properties: - compatible = "fsl,imx6q-sabrelite", "fsl,imx6q"; +i.MX6 Quad SABRE Smart Device Board +Required root node properties: + - compatible = "fsl,imx6q-sabresd", "fsl,imx6q"; + Generic i.MX boards ------------------- diff --git a/trunk/Documentation/devicetree/bindings/arm/samsung/interrupt-combiner.txt b/trunk/Documentation/devicetree/bindings/arm/samsung/interrupt-combiner.txt new file mode 100644 index 000000000000..f2f2171e530e --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/arm/samsung/interrupt-combiner.txt @@ -0,0 +1,52 @@ +* Samsung Exynos Interrupt Combiner Controller + +Samsung's Exynos4 architecture includes a interrupt combiner controller which +can combine interrupt sources as a group and provide a single interrupt request +for the group. The interrupt request from each group are connected to a parent +interrupt controller, such as GIC in case of Exynos4210. + +The interrupt combiner controller consists of multiple combiners. Upto eight +interrupt sources can be connected to a combiner. The combiner outputs one +combined interrupt for its eight interrupt sources. The combined interrupt +is usually connected to a parent interrupt controller. + +A single node in the device tree is used to describe the interrupt combiner +controller module (which includes multiple combiners). A combiner in the +interrupt controller module shares config/control registers with other +combiners. For example, a 32-bit interrupt enable/disable config register +can accommodate upto 4 interrupt combiners (with each combiner supporting +upto 8 interrupt sources). + +Required properties: +- compatible: should be "samsung,exynos4210-combiner". +- interrupt-controller: Identifies the node as an interrupt controller. +- #interrupt-cells: should be <2>. The meaning of the cells are + * First Cell: Combiner Group Number. + * Second Cell: Interrupt number within the group. +- reg: Base address and size of interrupt combiner registers. +- interrupts: The list of interrupts generated by the combiners which are then + connected to a parent interrupt controller. The format of the interrupt + specifier depends in the interrupt parent controller. + +Optional properties: +- samsung,combiner-nr: The number of interrupt combiners supported. If this + property is not specified, the default number of combiners is assumed + to be 16. +- interrupt-parent: pHandle of the parent interrupt controller, if not + inherited from the parent node. + + +Example: + + The following is a an example from the Exynos4210 SoC dtsi file. + + combiner:interrupt-controller@10440000 { + compatible = "samsung,exynos4210-combiner"; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x10440000 0x1000>; + 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>; + }; diff --git a/trunk/Documentation/devicetree/bindings/arm/spear-timer.txt b/trunk/Documentation/devicetree/bindings/arm/spear-timer.txt new file mode 100644 index 000000000000..c0017221cf55 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/arm/spear-timer.txt @@ -0,0 +1,18 @@ +* SPEAr ARM Timer + +** Timer node required properties: + +- compatible : Should be: + "st,spear-timer" +- reg: Address range of the timer registers +- interrupt-parent: Should be the phandle for the interrupt controller + that services interrupts for this device +- interrupt: Should contain the timer interrupt number + +Example: + + timer@f0000000 { + compatible = "st,spear-timer"; + reg = <0xf0000000 0x400>; + interrupts = <2>; + }; diff --git a/trunk/Documentation/devicetree/bindings/arm/spear.txt b/trunk/Documentation/devicetree/bindings/arm/spear.txt index aa5f355cc947..0d42949df6c2 100644 --- a/trunk/Documentation/devicetree/bindings/arm/spear.txt +++ b/trunk/Documentation/devicetree/bindings/arm/spear.txt @@ -2,25 +2,25 @@ ST SPEAr Platforms Device Tree Bindings --------------------------------------- Boards with the ST SPEAr600 SoC shall have the following properties: - Required root node property: - compatible = "st,spear600"; Boards with the ST SPEAr300 SoC shall have the following properties: - Required root node property: - compatible = "st,spear300"; Boards with the ST SPEAr310 SoC shall have the following properties: - Required root node property: - compatible = "st,spear310"; Boards with the ST SPEAr320 SoC shall have the following properties: +Required root node property: +compatible = "st,spear320"; +Boards with the ST SPEAr1310 SoC shall have the following properties: Required root node property: +compatible = "st,spear1310"; -compatible = "st,spear320"; +Boards with the ST SPEAr1340 SoC shall have the following properties: +Required root node property: +compatible = "st,spear1340"; diff --git a/trunk/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-ahb.txt b/trunk/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-ahb.txt new file mode 100644 index 000000000000..234406d41c12 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-ahb.txt @@ -0,0 +1,11 @@ +NVIDIA Tegra AHB + +Required properties: +- compatible : "nvidia,tegra20-ahb" or "nvidia,tegra30-ahb" +- reg : Should contain 1 register ranges(address and length) + +Example: + ahb: ahb@6000c004 { + compatible = "nvidia,tegra20-ahb"; + reg = <0x6000c004 0x10c>; /* AHB Arbitration + Gizmo Controller */ + }; diff --git a/trunk/Documentation/devicetree/bindings/dma/fsl-mxs-dma.txt b/trunk/Documentation/devicetree/bindings/dma/fsl-mxs-dma.txt new file mode 100644 index 000000000000..ded0398d3bdc --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/dma/fsl-mxs-dma.txt @@ -0,0 +1,19 @@ +* Freescale MXS DMA + +Required properties: +- compatible : Should be "fsl,-dma-apbh" or "fsl,-dma-apbx" +- reg : Should contain registers location and length + +Supported chips: +imx23, imx28. + +Examples: +dma-apbh@80004000 { + compatible = "fsl,imx28-dma-apbh"; + reg = <0x80004000 2000>; +}; + +dma-apbx@80024000 { + compatible = "fsl,imx28-dma-apbx"; + reg = <0x80024000 2000>; +}; diff --git a/trunk/Documentation/devicetree/bindings/dma/snps-dma.txt b/trunk/Documentation/devicetree/bindings/dma/snps-dma.txt new file mode 100644 index 000000000000..c0d85dbcada5 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/dma/snps-dma.txt @@ -0,0 +1,17 @@ +* Synopsys Designware DMA Controller + +Required properties: +- compatible: "snps,dma-spear1340" +- reg: Address range of the DMAC registers +- interrupt-parent: Should be the phandle for the interrupt controller + that services interrupts for this device +- interrupt: Should contain the DMAC interrupt number + +Example: + + dma@fc000000 { + compatible = "snps,dma-spear1340"; + reg = <0xfc000000 0x1000>; + interrupt-parent = <&vic1>; + interrupts = <12>; + }; diff --git a/trunk/Documentation/devicetree/bindings/gpio/gpio-mm-lantiq.txt b/trunk/Documentation/devicetree/bindings/gpio/gpio-mm-lantiq.txt new file mode 100644 index 000000000000..f93d51478d5a --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/gpio/gpio-mm-lantiq.txt @@ -0,0 +1,38 @@ +Lantiq SoC External Bus memory mapped GPIO controller + +By attaching hardware latches to the EBU it is possible to create output +only gpios. This driver configures a special memory address, which when +written to outputs 16 bit to the latches. + +The node describing the memory mapped GPIOs needs to be a child of the node +describing the "lantiq,localbus". + +Required properties: +- compatible : Should be "lantiq,gpio-mm-lantiq" +- reg : Address and length of the register set for the device +- #gpio-cells : Should be two. The first cell is the pin number and + the second cell is used to specify optional parameters (currently + unused). +- gpio-controller : Marks the device node as a gpio controller. + +Optional properties: +- lantiq,shadow : The default value that we shall assume as already set on the + shift register cascade. + +Example: + +localbus@0 { + #address-cells = <2>; + #size-cells = <1>; + ranges = <0 0 0x0 0x3ffffff /* addrsel0 */ + 1 0 0x4000000 0x4000010>; /* addsel1 */ + compatible = "lantiq,localbus", "simple-bus"; + + gpio_mm0: gpio@4000000 { + compatible = "lantiq,gpio-mm"; + reg = <1 0x0 0x10>; + gpio-controller; + #gpio-cells = <2>; + lantiq,shadow = <0x77f> + }; +} diff --git a/trunk/Documentation/devicetree/bindings/gpio/gpio-mxs.txt b/trunk/Documentation/devicetree/bindings/gpio/gpio-mxs.txt new file mode 100644 index 000000000000..0c35673f7a3e --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/gpio/gpio-mxs.txt @@ -0,0 +1,87 @@ +* Freescale MXS GPIO controller + +The Freescale MXS GPIO controller is part of MXS PIN controller. The +GPIOs are organized in port/bank. Each port consists of 32 GPIOs. + +As the GPIO controller is embedded in the PIN controller and all the +GPIO ports share the same IO space with PIN controller, the GPIO node +will be represented as sub-nodes of MXS pinctrl node. + +Required properties for GPIO node: +- compatible : Should be "fsl,-gpio". The supported SoCs include + imx23 and imx28. +- interrupts : Should be the port interrupt shared by all 32 pins. +- 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 (currently + unused). +- interrupt-controller: Marks the device node as an interrupt controller. +- #interrupt-cells : Should be 2. The first cell is the GPIO number. + The second cell bits[3:0] is used to specify trigger type and level flags: + 1 = low-to-high edge triggered. + 2 = high-to-low edge triggered. + 4 = active high level-sensitive. + 8 = active low level-sensitive. + +Note: Each GPIO port should have an alias correctly numbered in "aliases" +node. + +Examples: + +aliases { + gpio0 = &gpio0; + gpio1 = &gpio1; + gpio2 = &gpio2; + gpio3 = &gpio3; + gpio4 = &gpio4; +}; + +pinctrl@80018000 { + compatible = "fsl,imx28-pinctrl", "simple-bus"; + reg = <0x80018000 2000>; + + gpio0: gpio@0 { + compatible = "fsl,imx28-gpio"; + interrupts = <127>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio1: gpio@1 { + compatible = "fsl,imx28-gpio"; + interrupts = <126>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio2: gpio@2 { + compatible = "fsl,imx28-gpio"; + interrupts = <125>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio3: gpio@3 { + compatible = "fsl,imx28-gpio"; + interrupts = <124>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio4: gpio@4 { + compatible = "fsl,imx28-gpio"; + interrupts = <123>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; +}; diff --git a/trunk/Documentation/devicetree/bindings/gpio/gpio-stp-xway.txt b/trunk/Documentation/devicetree/bindings/gpio/gpio-stp-xway.txt new file mode 100644 index 000000000000..854de130a971 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/gpio/gpio-stp-xway.txt @@ -0,0 +1,42 @@ +Lantiq SoC Serial To Parallel (STP) GPIO controller + +The Serial To Parallel (STP) is found on MIPS based Lantiq socs. It is a +peripheral controller used to drive external shift register cascades. At most +3 groups of 8 bits can be driven. The hardware is able to allow the DSL modem +to drive the 2 LSBs of the cascade automatically. + + +Required properties: +- compatible : Should be "lantiq,gpio-stp-xway" +- reg : Address and length of the register set for the device +- #gpio-cells : Should be two. The first cell is the pin number and + the second cell is used to specify optional parameters (currently + unused). +- gpio-controller : Marks the device node as a gpio controller. + +Optional properties: +- lantiq,shadow : The default value that we shall assume as already set on the + shift register cascade. +- lantiq,groups : Set the 3 bit mask to select which of the 3 groups are enabled + in the shift register cascade. +- lantiq,dsl : The dsl core can control the 2 LSBs of the gpio cascade. This 2 bit + property can enable this feature. +- lantiq,phy1 : The gphy1 core can control 3 bits of the gpio cascade. +- lantiq,phy2 : The gphy2 core can control 3 bits of the gpio cascade. +- lantiq,rising : use rising instead of falling edge for the shift register + +Example: + +gpio1: stp@E100BB0 { + compatible = "lantiq,gpio-stp-xway"; + reg = <0xE100BB0 0x40>; + #gpio-cells = <2>; + gpio-controller; + + lantiq,shadow = <0xffff>; + lantiq,groups = <0x7>; + lantiq,dsl = <0x3>; + lantiq,phy1 = <0x7>; + lantiq,phy2 = <0x7>; + /* lantiq,rising; */ +}; diff --git a/trunk/Documentation/devicetree/bindings/i2c/i2c-mux-pinctrl.txt b/trunk/Documentation/devicetree/bindings/i2c/i2c-mux-pinctrl.txt new file mode 100644 index 000000000000..ae8af1694e95 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/i2c/i2c-mux-pinctrl.txt @@ -0,0 +1,93 @@ +Pinctrl-based I2C Bus Mux + +This binding describes an I2C bus multiplexer that uses pin multiplexing to +route the I2C signals, and represents the pin multiplexing configuration +using the pinctrl device tree bindings. + + +-----+ +-----+ + | dev | | dev | + +------------------------+ +-----+ +-----+ + | SoC | | | + | /----|------+--------+ + | +---+ +------+ | child bus A, on first set of pins + | |I2C|---|Pinmux| | + | +---+ +------+ | child bus B, on second set of pins + | \----|------+--------+--------+ + | | | | | + +------------------------+ +-----+ +-----+ +-----+ + | dev | | dev | | dev | + +-----+ +-----+ +-----+ + +Required properties: +- compatible: i2c-mux-pinctrl +- i2c-parent: The phandle of the I2C bus that this multiplexer's master-side + port is connected to. + +Also required are: + +* Standard pinctrl properties that specify the pin mux state for each child + bus. See ../pinctrl/pinctrl-bindings.txt. + +* Standard I2C mux properties. See mux.txt in this directory. + +* I2C child bus nodes. See mux.txt in this directory. + +For each named state defined in the pinctrl-names property, an I2C child bus +will be created. I2C child bus numbers are assigned based on the index into +the pinctrl-names property. + +The only exception is that no bus will be created for a state named "idle". If +such a state is defined, it must be the last entry in pinctrl-names. For +example: + + pinctrl-names = "ddc", "pta", "idle" -> ddc = bus 0, pta = bus 1 + pinctrl-names = "ddc", "idle", "pta" -> Invalid ("idle" not last) + pinctrl-names = "idle", "ddc", "pta" -> Invalid ("idle" not last) + +Whenever an access is made to a device on a child bus, the relevant pinctrl +state will be programmed into hardware. + +If an idle state is defined, whenever an access is not being made to a device +on a child bus, the idle pinctrl state will be programmed into hardware. + +If an idle state is not defined, the most recently used pinctrl state will be +left programmed into hardware whenever no access is being made of a device on +a child bus. + +Example: + + i2cmux { + compatible = "i2c-mux-pinctrl"; + #address-cells = <1>; + #size-cells = <0>; + + i2c-parent = <&i2c1>; + + pinctrl-names = "ddc", "pta", "idle"; + pinctrl-0 = <&state_i2cmux_ddc>; + pinctrl-1 = <&state_i2cmux_pta>; + pinctrl-2 = <&state_i2cmux_idle>; + + i2c@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + eeprom { + compatible = "eeprom"; + reg = <0x50>; + }; + }; + + i2c@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + eeprom { + compatible = "eeprom"; + reg = <0x50>; + }; + }; + }; + diff --git a/trunk/Documentation/devicetree/bindings/i2c/i2c-mxs.txt b/trunk/Documentation/devicetree/bindings/i2c/i2c-mxs.txt new file mode 100644 index 000000000000..1bfc02de1b0c --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/i2c/i2c-mxs.txt @@ -0,0 +1,16 @@ +* Freescale MXS Inter IC (I2C) Controller + +Required properties: +- compatible: Should be "fsl,-i2c" +- reg: Should contain registers location and length +- interrupts: Should contain ERROR and DMA interrupts + +Examples: + +i2c0: i2c@80058000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx28-i2c"; + reg = <0x80058000 2000>; + interrupts = <111 68>; +}; diff --git a/trunk/Documentation/devicetree/bindings/i2c/mux.txt b/trunk/Documentation/devicetree/bindings/i2c/mux.txt new file mode 100644 index 000000000000..af84cce5cd7b --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/i2c/mux.txt @@ -0,0 +1,60 @@ +Common i2c bus multiplexer/switch properties. + +An i2c bus multiplexer/switch will have several child busses that are +numbered uniquely in a device dependent manner. The nodes for an i2c bus +multiplexer/switch will have one child node for each child +bus. + +Required properties: +- #address-cells = <1>; +- #size-cells = <0>; + +Required properties for child nodes: +- #address-cells = <1>; +- #size-cells = <0>; +- reg : The sub-bus number. + +Optional properties for child nodes: +- Other properties specific to the multiplexer/switch hardware. +- Child nodes conforming to i2c bus binding + + +Example : + + /* + An NXP pca9548 8 channel I2C multiplexer at address 0x70 + with two NXP pca8574 GPIO expanders attached, one each to + ports 3 and 4. + */ + + mux@70 { + compatible = "nxp,pca9548"; + reg = <0x70>; + #address-cells = <1>; + #size-cells = <0>; + + i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + + gpio1: gpio@38 { + compatible = "nxp,pca8574"; + reg = <0x38>; + #gpio-cells = <2>; + gpio-controller; + }; + }; + i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + + gpio2: gpio@38 { + compatible = "nxp,pca8574"; + reg = <0x38>; + #gpio-cells = <2>; + gpio-controller; + }; + }; + }; diff --git a/trunk/Documentation/devicetree/bindings/i2c/samsung-i2c.txt b/trunk/Documentation/devicetree/bindings/i2c/samsung-i2c.txt index 38832c712919..b6cb5a12c672 100644 --- a/trunk/Documentation/devicetree/bindings/i2c/samsung-i2c.txt +++ b/trunk/Documentation/devicetree/bindings/i2c/samsung-i2c.txt @@ -6,14 +6,18 @@ Required properties: - compatible: value should be either of the following. (a) "samsung, s3c2410-i2c", for i2c compatible with s3c2410 i2c. (b) "samsung, s3c2440-i2c", for i2c compatible with s3c2440 i2c. + (c) "samsung, s3c2440-hdmiphy-i2c", for s3c2440-like i2c used + inside HDMIPHY block found on several samsung SoCs - reg: physical base address of the controller and length of memory mapped region. - interrupts: interrupt number to the cpu. - samsung,i2c-sda-delay: Delay (in ns) applied to data line (SDA) edges. - - gpios: The order of the gpios should be the following: . - The gpio specifier depends on the gpio controller. Optional properties: + - gpios: The order of the gpios should be the following: . + The gpio specifier depends on the gpio controller. Required in all + cases except for "samsung,s3c2440-hdmiphy-i2c" whose input/output + lines are permanently wired to the respective client - samsung,i2c-slave-addr: Slave address in multi-master enviroment. If not specified, default value is 0. - samsung,i2c-max-bus-freq: Desired frequency in Hz of the bus. If not diff --git a/trunk/Documentation/devicetree/bindings/i2c/xiic.txt b/trunk/Documentation/devicetree/bindings/i2c/xiic.txt new file mode 100644 index 000000000000..ceabbe91ae44 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/i2c/xiic.txt @@ -0,0 +1,22 @@ +Xilinx IIC controller: + +Required properties: +- compatible : Must be "xlnx,xps-iic-2.00.a" +- reg : IIC register location and length +- interrupts : IIC controller unterrupt +- #address-cells = <1> +- #size-cells = <0> + +Optional properties: +- Child nodes conforming to i2c bus binding + +Example: + + axi_iic_0: i2c@40800000 { + compatible = "xlnx,xps-iic-2.00.a"; + interrupts = < 1 2 >; + reg = < 0x40800000 0x10000 >; + + #size-cells = <0>; + #address-cells = <1>; + }; diff --git a/trunk/Documentation/devicetree/bindings/iommu/nvidia,tegra20-gart.txt b/trunk/Documentation/devicetree/bindings/iommu/nvidia,tegra20-gart.txt new file mode 100644 index 000000000000..099d9362ebc1 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/iommu/nvidia,tegra20-gart.txt @@ -0,0 +1,14 @@ +NVIDIA Tegra 20 GART + +Required properties: +- compatible: "nvidia,tegra20-gart" +- reg: Two pairs of cells specifying the physical address and size of + the memory controller registers and the GART aperture respectively. + +Example: + + gart { + compatible = "nvidia,tegra20-gart"; + reg = <0x7000f024 0x00000018 /* controller registers */ + 0x58000000 0x02000000>; /* GART aperture */ + }; diff --git a/trunk/Documentation/devicetree/bindings/mfd/da9052-i2c.txt b/trunk/Documentation/devicetree/bindings/mfd/da9052-i2c.txt new file mode 100644 index 000000000000..1857f4a6b9a9 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/mfd/da9052-i2c.txt @@ -0,0 +1,60 @@ +* Dialog DA9052/53 Power Management Integrated Circuit (PMIC) + +Required properties: +- compatible : Should be "dlg,da9052", "dlg,da9053-aa", + "dlg,da9053-ab", or "dlg,da9053-bb" + +Sub-nodes: +- regulators : Contain the regulator nodes. The DA9052/53 regulators are + bound using their names as listed below: + + buck0 : regulator BUCK0 + buck1 : regulator BUCK1 + buck2 : regulator BUCK2 + buck3 : regulator BUCK3 + ldo4 : regulator LDO4 + ldo5 : regulator LDO5 + ldo6 : regulator LDO6 + ldo7 : regulator LDO7 + ldo8 : regulator LDO8 + ldo9 : regulator LDO9 + ldo10 : regulator LDO10 + ldo11 : regulator LDO11 + ldo12 : regulator LDO12 + ldo13 : regulator LDO13 + + The bindings details of individual regulator device can be found in: + Documentation/devicetree/bindings/regulator/regulator.txt + +Examples: + +i2c@63fc8000 { /* I2C1 */ + status = "okay"; + + pmic: dialog@48 { + compatible = "dlg,da9053-aa"; + reg = <0x48>; + + regulators { + buck0 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <2075000>; + }; + + buck1 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <2075000>; + }; + + buck2 { + regulator-min-microvolt = <925000>; + regulator-max-microvolt = <2500000>; + }; + + buck3 { + regulator-min-microvolt = <925000>; + regulator-max-microvolt = <2500000>; + }; + }; + }; +}; diff --git a/trunk/Documentation/devicetree/bindings/mfd/tps65910.txt b/trunk/Documentation/devicetree/bindings/mfd/tps65910.txt new file mode 100644 index 000000000000..645f5eaadb3f --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/mfd/tps65910.txt @@ -0,0 +1,133 @@ +TPS65910 Power Management Integrated Circuit + +Required properties: +- compatible: "ti,tps65910" or "ti,tps65911" +- reg: I2C slave address +- interrupts: the interrupt outputs of the controller +- #gpio-cells: number of cells to describe a GPIO, this should be 2. + The first cell is the GPIO number. + The second cell is used to specify additional options . +- gpio-controller: mark the device as a GPIO 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 +- regulators: This is the list of child nodes that specify the regulator + initialization data for defined regulators. Not all regulators for the given + device need to be present. The definition for each of these nodes is defined + using the standard binding for regulators found at + Documentation/devicetree/bindings/regulator/regulator.txt. + + The valid names for regulators are: + tps65910: vrtc, vio, vdd1, vdd2, vdd3, vdig1, vdig2, vpll, vdac, vaux1, + vaux2, vaux33, vmmc + tps65911: vrtc, vio, vdd1, vdd3, vddctrl, ldo1, ldo2, ldo3, ldo4, ldo5, + ldo6, ldo7, ldo8 + +Optional properties: +- ti,vmbch-threshold: (tps65911) main battery charged threshold + comparator. (see VMBCH_VSEL in TPS65910 datasheet) +- ti,vmbch2-threshold: (tps65911) main battery discharged threshold + comparator. (see VMBCH_VSEL in TPS65910 datasheet) +- ti,en-gpio-sleep: enable sleep control for gpios + There should be 9 entries here, one for each gpio. + +Regulator Optional properties: +- ti,regulator-ext-sleep-control: enable external sleep + control through external inputs [0 (not enabled), 1 (EN1), 2 (EN2) or 4(EN3)] + If this property is not defined, it defaults to 0 (not enabled). + +Example: + + pmu: tps65910@d2 { + compatible = "ti,tps65910"; + reg = <0xd2>; + interrupt-parent = <&intc>; + interrupts = < 0 118 0x04 >; + + #gpio-cells = <2>; + gpio-controller; + + #interrupt-cells = <2>; + interrupt-controller; + + ti,vmbch-threshold = 0; + ti,vmbch2-threshold = 0; + + ti,en-gpio-sleep = <0 0 1 0 0 0 0 0 0>; + + regulators { + vdd1_reg: vdd1 { + regulator-min-microvolt = < 600000>; + regulator-max-microvolt = <1500000>; + regulator-always-on; + regulator-boot-on; + ti,regulator-ext-sleep-control = <0>; + }; + vdd2_reg: vdd2 { + regulator-min-microvolt = < 600000>; + regulator-max-microvolt = <1500000>; + regulator-always-on; + regulator-boot-on; + ti,regulator-ext-sleep-control = <4>; + }; + vddctrl_reg: vddctrl { + regulator-min-microvolt = < 600000>; + regulator-max-microvolt = <1400000>; + regulator-always-on; + regulator-boot-on; + ti,regulator-ext-sleep-control = <0>; + }; + vio_reg: vio { + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + ti,regulator-ext-sleep-control = <1>; + }; + ldo1_reg: ldo1 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <3300000>; + ti,regulator-ext-sleep-control = <0>; + }; + ldo2_reg: ldo2 { + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1050000>; + ti,regulator-ext-sleep-control = <0>; + }; + ldo3_reg: ldo3 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <3300000>; + ti,regulator-ext-sleep-control = <0>; + }; + ldo4_reg: ldo4 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + ti,regulator-ext-sleep-control = <0>; + }; + ldo5_reg: ldo5 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <3300000>; + ti,regulator-ext-sleep-control = <0>; + }; + ldo6_reg: ldo6 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + ti,regulator-ext-sleep-control = <0>; + }; + ldo7_reg: ldo7 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + regulator-boot-on; + ti,regulator-ext-sleep-control = <1>; + }; + ldo8_reg: ldo8 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + ti,regulator-ext-sleep-control = <1>; + }; + }; + }; diff --git a/trunk/Documentation/devicetree/bindings/mfd/twl6040.txt b/trunk/Documentation/devicetree/bindings/mfd/twl6040.txt new file mode 100644 index 000000000000..bc67c6f424aa --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/mfd/twl6040.txt @@ -0,0 +1,62 @@ +Texas Instruments TWL6040 family + +The TWL6040s are 8-channel high quality low-power audio codecs providing audio +and vibra functionality on OMAP4+ platforms. +They are connected ot the host processor via i2c for commands, McPDM for audio +data and commands. + +Required properties: +- compatible : Must be "ti,twl6040"; +- reg: must be 0x4b for i2c address +- interrupts: twl6040 has one interrupt line connecteded to the main SoC +- interrupt-parent: The parent interrupt controller +- twl6040,audpwron-gpio: Power on GPIO line for the twl6040 + +- vio-supply: Regulator for the twl6040 VIO supply +- v2v1-supply: Regulator for the twl6040 V2V1 supply + +Optional properties, nodes: +- enable-active-high: To power on the twl6040 during boot. + +Vibra functionality +Required properties: +- vddvibl-supply: Regulator for the left vibra motor +- vddvibr-supply: Regulator for the right vibra motor +- vibra { }: Configuration section for vibra parameters containing the following + properties: +- ti,vibldrv-res: Resistance parameter for left driver +- ti,vibrdrv-res: Resistance parameter for right driver +- ti,viblmotor-res: Resistance parameter for left motor +- ti,viblmotor-res: Resistance parameter for right motor + +Optional properties within vibra { } section: +- vddvibl_uV: If the vddvibl default voltage need to be changed +- vddvibr_uV: If the vddvibr default voltage need to be changed + +Example: +&i2c1 { + twl6040: twl@4b { + compatible = "ti,twl6040"; + reg = <0x4b>; + + interrupts = <0 119 4>; + interrupt-parent = <&gic>; + twl6040,audpwron-gpio = <&gpio4 31 0>; + + vio-supply = <&v1v8>; + v2v1-supply = <&v2v1>; + enable-active-high; + + /* regulators for vibra motor */ + vddvibl-supply = <&vbat>; + vddvibr-supply = <&vbat>; + + vibra { + /* Vibra driver, motor resistance parameters */ + ti,vibldrv-res = <8>; + ti,vibrdrv-res = <3>; + ti,viblmotor-res = <10>; + ti,vibrmotor-res = <10>; + }; + }; +}; diff --git a/trunk/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt b/trunk/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt index 64bcb8be973c..0d93b4b0e0e3 100644 --- a/trunk/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt +++ b/trunk/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt @@ -11,9 +11,11 @@ Required properties: - interrupt-parent : interrupt source phandle. - clock-frequency : specifies eSDHC base clock frequency. - sdhci,wp-inverted : (optional) specifies that eSDHC controller - reports inverted write-protect state; + reports inverted write-protect state; New devices should use + the generic "wp-inverted" property. - sdhci,1-bit-only : (optional) specifies that a controller can - only handle 1-bit data transfers. + only handle 1-bit data transfers. New devices should use the + generic "bus-width = <1>" property. - sdhci,auto-cmd12: (optional) specifies that a controller can only handle auto CMD12. diff --git a/trunk/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt b/trunk/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt index ab22fe6e73ab..c7e404b3ef05 100644 --- a/trunk/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt +++ b/trunk/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt @@ -9,7 +9,7 @@ Required properties: - interrupts : Should contain eSDHC interrupt Optional properties: -- fsl,card-wired : Indicate the card is wired to host permanently +- non-removable : Indicate the card is wired to host permanently - fsl,cd-internal : Indicate to use controller internal card detection - fsl,wp-internal : Indicate to use controller internal write protection - cd-gpios : Specify GPIOs for card detection diff --git a/trunk/Documentation/devicetree/bindings/mmc/mmc-spi-slot.txt b/trunk/Documentation/devicetree/bindings/mmc/mmc-spi-slot.txt index 89a0084df2f7..d64aea5a4203 100644 --- a/trunk/Documentation/devicetree/bindings/mmc/mmc-spi-slot.txt +++ b/trunk/Documentation/devicetree/bindings/mmc/mmc-spi-slot.txt @@ -10,7 +10,8 @@ Required properties: Optional properties: - gpios : may specify GPIOs in this order: Card-Detect GPIO, - Write-Protect GPIO. + Write-Protect GPIO. Note that this does not follow the + binding from mmc.txt, for historic reasons. - interrupts : the interrupt of a card detect interrupt. - interrupt-parent : the phandle for the interrupt controller that services interrupts for this device. diff --git a/trunk/Documentation/devicetree/bindings/mmc/mmc.txt b/trunk/Documentation/devicetree/bindings/mmc/mmc.txt new file mode 100644 index 000000000000..6e70dcde0a71 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/mmc/mmc.txt @@ -0,0 +1,27 @@ +These properties are common to multiple MMC host controllers. Any host +that requires the respective functionality should implement them using +these definitions. + +Required properties: +- bus-width: Number of data lines, can be <1>, <4>, or <8> + +Optional properties: +- cd-gpios : Specify GPIOs for card detection, see gpio binding +- wp-gpios : Specify GPIOs for write protection, see gpio binding +- cd-inverted: when present, polarity on the wp gpio line is inverted +- wp-inverted: when present, polarity on the wp gpio line is inverted +- non-removable: non-removable slot (like eMMC) +- max-frequency: maximum operating clock frequency + +Example: + +sdhci@ab000000 { + compatible = "sdhci"; + reg = <0xab000000 0x200>; + interrupts = <23>; + bus-width = <4>; + cd-gpios = <&gpio 69 0>; + cd-inverted; + wp-gpios = <&gpio 70 0>; + max-frequency = <50000000>; +} diff --git a/trunk/Documentation/devicetree/bindings/mmc/mmci.txt b/trunk/Documentation/devicetree/bindings/mmc/mmci.txt new file mode 100644 index 000000000000..14a81d526118 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/mmc/mmci.txt @@ -0,0 +1,19 @@ +* ARM PrimeCell MultiMedia Card Interface (MMCI) PL180/1 + +The ARM PrimeCell MMCI PL180 and PL181 provides and interface for +reading and writing to MultiMedia and SD cards alike. + +Required properties: +- compatible : contains "arm,pl18x", "arm,primecell". +- reg : contains pl18x registers and length. +- interrupts : contains the device IRQ(s). +- arm,primecell-periphid : contains the PrimeCell Peripheral ID. + +Optional properties: +- wp-gpios : contains any write protect (ro) gpios +- cd-gpios : contains any card detection gpios +- cd-inverted : indicates whether the cd gpio is inverted +- max-frequency : contains the maximum operating frequency +- bus-width : number of data lines, can be <1>, <4>, or <8> +- mmc-cap-mmc-highspeed : indicates whether MMC is high speed capable +- mmc-cap-sd-highspeed : indicates whether SD is high speed capable diff --git a/trunk/Documentation/devicetree/bindings/mmc/mxs-mmc.txt b/trunk/Documentation/devicetree/bindings/mmc/mxs-mmc.txt new file mode 100644 index 000000000000..14d870a9e3db --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/mmc/mxs-mmc.txt @@ -0,0 +1,25 @@ +* Freescale MXS MMC controller + +The Freescale MXS Synchronous Serial Ports (SSP) can act as a MMC controller +to support MMC, SD, and SDIO types of memory cards. + +Required properties: +- compatible: Should be "fsl,-mmc". The supported chips include + imx23 and imx28. +- reg: Should contain registers location and length +- interrupts: Should contain ERROR and DMA interrupts +- fsl,ssp-dma-channel: APBH DMA channel for the SSP +- bus-width: Number of data lines, can be <1>, <4>, or <8> + +Optional properties: +- wp-gpios: Specify GPIOs for write protection + +Examples: + +ssp0: ssp@80010000 { + compatible = "fsl,imx28-mmc"; + reg = <0x80010000 2000>; + interrupts = <96 82>; + fsl,ssp-dma-channel = <0>; + bus-width = <8>; +}; diff --git a/trunk/Documentation/devicetree/bindings/mmc/nvidia-sdhci.txt b/trunk/Documentation/devicetree/bindings/mmc/nvidia-sdhci.txt index 7e51154679a6..f77c3031607f 100644 --- a/trunk/Documentation/devicetree/bindings/mmc/nvidia-sdhci.txt +++ b/trunk/Documentation/devicetree/bindings/mmc/nvidia-sdhci.txt @@ -7,12 +7,12 @@ Required properties: - compatible : Should be "nvidia,-sdhci" - reg : Should contain SD/MMC registers location and length - interrupts : Should contain SD/MMC interrupt +- bus-width : Number of data lines, can be <1>, <4>, or <8> Optional properties: - cd-gpios : Specify GPIOs for card detection - wp-gpios : Specify GPIOs for write protection - power-gpios : Specify GPIOs for power control -- support-8bit : Boolean, indicates if 8-bit mode should be used. Example: @@ -23,5 +23,5 @@ sdhci@c8000200 { cd-gpios = <&gpio 69 0>; /* gpio PI5 */ wp-gpios = <&gpio 57 0>; /* gpio PH1 */ power-gpios = <&gpio 155 0>; /* gpio PT3 */ - support-8bit; + bus-width = <8>; }; diff --git a/trunk/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt b/trunk/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt index dbd4368ab8cc..8a53958c9a9f 100644 --- a/trunk/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt +++ b/trunk/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt @@ -15,7 +15,7 @@ Optional properties: ti,dual-volt: boolean, supports dual voltage cards -supply: phandle to the regulator device tree node "supply-name" examples are "vmmc", "vmmc_aux" etc -ti,bus-width: Number of data lines, default assumed is 1 if the property is missing. +bus-width: Number of data lines, default assumed is 1 if the property is missing. cd-gpios: GPIOs for card detection wp-gpios: GPIOs for write protection ti,non-removable: non-removable slot (like eMMC) @@ -27,7 +27,7 @@ Example: reg = <0x4809c000 0x400>; ti,hwmods = "mmc1"; ti,dual-volt; - ti,bus-width = <4>; + bus-width = <4>; vmmc-supply = <&vmmc>; /* phandle to regulator node */ ti,non-removable; }; diff --git a/trunk/Documentation/devicetree/bindings/mtd/gpmi-nand.txt b/trunk/Documentation/devicetree/bindings/mtd/gpmi-nand.txt new file mode 100644 index 000000000000..1a5bbd346d22 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/mtd/gpmi-nand.txt @@ -0,0 +1,33 @@ +* Freescale General-Purpose Media Interface (GPMI) + +The GPMI nand controller provides an interface to control the +NAND flash chips. We support only one NAND chip now. + +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. + +The device tree may optionally contain sub-nodes describing partitions of the +address space. See partition.txt for more detail. + +Examples: + +gpmi-nand@8000c000 { + compatible = "fsl,imx28-gpmi-nand"; + #address-cells = <1>; + #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>; + + partition@0 { + ... + }; +}; diff --git a/trunk/Documentation/devicetree/bindings/mtd/mxc-nand.txt b/trunk/Documentation/devicetree/bindings/mtd/mxc-nand.txt new file mode 100644 index 000000000000..b5833d11c7be --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/mtd/mxc-nand.txt @@ -0,0 +1,19 @@ +* Freescale's mxc_nand + +Required properties: +- compatible: "fsl,imxXX-nand" +- reg: address range of the nfc block +- interrupts: irq to be used +- nand-bus-width: see nand.txt +- nand-ecc-mode: see nand.txt +- nand-on-flash-bbt: see nand.txt + +Example: + + nand@d8000000 { + compatible = "fsl,imx27-nand"; + reg = <0xd8000000 0x1000>; + interrupts = <29>; + nand-bus-width = <8>; + nand-ecc-mode = "hw"; + }; diff --git a/trunk/Documentation/devicetree/bindings/net/fsl-fec.txt b/trunk/Documentation/devicetree/bindings/net/fsl-fec.txt index de439517dff0..7ab9e1a2d8be 100644 --- a/trunk/Documentation/devicetree/bindings/net/fsl-fec.txt +++ b/trunk/Documentation/devicetree/bindings/net/fsl-fec.txt @@ -14,7 +14,7 @@ Optional properties: Example: -fec@83fec000 { +ethernet@83fec000 { compatible = "fsl,imx51-fec", "fsl,imx27-fec"; reg = <0x83fec000 0x4000>; interrupts = <87>; diff --git a/trunk/Documentation/devicetree/bindings/pinctrl/pinctrl_spear.txt b/trunk/Documentation/devicetree/bindings/pinctrl/pinctrl_spear.txt index 3664d37e6799..b4480d5c3aca 100644 --- a/trunk/Documentation/devicetree/bindings/pinctrl/pinctrl_spear.txt +++ b/trunk/Documentation/devicetree/bindings/pinctrl/pinctrl_spear.txt @@ -4,6 +4,8 @@ Required properties: - compatible : "st,spear300-pinmux" : "st,spear310-pinmux" : "st,spear320-pinmux" + : "st,spear1310-pinmux" + : "st,spear1340-pinmux" - reg : Address range of the pinctrl registers - st,pinmux-mode: Mandatory for SPEAr300 and SPEAr320 and invalid for others. - Its values for SPEAr300: @@ -89,6 +91,37 @@ For SPEAr320 machines: "rmii0_1_grp", "i2c1_8_9_grp", "i2c1_98_99_grp", "i2c2_0_1_grp", "i2c2_2_3_grp", "i2c2_19_20_grp", "i2c2_75_76_grp", "i2c2_96_97_grp" +For SPEAr1310 machines: + "i2c0_grp", "ssp0_grp", "ssp0_cs0_grp", "ssp0_cs1_2_grp", "i2s0_grp", + "i2s1_grp", "clcd_grp", "clcd_high_res_grp", "arm_gpio_grp", + "smi_2_chips_grp", "smi_4_chips_grp", "gmii_grp", "rgmii_grp", + "smii_0_1_2_grp", "ras_mii_txclk_grp", "nand_8bit_grp", + "nand_16bit_grp", "nand_4_chips_grp", "keyboard_6x6_grp", + "keyboard_rowcol6_8_grp", "uart0_grp", "uart0_modem_grp", + "gpt0_tmr0_grp", "gpt0_tmr1_grp", "gpt1_tmr0_grp", "gpt1_tmr1_grp", + "sdhci_grp", "cf_grp", "xd_grp", "touch_xy_grp", + "uart1_disable_i2c_grp", "uart1_disable_sd_grp", "uart2_3_grp", + "uart4_grp", "uart5_grp", "rs485_0_1_tdm_0_1_grp", "i2c_1_2_grp", + "i2c3_dis_smi_clcd_grp", "i2c3_dis_sd_i2s0_grp", "i2c_4_5_dis_smi_grp", + "i2c4_dis_sd_grp", "i2c5_dis_sd_grp", "i2c_6_7_dis_kbd_grp", + "i2c6_dis_sd_grp", "i2c7_dis_sd_grp", "can0_dis_nor_grp", + "can0_dis_sd_grp", "can1_dis_sd_grp", "can1_dis_kbd_grp", "pcie0_grp", + "pcie1_grp", "pcie2_grp", "sata0_grp", "sata1_grp", "sata2_grp", + "ssp1_dis_kbd_grp", "ssp1_dis_sd_grp", "gpt64_grp" + +For SPEAr1340 machines: + "pads_as_gpio_grp", "fsmc_8bit_grp", "fsmc_16bit_grp", "fsmc_pnor_grp", + "keyboard_row_col_grp", "keyboard_col5_grp", "spdif_in_grp", + "spdif_out_grp", "gpt_0_1_grp", "pwm0_grp", "pwm1_grp", "pwm2_grp", + "pwm3_grp", "vip_mux_grp", "vip_mux_cam0_grp", "vip_mux_cam1_grp", + "vip_mux_cam2_grp", "vip_mux_cam3_grp", "cam0_grp", "cam1_grp", + "cam2_grp", "cam3_grp", "smi_grp", "ssp0_grp", "ssp0_cs1_grp", + "ssp0_cs2_grp", "ssp0_cs3_grp", "uart0_grp", "uart0_enh_grp", + "uart1_grp", "i2s_in_grp", "i2s_out_grp", "gmii_grp", "rgmii_grp", + "rmii_grp", "sgmii_grp", "i2c0_grp", "i2c1_grp", "cec0_grp", "cec1_grp", + "sdhci_grp", "cf_grp", "xd_grp", "clcd_grp", "arm_trace_grp", + "miphy_dbg_grp", "pcie_grp", "sata_grp" + Valid values for function names are: For All SPEAr3xx machines: "firda", "i2c0", "ssp_cs", "ssp0", "mii0", "gpio0", "uart0_ext", @@ -106,3 +139,17 @@ For SPEAr320 machines: "uart2", "uart3", "uart4", "uart5", "uart6", "rs485", "touchscreen", "can0", "can1", "pwm0_1", "pwm2", "pwm3", "ssp1", "ssp2", "mii2", "mii0_1", "i2c1", "i2c2" + + +For SPEAr1310 machines: + "i2c0", "ssp0", "i2s0", "i2s1", "clcd", "arm_gpio", "smi", "gmii", + "rgmii", "smii_0_1_2", "ras_mii_txclk", "nand", "keyboard", "uart0", + "gpt0", "gpt1", "sdhci", "cf", "xd", "touchscreen", "uart1", "uart2_3", + "uart4", "uart5", "rs485_0_1_tdm_0_1", "i2c_1_2", "i2c3_i2s1", + "i2c_4_5", "i2c_6_7", "can0", "can1", "pci", "sata", "ssp1", "gpt64" + +For SPEAr1340 machines: + "pads_as_gpio", "fsmc", "keyboard", "spdif_in", "spdif_out", "gpt_0_1", + "pwm", "vip", "cam0", "cam1", "cam2", "cam3", "smi", "ssp0", "uart0", + "uart1", "i2s", "gmac", "i2c0", "i2c1", "cec0", "cec1", "sdhci", "cf", + "xd", "clcd", "arm_trace", "miphy_dbg", "pcie", "sata" diff --git a/trunk/Documentation/devicetree/bindings/rtc/lpc32xx-rtc.txt b/trunk/Documentation/devicetree/bindings/rtc/lpc32xx-rtc.txt new file mode 100644 index 000000000000..a87a1e9bc060 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/rtc/lpc32xx-rtc.txt @@ -0,0 +1,15 @@ +* NXP LPC32xx SoC Real Time Clock controller + +Required properties: +- compatible: must be "nxp,lpc3220-rtc" +- reg: physical base address of the controller and length of memory mapped + region. +- interrupts: The RTC interrupt + +Example: + + rtc@40024000 { + compatible = "nxp,lpc3220-rtc"; + reg = <0x40024000 0x1000>; + interrupts = <52 0>; + }; diff --git a/trunk/Documentation/devicetree/bindings/rtc/spear-rtc.txt b/trunk/Documentation/devicetree/bindings/rtc/spear-rtc.txt new file mode 100644 index 000000000000..ca67ac62108e --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/rtc/spear-rtc.txt @@ -0,0 +1,17 @@ +* SPEAr RTC + +Required properties: +- compatible : "st,spear600-rtc" +- reg : Address range of the rtc registers +- interrupt-parent: Should be the phandle for the interrupt controller + that services interrupts for this device +- interrupt: Should contain the rtc interrupt number + +Example: + + rtc@fc000000 { + compatible = "st,spear600-rtc"; + reg = <0xfc000000 0x1000>; + interrupt-parent = <&vic1>; + interrupts = <12>; + }; diff --git a/trunk/Documentation/devicetree/bindings/sound/omap-dmic.txt b/trunk/Documentation/devicetree/bindings/sound/omap-dmic.txt new file mode 100644 index 000000000000..fd8105f18978 --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/sound/omap-dmic.txt @@ -0,0 +1,21 @@ +* Texas Instruments OMAP4+ Digital Microphone Module + +Required properties: +- compatible: "ti,omap4-dmic" +- reg: Register location and size as an array: + , + ; +- interrupts: Interrupt number for DMIC +- interrupt-parent: The parent interrupt controller +- ti,hwmods: Name of the hwmod associated with OMAP dmic IP + +Example: + +dmic: dmic@4012e000 { + compatible = "ti,omap4-dmic"; + reg = <0x4012e000 0x7f>, /* MPU private access */ + <0x4902e000 0x7f>; /* L3 Interconnect */ + interrupts = <0 114 0x4>; + interrupt-parent = <&gic>; + ti,hwmods = "dmic"; +}; diff --git a/trunk/Documentation/devicetree/bindings/sound/omap-mcpdm.txt b/trunk/Documentation/devicetree/bindings/sound/omap-mcpdm.txt new file mode 100644 index 000000000000..0741dff048dd --- /dev/null +++ b/trunk/Documentation/devicetree/bindings/sound/omap-mcpdm.txt @@ -0,0 +1,21 @@ +* Texas Instruments OMAP4+ McPDM + +Required properties: +- compatible: "ti,omap4-mcpdm" +- reg: Register location and size as an array: + , + ; +- interrupts: Interrupt number for McPDM +- interrupt-parent: The parent interrupt controller +- ti,hwmods: Name of the hwmod associated to the McPDM + +Example: + +mcpdm: mcpdm@40132000 { + compatible = "ti,omap4-mcpdm"; + reg = <0x40132000 0x7f>, /* MPU private access */ + <0x49032000 0x7f>; /* L3 Interconnect */ + interrupts = <0 112 0x4>; + interrupt-parent = <&gic>; + ti,hwmods = "mcpdm"; +}; diff --git a/trunk/Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt b/trunk/Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt index a9c0406280e8..b462d0c54823 100644 --- a/trunk/Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt +++ b/trunk/Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt @@ -11,7 +11,7 @@ Optional properties: Example: -uart@73fbc000 { +serial@73fbc000 { compatible = "fsl,imx51-uart", "fsl,imx21-uart"; reg = <0x73fbc000 0x4000>; interrupts = <31>; diff --git a/trunk/Documentation/devicetree/bindings/usb/tegra-usb.txt b/trunk/Documentation/devicetree/bindings/usb/tegra-usb.txt index 007005ddbe12..e9b005dc7625 100644 --- a/trunk/Documentation/devicetree/bindings/usb/tegra-usb.txt +++ b/trunk/Documentation/devicetree/bindings/usb/tegra-usb.txt @@ -12,6 +12,9 @@ Required properties : - nvidia,vbus-gpio : If present, specifies a gpio that needs to be activated for the bus to be powered. +Required properties for phy_type == ulpi: + - nvidia,phy-reset-gpio : The GPIO used to reset the PHY. + Optional properties: - dr_mode : dual role mode. Indicates the working mode for nvidia,tegra20-ehci compatible controllers. Can be "host", "peripheral", diff --git a/trunk/Documentation/dma-buf-sharing.txt b/trunk/Documentation/dma-buf-sharing.txt index 3bbd5c51605a..ad86fb86c9a0 100644 --- a/trunk/Documentation/dma-buf-sharing.txt +++ b/trunk/Documentation/dma-buf-sharing.txt @@ -29,13 +29,6 @@ The buffer-user in memory, mapped into its own address space, so it can access the same area of memory. -*IMPORTANT*: [see https://lkml.org/lkml/2011/12/20/211 for more details] -For this first version, A buffer shared using the dma_buf sharing API: -- *may* be exported to user space using "mmap" *ONLY* by exporter, outside of - this framework. -- with this new iteration of the dma-buf api cpu access from the kernel has been - enable, see below for the details. - dma-buf operations for device dma only -------------------------------------- @@ -300,6 +293,17 @@ Access to a dma_buf from the kernel context involves three steps: Note that these calls need to always succeed. The exporter needs to complete any preparations that might fail in begin_cpu_access. + For some cases the overhead of kmap can be too high, a vmap interface + is introduced. This interface should be used very carefully, as vmalloc + space is a limited resources on many architectures. + + Interfaces: + void *dma_buf_vmap(struct dma_buf *dmabuf) + void dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr) + + The vmap call can fail if there is no vmap support in the exporter, or if it + runs out of vmalloc space. Fallback to kmap should be implemented. + 3. Finish access When the importer is done accessing the range specified in begin_cpu_access, @@ -313,6 +317,83 @@ Access to a dma_buf from the kernel context involves three steps: enum dma_data_direction dir); +Direct Userspace Access/mmap Support +------------------------------------ + +Being able to mmap an export dma-buf buffer object has 2 main use-cases: +- CPU fallback processing in a pipeline and +- supporting existing mmap interfaces in importers. + +1. CPU fallback processing in a pipeline + + In many processing pipelines it is sometimes required that the cpu can access + the data in a dma-buf (e.g. for thumbnail creation, snapshots, ...). To avoid + the need to handle this specially in userspace frameworks for buffer sharing + it's ideal if the dma_buf fd itself can be used to access the backing storage + from userspace using mmap. + + Furthermore Android's ION framework already supports this (and is otherwise + rather similar to dma-buf from a userspace consumer side with using fds as + handles, too). So it's beneficial to support this in a similar fashion on + dma-buf to have a good transition path for existing Android userspace. + + No special interfaces, userspace simply calls mmap on the dma-buf fd. + +2. Supporting existing mmap interfaces in exporters + + Similar to the motivation for kernel cpu access it is again important that + the userspace code of a given importing subsystem can use the same interfaces + with a imported dma-buf buffer object as with a native buffer object. This is + especially important for drm where the userspace part of contemporary OpenGL, + X, and other drivers is huge, and reworking them to use a different way to + mmap a buffer rather invasive. + + The assumption in the current dma-buf interfaces is that redirecting the + initial mmap is all that's needed. A survey of some of the existing + subsystems shows that no driver seems to do any nefarious thing like syncing + up with outstanding asynchronous processing on the device or allocating + special resources at fault time. So hopefully this is good enough, since + adding interfaces to intercept pagefaults and allow pte shootdowns would + increase the complexity quite a bit. + + Interface: + int dma_buf_mmap(struct dma_buf *, struct vm_area_struct *, + unsigned long); + + If the importing subsystem simply provides a special-purpose mmap call to set + up a mapping in userspace, calling do_mmap with dma_buf->file will equally + achieve that for a dma-buf object. + +3. Implementation notes for exporters + + Because dma-buf buffers have invariant size over their lifetime, the dma-buf + core checks whether a vma is too large and rejects such mappings. The + exporter hence does not need to duplicate this check. + + Because existing importing subsystems might presume coherent mappings for + userspace, the exporter needs to set up a coherent mapping. If that's not + possible, it needs to fake coherency by manually shooting down ptes when + leaving the cpu domain and flushing caches at fault time. Note that all the + dma_buf files share the same anon inode, hence the exporter needs to replace + the dma_buf file stored in vma->vm_file with it's own if pte shootdown is + requred. This is because the kernel uses the underlying inode's address_space + for vma tracking (and hence pte tracking at shootdown time with + unmap_mapping_range). + + If the above shootdown dance turns out to be too expensive in certain + scenarios, we can extend dma-buf with a more explicit cache tracking scheme + for userspace mappings. But the current assumption is that using mmap is + always a slower path, so some inefficiencies should be acceptable. + + Exporters that shoot down mappings (for any reasons) shall not do any + synchronization at fault time with outstanding device operations. + Synchronization is an orthogonal issue to sharing the backing storage of a + buffer and hence should not be handled by dma-buf itself. This is explictly + mentioned here because many people seem to want something like this, but if + different exporters handle this differently, buffer sharing can fail in + interesting ways depending upong the exporter (if userspace starts depending + upon this implicit synchronization). + Miscellaneous notes ------------------- @@ -336,6 +417,20 @@ Miscellaneous notes the exporting driver to create a dmabuf fd must provide a way to let userspace control setting of O_CLOEXEC flag passed in to dma_buf_fd(). +- If an exporter needs to manually flush caches and hence needs to fake + coherency for mmap support, it needs to be able to zap all the ptes pointing + at the backing storage. Now linux mm needs a struct address_space associated + with the struct file stored in vma->vm_file to do that with the function + unmap_mapping_range. But the dma_buf framework only backs every dma_buf fd + with the anon_file struct file, i.e. all dma_bufs share the same file. + + Hence exporters need to setup their own file (and address_space) association + by setting vma->vm_file and adjusting vma->vm_pgoff in the dma_buf mmap + callback. In the specific case of a gem driver the exporter could use the + shmem file already provided by gem (and set vm_pgoff = 0). Exporters can then + zap ptes by unmapping the corresponding range of the struct address_space + associated with their own file. + References: [1] struct dma_buf_ops in include/linux/dma-buf.h [2] All interfaces mentioned above defined in include/linux/dma-buf.h diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index 4ba1eb7590a7..56000b33340b 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -595,3 +595,20 @@ Why: KVM tracepoints provide mostly equivalent information in a much more flexible fashion. ---------------------------- + +What: at91-mci driver ("CONFIG_MMC_AT91") +When: 3.7 +Why: There are two mci drivers: at91-mci and atmel-mci. The PDC support + was added to atmel-mci as a first step to support more chips. + Then at91-mci was kept only for old IP versions (on at91rm9200 and + at91sam9261). The support of these IP versions has just been added + to atmel-mci, so atmel-mci can be used for all chips. +Who: Ludovic Desroches + +---------------------------- + +What: net/wanrouter/ +When: June 2013 +Why: Unsupported/unmaintained/unused since 2.6 + +---------------------------- diff --git a/trunk/Documentation/filesystems/Locking b/trunk/Documentation/filesystems/Locking index 4fca82e5276e..8e2da1e06e3b 100644 --- a/trunk/Documentation/filesystems/Locking +++ b/trunk/Documentation/filesystems/Locking @@ -60,8 +60,8 @@ ata *); ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t); ssize_t (*listxattr) (struct dentry *, char *, size_t); int (*removexattr) (struct dentry *, const char *); - void (*truncate_range)(struct inode *, loff_t, loff_t); int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, u64 len); + void (*update_time)(struct inode *, struct timespec *, int); locking rules: all may block @@ -87,8 +87,9 @@ setxattr: yes getxattr: no listxattr: no removexattr: yes -truncate_range: yes fiemap: no +update_time: no + Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on victim. cross-directory ->rename() has (per-superblock) ->s_vfs_rename_sem. diff --git a/trunk/Documentation/filesystems/ext3.txt b/trunk/Documentation/filesystems/ext3.txt index b100adc38adb..293855e95000 100644 --- a/trunk/Documentation/filesystems/ext3.txt +++ b/trunk/Documentation/filesystems/ext3.txt @@ -59,9 +59,9 @@ commit=nrsec (*) Ext3 can be told to sync all its data and metadata Setting it to very large values will improve performance. -barrier=<0(*)|1> This enables/disables the use of write barriers in -barrier the jbd code. barrier=0 disables, barrier=1 enables. -nobarrier (*) This also requires an IO stack which can support +barrier=<0|1(*)> This enables/disables the use of write barriers in +barrier (*) the jbd code. barrier=0 disables, barrier=1 enables. +nobarrier This also requires an IO stack which can support barriers, and if jbd gets an error on a barrier write, it will disable again with a warning. Write barriers enforce proper on-disk ordering diff --git a/trunk/Documentation/filesystems/porting b/trunk/Documentation/filesystems/porting index 74acd9618819..8c91d1057d9a 100644 --- a/trunk/Documentation/filesystems/porting +++ b/trunk/Documentation/filesystems/porting @@ -297,7 +297,8 @@ in the beginning of ->setattr unconditionally. be used instead. It gets called whenever the inode is evicted, whether it has remaining links or not. Caller does *not* evict the pagecache or inode-associated metadata buffers; getting rid of those is responsibility of method, as it had -been for ->delete_inode(). +been for ->delete_inode(). Caller makes sure async writeback cannot be running +for the inode while (or after) ->evict_inode() is called. ->drop_inode() returns int now; it's called on final iput() with inode->i_lock held and it returns true if filesystems wants the inode to be @@ -306,14 +307,11 @@ updated appropriately. generic_delete_inode() is also alive and it consists simply of return 1. Note that all actual eviction work is done by caller after ->drop_inode() returns. - clear_inode() is gone; use end_writeback() instead. As before, it must -be called exactly once on each call of ->evict_inode() (as it used to be for -each call of ->delete_inode()). Unlike before, if you are using inode-associated -metadata buffers (i.e. mark_buffer_dirty_inode()), it's your responsibility to -call invalidate_inode_buffers() before end_writeback(). - No async writeback (and thus no calls of ->write_inode()) will happen -after end_writeback() returns, so actions that should not overlap with ->write_inode() -(e.g. freeing on-disk inode if i_nlink is 0) ought to be done after that call. + As before, clear_inode() must be called exactly once on each call of +->evict_inode() (as it used to be for each call of ->delete_inode()). Unlike +before, if you are using inode-associated metadata buffers (i.e. +mark_buffer_dirty_inode()), it's your responsibility to call +invalidate_inode_buffers() before clear_inode(). NOTE: checking i_nlink in the beginning of ->write_inode() and bailing out if it's zero is not *and* *never* *had* *been* enough. Final unlink() and iput() diff --git a/trunk/Documentation/filesystems/proc.txt b/trunk/Documentation/filesystems/proc.txt index ef088e55ab2e..fb0a6aeb936c 100644 --- a/trunk/Documentation/filesystems/proc.txt +++ b/trunk/Documentation/filesystems/proc.txt @@ -40,6 +40,7 @@ Table of Contents 3.4 /proc//coredump_filter - Core dump filtering settings 3.5 /proc//mountinfo - Information about mounts 3.6 /proc//comm & /proc//task//comm + 3.7 /proc//task//children - Information about task children 4 Configuring procfs 4.1 Mount options @@ -310,6 +311,11 @@ Table 1-4: Contents of the stat files (as of 2.6.30-rc7) start_data address above which program data+bss is placed end_data address below which program data+bss is placed start_brk address above which program heap can be expanded with brk() + arg_start address above which program command line is placed + arg_end address below which program command line is placed + env_start address above which program environment is placed + env_end address below which program environment is placed + exit_code the thread's exit_code in the form reported by the waitpid system call .............................................................................. The /proc/PID/maps file containing the currently mapped memory regions and @@ -743,6 +749,7 @@ Committed_AS: 100056 kB VmallocTotal: 112216 kB VmallocUsed: 428 kB VmallocChunk: 111088 kB +AnonHugePages: 49152 kB MemTotal: Total usable ram (i.e. physical ram minus a few reserved bits and the kernel binary code) @@ -776,6 +783,7 @@ VmallocChunk: 111088 kB Dirty: Memory which is waiting to get written back to the disk Writeback: Memory which is actively being written back to the disk AnonPages: Non-file backed pages mapped into userspace page tables +AnonHugePages: Non-file backed huge pages mapped into userspace page tables Mapped: files which have been mmaped, such as libraries Slab: in-kernel data structures cache SReclaimable: Part of Slab, that might be reclaimed, such as caches @@ -1576,6 +1584,23 @@ then the kernel's TASK_COMM_LEN (currently 16 chars) will result in a truncated comm value. +3.7 /proc//task//children - Information about task children +------------------------------------------------------------------------- +This file provides a fast way to retrieve first level children pids +of a task pointed by / pair. The format is a space separated +stream of pids. + +Note the "first level" here -- if a child has own children they will +not be listed here, one needs to read /proc//task//children +to obtain the descendants. + +Since this interface is intended to be fast and cheap it doesn't +guarantee to provide precise results and some children might be +skipped, especially if they've exited right after we printed their +pids, so one need to either stop or freeze processes being inspected +if precise results are needed. + + ------------------------------------------------------------------------------ Configuring procfs ------------------------------------------------------------------------------ diff --git a/trunk/Documentation/filesystems/vfs.txt b/trunk/Documentation/filesystems/vfs.txt index 0d0492028082..efd23f481704 100644 --- a/trunk/Documentation/filesystems/vfs.txt +++ b/trunk/Documentation/filesystems/vfs.txt @@ -363,7 +363,7 @@ struct inode_operations { ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t); ssize_t (*listxattr) (struct dentry *, char *, size_t); int (*removexattr) (struct dentry *, const char *); - void (*truncate_range)(struct inode *, loff_t, loff_t); + void (*update_time)(struct inode *, struct timespec *, int); }; Again, all methods are called without any locks being held, unless @@ -472,9 +472,9 @@ otherwise noted. removexattr: called by the VFS to remove an extended attribute from a file. This method is called by removexattr(2) system call. - truncate_range: a method provided by the underlying filesystem to truncate a - range of blocks , i.e. punch a hole somewhere in a file. - + update_time: called by the VFS to update a specific time or the i_version of + an inode. If this is not defined the VFS will update the inode itself + and call mark_inode_dirty_sync. The Address Space Object ======================== @@ -760,7 +760,7 @@ struct file_operations ---------------------- This describes how the VFS can manipulate an open file. As of kernel -2.6.22, the following members are defined: +3.5, the following members are defined: struct file_operations { struct module *owner; @@ -790,6 +790,8 @@ struct file_operations { int (*flock) (struct file *, int, struct file_lock *); ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, size_t, unsigned int); ssize_t (*splice_read)(struct file *, struct pipe_inode_info *, size_t, unsigned int); + int (*setlease)(struct file *, long arg, struct file_lock **); + long (*fallocate)(struct file *, int mode, loff_t offset, loff_t len); }; Again, all methods are called without any locks being held, unless @@ -858,6 +860,11 @@ otherwise noted. splice_read: called by the VFS to splice data from file to a pipe. This method is used by the splice(2) system call + setlease: called by the VFS to set or release a file lock lease. + setlease has the file_lock_lock held and must not sleep. + + fallocate: called by the VFS to preallocate blocks or punch a hole. + Note that the file operations are implemented by the specific filesystem in which the inode resides. When opening a device node (character or block special) most filesystems will call special diff --git a/trunk/Documentation/hwmon/coretemp b/trunk/Documentation/hwmon/coretemp index 84d46c0c71a3..c86b50c03ea8 100644 --- a/trunk/Documentation/hwmon/coretemp +++ b/trunk/Documentation/hwmon/coretemp @@ -6,7 +6,9 @@ Supported chips: Prefix: 'coretemp' CPUID: family 0x6, models 0xe (Pentium M DC), 0xf (Core 2 DC 65nm), 0x16 (Core 2 SC 65nm), 0x17 (Penryn 45nm), - 0x1a (Nehalem), 0x1c (Atom), 0x1e (Lynnfield) + 0x1a (Nehalem), 0x1c (Atom), 0x1e (Lynnfield), + 0x26 (Tunnel Creek Atom), 0x27 (Medfield Atom), + 0x36 (Cedar Trail Atom) Datasheet: Intel 64 and IA-32 Architectures Software Developer's Manual Volume 3A: System Programming Guide http://softwarecommunity.intel.com/Wiki/Mobility/720.htm @@ -52,6 +54,17 @@ Some information comes from ark.intel.com Process Processor TjMax(C) +22nm Core i5/i7 Processors + i7 3920XM, 3820QM, 3720QM, 3667U, 3520M 105 + i5 3427U, 3360M/3320M 105 + i7 3770/3770K 105 + i5 3570/3570K, 3550, 3470/3450 105 + i7 3770S 103 + i5 3570S/3550S, 3475S/3470S/3450S 103 + i7 3770T 94 + i5 3570T 94 + i5 3470T 91 + 32nm Core i3/i5/i7 Processors i7 660UM/640/620, 640LM/620, 620M, 610E 105 i5 540UM/520/430, 540M/520/450/430 105 @@ -65,6 +78,11 @@ Process Processor TjMax(C) U3400 105 P4505/P4500 90 +32nm Atom Processors + Z2460 90 + D2700/2550/2500 100 + N2850/2800/2650/2600 100 + 45nm Xeon Processors 5400 Quad-Core X5492, X5482, X5472, X5470, X5460, X5450 85 E5472, E5462, E5450/40/30/20/10/05 85 @@ -85,6 +103,8 @@ Process Processor TjMax(C) N475/470/455/450 100 N280/270 90 330/230 125 + E680/660/640/620 90 + E680T/660T/640T/620T 110 45nm Core2 Processors Solo ULV SU3500/3300 100 diff --git a/trunk/Documentation/i2c/functionality b/trunk/Documentation/i2c/functionality index 42c17c1fb3cd..b0ff2ab596ce 100644 --- a/trunk/Documentation/i2c/functionality +++ b/trunk/Documentation/i2c/functionality @@ -18,9 +18,9 @@ For the most up-to-date list of functionality constants, please check adapters typically can not do these) I2C_FUNC_10BIT_ADDR Handles the 10-bit address extensions I2C_FUNC_PROTOCOL_MANGLING Knows about the I2C_M_IGNORE_NAK, - I2C_M_REV_DIR_ADDR, I2C_M_NOSTART and - I2C_M_NO_RD_ACK flags (which modify the - I2C protocol!) + I2C_M_REV_DIR_ADDR and I2C_M_NO_RD_ACK + flags (which modify the I2C protocol!) + I2C_FUNC_NOSTART Can skip repeated start sequence I2C_FUNC_SMBUS_QUICK Handles the SMBus write_quick command I2C_FUNC_SMBUS_READ_BYTE Handles the SMBus read_byte command I2C_FUNC_SMBUS_WRITE_BYTE Handles the SMBus write_byte command @@ -50,6 +50,9 @@ A few combinations of the above flags are also defined for your convenience: emulated by a real I2C adapter (using the transparent emulation layer) +In kernel versions prior to 3.5 I2C_FUNC_NOSTART was implemented as +part of I2C_FUNC_PROTOCOL_MANGLING. + ADAPTER IMPLEMENTATION ---------------------- diff --git a/trunk/Documentation/i2c/i2c-protocol b/trunk/Documentation/i2c/i2c-protocol index 10518dd58814..0b3e62d1f77a 100644 --- a/trunk/Documentation/i2c/i2c-protocol +++ b/trunk/Documentation/i2c/i2c-protocol @@ -49,7 +49,9 @@ a byte read, followed by a byte write: Modified transactions ===================== -We have found some I2C devices that needs the following modifications: +The following modifications to the I2C protocol can also be generated, +with the exception of I2C_M_NOSTART these are usually only needed to +work around device issues: Flag I2C_M_NOSTART: In a combined transaction, no 'S Addr Wr/Rd [A]' is generated at some @@ -60,6 +62,11 @@ We have found some I2C devices that needs the following modifications: we do not generate Addr, but we do generate the startbit S. This will probably confuse all other clients on your bus, so don't try this. + This is often used to gather transmits from multiple data buffers in + system memory into something that appears as a single transfer to the + I2C device but may also be used between direction changes by some + rare devices. + Flags I2C_M_REV_DIR_ADDR This toggles the Rd/Wr flag. That is, if you want to do a write, but need to emit an Rd instead of a Wr, or vice versa, you set this diff --git a/trunk/Documentation/i2c/muxes/gpio-i2cmux b/trunk/Documentation/i2c/muxes/i2c-mux-gpio similarity index 85% rename from trunk/Documentation/i2c/muxes/gpio-i2cmux rename to trunk/Documentation/i2c/muxes/i2c-mux-gpio index 811cd78d4cdc..bd9b2299b739 100644 --- a/trunk/Documentation/i2c/muxes/gpio-i2cmux +++ b/trunk/Documentation/i2c/muxes/i2c-mux-gpio @@ -1,11 +1,11 @@ -Kernel driver gpio-i2cmux +Kernel driver i2c-gpio-mux Author: Peter Korsgaard Description ----------- -gpio-i2cmux is an i2c mux driver providing access to I2C bus segments +i2c-gpio-mux is an i2c mux driver providing access to I2C bus segments from a master I2C bus and a hardware MUX controlled through GPIO pins. E.G.: @@ -26,16 +26,16 @@ according to the settings of the GPIO pins 1..N. Usage ----- -gpio-i2cmux uses the platform bus, so you need to provide a struct +i2c-gpio-mux uses the platform bus, so you need to provide a struct platform_device with the platform_data pointing to a struct gpio_i2cmux_platform_data with the I2C adapter number of the master bus, the number of bus segments to create and the GPIO pins used -to control it. See include/linux/gpio-i2cmux.h for details. +to control it. See include/linux/i2c-gpio-mux.h for details. E.G. something like this for a MUX providing 4 bus segments controlled through 3 GPIO pins: -#include +#include #include static const unsigned myboard_gpiomux_gpios[] = { @@ -57,7 +57,7 @@ static struct gpio_i2cmux_platform_data myboard_i2cmux_data = { }; static struct platform_device myboard_i2cmux = { - .name = "gpio-i2cmux", + .name = "i2c-gpio-mux", .id = 0, .dev = { .platform_data = &myboard_i2cmux_data, diff --git a/trunk/Documentation/initrd.txt b/trunk/Documentation/initrd.txt index 1ba84f3584e3..4e1839ccb555 100644 --- a/trunk/Documentation/initrd.txt +++ b/trunk/Documentation/initrd.txt @@ -362,5 +362,5 @@ Resources http://www.almesberger.net/cv/papers/ols2k-9.ps.gz [2] newlib package (experimental), with initrd example http://sources.redhat.com/newlib/ -[3] Brouwer, Andries; "util-linux: Miscellaneous utilities for Linux" - ftp://ftp.win.tue.nl/pub/linux-local/utils/util-linux/ +[3] util-linux: Miscellaneous utilities for Linux + http://www.kernel.org/pub/linux/utils/util-linux/ diff --git a/trunk/Documentation/kbuild/kbuild.txt b/trunk/Documentation/kbuild/kbuild.txt index 68e32bb6bd80..6466704d47b5 100644 --- a/trunk/Documentation/kbuild/kbuild.txt +++ b/trunk/Documentation/kbuild/kbuild.txt @@ -50,6 +50,10 @@ LDFLAGS_MODULE -------------------------------------------------- Additional options used for $(LD) when linking modules. +LDFLAGS_vmlinux +-------------------------------------------------- +Additional options passed to final link of vmlinux. + KBUILD_VERBOSE -------------------------------------------------- Set the kbuild verbosity. Can be assigned same values as "V=...". @@ -214,3 +218,18 @@ KBUILD_BUILD_USER, KBUILD_BUILD_HOST These two variables allow to override the user@host string displayed during boot and in /proc/version. The default value is the output of the commands whoami and host, respectively. + +KBUILD_LDS +-------------------------------------------------- +The linker script with full path. Assigned by the top-level Makefile. + +KBUILD_VMLINUX_INIT +-------------------------------------------------- +All object files for the init (first) part of vmlinux. +Files specified with KBUILD_VMLINUX_INIT are linked first. + +KBUILD_VMLINUX_MAIN +-------------------------------------------------- +All object files for the main part of vmlinux. +KBUILD_VMLINUX_INIT and KBUILD_VMLINUX_MAIN together specify +all the object files used to link vmlinux. diff --git a/trunk/Documentation/kbuild/kconfig.txt b/trunk/Documentation/kbuild/kconfig.txt index 9d5f2a90dca9..a09f1a6a830c 100644 --- a/trunk/Documentation/kbuild/kconfig.txt +++ b/trunk/Documentation/kbuild/kconfig.txt @@ -53,15 +53,15 @@ KCONFIG_ALLCONFIG -------------------------------------------------- (partially based on lkml email from/by Rob Landley, re: miniconfig) -------------------------------------------------- -The allyesconfig/allmodconfig/allnoconfig/randconfig variants can -also use the environment variable KCONFIG_ALLCONFIG as a flag or a -filename that contains config symbols that the user requires to be -set to a specific value. If KCONFIG_ALLCONFIG is used without a -filename, "make *config" checks for a file named -"all{yes/mod/no/def/random}.config" (corresponding to the *config command -that was used) for symbol values that are to be forced. If this file -is not found, it checks for a file named "all.config" to contain forced -values. +The allyesconfig/allmodconfig/allnoconfig/randconfig variants can also +use the environment variable KCONFIG_ALLCONFIG as a flag or a filename +that contains config symbols that the user requires to be set to a +specific value. If KCONFIG_ALLCONFIG is used without a filename where +KCONFIG_ALLCONFIG == "" or KCONFIG_ALLCONFIG == "1", "make *config" +checks for a file named "all{yes/mod/no/def/random}.config" +(corresponding to the *config command that was used) for symbol values +that are to be forced. If this file is not found, it checks for a +file named "all.config" to contain forced values. This enables you to create "miniature" config (miniconfig) or custom config files containing just the config symbols that you are interested diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index b69cfdc12112..a92c5ebf373e 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -335,6 +335,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted. requirements as needed. This option does not override iommu=pt + amd_iommu_dump= [HW,X86-64] + Enable AMD IOMMU driver option to dump the ACPI table + for AMD IOMMU. With this option enabled, AMD IOMMU + driver will print ACPI tables for AMD IOMMU during + IOMMU initialization. + amijoy.map= [HW,JOY] Amiga joystick support Map of devices attached to JOY0DAT and JOY1DAT Format: , @@ -397,8 +403,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. atkbd.softrepeat= [HW] Use software keyboard repeat - autotest [IA-64] - baycom_epp= [HW,AX25] Format: , @@ -508,6 +512,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted. Also note the kernel might malfunction if you disable some critical bits. + cma=nn[MG] [ARM,KNL] + Sets the size of kernel global memory area for contiguous + memory allocations. For more information, see + include/linux/dma-contiguous.h + cmo_free_hint= [PPC] Format: { yes | no } Specify whether pages are marked as being inactive when they are freed. This is used in CMO environments @@ -515,6 +524,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. a hypervisor. Default: yes + coherent_pool=nn[KMG] [ARM,KNL] + Sets the size of memory pool for coherent, atomic dma + allocations if Contiguous Memory Allocator (CMA) is used. + code_bytes [X86] How many bytes of object code to print in an oops report. Range: 0 - 8192 @@ -1444,8 +1457,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. devices can be requested on-demand with the /dev/loop-control interface. - mcatest= [IA-64] - mce [X86-32] Machine Check Exception mce=option [X86-64] See Documentation/x86/x86_64/boot-options.txt @@ -2532,6 +2543,15 @@ bytes respectively. Such letter suffixes can also be entirely omitted. sched_debug [KNL] Enables verbose scheduler debug messages. + skew_tick= [KNL] Offset the periodic timer tick per cpu to mitigate + xtime_lock contention on larger systems, and/or RCU lock + contention on all systems with CONFIG_MAXSMP set. + Format: { "0" | "1" } + 0 -- disable. (may be 1 via CONFIG_CMDLINE="skew_tick=1" + 1 -- enable. + Note: increases power consumption, thus should only be + enabled if running jitter sensitive (HPC/RT) workloads. + security= [SECURITY] Choose a security module to enable at boot. If this boot parameter is not specified, only the first security module asking for security registration will be diff --git a/trunk/Documentation/leds/ledtrig-transient.txt b/trunk/Documentation/leds/ledtrig-transient.txt new file mode 100644 index 000000000000..3bd38b487df1 --- /dev/null +++ b/trunk/Documentation/leds/ledtrig-transient.txt @@ -0,0 +1,152 @@ +LED Transient Trigger +===================== + +The leds timer trigger does not currently have an interface to activate +a one shot timer. The current support allows for setting two timers, one for +specifying how long a state to be on, and the second for how long the state +to be off. The delay_on value specifies the time period an LED should stay +in on state, followed by a delay_off value that specifies how long the LED +should stay in off state. The on and off cycle repeats until the trigger +gets deactivated. There is no provision for one time activation to implement +features that require an on or off state to be held just once and then stay in +the original state forever. + +Without one shot timer interface, user space can still use timer trigger to +set a timer to hold a state, however when user space application crashes or +goes away without deactivating the timer, the hardware will be left in that +state permanently. + +As a specific example of this use-case, let's look at vibrate feature on +phones. Vibrate function on phones is implemented using PWM pins on SoC or +PMIC. There is a need to activate one shot timer to control the vibrate +feature, to prevent user space crashes leaving the phone in vibrate mode +permanently causing the battery to drain. + +Transient trigger addresses the need for one shot timer activation. The +transient trigger can be enabled and disabled just like the other leds +triggers. + +When an led class device driver registers itself, it can specify all leds +triggers it supports and a default trigger. During registration, activation +routine for the default trigger gets called. During registration of an led +class device, the LED state does not change. + +When the driver unregisters, deactivation routine for the currently active +trigger will be called, and LED state is changed to LED_OFF. + +Driver suspend changes the LED state to LED_OFF and resume doesn't change +the state. Please note that there is no explicit interaction between the +suspend and resume actions and the currently enabled trigger. LED state +changes are suspended while the driver is in suspend state. Any timers +that are active at the time driver gets suspended, continue to run, without +being able to actually change the LED state. Once driver is resumed, triggers +start functioning again. + +LED state changes are controlled using brightness which is a common led +class device property. When brightness is set to 0 from user space via +echo 0 > brightness, it will result in deactivating the current trigger. + +Transient trigger uses standard register and unregister interfaces. During +trigger registration, for each led class device that specifies this trigger +as its default trigger, trigger activation routine will get called. During +registration, the LED state does not change, unless there is another trigger +active, in which case LED state changes to LED_OFF. + +During trigger unregistration, LED state gets changed to LED_OFF. + +Transient trigger activation routine doesn't change the LED state. It +creates its properties and does its initialization. Transient trigger +deactivation routine, will cancel any timer that is active before it cleans +up and removes the properties it created. It will restore the LED state to +non-transient state. When driver gets suspended, irrespective of the transient +state, the LED state changes to LED_OFF. + +Transient trigger can be enabled and disabled from user space on led class +devices, that support this trigger as shown below: + +echo transient > trigger +echo none > trigger + +NOTE: Add a new property trigger state to control the state. + +This trigger exports three properties, activate, state, and duration. When +transient trigger is activated these properties are set to default values. + +- duration allows setting timer value in msecs. The initial value is 0. +- activate allows activating and deactivating the timer specified by + duration as needed. The initial and default value is 0. This will allow + duration to be set after trigger activation. +- state allows user to specify a transient state to be held for the specified + duration. + + activate - one shot timer activate mechanism. + 1 when activated, 0 when deactivated. + default value is zero when transient trigger is enabled, + to allow duration to be set. + + activate state indicates a timer with a value of specified + duration running. + deactivated state indicates that there is no active timer + running. + + duration - one shot timer value. When activate is set, duration value + is used to start a timer that runs once. This value doesn't + get changed by the trigger unless user does a set via + echo new_value > duration + + state - transient state to be held. It has two values 0 or 1. 0 maps + to LED_OFF and 1 maps to LED_FULL. The specified state is + held for the duration of the one shot timer and then the + state gets changed to the non-transient state which is the + inverse of transient state. + If state = LED_FULL, when the timer runs out the state will + go back to LED_OFF. + If state = LED_OFF, when the timer runs out the state will + go back to LED_FULL. + Please note that current LED state is not checked prior to + changing the state to the specified state. + Driver could map these values to inverted depending on the + default states it defines for the LED in its brightness_set() + interface which is called from the led brightness_set() + interfaces to control the LED state. + +When timer expires activate goes back to deactivated state, duration is left +at the set value to be used when activate is set at a future time. This will +allow user app to set the time once and activate it to run it once for the +specified value as needed. When timer expires, state is restored to the +non-transient state which is the inverse of the transient state. + + echo 1 > activate - starts timer = duration when duration is not 0. + echo 0 > activate - cancels currently running timer. + echo n > duration - stores timer value to be used upon next + activate. Currently active timer if + any, continues to run for the specified time. + echo 0 > duration - stores timer value to be used upon next + activate. Currently active timer if any, + continues to run for the specified time. + echo 1 > state - stores desired transient state LED_FULL to be + held for the specified duration. + echo 0 > state - stores desired transient state LED_OFF to be + held for the specified duration. + +What is not supported: +====================== +- Timer activation is one shot and extending and/or shortening the timer + is not supported. + +Example use-case 1: + echo transient > trigger + echo n > duration + echo 1 > state +repeat the following step as needed: + echo 1 > activate - start timer = duration to run once + echo 1 > activate - start timer = duration to run once + echo none > trigger + +This trigger is intended to be used for for the following example use cases: + - Control of vibrate (phones, tablets etc.) hardware by user space app. + - Use of LED by user space app as activity indicator. + - Use of LED by user space app as a kind of watchdog indicator -- as + long as the app is alive, it can keep the LED illuminated, if it dies + the LED will be extinguished automatically. + - Use by any user space app that needs a transient GPIO output. diff --git a/trunk/Documentation/networking/stmmac.txt b/trunk/Documentation/networking/stmmac.txt index ab1e8d7004c5..5cb9a1972460 100644 --- a/trunk/Documentation/networking/stmmac.txt +++ b/trunk/Documentation/networking/stmmac.txt @@ -10,8 +10,8 @@ Currently this network device driver is for all STM embedded MAC/GMAC (i.e. 7xxx/5xxx SoCs), SPEAr (arm), Loongson1B (mips) and XLINX XC2V3000 FF1152AMT0221 D1215994A VIRTEX FPGA board. -DWC Ether MAC 10/100/1000 Universal version 3.60a (and older) and DWC Ether MAC 10/100 -Universal version 4.0 have been used for developing this driver. +DWC Ether MAC 10/100/1000 Universal version 3.60a (and older) and DWC Ether +MAC 10/100 Universal version 4.0 have been used for developing this driver. This driver supports both the platform bus and PCI. @@ -54,27 +54,27 @@ net_device structure enabling the scatter/gather feature. When one or more packets are received, an interrupt happens. The interrupts are not queued so the driver has to scan all the descriptors in the ring during the receive process. -This is based on NAPI so the interrupt handler signals only if there is work to be -done, and it exits. +This is based on NAPI so the interrupt handler signals only if there is work +to be done, and it exits. Then the poll method will be scheduled at some future point. The incoming packets are stored, by the DMA, in a list of pre-allocated socket buffers in order to avoid the memcpy (Zero-copy). 4.3) Timer-Driver Interrupt -Instead of having the device that asynchronously notifies the frame receptions, the -driver configures a timer to generate an interrupt at regular intervals. -Based on the granularity of the timer, the frames that are received by the device -will experience different levels of latency. Some NICs have dedicated timer -device to perform this task. STMMAC can use either the RTC device or the TMU -channel 2 on STLinux platforms. +Instead of having the device that asynchronously notifies the frame receptions, +the driver configures a timer to generate an interrupt at regular intervals. +Based on the granularity of the timer, the frames that are received by the +device will experience different levels of latency. Some NICs have dedicated +timer device to perform this task. STMMAC can use either the RTC device or the +TMU channel 2 on STLinux platforms. The timers frequency can be passed to the driver as parameter; when change it, take care of both hardware capability and network stability/performance impact. -Several performance tests on STM platforms showed this optimisation allows to spare -the CPU while having the maximum throughput. +Several performance tests on STM platforms showed this optimisation allows to +spare the CPU while having the maximum throughput. 4.4) WOL -Wake up on Lan feature through Magic and Unicast frames are supported for the GMAC -core. +Wake up on Lan feature through Magic and Unicast frames are supported for the +GMAC core. 4.5) DMA descriptors Driver handles both normal and enhanced descriptors. The latter has been only @@ -106,7 +106,8 @@ Several driver's information can be passed through the platform These are included in the include/linux/stmmac.h header file and detailed below as well: - struct plat_stmmacenet_data { +struct plat_stmmacenet_data { + char *phy_bus_name; int bus_id; int phy_addr; int interface; @@ -124,19 +125,24 @@ and detailed below as well: void (*bus_setup)(void __iomem *ioaddr); int (*init)(struct platform_device *pdev); void (*exit)(struct platform_device *pdev); + void *custom_cfg; + void *custom_data; void *bsp_priv; }; Where: + o phy_bus_name: phy bus name to attach to the stmmac. o bus_id: bus identifier. o phy_addr: the physical address can be passed from the platform. If it is set to -1 the driver will automatically detect it at run-time by probing all the 32 addresses. o interface: PHY device's interface. o mdio_bus_data: specific platform fields for the MDIO bus. - o pbl: the Programmable Burst Length is maximum number of beats to + o dma_cfg: internal DMA parameters + o pbl: the Programmable Burst Length is maximum number of beats to be transferred in one DMA transaction. GMAC also enables the 4xPBL by default. + o fixed_burst/mixed_burst/burst_len o clk_csr: fixed CSR Clock range selection. o has_gmac: uses the GMAC core. o enh_desc: if sets the MAC will use the enhanced descriptor structure. @@ -160,8 +166,9 @@ Where: this is sometime necessary on some platforms (e.g. ST boxes) where the HW needs to have set some PIO lines or system cfg registers. - o custom_cfg: this is a custom configuration that can be passed while - initialising the resources. + o custom_cfg/custom_data: this is a custom configuration that can be passed + while initialising the resources. + o bsp_priv: another private poiter. For MDIO bus The we have: @@ -180,7 +187,6 @@ Where: o irqs: list of IRQs, one per PHY. o probed_phy_irq: if irqs is NULL, use this for probed PHY. - For DMA engine we have the following internal fields that should be tuned according to the HW capabilities. diff --git a/trunk/Documentation/power/charger-manager.txt b/trunk/Documentation/power/charger-manager.txt index fdcca991df30..b4f7f4b23f64 100644 --- a/trunk/Documentation/power/charger-manager.txt +++ b/trunk/Documentation/power/charger-manager.txt @@ -44,6 +44,16 @@ Charger Manager supports the following: Normally, the platform will need to resume and suspend some devices that are used by Charger Manager. +* Support for premature full-battery event handling + If the battery voltage drops by "fullbatt_vchkdrop_uV" after + "fullbatt_vchkdrop_ms" from the full-battery event, the framework + restarts charging. This check is also performed while suspended by + setting wakeup time accordingly and using suspend_again. + +* Support for uevent-notify + With the charger-related events, the device sends + notification to users with UEVENT. + 2. Global Charger-Manager Data related with suspend_again ======================================================== In order to setup Charger Manager with suspend-again feature @@ -55,7 +65,7 @@ if there are multiple batteries. If there are multiple batteries, the multiple instances of Charger Manager share the same charger_global_desc and it will manage in-suspend monitoring for all instances of Charger Manager. -The user needs to provide all the two entries properly in order to activate +The user needs to provide all the three entries properly in order to activate in-suspend monitoring: struct charger_global_desc { @@ -74,6 +84,11 @@ bool (*rtc_only_wakeup)(void); same struct. If there is any other wakeup source triggered the wakeup, it should return false. If the "rtc" is the only wakeup reason, it should return true. + +bool assume_timer_stops_in_suspend; + : if true, Charger Manager assumes that + the timer (CM uses jiffies as timer) stops during suspend. Then, CM + assumes that the suspend-duration is same as the alarm length. }; 3. How to setup suspend_again @@ -111,6 +126,16 @@ enum polling_modes polling_mode; CM_POLL_CHARGING_ONLY: poll this battery if and only if the battery is being charged. +unsigned int fullbatt_vchkdrop_ms; +unsigned int fullbatt_vchkdrop_uV; + : If both have non-zero values, Charger Manager will check the + battery voltage drop fullbatt_vchkdrop_ms after the battery is fully + charged. If the voltage drop is over fullbatt_vchkdrop_uV, Charger + Manager will try to recharge the battery by disabling and enabling + chargers. Recharge with voltage drop condition only (without delay + condition) is needed to be implemented with hardware interrupts from + fuel gauges or charger devices/chips. + unsigned int fullbatt_uV; : If specified with a non-zero value, Charger Manager assumes that the battery is full (capacity = 100) if the battery is not being @@ -122,6 +147,8 @@ unsigned int polling_interval_ms; this battery every polling_interval_ms or more frequently. enum data_source battery_present; + : CM_BATTERY_PRESENT: assume that the battery exists. + CM_NO_BATTERY: assume that the battery does not exists. CM_FUEL_GAUGE: get battery presence information from fuel gauge. CM_CHARGER_STAT: get battery presence from chargers. @@ -151,7 +178,17 @@ bool measure_battery_temp; the value of measure_battery_temp. }; -5. Other Considerations +5. Notify Charger-Manager of charger events: cm_notify_event() +========================================================= +If there is an charger event is required to notify +Charger Manager, a charger device driver that triggers the event can call +cm_notify_event(psy, type, msg) to notify the corresponding Charger Manager. +In the function, psy is the charger driver's power_supply pointer, which is +associated with Charger-Manager. The parameter "type" +is the same as irq's type (enum cm_event_types). The event message "msg" is +optional and is effective only if the event type is "UNDESCRIBED" or "OTHERS". + +6. Other Considerations ======================= At the charger/battery-related events such as battery-pulled-out, diff --git a/trunk/Documentation/power/power_supply_class.txt b/trunk/Documentation/power/power_supply_class.txt index 9f16c5178b66..211831d4095f 100644 --- a/trunk/Documentation/power/power_supply_class.txt +++ b/trunk/Documentation/power/power_supply_class.txt @@ -84,6 +84,8 @@ are already charged or discharging, 'n/a' can be displayed (or HEALTH - represents health of the battery, values corresponds to POWER_SUPPLY_HEALTH_*, defined in battery.h. +VOLTAGE_OCV - open circuit voltage of the battery. + VOLTAGE_MAX_DESIGN, VOLTAGE_MIN_DESIGN - design values for maximal and minimal power supply voltages. Maximal/minimal means values of voltages when battery considered "full"/"empty" at normal conditions. Yes, there is diff --git a/trunk/Documentation/stable_kernel_rules.txt b/trunk/Documentation/stable_kernel_rules.txt index f0ab5cf28fca..4a7b54bd37e8 100644 --- a/trunk/Documentation/stable_kernel_rules.txt +++ b/trunk/Documentation/stable_kernel_rules.txt @@ -12,6 +12,12 @@ Rules on what kind of patches are accepted, and which ones are not, into the marked CONFIG_BROKEN), an oops, a hang, data corruption, a real security issue, or some "oh, that's not good" issue. In short, something critical. + - Serious issues as reported by a user of a distribution kernel may also + be considered if they fix a notable performance or interactivity issue. + As these fixes are not as obvious and have a higher risk of a subtle + regression they should only be submitted by a distribution kernel + maintainer and include an addendum linking to a bugzilla entry if it + exists and additional information on the user-visible impact. - New device IDs and quirks are also accepted. - No "theoretical race condition" issues, unless an explanation of how the race can be exploited is also provided. diff --git a/trunk/Documentation/sysctl/fs.txt b/trunk/Documentation/sysctl/fs.txt index 88fd7f5c8dcd..13d6166d7a27 100644 --- a/trunk/Documentation/sysctl/fs.txt +++ b/trunk/Documentation/sysctl/fs.txt @@ -225,6 +225,13 @@ a queue must be less or equal then msg_max. maximum message size value (it is every message queue's attribute set during its creation). +/proc/sys/fs/mqueue/msg_default is a read/write file for setting/getting the +default number of messages in a queue value if attr parameter of mq_open(2) is +NULL. If it exceed msg_max, the default value is initialized msg_max. + +/proc/sys/fs/mqueue/msgsize_default is a read/write file for setting/getting +the default message size value if attr parameter of mq_open(2) is NULL. If it +exceed msgsize_max, the default value is initialized msgsize_max. 4. /proc/sys/fs/epoll - Configuration options for the epoll interface -------------------------------------------------------- diff --git a/trunk/Documentation/vm/frontswap.txt b/trunk/Documentation/vm/frontswap.txt new file mode 100644 index 000000000000..37067cf455f4 --- /dev/null +++ b/trunk/Documentation/vm/frontswap.txt @@ -0,0 +1,278 @@ +Frontswap provides a "transcendent memory" interface for swap pages. +In some environments, dramatic performance savings may be obtained because +swapped pages are saved in RAM (or a RAM-like device) instead of a swap disk. + +(Note, frontswap -- and cleancache (merged at 3.0) -- are the "frontends" +and the only necessary changes to the core kernel for transcendent memory; +all other supporting code -- the "backends" -- is implemented as drivers. +See the LWN.net article "Transcendent memory in a nutshell" for a detailed +overview of frontswap and related kernel parts: +https://lwn.net/Articles/454795/ ) + +Frontswap is so named because it can be thought of as the opposite of +a "backing" store for a swap device. The storage is assumed to be +a synchronous concurrency-safe page-oriented "pseudo-RAM device" conforming +to the requirements of transcendent memory (such as Xen's "tmem", or +in-kernel compressed memory, aka "zcache", or future RAM-like devices); +this pseudo-RAM device is not directly accessible or addressable by the +kernel and is of unknown and possibly time-varying size. The driver +links itself to frontswap by calling frontswap_register_ops to set the +frontswap_ops funcs appropriately and the functions it provides must +conform to certain policies as follows: + +An "init" prepares the device to receive frontswap pages associated +with the specified swap device number (aka "type"). A "store" will +copy the page to transcendent memory and associate it with the type and +offset associated with the page. A "load" will copy the page, if found, +from transcendent memory into kernel memory, but will NOT remove the page +from from transcendent memory. An "invalidate_page" will remove the page +from transcendent memory and an "invalidate_area" will remove ALL pages +associated with the swap type (e.g., like swapoff) and notify the "device" +to refuse further stores with that swap type. + +Once a page is successfully stored, a matching load on the page will normally +succeed. So when the kernel finds itself in a situation where it needs +to swap out a page, it first attempts to use frontswap. If the store returns +success, the data has been successfully saved to transcendent memory and +a disk write and, if the data is later read back, a disk read are avoided. +If a store returns failure, transcendent memory has rejected the data, and the +page can be written to swap as usual. + +If a backend chooses, frontswap can be configured as a "writethrough +cache" by calling frontswap_writethrough(). In this mode, the reduction +in swap device writes is lost (and also a non-trivial performance advantage) +in order to allow the backend to arbitrarily "reclaim" space used to +store frontswap pages to more completely manage its memory usage. + +Note that if a page is stored and the page already exists in transcendent memory +(a "duplicate" store), either the store succeeds and the data is overwritten, +or the store fails AND the page is invalidated. This ensures stale data may +never be obtained from frontswap. + +If properly configured, monitoring of frontswap is done via debugfs in +the /sys/kernel/debug/frontswap directory. The effectiveness of +frontswap can be measured (across all swap devices) with: + +failed_stores - how many store attempts have failed +loads - how many loads were attempted (all should succeed) +succ_stores - how many store attempts have succeeded +invalidates - how many invalidates were attempted + +A backend implementation may provide additional metrics. + +FAQ + +1) Where's the value? + +When a workload starts swapping, performance falls through the floor. +Frontswap significantly increases performance in many such workloads by +providing a clean, dynamic interface to read and write swap pages to +"transcendent memory" that is otherwise not directly addressable to the kernel. +This interface is ideal when data is transformed to a different form +and size (such as with compression) or secretly moved (as might be +useful for write-balancing for some RAM-like devices). Swap pages (and +evicted page-cache pages) are a great use for this kind of slower-than-RAM- +but-much-faster-than-disk "pseudo-RAM device" and the frontswap (and +cleancache) interface to transcendent memory provides a nice way to read +and write -- and indirectly "name" -- the pages. + +Frontswap -- and cleancache -- with a fairly small impact on the kernel, +provides a huge amount of flexibility for more dynamic, flexible RAM +utilization in various system configurations: + +In the single kernel case, aka "zcache", pages are compressed and +stored in local memory, thus increasing the total anonymous pages +that can be safely kept in RAM. Zcache essentially trades off CPU +cycles used in compression/decompression for better memory utilization. +Benchmarks have shown little or no impact when memory pressure is +low while providing a significant performance improvement (25%+) +on some workloads under high memory pressure. + +"RAMster" builds on zcache by adding "peer-to-peer" transcendent memory +support for clustered systems. Frontswap pages are locally compressed +as in zcache, but then "remotified" to another system's RAM. This +allows RAM to be dynamically load-balanced back-and-forth as needed, +i.e. when system A is overcommitted, it can swap to system B, and +vice versa. RAMster can also be configured as a memory server so +many servers in a cluster can swap, dynamically as needed, to a single +server configured with a large amount of RAM... without pre-configuring +how much of the RAM is available for each of the clients! + +In the virtual case, the whole point of virtualization is to statistically +multiplex physical resources acrosst the varying demands of multiple +virtual machines. This is really hard to do with RAM and efforts to do +it well with no kernel changes have essentially failed (except in some +well-publicized special-case workloads). +Specifically, the Xen Transcendent Memory backend allows otherwise +"fallow" hypervisor-owned RAM to not only be "time-shared" between multiple +virtual machines, but the pages can be compressed and deduplicated to +optimize RAM utilization. And when guest OS's are induced to surrender +underutilized RAM (e.g. with "selfballooning"), sudden unexpected +memory pressure may result in swapping; frontswap allows those pages +to be swapped to and from hypervisor RAM (if overall host system memory +conditions allow), thus mitigating the potentially awful performance impact +of unplanned swapping. + +A KVM implementation is underway and has been RFC'ed to lkml. And, +using frontswap, investigation is also underway on the use of NVM as +a memory extension technology. + +2) Sure there may be performance advantages in some situations, but + what's the space/time overhead of frontswap? + +If CONFIG_FRONTSWAP is disabled, every frontswap hook compiles into +nothingness and the only overhead is a few extra bytes per swapon'ed +swap device. If CONFIG_FRONTSWAP is enabled but no frontswap "backend" +registers, there is one extra global variable compared to zero for +every swap page read or written. If CONFIG_FRONTSWAP is enabled +AND a frontswap backend registers AND the backend fails every "store" +request (i.e. provides no memory despite claiming it might), +CPU overhead is still negligible -- and since every frontswap fail +precedes a swap page write-to-disk, the system is highly likely +to be I/O bound and using a small fraction of a percent of a CPU +will be irrelevant anyway. + +As for space, if CONFIG_FRONTSWAP is enabled AND a frontswap backend +registers, one bit is allocated for every swap page for every swap +device that is swapon'd. This is added to the EIGHT bits (which +was sixteen until about 2.6.34) that the kernel already allocates +for every swap page for every swap device that is swapon'd. (Hugh +Dickins has observed that frontswap could probably steal one of +the existing eight bits, but let's worry about that minor optimization +later.) For very large swap disks (which are rare) on a standard +4K pagesize, this is 1MB per 32GB swap. + +When swap pages are stored in transcendent memory instead of written +out to disk, there is a side effect that this may create more memory +pressure that can potentially outweigh the other advantages. A +backend, such as zcache, must implement policies to carefully (but +dynamically) manage memory limits to ensure this doesn't happen. + +3) OK, how about a quick overview of what this frontswap patch does + in terms that a kernel hacker can grok? + +Let's assume that a frontswap "backend" has registered during +kernel initialization; this registration indicates that this +frontswap backend has access to some "memory" that is not directly +accessible by the kernel. Exactly how much memory it provides is +entirely dynamic and random. + +Whenever a swap-device is swapon'd frontswap_init() is called, +passing the swap device number (aka "type") as a parameter. +This notifies frontswap to expect attempts to "store" swap pages +associated with that number. + +Whenever the swap subsystem is readying a page to write to a swap +device (c.f swap_writepage()), frontswap_store is called. Frontswap +consults with the frontswap backend and if the backend says it does NOT +have room, frontswap_store returns -1 and the kernel swaps the page +to the swap device as normal. Note that the response from the frontswap +backend is unpredictable to the kernel; it may choose to never accept a +page, it could accept every ninth page, or it might accept every +page. But if the backend does accept a page, the data from the page +has already been copied and associated with the type and offset, +and the backend guarantees the persistence of the data. In this case, +frontswap sets a bit in the "frontswap_map" for the swap device +corresponding to the page offset on the swap device to which it would +otherwise have written the data. + +When the swap subsystem needs to swap-in a page (swap_readpage()), +it first calls frontswap_load() which checks the frontswap_map to +see if the page was earlier accepted by the frontswap backend. If +it was, the page of data is filled from the frontswap backend and +the swap-in is complete. If not, the normal swap-in code is +executed to obtain the page of data from the real swap device. + +So every time the frontswap backend accepts a page, a swap device read +and (potentially) a swap device write are replaced by a "frontswap backend +store" and (possibly) a "frontswap backend loads", which are presumably much +faster. + +4) Can't frontswap be configured as a "special" swap device that is + just higher priority than any real swap device (e.g. like zswap, + or maybe swap-over-nbd/NFS)? + +No. First, the existing swap subsystem doesn't allow for any kind of +swap hierarchy. Perhaps it could be rewritten to accomodate a hierarchy, +but this would require fairly drastic changes. Even if it were +rewritten, the existing swap subsystem uses the block I/O layer which +assumes a swap device is fixed size and any page in it is linearly +addressable. Frontswap barely touches the existing swap subsystem, +and works around the constraints of the block I/O subsystem to provide +a great deal of flexibility and dynamicity. + +For example, the acceptance of any swap page by the frontswap backend is +entirely unpredictable. This is critical to the definition of frontswap +backends because it grants completely dynamic discretion to the +backend. In zcache, one cannot know a priori how compressible a page is. +"Poorly" compressible pages can be rejected, and "poorly" can itself be +defined dynamically depending on current memory constraints. + +Further, frontswap is entirely synchronous whereas a real swap +device is, by definition, asynchronous and uses block I/O. The +block I/O layer is not only unnecessary, but may perform "optimizations" +that are inappropriate for a RAM-oriented device including delaying +the write of some pages for a significant amount of time. Synchrony is +required to ensure the dynamicity of the backend and to avoid thorny race +conditions that would unnecessarily and greatly complicate frontswap +and/or the block I/O subsystem. That said, only the initial "store" +and "load" operations need be synchronous. A separate asynchronous thread +is free to manipulate the pages stored by frontswap. For example, +the "remotification" thread in RAMster uses standard asynchronous +kernel sockets to move compressed frontswap pages to a remote machine. +Similarly, a KVM guest-side implementation could do in-guest compression +and use "batched" hypercalls. + +In a virtualized environment, the dynamicity allows the hypervisor +(or host OS) to do "intelligent overcommit". For example, it can +choose to accept pages only until host-swapping might be imminent, +then force guests to do their own swapping. + +There is a downside to the transcendent memory specifications for +frontswap: Since any "store" might fail, there must always be a real +slot on a real swap device to swap the page. Thus frontswap must be +implemented as a "shadow" to every swapon'd device with the potential +capability of holding every page that the swap device might have held +and the possibility that it might hold no pages at all. This means +that frontswap cannot contain more pages than the total of swapon'd +swap devices. For example, if NO swap device is configured on some +installation, frontswap is useless. Swapless portable devices +can still use frontswap but a backend for such devices must configure +some kind of "ghost" swap device and ensure that it is never used. + +5) Why this weird definition about "duplicate stores"? If a page + has been previously successfully stored, can't it always be + successfully overwritten? + +Nearly always it can, but no, sometimes it cannot. Consider an example +where data is compressed and the original 4K page has been compressed +to 1K. Now an attempt is made to overwrite the page with data that +is non-compressible and so would take the entire 4K. But the backend +has no more space. In this case, the store must be rejected. Whenever +frontswap rejects a store that would overwrite, it also must invalidate +the old data and ensure that it is no longer accessible. Since the +swap subsystem then writes the new data to the read swap device, +this is the correct course of action to ensure coherency. + +6) What is frontswap_shrink for? + +When the (non-frontswap) swap subsystem swaps out a page to a real +swap device, that page is only taking up low-value pre-allocated disk +space. But if frontswap has placed a page in transcendent memory, that +page may be taking up valuable real estate. The frontswap_shrink +routine allows code outside of the swap subsystem to force pages out +of the memory managed by frontswap and back into kernel-addressable memory. +For example, in RAMster, a "suction driver" thread will attempt +to "repatriate" pages sent to a remote machine back to the local machine; +this is driven using the frontswap_shrink mechanism when memory pressure +subsides. + +7) Why does the frontswap patch create the new include file swapfile.h? + +The frontswap code depends on some swap-subsystem-internal data +structures that have, over the years, moved back and forth between +static and global. This seemed a reasonable compromise: Define +them as global but declare them in a new include file that isn't +included by the large number of source files that include swap.h. + +Dan Magenheimer, last updated April 9, 2012 diff --git a/trunk/Documentation/vm/pagemap.txt b/trunk/Documentation/vm/pagemap.txt index 4600cbe3d6be..7587493c67f1 100644 --- a/trunk/Documentation/vm/pagemap.txt +++ b/trunk/Documentation/vm/pagemap.txt @@ -16,7 +16,7 @@ There are three components to pagemap: * Bits 0-4 swap type if swapped * Bits 5-54 swap offset if swapped * Bits 55-60 page shift (page size = 1< @@ -39,6 +39,10 @@ watchdog_device structure. The watchdog device structure looks like this: struct watchdog_device { + int id; + struct cdev cdev; + struct device *dev; + struct device *parent; const struct watchdog_info *info; const struct watchdog_ops *ops; unsigned int bootstatus; @@ -46,10 +50,20 @@ struct watchdog_device { unsigned int min_timeout; unsigned int max_timeout; void *driver_data; + struct mutex lock; unsigned long status; }; It contains following fields: +* id: set by watchdog_register_device, id 0 is special. It has both a + /dev/watchdog0 cdev (dynamic major, minor 0) as well as the old + /dev/watchdog miscdev. The id is set automatically when calling + watchdog_register_device. +* cdev: cdev for the dynamic /dev/watchdog device nodes. This + field is also populated by watchdog_register_device. +* dev: device under the watchdog class (created by watchdog_register_device). +* parent: set this to the parent device (or NULL) before calling + watchdog_register_device. * info: a pointer to a watchdog_info structure. This structure gives some additional information about the watchdog timer itself. (Like it's unique name) * ops: a pointer to the list of watchdog operations that the watchdog supports. @@ -61,6 +75,7 @@ It contains following fields: * driver_data: a pointer to the drivers private data of a watchdog device. This data should only be accessed via the watchdog_set_drvdata and watchdog_get_drvdata routines. +* lock: Mutex for WatchDog Timer Driver Core internal use only. * status: this field contains a number of status bits that give extra information about the status of the device (Like: is the watchdog timer running/active, is the nowayout bit set, is the device opened via @@ -78,6 +93,8 @@ struct watchdog_ops { unsigned int (*status)(struct watchdog_device *); int (*set_timeout)(struct watchdog_device *, unsigned int); unsigned int (*get_timeleft)(struct watchdog_device *); + void (*ref)(struct watchdog_device *); + void (*unref)(struct watchdog_device *); long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long); }; @@ -85,6 +102,21 @@ It is important that you first define the module owner of the watchdog timer driver's operations. This module owner will be used to lock the module when the watchdog is active. (This to avoid a system crash when you unload the module and /dev/watchdog is still open). + +If the watchdog_device struct is dynamically allocated, just locking the module +is not enough and a driver also needs to define the ref and unref operations to +ensure the structure holding the watchdog_device does not go away. + +The simplest (and usually sufficient) implementation of this is to: +1) Add a kref struct to the same structure which is holding the watchdog_device +2) Define a release callback for the kref which frees the struct holding both +3) Call kref_init on this kref *before* calling watchdog_register_device() +4) Define a ref operation calling kref_get on this kref +5) Define a unref operation calling kref_put on this kref +6) When it is time to cleanup: + * Do not kfree() the struct holding both, the last kref_put will do this! + * *After* calling watchdog_unregister_device() call kref_put on the kref + Some operations are mandatory and some are optional. The mandatory operations are: * start: this is a pointer to the routine that starts the watchdog timer @@ -125,6 +157,10 @@ they are supported. These optional routines/operations are: (Note: the WDIOF_SETTIMEOUT needs to be set in the options field of the watchdog's info structure). * get_timeleft: this routines returns the time that's left before a reset. +* ref: the operation that calls kref_get on the kref of a dynamically + allocated watchdog_device struct. +* unref: the operation that calls kref_put on the kref of a dynamically + allocated watchdog_device struct. * ioctl: if this routine is present then it will be called first before we do our own internal ioctl call handling. This routine should return -ENOIOCTLCMD if a command is not supported. The parameters that are passed to the ioctl @@ -144,6 +180,11 @@ bit-operations. The status bits that are defined are: (This bit should only be used by the WatchDog Timer Driver Core). * WDOG_NO_WAY_OUT: this bit stores the nowayout setting for the watchdog. If this bit is set then the watchdog timer will not be able to stop. +* WDOG_UNREGISTERED: this bit gets set by the WatchDog Timer Driver Core + after calling watchdog_unregister_device, and then checked before calling + any watchdog_ops, so that you can be sure that no operations (other then + unref) will get called after unregister, even if userspace still holds a + reference to /dev/watchdog To set the WDOG_NO_WAY_OUT status bit (before registering your watchdog timer device) you can either: diff --git a/trunk/Documentation/watchdog/watchdog-parameters.txt b/trunk/Documentation/watchdog/watchdog-parameters.txt index 17ddd822b456..04fddbacdbde 100644 --- a/trunk/Documentation/watchdog/watchdog-parameters.txt +++ b/trunk/Documentation/watchdog/watchdog-parameters.txt @@ -78,6 +78,11 @@ wd0_timeout: Default watchdog0 timeout in 1/10secs wd1_timeout: Default watchdog1 timeout in 1/10secs wd2_timeout: Default watchdog2 timeout in 1/10secs ------------------------------------------------- +da9052wdt: +timeout: Watchdog timeout in seconds. 2<= timeout <=131, default=2.048s +nowayout: Watchdog cannot be stopped once started + (default=kernel config parameter) +------------------------------------------------- davinci_wdt: heartbeat: Watchdog heartbeat period in seconds from 1 to 600, default 60 ------------------------------------------------- diff --git a/trunk/Documentation/x86/efi-stub.txt b/trunk/Documentation/x86/efi-stub.txt new file mode 100644 index 000000000000..44e6bb6ead10 --- /dev/null +++ b/trunk/Documentation/x86/efi-stub.txt @@ -0,0 +1,65 @@ + The EFI Boot Stub + --------------------------- + +On the x86 platform, a bzImage can masquerade as a PE/COFF image, +thereby convincing EFI firmware loaders to load it as an EFI +executable. The code that modifies the bzImage header, along with the +EFI-specific entry point that the firmware loader jumps to are +collectively known as the "EFI boot stub", and live in +arch/x86/boot/header.S and arch/x86/boot/compressed/eboot.c, +respectively. + +By using the EFI boot stub it's possible to boot a Linux kernel +without the use of a conventional EFI boot loader, such as grub or +elilo. Since the EFI boot stub performs the jobs of a boot loader, in +a certain sense it *IS* the boot loader. + +The EFI boot stub is enabled with the CONFIG_EFI_STUB kernel option. + + +**** How to install bzImage.efi + +The bzImage located in arch/x86/boot/bzImage must be copied to the EFI +System Partiion (ESP) and renamed with the extension ".efi". Without +the extension the EFI firmware loader will refuse to execute it. It's +not possible to execute bzImage.efi from the usual Linux file systems +because EFI firmware doesn't have support for them. + + +**** Passing kernel parameters from the EFI shell + +Arguments to the kernel can be passed after bzImage.efi, e.g. + + fs0:> bzImage.efi console=ttyS0 root=/dev/sda4 + + +**** The "initrd=" option + +Like most boot loaders, the EFI stub allows the user to specify +multiple initrd files using the "initrd=" option. This is the only EFI +stub-specific command line parameter, everything else is passed to the +kernel when it boots. + +The path to the initrd file must be an absolute path from the +beginning of the ESP, relative path names do not work. Also, the path +is an EFI-style path and directory elements must be separated with +backslashes (\). For example, given the following directory layout, + +fs0:> + Kernels\ + bzImage.efi + initrd-large.img + + Ramdisks\ + initrd-small.img + initrd-medium.img + +to boot with the initrd-large.img file if the current working +directory is fs0:\Kernels, the following command must be used, + + fs0:\Kernels> bzImage.efi initrd=\Kernels\initrd-large.img + +Notice how bzImage.efi can be specified with a relative path. That's +because the image we're executing is interpreted by the EFI shell, +which understands relative paths, whereas the rest of the command line +is passed to bzImage.efi. diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 150a29f3cd33..eb22272b2116 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -579,7 +579,7 @@ F: drivers/net/appletalk/ F: net/appletalk/ ARASAN COMPACT FLASH PATA CONTROLLER -M: Viresh Kumar +M: Viresh Kumar L: linux-ide@vger.kernel.org S: Maintained F: include/linux/pata_arasan_cf_data.h @@ -1077,7 +1077,7 @@ F: drivers/media/video/s5p-fimc/ ARM/SAMSUNG S5P SERIES Multi Format Codec (MFC) SUPPORT M: Kyungmin Park M: Kamil Debski -M: Jeongtae Park +M: Jeongtae Park L: linux-arm-kernel@lists.infradead.org L: linux-media@vger.kernel.org S: Maintained @@ -1646,11 +1646,11 @@ S: Maintained F: drivers/gpio/gpio-bt8xx.c BTRFS FILE SYSTEM -M: Chris Mason +M: Chris Mason L: linux-btrfs@vger.kernel.org W: http://btrfs.wiki.kernel.org/ Q: http://patchwork.kernel.org/project/linux-btrfs/list/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs.git S: Maintained F: Documentation/filesystems/btrfs.txt F: fs/btrfs/ @@ -1743,10 +1743,10 @@ F: include/linux/can/platform/ CAPABILITIES M: Serge Hallyn L: linux-security-module@vger.kernel.org -S: Supported +S: Supported F: include/linux/capability.h F: security/capability.c -F: security/commoncap.c +F: security/commoncap.c F: kernel/capability.c CELL BROADBAND ENGINE ARCHITECTURE @@ -1800,6 +1800,9 @@ F: include/linux/cfag12864b.h CFG80211 and NL80211 M: Johannes Berg L: linux-wireless@vger.kernel.org +W: http://wireless.kernel.org/ +T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git S: Maintained F: include/linux/nl80211.h F: include/net/cfg80211.h @@ -1905,6 +1908,16 @@ F: Documentation/filesystems/coda.txt F: fs/coda/ F: include/linux/coda*.h +COMMON CLK FRAMEWORK +M: Mike Turquette +M: Mike Turquette +L: linux-arm-kernel@lists.infradead.org (same as CLK API & CLKDEV) +T: git git://git.linaro.org/people/mturquette/linux.git +S: Maintained +F: drivers/clk/clk.c +F: drivers/clk/clk-* +F: include/linux/clk-pr* + COMMON INTERNET FILE SYSTEM (CIFS) M: Steve French L: linux-cifs@vger.kernel.org @@ -2136,11 +2149,11 @@ S: Orphan F: drivers/net/wan/pc300* CYTTSP TOUCHSCREEN DRIVER -M: Javier Martinez Canillas -L: linux-input@vger.kernel.org -S: Maintained -F: drivers/input/touchscreen/cyttsp* -F: include/linux/input/cyttsp.h +M: Javier Martinez Canillas +L: linux-input@vger.kernel.org +S: Maintained +F: drivers/input/touchscreen/cyttsp* +F: include/linux/input/cyttsp.h DAMA SLAVE for AX.25 M: Joerg Reuter @@ -2260,7 +2273,7 @@ F: include/linux/device-mapper.h F: include/linux/dm-*.h DIOLAN U2C-12 I2C DRIVER -M: Guenter Roeck +M: Guenter Roeck L: linux-i2c@vger.kernel.org S: Maintained F: drivers/i2c/busses/i2c-diolan-u2c.c @@ -2808,6 +2821,12 @@ F: Documentation/firmware_class/ F: drivers/base/firmware*.c F: include/linux/firmware.h +FLOPPY DRIVER +M: Jiri Kosina +T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/floppy.git +S: Odd fixes +F: drivers/block/floppy.c + FPU EMULATOR M: Bill Metzenthen W: http://floatingpoint.sourceforge.net/emulator/index.html @@ -2914,6 +2933,13 @@ F: Documentation/power/freezing-of-tasks.txt F: include/linux/freezer.h F: kernel/freezer.c +FRONTSWAP API +M: Konrad Rzeszutek Wilk +L: linux-kernel@vger.kernel.org +S: Maintained +F: mm/frontswap.c +F: include/linux/frontswap.h + FS-CACHE: LOCAL CACHING FOR NETWORK FILESYSTEMS M: David Howells L: linux-cachefs@redhat.com @@ -2978,9 +3004,9 @@ GENERIC GPIO I2C MULTIPLEXER DRIVER M: Peter Korsgaard L: linux-i2c@vger.kernel.org S: Supported -F: drivers/i2c/muxes/gpio-i2cmux.c -F: include/linux/gpio-i2cmux.h -F: Documentation/i2c/muxes/gpio-i2cmux +F: drivers/i2c/muxes/i2c-mux-gpio.c +F: include/linux/i2c-mux-gpio.h +F: Documentation/i2c/muxes/i2c-mux-gpio GENERIC HDLC (WAN) DRIVERS M: Krzysztof Halasa @@ -3122,7 +3148,7 @@ F: drivers/tty/hvc/ HARDWARE MONITORING M: Jean Delvare -M: Guenter Roeck +M: Guenter Roeck L: lm-sensors@lm-sensors.org W: http://www.lm-sensors.org/ T: quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-hwmon/ @@ -3222,10 +3248,8 @@ F: include/linux/clockchips.h F: include/linux/hrtimer.h HIGH-SPEED SCC DRIVER FOR AX.25 -M: Klaus Kudielka L: linux-hams@vger.kernel.org -W: http://www.nt.tuwien.ac.at/~kkudielk/Linux/ -S: Maintained +S: Orphan F: drivers/net/hamradio/dmascc.c F: drivers/net/hamradio/scc.c @@ -3372,6 +3396,12 @@ W: http://www.developer.ibm.com/welcome/netfinity/serveraid.html S: Supported F: drivers/scsi/ips.* +ICH LPC AND GPIO DRIVER +M: Peter Tyser +S: Maintained +F: drivers/mfd/lpc_ich.c +F: drivers/gpio/gpio-ich.c + IDE SUBSYSTEM M: "David S. Miller" L: linux-ide@vger.kernel.org @@ -4076,6 +4106,8 @@ F: drivers/scsi/53c700* LED SUBSYSTEM M: Bryan Wu M: Richard Purdie +L: linux-leds@vger.kernel.org +T: git git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/linux-leds.git S: Maintained F: drivers/leds/ F: include/linux/leds.h @@ -4320,7 +4352,8 @@ MAC80211 M: Johannes Berg L: linux-wireless@vger.kernel.org W: http://linuxwireless.org/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git S: Maintained F: Documentation/networking/mac80211-injection.txt F: include/net/mac80211.h @@ -4331,7 +4364,8 @@ M: Stefano Brivio M: Mattias Nissler L: linux-wireless@vger.kernel.org W: http://linuxwireless.org/en/developers/Documentation/mac80211/RateControl/PID -T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git S: Maintained F: net/mac80211/rc80211_pid* @@ -4391,6 +4425,13 @@ S: Orphan F: drivers/video/matrox/matroxfb_* F: include/linux/matroxfb.h +MAX16065 HARDWARE MONITOR DRIVER +M: Guenter Roeck +L: lm-sensors@lm-sensors.org +S: Maintained +F: Documentation/hwmon/max16065 +F: drivers/hwmon/max16065.c + MAX6650 HARDWARE MONITOR AND FAN CONTROLLER DRIVER M: "Hans J. Koch" L: lm-sensors@lm-sensors.org @@ -4495,12 +4536,6 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: drivers/mmc/host/imxmmc.* -MOUSE AND MISC DEVICES [GENERAL] -M: Alessandro Rubini -S: Maintained -F: drivers/input/mouse/ -F: include/linux/gpio_mouse.h - MOXA SMARTIO/INDUSTIO/INTELLIO SERIAL CARD M: Jiri Slaby S: Maintained @@ -5135,10 +5170,10 @@ F: drivers/leds/leds-pca9532.c F: include/linux/leds-pca9532.h PCA9541 I2C BUS MASTER SELECTOR DRIVER -M: Guenter Roeck +M: Guenter Roeck L: linux-i2c@vger.kernel.org S: Maintained -F: drivers/i2c/muxes/pca9541.c +F: drivers/i2c/muxes/i2c-mux-pca9541.c PCA9564/PCA9665 I2C BUS DRIVER M: Wolfram Sang @@ -5155,7 +5190,7 @@ S: Maintained F: drivers/firmware/pcdp.* PCI ERROR RECOVERY -M: Linas Vepstas +M: Linas Vepstas L: linux-pci@vger.kernel.org S: Supported F: Documentation/PCI/pci-error-recovery.txt @@ -5261,7 +5296,7 @@ S: Maintained F: drivers/pinctrl/ PIN CONTROLLER - ST SPEAR -M: Viresh Kumar +M: Viresh Kumar L: spear-devel@list.st.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) W: http://www.st.com/spear @@ -5285,7 +5320,7 @@ F: drivers/video/fb-puv3.c F: drivers/rtc/rtc-puv3.c PMBUS HARDWARE MONITORING DRIVERS -M: Guenter Roeck +M: Guenter Roeck L: lm-sensors@lm-sensors.org W: http://www.lm-sensors.org/ W: http://www.roeck-us.net/linux/drivers/ @@ -5323,7 +5358,7 @@ M: David Woodhouse T: git git://git.infradead.org/battery-2.6.git S: Maintained F: include/linux/power_supply.h -F: drivers/power/power_supply* +F: drivers/power/ PNP SUPPORT M: Adam Belay @@ -5681,6 +5716,9 @@ F: include/linux/remoteproc.h RFKILL M: Johannes Berg L: linux-wireless@vger.kernel.org +W: http://wireless.kernel.org/ +T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git S: Maintained F: Documentation/rfkill.txt F: net/rfkill/ @@ -5835,7 +5873,7 @@ S: Maintained F: drivers/tty/serial SYNOPSYS DESIGNWARE DMAC DRIVER -M: Viresh Kumar +M: Viresh Kumar S: Maintained F: include/linux/dw_dmac.h F: drivers/dma/dw_dmac_regs.h @@ -5983,7 +6021,7 @@ S: Maintained F: drivers/mmc/host/sdhci-s3c.c SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) ST SPEAR DRIVER -M: Viresh Kumar +M: Viresh Kumar L: spear-devel@list.st.com L: linux-mmc@vger.kernel.org S: Maintained @@ -6339,15 +6377,26 @@ S: Maintained F: include/linux/compiler.h SPEAR PLATFORM SUPPORT -M: Viresh Kumar +M: Viresh Kumar +M: Shiraz Hashim L: spear-devel@list.st.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) W: http://www.st.com/spear S: Maintained F: arch/arm/plat-spear/ +SPEAR13XX MACHINE SUPPORT +M: Viresh Kumar +M: Shiraz Hashim +L: spear-devel@list.st.com +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +W: http://www.st.com/spear +S: Maintained +F: arch/arm/mach-spear13xx/ + SPEAR3XX MACHINE SUPPORT -M: Viresh Kumar +M: Viresh Kumar +M: Shiraz Hashim L: spear-devel@list.st.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) W: http://www.st.com/spear @@ -6356,6 +6405,8 @@ F: arch/arm/mach-spear3xx/ SPEAR6XX MACHINE SUPPORT M: Rajeev Kumar +M: Shiraz Hashim +M: Viresh Kumar L: spear-devel@list.st.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) W: http://www.st.com/spear @@ -6363,14 +6414,12 @@ S: Maintained F: arch/arm/mach-spear6xx/ SPEAR CLOCK FRAMEWORK SUPPORT -M: Viresh Kumar +M: Viresh Kumar L: spear-devel@list.st.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) W: http://www.st.com/spear S: Maintained -F: arch/arm/mach-spear*/clock.c -F: arch/arm/plat-spear/clock.c -F: arch/arm/plat-spear/include/plat/clock.h +F: drivers/clk/spear/ SPI SUBSYSTEM M: Grant Likely @@ -6632,7 +6681,7 @@ F: include/linux/taskstats* F: kernel/taskstats.c TC CLASSIFIER -M: Jamal Hadi Salim +M: Jamal Hadi Salim L: netdev@vger.kernel.org S: Maintained F: include/linux/pkt_cls.h @@ -7266,11 +7315,11 @@ F: Documentation/DocBook/uio-howto.tmpl F: drivers/uio/ F: include/linux/uio*.h -UTIL-LINUX-NG PACKAGE +UTIL-LINUX PACKAGE M: Karel Zak -L: util-linux-ng@vger.kernel.org -W: http://kernel.org/~kzak/util-linux-ng/ -T: git git://git.kernel.org/pub/scm/utils/util-linux-ng/util-linux-ng.git +L: util-linux@vger.kernel.org +W: http://en.wikipedia.org/wiki/Util-linux +T: git git://git.kernel.org/pub/scm/utils/util-linux/util-linux.git S: Maintained UVESAFB DRIVER @@ -7372,7 +7421,7 @@ F: include/linux/vlynq.h VME SUBSYSTEM M: Martyn Welch -M: Manohar Vanga +M: Manohar Vanga M: Greg Kroah-Hartman L: devel@driverdev.osuosl.org S: Maintained diff --git a/trunk/Makefile b/trunk/Makefile index b62c1e09444a..81ea15450049 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 3 -PATCHLEVEL = 4 +PATCHLEVEL = 5 SUBLEVEL = 0 -EXTRAVERSION = +EXTRAVERSION = -rc5 NAME = Saber-toothed Squirrel # *DOCUMENTATION* @@ -231,10 +231,6 @@ endif # Where to locate arch specific headers hdr-arch := $(SRCARCH) -ifeq ($(ARCH),m68knommu) - hdr-arch := m68k -endif - KCONFIG_CONFIG ?= .config export KCONFIG_CONFIG @@ -341,7 +337,6 @@ AWK = awk GENKSYMS = scripts/genksyms/genksyms INSTALLKERNEL := installkernel DEPMOD = /sbin/depmod -KALLSYMS = scripts/kallsyms PERL = perl CHECK = sparse @@ -566,6 +561,8 @@ else KBUILD_CFLAGS += -O2 endif +include $(srctree)/arch/$(SRCARCH)/Makefile + ifdef CONFIG_READABLE_ASM # Disable optimizations that make assembler listings hard to read. # reorder blocks reorders the control in the function @@ -576,8 +573,6 @@ KBUILD_CFLAGS += $(call cc-option,-fno-reorder-blocks,) \ $(call cc-option,-fno-partial-inlining) endif -include $(srctree)/arch/$(SRCARCH)/Makefile - ifneq ($(CONFIG_FRAME_WARN),0) KBUILD_CFLAGS += $(call cc-option,-Wframe-larger-than=${CONFIG_FRAME_WARN}) endif @@ -739,197 +734,21 @@ libs-y1 := $(patsubst %/, %/lib.a, $(libs-y)) libs-y2 := $(patsubst %/, %/built-in.o, $(libs-y)) libs-y := $(libs-y1) $(libs-y2) -# Build vmlinux -# --------------------------------------------------------------------------- -# vmlinux is built from the objects selected by $(vmlinux-init) and -# $(vmlinux-main). Most are built-in.o files from top-level directories -# in the kernel tree, others are specified in arch/$(ARCH)/Makefile. -# Ordering when linking is important, and $(vmlinux-init) must be first. -# -# vmlinux -# ^ -# | -# +-< $(vmlinux-init) -# | +--< init/version.o + more -# | -# +--< $(vmlinux-main) -# | +--< driver/built-in.o mm/built-in.o + more -# | -# +-< kallsyms.o (see description in CONFIG_KALLSYMS section) -# -# vmlinux version (uname -v) cannot be updated during normal -# descending-into-subdirs phase since we do not yet know if we need to -# update vmlinux. -# Therefore this step is delayed until just before final link of vmlinux - -# except in the kallsyms case where it is done just before adding the -# symbols to the kernel. -# -# System.map is generated to document addresses of all kernel symbols - -vmlinux-init := $(head-y) $(init-y) -vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y) -vmlinux-all := $(vmlinux-init) $(vmlinux-main) -vmlinux-lds := arch/$(SRCARCH)/kernel/vmlinux.lds -export KBUILD_VMLINUX_OBJS := $(vmlinux-all) - -# Rule to link vmlinux - also used during CONFIG_KALLSYMS -# May be overridden by arch/$(ARCH)/Makefile -quiet_cmd_vmlinux__ ?= LD $@ - cmd_vmlinux__ ?= $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) -o $@ \ - -T $(vmlinux-lds) $(vmlinux-init) \ - --start-group $(vmlinux-main) --end-group \ - $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o FORCE ,$^) - -# Generate new vmlinux version -quiet_cmd_vmlinux_version = GEN .version - cmd_vmlinux_version = set -e; \ - if [ ! -r .version ]; then \ - rm -f .version; \ - echo 1 >.version; \ - else \ - mv .version .old_version; \ - expr 0$$(cat .old_version) + 1 >.version; \ - fi; \ - $(MAKE) $(build)=init - -# Generate System.map -quiet_cmd_sysmap = SYSMAP - cmd_sysmap = $(CONFIG_SHELL) $(srctree)/scripts/mksysmap - -# Sort exception table at build time -quiet_cmd_sortextable = SORTEX - cmd_sortextable = $(objtree)/scripts/sortextable - -# Link of vmlinux -# If CONFIG_KALLSYMS is set .version is already updated -# Generate System.map and verify that the content is consistent -# Use + in front of the vmlinux_version rule to silent warning with make -j2 -# First command is ':' to allow us to use + in front of the rule -define rule_vmlinux__ - : - $(if $(CONFIG_KALLSYMS),,+$(call cmd,vmlinux_version)) - - $(call cmd,vmlinux__) - $(Q)echo 'cmd_$@ := $(cmd_vmlinux__)' > $(@D)/.$(@F).cmd - - $(if $(CONFIG_BUILDTIME_EXTABLE_SORT), \ - $(Q)$(if $($(quiet)cmd_sortextable), \ - echo ' $($(quiet)cmd_sortextable) vmlinux' &&) \ - $(cmd_sortextable) vmlinux) - - - $(Q)$(if $($(quiet)cmd_sysmap), \ - echo ' $($(quiet)cmd_sysmap) System.map' &&) \ - $(cmd_sysmap) $@ System.map; \ - if [ $$? -ne 0 ]; then \ - rm -f $@; \ - /bin/false; \ - fi; - $(verify_kallsyms) -endef - +# Externally visible symbols (used by link-vmlinux.sh) +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 -ifdef CONFIG_KALLSYMS -# Generate section listing all symbols and add it into vmlinux $(kallsyms.o) -# It's a three stage process: -# o .tmp_vmlinux1 has all symbols and sections, but __kallsyms is -# empty -# Running kallsyms on that gives us .tmp_kallsyms1.o with -# the right size - vmlinux version (uname -v) is updated during this step -# o .tmp_vmlinux2 now has a __kallsyms section of the right size, -# but due to the added section, some addresses have shifted. -# From here, we generate a correct .tmp_kallsyms2.o -# o The correct .tmp_kallsyms2.o is linked into the final vmlinux. -# o Verify that the System.map from vmlinux matches the map from -# .tmp_vmlinux2, just in case we did not generate kallsyms correctly. -# o If 'make KALLSYMS_EXTRA_PASS=1" was used, do an extra pass using -# .tmp_vmlinux3 and .tmp_kallsyms3.o. This is only meant as a -# temporary bypass to allow the kernel to be built while the -# maintainers work out what went wrong with kallsyms. - -last_kallsyms := 2 - -ifdef KALLSYMS_EXTRA_PASS -ifneq ($(KALLSYMS_EXTRA_PASS),0) -last_kallsyms := 3 -endif -endif - -kallsyms.o := .tmp_kallsyms$(last_kallsyms).o - -define verify_kallsyms - $(Q)$(if $($(quiet)cmd_sysmap), \ - echo ' $($(quiet)cmd_sysmap) .tmp_System.map' &&) \ - $(cmd_sysmap) .tmp_vmlinux$(last_kallsyms) .tmp_System.map - $(Q)cmp -s System.map .tmp_System.map || \ - (echo Inconsistent kallsyms data; \ - echo This is a bug - please report about it; \ - echo Try "make KALLSYMS_EXTRA_PASS=1" as a workaround; \ - rm .tmp_kallsyms* ; /bin/false ) -endef - -# Update vmlinux version before link -# Use + in front of this rule to silent warning about make -j1 -# First command is ':' to allow us to use + in front of this rule -cmd_ksym_ld = $(cmd_vmlinux__) -define rule_ksym_ld - : - +$(call cmd,vmlinux_version) - $(call cmd,vmlinux__) - $(Q)echo 'cmd_$@ := $(cmd_vmlinux__)' > $(@D)/.$(@F).cmd -endef +vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_INIT) $(KBUILD_VMLINUX_MAIN) -# Generate .S file with all kernel symbols -quiet_cmd_kallsyms = KSYM $@ - cmd_kallsyms = $(NM) -n $< | $(KALLSYMS) \ - $(if $(CONFIG_KALLSYMS_ALL),--all-symbols) > $@ +# Final link of vmlinux + cmd_link-vmlinux = $(CONFIG_SHELL) $< $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) +quiet_cmd_link-vmlinux = LINK $@ -.tmp_kallsyms1.o .tmp_kallsyms2.o .tmp_kallsyms3.o: %.o: %.S scripts FORCE - $(call if_changed_dep,as_o_S) - -.tmp_kallsyms%.S: .tmp_vmlinux% $(KALLSYMS) - $(call cmd,kallsyms) - -# .tmp_vmlinux1 must be complete except kallsyms, so update vmlinux version -.tmp_vmlinux1: $(vmlinux-lds) $(vmlinux-all) FORCE - $(call if_changed_rule,ksym_ld) - -.tmp_vmlinux2: $(vmlinux-lds) $(vmlinux-all) .tmp_kallsyms1.o FORCE - $(call if_changed,vmlinux__) - -.tmp_vmlinux3: $(vmlinux-lds) $(vmlinux-all) .tmp_kallsyms2.o FORCE - $(call if_changed,vmlinux__) - -# Needs to visit scripts/ before $(KALLSYMS) can be used. -$(KALLSYMS): scripts ; - -# Generate some data for debugging strange kallsyms problems -debug_kallsyms: .tmp_map$(last_kallsyms) - -.tmp_map%: .tmp_vmlinux% FORCE - ($(OBJDUMP) -h $< | $(AWK) '/^ +[0-9]/{print $$4 " 0 " $$2}'; $(NM) $<) | sort > $@ - -.tmp_map3: .tmp_map2 - -.tmp_map2: .tmp_map1 - -endif # ifdef CONFIG_KALLSYMS - -# Do modpost on a prelinked vmlinux. The finally linked vmlinux has -# relevant sections renamed as per the linker script. -quiet_cmd_vmlinux-modpost = LD $@ - cmd_vmlinux-modpost = $(LD) $(LDFLAGS) -r -o $@ \ - $(vmlinux-init) --start-group $(vmlinux-main) --end-group \ - $(filter-out $(vmlinux-init) $(vmlinux-main) FORCE ,$^) -define rule_vmlinux-modpost - : - +$(call cmd,vmlinux-modpost) - $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $@ - $(Q)echo 'cmd_$@ := $(cmd_vmlinux-modpost)' > $(dot-target).cmd -endef - -# vmlinux image - including updated kernel symbols -vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o $(kallsyms.o) FORCE +# Include targets which we want to +# execute if the rest of the kernel build went well. +vmlinux: scripts/link-vmlinux.sh $(vmlinux-deps) FORCE ifdef CONFIG_HEADERS_CHECK $(Q)$(MAKE) -f $(srctree)/Makefile headers_check endif @@ -939,22 +758,11 @@ endif ifdef CONFIG_BUILD_DOCSRC $(Q)$(MAKE) $(build)=Documentation endif - $(call vmlinux-modpost) - $(call if_changed_rule,vmlinux__) - $(Q)rm -f .old_version - -# build vmlinux.o first to catch section mismatch errors early -ifdef CONFIG_KALLSYMS -.tmp_vmlinux1: vmlinux.o -endif - -modpost-init := $(filter-out init/built-in.o, $(vmlinux-init)) -vmlinux.o: $(modpost-init) $(vmlinux-main) FORCE - $(call if_changed_rule,vmlinux-modpost) + +$(call if_changed,link-vmlinux) # The actual objects are generated when descending, # make sure no implicit rule kicks in -$(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ; +$(sort $(vmlinux-deps)): $(vmlinux-dirs) ; # Handle descending into subdirectories listed in $(vmlinux-dirs) # Preset locale variables to speed up the build process. Limit locale @@ -1181,8 +989,6 @@ endif # CONFIG_MODULES # Directories & files removed with 'make clean' CLEAN_DIRS += $(MODVERDIR) -CLEAN_FILES += vmlinux System.map \ - .tmp_kallsyms* .tmp_version .tmp_vmlinux* .tmp_System.map # Directories & files removed with 'make mrproper' MRPROPER_DIRS += include/config usr/include include/generated \ @@ -1428,6 +1234,7 @@ scripts: ; endif # KBUILD_EXTMOD clean: $(clean-dirs) + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/link-vmlinux.sh clean $(call cmd,rmdirs) $(call cmd,rmfiles) @find $(if $(KBUILD_EXTMOD), $(KBUILD_EXTMOD), .) $(RCS_FIND_IGNORE) \ @@ -1568,14 +1375,6 @@ quiet_cmd_depmod = DEPMOD $(KERNELRELEASE) cmd_crmodverdir = $(Q)mkdir -p $(MODVERDIR) \ $(if $(KBUILD_MODULES),; rm -f $(MODVERDIR)/*) -a_flags = -Wp,-MD,$(depfile) $(KBUILD_AFLAGS) $(AFLAGS_KERNEL) \ - $(KBUILD_AFLAGS_KERNEL) \ - $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(KBUILD_CPPFLAGS) \ - $(modkern_aflags) $(EXTRA_AFLAGS) $(AFLAGS_$(basetarget).o) - -quiet_cmd_as_o_S = AS $@ -cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< - # read all saved command lines targets := $(wildcard $(sort $(targets))) diff --git a/trunk/arch/Kconfig b/trunk/arch/Kconfig index e9a910876cda..8c3d957fa8e2 100644 --- a/trunk/arch/Kconfig +++ b/trunk/arch/Kconfig @@ -159,6 +159,9 @@ config HAVE_ARCH_TRACEHOOK config HAVE_DMA_ATTRS bool +config HAVE_DMA_CONTIGUOUS + bool + config USE_GENERIC_SMP_HELPERS bool diff --git a/trunk/arch/alpha/include/asm/posix_types.h b/trunk/arch/alpha/include/asm/posix_types.h index 24779fc95994..5a8a48320efe 100644 --- a/trunk/arch/alpha/include/asm/posix_types.h +++ b/trunk/arch/alpha/include/asm/posix_types.h @@ -10,9 +10,6 @@ typedef unsigned int __kernel_ino_t; #define __kernel_ino_t __kernel_ino_t -typedef unsigned int __kernel_nlink_t; -#define __kernel_nlink_t __kernel_nlink_t - typedef unsigned long __kernel_sigset_t; /* at least 32 bits */ #include diff --git a/trunk/arch/alpha/kernel/signal.c b/trunk/arch/alpha/kernel/signal.c index 10ab2d74ecbb..a8c97d42ec8e 100644 --- a/trunk/arch/alpha/kernel/signal.c +++ b/trunk/arch/alpha/kernel/signal.c @@ -226,7 +226,6 @@ do_sigreturn(struct sigcontext __user *sc, struct pt_regs *regs, if (__get_user(set.sig[0], &sc->sc_mask)) goto give_sigsegv; - sigdelsetmask(&set, ~_BLOCKABLE); set_current_blocked(&set); if (restore_sigcontext(sc, regs, sw)) @@ -261,7 +260,6 @@ do_rt_sigreturn(struct rt_sigframe __user *frame, struct pt_regs *regs, if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) goto give_sigsegv; - sigdelsetmask(&set, ~_BLOCKABLE); set_current_blocked(&set); if (restore_sigcontext(&frame->uc.uc_mcontext, regs, sw)) @@ -468,12 +466,9 @@ static inline void handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, struct pt_regs * regs, struct switch_stack *sw) { - sigset_t *oldset = ¤t->blocked; + sigset_t *oldset = sigmask_to_save(); int ret; - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - oldset = ¤t->saved_sigmask; - if (ka->sa.sa_flags & SA_SIGINFO) ret = setup_rt_frame(sig, ka, info, oldset, regs, sw); else @@ -483,12 +478,7 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, force_sigsegv(sig, current); return; } - block_sigmask(ka, sig); - /* A signal was successfully delivered, and the - saved sigmask was stored on the signal frame, - and will be restored by sigreturn. So we can - simply clear the restore sigmask flag. */ - clear_thread_flag(TIF_RESTORE_SIGMASK); + signal_delivered(sig, info, ka, regs, 0); } static inline void @@ -572,9 +562,7 @@ do_signal(struct pt_regs * regs, struct switch_stack * sw, } /* If there's no signal to deliver, we just restore the saved mask. */ - if (test_and_clear_thread_flag(TIF_RESTORE_SIGMASK)) - set_current_blocked(¤t->saved_sigmask); - + restore_saved_sigmask(); if (single_stepping) ptrace_set_bpt(current); /* re-set breakpoint */ } @@ -590,7 +578,5 @@ do_notify_resume(struct pt_regs *regs, struct switch_stack *sw, if (thread_info_flags & _TIF_NOTIFY_RESUME) { clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); - if (current->replacement_session_keyring) - key_replace_session_keyring(); } } diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index 5458aa9db067..a91009c61870 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -5,6 +5,8 @@ config ARM select HAVE_AOUT select HAVE_DMA_API_DEBUG select HAVE_IDE if PCI || ISA || PCMCIA + select HAVE_DMA_ATTRS + select HAVE_DMA_CONTIGUOUS if (CPU_V6 || CPU_V6K || CPU_V7) select HAVE_MEMBLOCK select RTC_LIB select SYS_SUPPORTS_APM_EMULATION @@ -54,6 +56,14 @@ config ARM config ARM_HAS_SG_CHAIN bool +config NEED_SG_DMA_LENGTH + bool + +config ARM_DMA_USE_IOMMU + select NEED_SG_DMA_LENGTH + select ARM_HAS_SG_CHAIN + bool + config HAVE_PWM bool @@ -283,6 +293,7 @@ config ARCH_VERSATILE select ICST select GENERIC_CLOCKEVENTS select ARCH_WANT_OPTIONAL_GPIOLIB + select NEED_MACH_IO_H if PCI select PLAT_VERSATILE select PLAT_VERSATILE_CLCD select PLAT_VERSATILE_FPGA_IRQ @@ -445,8 +456,10 @@ config ARCH_MXS select ARCH_REQUIRE_GPIOLIB select CLKDEV_LOOKUP select CLKSRC_MMIO + select COMMON_CLK select HAVE_CLK_PREPARE select PINCTRL + select USE_OF help Support for Freescale MXS-based family of processors @@ -512,7 +525,7 @@ config ARCH_IXP4XX select ARCH_HAS_DMA_SET_COHERENT_MASK select CLKSRC_MMIO select CPU_XSCALE - select GENERIC_GPIO + select ARCH_REQUIRE_GPIOLIB select GENERIC_CLOCKEVENTS select MIGHT_HAVE_PCI select NEED_MACH_IO_H @@ -576,6 +589,7 @@ config ARCH_ORION5X select PCI select ARCH_REQUIRE_GPIOLIB select GENERIC_CLOCKEVENTS + select NEED_MACH_IO_H select PLAT_ORION help Support for the following Marvell Orion 5x series SoCs: @@ -936,6 +950,7 @@ config PLAT_SPEAR select ARM_AMBA select ARCH_REQUIRE_GPIOLIB select CLKDEV_LOOKUP + select COMMON_CLK select CLKSRC_MMIO select GENERIC_CLOCKEVENTS select HAVE_CLK @@ -1040,7 +1055,6 @@ source "arch/arm/mach-sa1100/Kconfig" source "arch/arm/plat-samsung/Kconfig" source "arch/arm/plat-s3c24xx/Kconfig" -source "arch/arm/plat-s5p/Kconfig" source "arch/arm/plat-spear/Kconfig" @@ -1091,6 +1105,7 @@ config PLAT_ORION bool select CLKSRC_MMIO select GENERIC_IRQ_CHIP + select COMMON_CLK config PLAT_PXA bool diff --git a/trunk/arch/arm/Kconfig.debug b/trunk/arch/arm/Kconfig.debug index 85348a09d655..01a134141216 100644 --- a/trunk/arch/arm/Kconfig.debug +++ b/trunk/arch/arm/Kconfig.debug @@ -103,6 +103,35 @@ choice Say Y here if you want the debug print routines to direct their output to the second serial port on these devices. + config DEBUG_DAVINCI_DA8XX_UART1 + bool "Kernel low-level debugging on DaVinci DA8XX using UART1" + depends on ARCH_DAVINCI_DA8XX + help + Say Y here if you want the debug print routines to direct + their output to UART1 serial port on DaVinci DA8XX devices. + + config DEBUG_DAVINCI_DA8XX_UART2 + bool "Kernel low-level debugging on DaVinci DA8XX using UART2" + depends on ARCH_DAVINCI_DA8XX + help + Say Y here if you want the debug print routines to direct + their output to UART2 serial port on DaVinci DA8XX devices. + + config DEBUG_DAVINCI_DMx_UART0 + bool "Kernel low-level debugging on DaVinci DMx using UART0" + depends on ARCH_DAVINCI_DMx + help + Say Y here if you want the debug print routines to direct + their output to UART0 serial port on DaVinci DMx devices. + + config DEBUG_DAVINCI_TNETV107X_UART1 + bool "Kernel low-level debugging on DaVinci TNETV107x using UART1" + depends on ARCH_DAVINCI_TNETV107X + help + Say Y here if you want the debug print routines to direct + their output to UART1 serial port on DaVinci TNETV107X + devices. + config DEBUG_DC21285_PORT bool "Kernel low-level debugging messages via footbridge serial port" depends on FOOTBRIDGE @@ -180,6 +209,14 @@ choice Say Y here if you want kernel low-level debugging support on i.MX50 or i.MX53. + config DEBUG_IMX6Q_UART2 + bool "i.MX6Q Debug UART2" + depends on SOC_IMX6Q + help + Say Y here if you want kernel low-level debugging support + on i.MX6Q UART2. This is correct for e.g. the SabreLite + board. + config DEBUG_IMX6Q_UART4 bool "i.MX6Q Debug UART4" depends on SOC_IMX6Q diff --git a/trunk/arch/arm/Makefile b/trunk/arch/arm/Makefile index 157900da8782..0298b00fe241 100644 --- a/trunk/arch/arm/Makefile +++ b/trunk/arch/arm/Makefile @@ -160,9 +160,7 @@ machine-$(CONFIG_ARCH_MXS) := mxs machine-$(CONFIG_ARCH_NETX) := netx machine-$(CONFIG_ARCH_NOMADIK) := nomadik machine-$(CONFIG_ARCH_OMAP1) := omap1 -machine-$(CONFIG_ARCH_OMAP2) := omap2 -machine-$(CONFIG_ARCH_OMAP3) := omap2 -machine-$(CONFIG_ARCH_OMAP4) := omap2 +machine-$(CONFIG_ARCH_OMAP2PLUS) := omap2 machine-$(CONFIG_ARCH_ORION5X) := orion5x machine-$(CONFIG_ARCH_PICOXCELL) := picoxcell machine-$(CONFIG_ARCH_PNX4008) := pnx4008 @@ -188,6 +186,8 @@ machine-$(CONFIG_ARCH_VEXPRESS) := vexpress machine-$(CONFIG_ARCH_VT8500) := vt8500 machine-$(CONFIG_ARCH_W90X900) := w90x900 machine-$(CONFIG_FOOTBRIDGE) := footbridge +machine-$(CONFIG_MACH_SPEAR1310) := spear13xx +machine-$(CONFIG_MACH_SPEAR1340) := spear13xx machine-$(CONFIG_MACH_SPEAR300) := spear3xx machine-$(CONFIG_MACH_SPEAR310) := spear3xx machine-$(CONFIG_MACH_SPEAR320) := spear3xx @@ -205,7 +205,7 @@ plat-$(CONFIG_PLAT_NOMADIK) := nomadik plat-$(CONFIG_PLAT_ORION) := orion plat-$(CONFIG_PLAT_PXA) := pxa plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx samsung -plat-$(CONFIG_PLAT_S5P) := s5p samsung +plat-$(CONFIG_PLAT_S5P) := samsung plat-$(CONFIG_PLAT_SPEAR) := spear plat-$(CONFIG_PLAT_VERSATILE) := versatile diff --git a/trunk/arch/arm/boot/dts/db8500.dtsi b/trunk/arch/arm/boot/dts/db8500.dtsi index 881bc3987844..4ad5160018cb 100644 --- a/trunk/arch/arm/boot/dts/db8500.dtsi +++ b/trunk/arch/arm/boot/dts/db8500.dtsi @@ -58,6 +58,8 @@ "st,nomadik-gpio"; reg = <0x8012e000 0x80>; interrupts = <0 119 0x4>; + interrupt-controller; + #interrupt-cells = <2>; supports-sleepmode; gpio-controller; #gpio-cells = <2>; @@ -69,6 +71,8 @@ "st,nomadik-gpio"; reg = <0x8012e080 0x80>; interrupts = <0 120 0x4>; + interrupt-controller; + #interrupt-cells = <2>; supports-sleepmode; gpio-controller; #gpio-cells = <2>; @@ -80,6 +84,8 @@ "st,nomadik-gpio"; reg = <0x8000e000 0x80>; interrupts = <0 121 0x4>; + interrupt-controller; + #interrupt-cells = <2>; supports-sleepmode; gpio-controller; #gpio-cells = <2>; @@ -91,6 +97,8 @@ "st,nomadik-gpio"; reg = <0x8000e080 0x80>; interrupts = <0 122 0x4>; + interrupt-controller; + #interrupt-cells = <2>; supports-sleepmode; gpio-controller; #gpio-cells = <2>; @@ -102,6 +110,8 @@ "st,nomadik-gpio"; reg = <0x8000e100 0x80>; interrupts = <0 123 0x4>; + interrupt-controller; + #interrupt-cells = <2>; supports-sleepmode; gpio-controller; #gpio-cells = <2>; @@ -113,6 +123,8 @@ "st,nomadik-gpio"; reg = <0x8000e180 0x80>; interrupts = <0 124 0x4>; + interrupt-controller; + #interrupt-cells = <2>; supports-sleepmode; gpio-controller; #gpio-cells = <2>; @@ -124,6 +136,8 @@ "st,nomadik-gpio"; reg = <0x8011e000 0x80>; interrupts = <0 125 0x4>; + interrupt-controller; + #interrupt-cells = <2>; supports-sleepmode; gpio-controller; #gpio-cells = <2>; @@ -135,6 +149,8 @@ "st,nomadik-gpio"; reg = <0x8011e080 0x80>; interrupts = <0 126 0x4>; + interrupt-controller; + #interrupt-cells = <2>; supports-sleepmode; gpio-controller; #gpio-cells = <2>; @@ -146,12 +162,18 @@ "st,nomadik-gpio"; reg = <0xa03fe000 0x80>; interrupts = <0 127 0x4>; + interrupt-controller; + #interrupt-cells = <2>; supports-sleepmode; gpio-controller; #gpio-cells = <2>; gpio-bank = <8>; }; + pinctrl { + compatible = "stericsson,nmk_pinctrl"; + }; + usb@a03e0000 { compatible = "stericsson,db8500-musb", "mentor,musb"; @@ -169,20 +191,195 @@ prcmu@80157000 { compatible = "stericsson,db8500-prcmu"; reg = <0x80157000 0x1000>; - interrupts = <46 47>; + interrupts = <0 47 0x4>; #address-cells = <1>; #size-cells = <1>; ranges; - prcmu-timer-4@80157450 { + prcmu-timer-4@80157450 { compatible = "stericsson,db8500-prcmu-timer-4"; reg = <0x80157450 0xC>; }; + db8500-prcmu-regulators { + compatible = "stericsson,db8500-prcmu-regulator"; + + // DB8500_REGULATOR_VAPE + db8500_vape_reg: db8500_vape { + regulator-name = "db8500-vape"; + regulator-always-on; + }; + + // DB8500_REGULATOR_VARM + db8500_varm_reg: db8500_varm { + regulator-name = "db8500-varm"; + }; + + // DB8500_REGULATOR_VMODEM + db8500_vmodem_reg: db8500_vmodem { + regulator-name = "db8500-vmodem"; + }; + + // DB8500_REGULATOR_VPLL + db8500_vpll_reg: db8500_vpll { + regulator-name = "db8500-vpll"; + }; + + // DB8500_REGULATOR_VSMPS1 + db8500_vsmps1_reg: db8500_vsmps1 { + regulator-name = "db8500-vsmps1"; + }; + + // DB8500_REGULATOR_VSMPS2 + db8500_vsmps2_reg: db8500_vsmps2 { + regulator-name = "db8500-vsmps2"; + }; + + // DB8500_REGULATOR_VSMPS3 + db8500_vsmps3_reg: db8500_vsmps3 { + regulator-name = "db8500-vsmps3"; + }; + + // DB8500_REGULATOR_VRF1 + db8500_vrf1_reg: db8500_vrf1 { + regulator-name = "db8500-vrf1"; + }; + + // DB8500_REGULATOR_SWITCH_SVAMMDSP + db8500_sva_mmdsp_reg: db8500_sva_mmdsp { + regulator-name = "db8500-sva-mmdsp"; + }; + + // DB8500_REGULATOR_SWITCH_SVAMMDSPRET + db8500_sva_mmdsp_ret_reg: db8500_sva_mmdsp_ret { + regulator-name = "db8500-sva-mmdsp-ret"; + }; + + // DB8500_REGULATOR_SWITCH_SVAPIPE + db8500_sva_pipe_reg: db8500_sva_pipe { + regulator-name = "db8500_sva_pipe"; + }; + + // DB8500_REGULATOR_SWITCH_SIAMMDSP + db8500_sia_mmdsp_reg: db8500_sia_mmdsp { + regulator-name = "db8500_sia_mmdsp"; + }; + + // DB8500_REGULATOR_SWITCH_SIAMMDSPRET + db8500_sia_mmdsp_ret_reg: db8500_sia_mmdsp_ret { + regulator-name = "db8500-sia-mmdsp-ret"; + }; + + // DB8500_REGULATOR_SWITCH_SIAPIPE + db8500_sia_pipe_reg: db8500_sia_pipe { + regulator-name = "db8500-sia-pipe"; + }; + + // DB8500_REGULATOR_SWITCH_SGA + db8500_sga_reg: db8500_sga { + regulator-name = "db8500-sga"; + vin-supply = <&db8500_vape_reg>; + }; + + // DB8500_REGULATOR_SWITCH_B2R2_MCDE + db8500_b2r2_mcde_reg: db8500_b2r2_mcde { + regulator-name = "db8500-b2r2-mcde"; + vin-supply = <&db8500_vape_reg>; + }; + + // DB8500_REGULATOR_SWITCH_ESRAM12 + db8500_esram12_reg: db8500_esram12 { + regulator-name = "db8500-esram12"; + }; + + // DB8500_REGULATOR_SWITCH_ESRAM12RET + db8500_esram12_ret_reg: db8500_esram12_ret { + regulator-name = "db8500-esram12-ret"; + }; + + // DB8500_REGULATOR_SWITCH_ESRAM34 + db8500_esram34_reg: db8500_esram34 { + regulator-name = "db8500-esram34"; + }; + + // DB8500_REGULATOR_SWITCH_ESRAM34RET + db8500_esram34_ret_reg: db8500_esram34_ret { + regulator-name = "db8500-esram34-ret"; + }; + }; + ab8500@5 { compatible = "stericsson,ab8500"; reg = <5>; /* mailbox 5 is i2c */ interrupts = <0 40 0x4>; + + ab8500-regulators { + compatible = "stericsson,ab8500-regulator"; + + // supplies to the display/camera + ab8500_ldo_aux1_reg: ab8500_ldo_aux1 { + regulator-name = "V-DISPLAY"; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2900000>; + regulator-boot-on; + /* BUG: If turned off MMC will be affected. */ + regulator-always-on; + }; + + // supplies to the on-board eMMC + ab8500_ldo_aux2_reg: ab8500_ldo_aux2 { + regulator-name = "V-eMMC1"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <3300000>; + }; + + // supply for VAUX3; SDcard slots + ab8500_ldo_aux3_reg: ab8500_ldo_aux3 { + regulator-name = "V-MMC-SD"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <3300000>; + }; + + // supply for v-intcore12; VINTCORE12 LDO + ab8500_ldo_initcore_reg: ab8500_ldo_initcore { + regulator-name = "V-INTCORE"; + }; + + // supply for tvout; gpadc; TVOUT LDO + ab8500_ldo_tvout_reg: ab8500_ldo_tvout { + regulator-name = "V-TVOUT"; + }; + + // supply for ab8500-usb; USB LDO + ab8500_ldo_usb_reg: ab8500_ldo_usb { + regulator-name = "dummy"; + }; + + // supply for ab8500-vaudio; VAUDIO LDO + ab8500_ldo_audio_reg: ab8500_ldo_audio { + regulator-name = "V-AUD"; + }; + + // supply for v-anamic1 VAMic1-LDO + ab8500_ldo_anamic1_reg: ab8500_ldo_anamic1 { + regulator-name = "V-AMIC1"; + }; + + // supply for v-amic2; VAMIC2 LDO; reuse constants for AMIC1 + ab8500_ldo_amamic2_reg: ab8500_ldo_amamic2 { + regulator-name = "V-AMIC2"; + }; + + // supply for v-dmic; VDMIC LDO + ab8500_ldo_dmic_reg: ab8500_ldo_dmic { + regulator-name = "V-DMIC"; + }; + + // supply for U8500 CSI/DSI; VANA LDO + ab8500_ldo_ana_reg: ab8500_ldo_ana { + regulator-name = "V-CSI/DSI"; + }; + }; }; }; @@ -235,7 +432,8 @@ status = "disabled"; // Add one of these for each child device - cs-gpios = <&gpio0 31 &gpio4 14 &gpio4 16 &gpio6 22 &gpio7 0>; + cs-gpios = <&gpio0 31 0x4 &gpio4 14 0x4 &gpio4 16 0x4 + &gpio6 22 0x4 &gpio7 0 0x4>; }; diff --git a/trunk/arch/arm/boot/dts/exynos5250-smdk5250.dts b/trunk/arch/arm/boot/dts/exynos5250-smdk5250.dts index 399d17b231d2..49945cc1bc7d 100644 --- a/trunk/arch/arm/boot/dts/exynos5250-smdk5250.dts +++ b/trunk/arch/arm/boot/dts/exynos5250-smdk5250.dts @@ -23,4 +23,52 @@ chosen { bootargs = "root=/dev/ram0 rw ramdisk=8192 console=ttySAC1,115200"; }; + + 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"; + reg = <0x50>; + }; + }; + + 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"; + reg = <0x51>; + }; + }; + + i2c@12C80000 { + status = "disabled"; + }; + + i2c@12C90000 { + status = "disabled"; + }; + + i2c@12CA0000 { + status = "disabled"; + }; + + i2c@12CB0000 { + status = "disabled"; + }; + + i2c@12CC0000 { + status = "disabled"; + }; + + i2c@12CD0000 { + status = "disabled"; + }; }; diff --git a/trunk/arch/arm/boot/dts/exynos5250.dtsi b/trunk/arch/arm/boot/dts/exynos5250.dtsi index dfc433599436..4272b2949228 100644 --- a/trunk/arch/arm/boot/dts/exynos5250.dtsi +++ b/trunk/arch/arm/boot/dts/exynos5250.dtsi @@ -23,11 +23,27 @@ compatible = "samsung,exynos5250"; interrupt-parent = <&gic>; - gic:interrupt-controller@10490000 { + gic:interrupt-controller@10481000 { compatible = "arm,cortex-a9-gic"; #interrupt-cells = <3>; interrupt-controller; - reg = <0x10490000 0x1000>, <0x10480000 0x100>; + reg = <0x10481000 0x1000>, <0x10482000 0x2000>; + }; + + combiner:interrupt-controller@10440000 { + compatible = "samsung,exynos4210-combiner"; + #interrupt-cells = <2>; + interrupt-controller; + samsung,combiner-nr = <32>; + reg = <0x10440000 0x1000>; + 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 16 0>, <0 17 0>, <0 18 0>, <0 19 0>, + <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>, + <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>, + <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>; }; watchdog { @@ -42,30 +58,6 @@ interrupts = <0 43 0>, <0 44 0>; }; - sdhci@12200000 { - compatible = "samsung,exynos4210-sdhci"; - reg = <0x12200000 0x100>; - interrupts = <0 75 0>; - }; - - sdhci@12210000 { - compatible = "samsung,exynos4210-sdhci"; - reg = <0x12210000 0x100>; - interrupts = <0 76 0>; - }; - - sdhci@12220000 { - compatible = "samsung,exynos4210-sdhci"; - reg = <0x12220000 0x100>; - interrupts = <0 77 0>; - }; - - sdhci@12230000 { - compatible = "samsung,exynos4210-sdhci"; - reg = <0x12230000 0x100>; - interrupts = <0 78 0>; - }; - serial@12C00000 { compatible = "samsung,exynos4210-uart"; reg = <0x12C00000 0x100>; @@ -94,48 +86,64 @@ compatible = "samsung,s3c2440-i2c"; reg = <0x12C60000 0x100>; interrupts = <0 56 0>; + #address-cells = <1>; + #size-cells = <0>; }; i2c@12C70000 { compatible = "samsung,s3c2440-i2c"; reg = <0x12C70000 0x100>; interrupts = <0 57 0>; + #address-cells = <1>; + #size-cells = <0>; }; i2c@12C80000 { compatible = "samsung,s3c2440-i2c"; reg = <0x12C80000 0x100>; interrupts = <0 58 0>; + #address-cells = <1>; + #size-cells = <0>; }; i2c@12C90000 { compatible = "samsung,s3c2440-i2c"; reg = <0x12C90000 0x100>; interrupts = <0 59 0>; + #address-cells = <1>; + #size-cells = <0>; }; i2c@12CA0000 { compatible = "samsung,s3c2440-i2c"; reg = <0x12CA0000 0x100>; interrupts = <0 60 0>; + #address-cells = <1>; + #size-cells = <0>; }; i2c@12CB0000 { compatible = "samsung,s3c2440-i2c"; reg = <0x12CB0000 0x100>; interrupts = <0 61 0>; + #address-cells = <1>; + #size-cells = <0>; }; i2c@12CC0000 { compatible = "samsung,s3c2440-i2c"; reg = <0x12CC0000 0x100>; interrupts = <0 62 0>; + #address-cells = <1>; + #size-cells = <0>; }; i2c@12CD0000 { compatible = "samsung,s3c2440-i2c"; reg = <0x12CD0000 0x100>; interrupts = <0 63 0>; + #address-cells = <1>; + #size-cells = <0>; }; amba { @@ -157,13 +165,13 @@ interrupts = <0 35 0>; }; - mdma0: pdma@10800000 { + mdma0: mdma@10800000 { compatible = "arm,pl330", "arm,primecell"; reg = <0x10800000 0x1000>; interrupts = <0 33 0>; }; - mdma1: pdma@11C10000 { + mdma1: mdma@11C10000 { compatible = "arm,pl330", "arm,primecell"; reg = <0x11C10000 0x1000>; interrupts = <0 124 0>; @@ -242,6 +250,12 @@ #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>; @@ -388,19 +402,19 @@ gpv2: gpio-controller@10D10040 { compatible = "samsung,exynos4-gpio"; - reg = <0x10D10040 0x20>; + reg = <0x10D10060 0x20>; #gpio-cells = <4>; }; gpv3: gpio-controller@10D10060 { compatible = "samsung,exynos4-gpio"; - reg = <0x10D10060 0x20>; + reg = <0x10D10080 0x20>; #gpio-cells = <4>; }; gpv4: gpio-controller@10D10080 { compatible = "samsung,exynos4-gpio"; - reg = <0x10D10080 0x20>; + reg = <0x10D100C0 0x20>; #gpio-cells = <4>; }; diff --git a/trunk/arch/arm/boot/dts/imx23-evk.dts b/trunk/arch/arm/boot/dts/imx23-evk.dts new file mode 100644 index 000000000000..70bffa929b65 --- /dev/null +++ b/trunk/arch/arm/boot/dts/imx23-evk.dts @@ -0,0 +1,43 @@ +/* + * Copyright 2012 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 + */ + +/dts-v1/; +/include/ "imx23.dtsi" + +/ { + model = "Freescale i.MX23 Evaluation Kit"; + compatible = "fsl,imx23-evk", "fsl,imx23"; + + memory { + reg = <0x40000000 0x08000000>; + }; + + apb@80000000 { + apbh@80000000 { + ssp0: ssp@80010000 { + compatible = "fsl,imx23-mmc"; + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_8bit_pins_a &mmc0_pins_fixup>; + bus-width = <8>; + wp-gpios = <&gpio1 30 0>; + status = "okay"; + }; + }; + + apbx@80040000 { + duart: serial@80070000 { + pinctrl-names = "default"; + pinctrl-0 = <&duart_pins_a>; + status = "okay"; + }; + }; + }; +}; diff --git a/trunk/arch/arm/boot/dts/imx23.dtsi b/trunk/arch/arm/boot/dts/imx23.dtsi new file mode 100644 index 000000000000..8c5f9994f3fc --- /dev/null +++ b/trunk/arch/arm/boot/dts/imx23.dtsi @@ -0,0 +1,295 @@ +/* + * Copyright 2012 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/ "skeleton.dtsi" + +/ { + interrupt-parent = <&icoll>; + + aliases { + gpio0 = &gpio0; + gpio1 = &gpio1; + gpio2 = &gpio2; + }; + + cpus { + cpu@0 { + compatible = "arm,arm926ejs"; + }; + }; + + apb@80000000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x80000000 0x80000>; + ranges; + + apbh@80000000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x80000000 0x40000>; + ranges; + + icoll: interrupt-controller@80000000 { + compatible = "fsl,imx23-icoll", "fsl,mxs-icoll"; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0x80000000 0x2000>; + }; + + dma-apbh@80004000 { + compatible = "fsl,imx23-dma-apbh"; + reg = <0x80004000 2000>; + }; + + ecc@80008000 { + reg = <0x80008000 2000>; + status = "disabled"; + }; + + bch@8000a000 { + reg = <0x8000a000 2000>; + status = "disabled"; + }; + + gpmi@8000c000 { + reg = <0x8000c000 2000>; + status = "disabled"; + }; + + ssp0: ssp@80010000 { + reg = <0x80010000 2000>; + interrupts = <15 14>; + fsl,ssp-dma-channel = <1>; + status = "disabled"; + }; + + etm@80014000 { + reg = <0x80014000 2000>; + status = "disabled"; + }; + + pinctrl@80018000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx23-pinctrl", "simple-bus"; + reg = <0x80018000 2000>; + + gpio0: gpio@0 { + compatible = "fsl,imx23-gpio", "fsl,mxs-gpio"; + interrupts = <16>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio1: gpio@1 { + compatible = "fsl,imx23-gpio", "fsl,mxs-gpio"; + interrupts = <17>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio2: gpio@2 { + compatible = "fsl,imx23-gpio", "fsl,mxs-gpio"; + interrupts = <18>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + duart_pins_a: duart@0 { + reg = <0>; + fsl,pinmux-ids = <0x11a2 0x11b2>; + fsl,drive-strength = <0>; + fsl,voltage = <1>; + fsl,pull-up = <0>; + }; + + mmc0_8bit_pins_a: mmc0-8bit@0 { + reg = <0>; + fsl,pinmux-ids = <0x2020 0x2030 0x2040 + 0x2050 0x0082 0x0092 0x00a2 + 0x00b2 0x2000 0x2010 0x2060>; + fsl,drive-strength = <1>; + fsl,voltage = <1>; + fsl,pull-up = <1>; + }; + + mmc0_pins_fixup: mmc0-pins-fixup { + fsl,pinmux-ids = <0x2010 0x2060>; + fsl,pull-up = <0>; + }; + }; + + digctl@8001c000 { + reg = <0x8001c000 2000>; + status = "disabled"; + }; + + emi@80020000 { + reg = <0x80020000 2000>; + status = "disabled"; + }; + + dma-apbx@80024000 { + compatible = "fsl,imx23-dma-apbx"; + reg = <0x80024000 2000>; + }; + + dcp@80028000 { + reg = <0x80028000 2000>; + status = "disabled"; + }; + + pxp@8002a000 { + reg = <0x8002a000 2000>; + status = "disabled"; + }; + + ocotp@8002c000 { + reg = <0x8002c000 2000>; + status = "disabled"; + }; + + axi-ahb@8002e000 { + reg = <0x8002e000 2000>; + status = "disabled"; + }; + + lcdif@80030000 { + reg = <0x80030000 2000>; + status = "disabled"; + }; + + ssp1: ssp@80034000 { + reg = <0x80034000 2000>; + interrupts = <2 20>; + fsl,ssp-dma-channel = <2>; + status = "disabled"; + }; + + tvenc@80038000 { + reg = <0x80038000 2000>; + status = "disabled"; + }; + }; + + apbx@80040000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x80040000 0x40000>; + ranges; + + clkctl@80040000 { + reg = <0x80040000 2000>; + status = "disabled"; + }; + + saif0: saif@80042000 { + reg = <0x80042000 2000>; + status = "disabled"; + }; + + power@80044000 { + reg = <0x80044000 2000>; + status = "disabled"; + }; + + saif1: saif@80046000 { + reg = <0x80046000 2000>; + status = "disabled"; + }; + + audio-out@80048000 { + reg = <0x80048000 2000>; + status = "disabled"; + }; + + audio-in@8004c000 { + reg = <0x8004c000 2000>; + status = "disabled"; + }; + + lradc@80050000 { + reg = <0x80050000 2000>; + status = "disabled"; + }; + + spdif@80054000 { + reg = <0x80054000 2000>; + status = "disabled"; + }; + + i2c@80058000 { + reg = <0x80058000 2000>; + status = "disabled"; + }; + + rtc@8005c000 { + reg = <0x8005c000 2000>; + status = "disabled"; + }; + + pwm@80064000 { + reg = <0x80064000 2000>; + status = "disabled"; + }; + + timrot@80068000 { + reg = <0x80068000 2000>; + status = "disabled"; + }; + + auart0: serial@8006c000 { + reg = <0x8006c000 0x2000>; + status = "disabled"; + }; + + auart1: serial@8006e000 { + reg = <0x8006e000 0x2000>; + status = "disabled"; + }; + + duart: serial@80070000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x80070000 0x2000>; + interrupts = <0>; + status = "disabled"; + }; + + usbphy@8007c000 { + reg = <0x8007c000 0x2000>; + status = "disabled"; + }; + }; + }; + + ahb@80080000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x80080000 0x80000>; + ranges; + + usbctrl@80080000 { + reg = <0x80080000 0x10000>; + status = "disabled"; + }; + }; +}; diff --git a/trunk/arch/arm/boot/dts/imx27-phytec-phycore.dts b/trunk/arch/arm/boot/dts/imx27-phytec-phycore.dts index a51a08fc2af9..2b0ff60247a4 100644 --- a/trunk/arch/arm/boot/dts/imx27-phytec-phycore.dts +++ b/trunk/arch/arm/boot/dts/imx27-phytec-phycore.dts @@ -27,22 +27,22 @@ status = "okay"; }; - uart@1000a000 { + serial@1000a000 { fsl,uart-has-rtscts; status = "okay"; }; - uart@1000b000 { + serial@1000b000 { fsl,uart-has-rtscts; status = "okay"; }; - uart@1000c000 { + serial@1000c000 { fsl,uart-has-rtscts; status = "okay"; }; - fec@1002b000 { + ethernet@1002b000 { status = "okay"; }; diff --git a/trunk/arch/arm/boot/dts/imx27.dtsi b/trunk/arch/arm/boot/dts/imx27.dtsi index bc5e7d5ddd54..386c769c38d1 100644 --- a/trunk/arch/arm/boot/dts/imx27.dtsi +++ b/trunk/arch/arm/boot/dts/imx27.dtsi @@ -59,28 +59,28 @@ status = "disabled"; }; - uart1: uart@1000a000 { + uart1: serial@1000a000 { compatible = "fsl,imx27-uart", "fsl,imx21-uart"; reg = <0x1000a000 0x1000>; interrupts = <20>; status = "disabled"; }; - uart2: uart@1000b000 { + uart2: serial@1000b000 { compatible = "fsl,imx27-uart", "fsl,imx21-uart"; reg = <0x1000b000 0x1000>; interrupts = <19>; status = "disabled"; }; - uart3: uart@1000c000 { + uart3: serial@1000c000 { compatible = "fsl,imx27-uart", "fsl,imx21-uart"; reg = <0x1000c000 0x1000>; interrupts = <18>; status = "disabled"; }; - uart4: uart@1000d000 { + uart4: serial@1000d000 { compatible = "fsl,imx27-uart", "fsl,imx21-uart"; reg = <0x1000d000 0x1000>; interrupts = <17>; @@ -183,14 +183,14 @@ status = "disabled"; }; - uart5: uart@1001b000 { + uart5: serial@1001b000 { compatible = "fsl,imx27-uart", "fsl,imx21-uart"; reg = <0x1001b000 0x1000>; interrupts = <49>; status = "disabled"; }; - uart6: uart@1001c000 { + uart6: serial@1001c000 { compatible = "fsl,imx27-uart", "fsl,imx21-uart"; reg = <0x1001c000 0x1000>; interrupts = <48>; @@ -206,12 +206,21 @@ status = "disabled"; }; - fec: fec@1002b000 { + fec: ethernet@1002b000 { compatible = "fsl,imx27-fec"; reg = <0x1002b000 0x4000>; interrupts = <50>; status = "disabled"; }; }; + nand@d8000000 { + #address-cells = <1>; + #size-cells = <1>; + + compatible = "fsl,imx27-nand"; + reg = <0xd8000000 0x1000>; + interrupts = <29>; + status = "disabled"; + }; }; }; diff --git a/trunk/arch/arm/boot/dts/imx28-evk.dts b/trunk/arch/arm/boot/dts/imx28-evk.dts new file mode 100644 index 000000000000..ee520a529cb4 --- /dev/null +++ b/trunk/arch/arm/boot/dts/imx28-evk.dts @@ -0,0 +1,114 @@ +/* + * Copyright 2012 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 + */ + +/dts-v1/; +/include/ "imx28.dtsi" + +/ { + model = "Freescale i.MX28 Evaluation Kit"; + compatible = "fsl,imx28-evk", "fsl,imx28"; + + memory { + reg = <0x40000000 0x08000000>; + }; + + apb@80000000 { + apbh@80000000 { + ssp0: ssp@80010000 { + compatible = "fsl,imx28-mmc"; + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_8bit_pins_a + &mmc0_cd_cfg &mmc0_sck_cfg>; + bus-width = <8>; + wp-gpios = <&gpio2 12 0>; + status = "okay"; + }; + + ssp1: ssp@80012000 { + compatible = "fsl,imx28-mmc"; + bus-width = <8>; + wp-gpios = <&gpio0 28 0>; + status = "okay"; + }; + }; + + apbx@80040000 { + saif0: saif@80042000 { + pinctrl-names = "default"; + pinctrl-0 = <&saif0_pins_a>; + status = "okay"; + }; + + saif1: saif@80046000 { + pinctrl-names = "default"; + pinctrl-0 = <&saif1_pins_a>; + fsl,saif-master = <&saif0>; + status = "okay"; + }; + + i2c0: i2c@80058000 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; + status = "okay"; + + sgtl5000: codec@0a { + compatible = "fsl,sgtl5000"; + reg = <0x0a>; + VDDA-supply = <®_3p3v>; + VDDIO-supply = <®_3p3v>; + + }; + }; + + duart: serial@80074000 { + pinctrl-names = "default"; + pinctrl-0 = <&duart_pins_a>; + status = "okay"; + }; + }; + }; + + ahb@80080000 { + mac0: ethernet@800f0000 { + phy-mode = "rmii"; + pinctrl-names = "default"; + pinctrl-0 = <&mac0_pins_a>; + status = "okay"; + }; + + mac1: ethernet@800f4000 { + phy-mode = "rmii"; + pinctrl-names = "default"; + pinctrl-0 = <&mac1_pins_a>; + status = "okay"; + }; + }; + + regulators { + compatible = "simple-bus"; + + reg_3p3v: 3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + }; + + sound { + compatible = "fsl,imx28-evk-sgtl5000", + "fsl,mxs-audio-sgtl5000"; + model = "imx28-evk-sgtl5000"; + saif-controllers = <&saif0 &saif1>; + audio-codec = <&sgtl5000>; + }; +}; diff --git a/trunk/arch/arm/boot/dts/imx28.dtsi b/trunk/arch/arm/boot/dts/imx28.dtsi new file mode 100644 index 000000000000..4634cb861a59 --- /dev/null +++ b/trunk/arch/arm/boot/dts/imx28.dtsi @@ -0,0 +1,497 @@ +/* + * Copyright 2012 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/ "skeleton.dtsi" + +/ { + interrupt-parent = <&icoll>; + + aliases { + gpio0 = &gpio0; + gpio1 = &gpio1; + gpio2 = &gpio2; + gpio3 = &gpio3; + gpio4 = &gpio4; + saif0 = &saif0; + saif1 = &saif1; + }; + + cpus { + cpu@0 { + compatible = "arm,arm926ejs"; + }; + }; + + apb@80000000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x80000000 0x80000>; + ranges; + + apbh@80000000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x80000000 0x3c900>; + ranges; + + icoll: interrupt-controller@80000000 { + compatible = "fsl,imx28-icoll", "fsl,mxs-icoll"; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0x80000000 0x2000>; + }; + + hsadc@80002000 { + reg = <0x80002000 2000>; + interrupts = <13 87>; + status = "disabled"; + }; + + dma-apbh@80004000 { + compatible = "fsl,imx28-dma-apbh"; + reg = <0x80004000 2000>; + }; + + perfmon@80006000 { + reg = <0x80006000 800>; + interrupts = <27>; + status = "disabled"; + }; + + bch@8000a000 { + reg = <0x8000a000 2000>; + interrupts = <41>; + status = "disabled"; + }; + + gpmi@8000c000 { + reg = <0x8000c000 2000>; + interrupts = <42 88>; + status = "disabled"; + }; + + ssp0: ssp@80010000 { + reg = <0x80010000 2000>; + interrupts = <96 82>; + fsl,ssp-dma-channel = <0>; + status = "disabled"; + }; + + ssp1: ssp@80012000 { + reg = <0x80012000 2000>; + interrupts = <97 83>; + fsl,ssp-dma-channel = <1>; + status = "disabled"; + }; + + ssp2: ssp@80014000 { + reg = <0x80014000 2000>; + interrupts = <98 84>; + fsl,ssp-dma-channel = <2>; + status = "disabled"; + }; + + ssp3: ssp@80016000 { + reg = <0x80016000 2000>; + interrupts = <99 85>; + fsl,ssp-dma-channel = <3>; + status = "disabled"; + }; + + pinctrl@80018000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx28-pinctrl", "simple-bus"; + reg = <0x80018000 2000>; + + gpio0: gpio@0 { + compatible = "fsl,imx28-gpio", "fsl,mxs-gpio"; + interrupts = <127>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio1: gpio@1 { + compatible = "fsl,imx28-gpio", "fsl,mxs-gpio"; + interrupts = <126>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio2: gpio@2 { + compatible = "fsl,imx28-gpio", "fsl,mxs-gpio"; + interrupts = <125>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio3: gpio@3 { + compatible = "fsl,imx28-gpio", "fsl,mxs-gpio"; + interrupts = <124>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio4: gpio@4 { + compatible = "fsl,imx28-gpio", "fsl,mxs-gpio"; + interrupts = <123>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + duart_pins_a: duart@0 { + reg = <0>; + fsl,pinmux-ids = <0x3102 0x3112>; + fsl,drive-strength = <0>; + fsl,voltage = <1>; + fsl,pull-up = <0>; + }; + + mac0_pins_a: mac0@0 { + reg = <0>; + fsl,pinmux-ids = <0x4000 0x4010 0x4020 + 0x4030 0x4040 0x4060 0x4070 + 0x4080 0x4100>; + fsl,drive-strength = <1>; + fsl,voltage = <1>; + fsl,pull-up = <1>; + }; + + mac1_pins_a: mac1@0 { + reg = <0>; + fsl,pinmux-ids = <0x40f1 0x4091 0x40a1 + 0x40e1 0x40b1 0x40c1>; + fsl,drive-strength = <1>; + fsl,voltage = <1>; + fsl,pull-up = <1>; + }; + + mmc0_8bit_pins_a: mmc0-8bit@0 { + reg = <0>; + fsl,pinmux-ids = <0x2000 0x2010 0x2020 + 0x2030 0x2040 0x2050 0x2060 + 0x2070 0x2080 0x2090 0x20a0>; + fsl,drive-strength = <1>; + fsl,voltage = <1>; + fsl,pull-up = <1>; + }; + + mmc0_cd_cfg: mmc0-cd-cfg { + fsl,pinmux-ids = <0x2090>; + fsl,pull-up = <0>; + }; + + mmc0_sck_cfg: mmc0-sck-cfg { + fsl,pinmux-ids = <0x20a0>; + fsl,drive-strength = <2>; + fsl,pull-up = <0>; + }; + + i2c0_pins_a: i2c0@0 { + reg = <0>; + fsl,pinmux-ids = <0x3180 0x3190>; + fsl,drive-strength = <1>; + fsl,voltage = <1>; + fsl,pull-up = <1>; + }; + + saif0_pins_a: saif0@0 { + reg = <0>; + fsl,pinmux-ids = + <0x3140 0x3150 0x3160 0x3170>; + fsl,drive-strength = <2>; + fsl,voltage = <1>; + fsl,pull-up = <1>; + }; + + saif1_pins_a: saif1@0 { + reg = <0>; + fsl,pinmux-ids = <0x31a0>; + fsl,drive-strength = <2>; + fsl,voltage = <1>; + fsl,pull-up = <1>; + }; + }; + + digctl@8001c000 { + reg = <0x8001c000 2000>; + interrupts = <89>; + status = "disabled"; + }; + + etm@80022000 { + reg = <0x80022000 2000>; + status = "disabled"; + }; + + dma-apbx@80024000 { + compatible = "fsl,imx28-dma-apbx"; + reg = <0x80024000 2000>; + }; + + dcp@80028000 { + reg = <0x80028000 2000>; + interrupts = <52 53 54>; + status = "disabled"; + }; + + pxp@8002a000 { + reg = <0x8002a000 2000>; + interrupts = <39>; + status = "disabled"; + }; + + ocotp@8002c000 { + reg = <0x8002c000 2000>; + status = "disabled"; + }; + + axi-ahb@8002e000 { + reg = <0x8002e000 2000>; + status = "disabled"; + }; + + lcdif@80030000 { + reg = <0x80030000 2000>; + interrupts = <38 86>; + status = "disabled"; + }; + + can0: can@80032000 { + reg = <0x80032000 2000>; + interrupts = <8>; + status = "disabled"; + }; + + can1: can@80034000 { + reg = <0x80034000 2000>; + interrupts = <9>; + status = "disabled"; + }; + + simdbg@8003c000 { + reg = <0x8003c000 200>; + status = "disabled"; + }; + + simgpmisel@8003c200 { + reg = <0x8003c200 100>; + status = "disabled"; + }; + + simsspsel@8003c300 { + reg = <0x8003c300 100>; + status = "disabled"; + }; + + simmemsel@8003c400 { + reg = <0x8003c400 100>; + status = "disabled"; + }; + + gpiomon@8003c500 { + reg = <0x8003c500 100>; + status = "disabled"; + }; + + simenet@8003c700 { + reg = <0x8003c700 100>; + status = "disabled"; + }; + + armjtag@8003c800 { + reg = <0x8003c800 100>; + status = "disabled"; + }; + }; + + apbx@80040000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x80040000 0x40000>; + ranges; + + clkctl@80040000 { + reg = <0x80040000 2000>; + status = "disabled"; + }; + + saif0: saif@80042000 { + compatible = "fsl,imx28-saif"; + reg = <0x80042000 2000>; + interrupts = <59 80>; + fsl,saif-dma-channel = <4>; + status = "disabled"; + }; + + power@80044000 { + reg = <0x80044000 2000>; + status = "disabled"; + }; + + saif1: saif@80046000 { + compatible = "fsl,imx28-saif"; + reg = <0x80046000 2000>; + interrupts = <58 81>; + fsl,saif-dma-channel = <5>; + status = "disabled"; + }; + + lradc@80050000 { + reg = <0x80050000 2000>; + status = "disabled"; + }; + + spdif@80054000 { + reg = <0x80054000 2000>; + interrupts = <45 66>; + status = "disabled"; + }; + + rtc@80056000 { + reg = <0x80056000 2000>; + interrupts = <28 29>; + status = "disabled"; + }; + + i2c0: i2c@80058000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx28-i2c"; + reg = <0x80058000 2000>; + interrupts = <111 68>; + status = "disabled"; + }; + + i2c1: i2c@8005a000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx28-i2c"; + reg = <0x8005a000 2000>; + interrupts = <110 69>; + status = "disabled"; + }; + + pwm@80064000 { + reg = <0x80064000 2000>; + status = "disabled"; + }; + + timrot@80068000 { + reg = <0x80068000 2000>; + status = "disabled"; + }; + + auart0: serial@8006a000 { + reg = <0x8006a000 0x2000>; + interrupts = <112 70 71>; + status = "disabled"; + }; + + auart1: serial@8006c000 { + reg = <0x8006c000 0x2000>; + interrupts = <113 72 73>; + status = "disabled"; + }; + + auart2: serial@8006e000 { + reg = <0x8006e000 0x2000>; + interrupts = <114 74 75>; + status = "disabled"; + }; + + auart3: serial@80070000 { + reg = <0x80070000 0x2000>; + interrupts = <115 76 77>; + status = "disabled"; + }; + + auart4: serial@80072000 { + reg = <0x80072000 0x2000>; + interrupts = <116 78 79>; + status = "disabled"; + }; + + duart: serial@80074000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x80074000 0x1000>; + interrupts = <47>; + status = "disabled"; + }; + + usbphy0: usbphy@8007c000 { + reg = <0x8007c000 0x2000>; + status = "disabled"; + }; + + usbphy1: usbphy@8007e000 { + reg = <0x8007e000 0x2000>; + status = "disabled"; + }; + }; + }; + + ahb@80080000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x80080000 0x80000>; + ranges; + + usbctrl0: usbctrl@80080000 { + reg = <0x80080000 0x10000>; + status = "disabled"; + }; + + usbctrl1: usbctrl@80090000 { + reg = <0x80090000 0x10000>; + status = "disabled"; + }; + + dflpt@800c0000 { + reg = <0x800c0000 0x10000>; + status = "disabled"; + }; + + mac0: ethernet@800f0000 { + compatible = "fsl,imx28-fec"; + reg = <0x800f0000 0x4000>; + interrupts = <101>; + status = "disabled"; + }; + + mac1: ethernet@800f4000 { + compatible = "fsl,imx28-fec"; + reg = <0x800f4000 0x4000>; + interrupts = <102>; + status = "disabled"; + }; + + switch@800f8000 { + reg = <0x800f8000 0x8000>; + status = "disabled"; + }; + + }; +}; diff --git a/trunk/arch/arm/boot/dts/imx51-babbage.dts b/trunk/arch/arm/boot/dts/imx51-babbage.dts index 9949e6060dee..de065b5976e6 100644 --- a/trunk/arch/arm/boot/dts/imx51-babbage.dts +++ b/trunk/arch/arm/boot/dts/imx51-babbage.dts @@ -17,10 +17,6 @@ model = "Freescale i.MX51 Babbage Board"; compatible = "fsl,imx51-babbage", "fsl,imx51"; - chosen { - bootargs = "console=ttymxc0,115200 root=/dev/mmcblk0p3 rootwait"; - }; - memory { reg = <0x90000000 0x20000000>; }; @@ -40,7 +36,7 @@ status = "okay"; }; - uart3: uart@7000c000 { + uart3: serial@7000c000 { fsl,uart-has-rtscts; status = "okay"; }; @@ -166,6 +162,11 @@ }; }; }; + + ssi2: ssi@70014000 { + fsl,mode = "i2s-slave"; + status = "okay"; + }; }; wdog@73f98000 { /* WDOG1 */ @@ -177,12 +178,12 @@ reg = <0x73fa8000 0x4000>; }; - uart1: uart@73fbc000 { + uart1: serial@73fbc000 { fsl,uart-has-rtscts; status = "okay"; }; - uart2: uart@73fc0000 { + uart2: serial@73fc0000 { status = "okay"; }; }; @@ -195,13 +196,20 @@ i2c@83fc4000 { /* I2C2 */ status = "okay"; - codec: sgtl5000@0a { + sgtl5000: codec@0a { compatible = "fsl,sgtl5000"; reg = <0x0a>; + clock-frequency = <26000000>; + VDDA-supply = <&vdig_reg>; + VDDIO-supply = <&vvideo_reg>; }; }; - fec@83fec000 { + audmux@83fd0000 { + status = "okay"; + }; + + ethernet@83fec000 { phy-mode = "mii"; status = "okay"; }; @@ -218,4 +226,18 @@ gpio-key,wakeup; }; }; + + sound { + compatible = "fsl,imx51-babbage-sgtl5000", + "fsl,imx-audio-sgtl5000"; + model = "imx51-babbage-sgtl5000"; + ssi-controller = <&ssi2>; + audio-codec = <&sgtl5000>; + audio-routing = + "MIC_IN", "Mic Jack", + "Mic Jack", "Mic Bias", + "Headphone Jack", "HP_OUT"; + mux-int-port = <2>; + mux-ext-port = <3>; + }; }; diff --git a/trunk/arch/arm/boot/dts/imx51.dtsi b/trunk/arch/arm/boot/dts/imx51.dtsi index 6663986fe1c8..bfa65abe8ef2 100644 --- a/trunk/arch/arm/boot/dts/imx51.dtsi +++ b/trunk/arch/arm/boot/dts/imx51.dtsi @@ -86,7 +86,7 @@ status = "disabled"; }; - uart3: uart@7000c000 { + uart3: serial@7000c000 { compatible = "fsl,imx51-uart", "fsl,imx21-uart"; reg = <0x7000c000 0x4000>; interrupts = <33>; @@ -102,6 +102,15 @@ status = "disabled"; }; + ssi2: ssi@70014000 { + compatible = "fsl,imx51-ssi", "fsl,imx21-ssi"; + reg = <0x70014000 0x4000>; + interrupts = <30>; + fsl,fifo-depth = <15>; + fsl,ssi-dma-events = <25 24 23 22>; /* TX0 RX0 TX1 RX1 */ + status = "disabled"; + }; + esdhc@70020000 { /* ESDHC3 */ compatible = "fsl,imx51-esdhc"; reg = <0x70020000 0x4000>; @@ -171,14 +180,14 @@ status = "disabled"; }; - uart1: uart@73fbc000 { + uart1: serial@73fbc000 { compatible = "fsl,imx51-uart", "fsl,imx21-uart"; reg = <0x73fbc000 0x4000>; interrupts = <31>; status = "disabled"; }; - uart2: uart@73fc0000 { + uart2: serial@73fc0000 { compatible = "fsl,imx51-uart", "fsl,imx21-uart"; reg = <0x73fc0000 0x4000>; interrupts = <32>; @@ -235,7 +244,31 @@ status = "disabled"; }; - fec@83fec000 { + ssi1: ssi@83fcc000 { + compatible = "fsl,imx51-ssi", "fsl,imx21-ssi"; + reg = <0x83fcc000 0x4000>; + interrupts = <29>; + fsl,fifo-depth = <15>; + fsl,ssi-dma-events = <29 28 27 26>; /* TX0 RX0 TX1 RX1 */ + status = "disabled"; + }; + + audmux@83fd0000 { + compatible = "fsl,imx51-audmux", "fsl,imx31-audmux"; + reg = <0x83fd0000 0x4000>; + status = "disabled"; + }; + + ssi3: ssi@83fe8000 { + compatible = "fsl,imx51-ssi", "fsl,imx21-ssi"; + reg = <0x83fe8000 0x4000>; + interrupts = <96>; + fsl,fifo-depth = <15>; + fsl,ssi-dma-events = <47 46 37 35>; /* TX0 RX0 TX1 RX1 */ + status = "disabled"; + }; + + ethernet@83fec000 { compatible = "fsl,imx51-fec", "fsl,imx27-fec"; reg = <0x83fec000 0x4000>; interrupts = <87>; diff --git a/trunk/arch/arm/boot/dts/imx53-ard.dts b/trunk/arch/arm/boot/dts/imx53-ard.dts index 2dccce46ed81..5b8eafcdbeec 100644 --- a/trunk/arch/arm/boot/dts/imx53-ard.dts +++ b/trunk/arch/arm/boot/dts/imx53-ard.dts @@ -17,10 +17,6 @@ model = "Freescale i.MX53 Automotive Reference Design Board"; compatible = "fsl,imx53-ard", "fsl,imx53"; - chosen { - bootargs = "console=ttymxc0,115200 root=/dev/mmcblk0p3 rootwait"; - }; - memory { reg = <0x70000000 0x40000000>; }; @@ -44,7 +40,7 @@ reg = <0x53fa8000 0x4000>; }; - uart1: uart@53fbc000 { + uart1: serial@53fbc000 { status = "okay"; }; }; diff --git a/trunk/arch/arm/boot/dts/imx53-evk.dts b/trunk/arch/arm/boot/dts/imx53-evk.dts index 5bac4aa4800b..9c798034675e 100644 --- a/trunk/arch/arm/boot/dts/imx53-evk.dts +++ b/trunk/arch/arm/boot/dts/imx53-evk.dts @@ -17,10 +17,6 @@ model = "Freescale i.MX53 Evaluation Kit"; compatible = "fsl,imx53-evk", "fsl,imx53"; - chosen { - bootargs = "console=ttymxc0,115200 root=/dev/mmcblk0p3 rootwait"; - }; - memory { reg = <0x70000000 0x80000000>; }; @@ -75,7 +71,7 @@ reg = <0x53fa8000 0x4000>; }; - uart1: uart@53fbc000 { + uart1: serial@53fbc000 { status = "okay"; }; }; @@ -99,7 +95,7 @@ }; }; - fec@63fec000 { + ethernet@63fec000 { phy-mode = "rmii"; phy-reset-gpios = <&gpio7 6 0>; status = "okay"; diff --git a/trunk/arch/arm/boot/dts/imx53-qsb.dts b/trunk/arch/arm/boot/dts/imx53-qsb.dts index 5c57c8672c36..2d803a9a6949 100644 --- a/trunk/arch/arm/boot/dts/imx53-qsb.dts +++ b/trunk/arch/arm/boot/dts/imx53-qsb.dts @@ -17,10 +17,6 @@ model = "Freescale i.MX53 Quick Start Board"; compatible = "fsl,imx53-qsb", "fsl,imx53"; - chosen { - bootargs = "console=ttymxc0,115200 root=/dev/mmcblk0p3 rootwait"; - }; - memory { reg = <0x70000000 0x40000000>; }; @@ -33,6 +29,11 @@ status = "okay"; }; + ssi2: ssi@50014000 { + fsl,mode = "i2s-slave"; + status = "okay"; + }; + esdhc@50020000 { /* ESDHC3 */ cd-gpios = <&gpio3 11 0>; wp-gpios = <&gpio3 12 0>; @@ -49,7 +50,7 @@ reg = <0x53fa8000 0x4000>; }; - uart1: uart@53fbc000 { + uart1: serial@53fbc000 { status = "okay"; }; }; @@ -62,9 +63,11 @@ i2c@63fc4000 { /* I2C2 */ status = "okay"; - codec: sgtl5000@0a { + sgtl5000: codec@0a { compatible = "fsl,sgtl5000"; reg = <0x0a>; + VDDA-supply = <®_3p2v>; + VDDIO-supply = <®_3p2v>; }; }; @@ -77,12 +80,88 @@ }; pmic: dialog@48 { - compatible = "dialog,da9053", "dialog,da9052"; + compatible = "dlg,da9053-aa", "dlg,da9052"; reg = <0x48>; + + regulators { + buck0 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <2075000>; + }; + + buck1 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <2075000>; + }; + + buck2 { + regulator-min-microvolt = <925000>; + regulator-max-microvolt = <2500000>; + }; + + buck3 { + regulator-min-microvolt = <925000>; + regulator-max-microvolt = <2500000>; + }; + + ldo4 { + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <1800000>; + }; + + ldo5 { + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <1800000>; + }; + + ldo6 { + regulator-min-microvolt = <1725000>; + regulator-max-microvolt = <3300000>; + }; + + ldo7 { + regulator-min-microvolt = <1725000>; + regulator-max-microvolt = <3300000>; + }; + + ldo8 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3600000>; + }; + + ldo9 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3600000>; + }; + + ldo10 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3600000>; + }; + + ldo11 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3600000>; + }; + + ldo12 { + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <3650000>; + }; + + ldo13 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3600000>; + }; + }; }; }; - fec@63fec000 { + audmux@63fd0000 { + status = "okay"; + }; + + ethernet@63fec000 { phy-mode = "rmii"; phy-reset-gpios = <&gpio7 6 0>; status = "okay"; @@ -122,4 +201,30 @@ linux,default-trigger = "heartbeat"; }; }; + + regulators { + compatible = "simple-bus"; + + reg_3p2v: 3p2v { + compatible = "regulator-fixed"; + regulator-name = "3P2V"; + regulator-min-microvolt = <3200000>; + regulator-max-microvolt = <3200000>; + regulator-always-on; + }; + }; + + sound { + compatible = "fsl,imx53-qsb-sgtl5000", + "fsl,imx-audio-sgtl5000"; + model = "imx53-qsb-sgtl5000"; + ssi-controller = <&ssi2>; + audio-codec = <&sgtl5000>; + audio-routing = + "MIC_IN", "Mic Jack", + "Mic Jack", "Mic Bias", + "Headphone Jack", "HP_OUT"; + mux-int-port = <2>; + mux-ext-port = <5>; + }; }; diff --git a/trunk/arch/arm/boot/dts/imx53-smd.dts b/trunk/arch/arm/boot/dts/imx53-smd.dts index c7ee86c2dfb5..08091029168e 100644 --- a/trunk/arch/arm/boot/dts/imx53-smd.dts +++ b/trunk/arch/arm/boot/dts/imx53-smd.dts @@ -17,10 +17,6 @@ model = "Freescale i.MX53 Smart Mobile Reference Design Board"; compatible = "fsl,imx53-smd", "fsl,imx53"; - chosen { - bootargs = "console=ttymxc0,115200 root=/dev/mmcblk0p3 rootwait"; - }; - memory { reg = <0x70000000 0x40000000>; }; @@ -35,11 +31,11 @@ }; esdhc@50008000 { /* ESDHC2 */ - fsl,card-wired; + non-removable; status = "okay"; }; - uart3: uart@5000c000 { + uart3: serial@5000c000 { fsl,uart-has-rtscts; status = "okay"; }; @@ -76,7 +72,7 @@ }; esdhc@50020000 { /* ESDHC3 */ - fsl,card-wired; + non-removable; status = "okay"; }; }; @@ -90,11 +86,11 @@ reg = <0x53fa8000 0x4000>; }; - uart1: uart@53fbc000 { + uart1: serial@53fbc000 { status = "okay"; }; - uart2: uart@53fc0000 { + uart2: serial@53fc0000 { status = "okay"; }; }; @@ -142,7 +138,7 @@ }; }; - fec@63fec000 { + ethernet@63fec000 { phy-mode = "rmii"; phy-reset-gpios = <&gpio7 6 0>; status = "okay"; diff --git a/trunk/arch/arm/boot/dts/imx53.dtsi b/trunk/arch/arm/boot/dts/imx53.dtsi index 5dd91b942c91..e3e869470cd3 100644 --- a/trunk/arch/arm/boot/dts/imx53.dtsi +++ b/trunk/arch/arm/boot/dts/imx53.dtsi @@ -88,7 +88,7 @@ status = "disabled"; }; - uart3: uart@5000c000 { + uart3: serial@5000c000 { compatible = "fsl,imx53-uart", "fsl,imx21-uart"; reg = <0x5000c000 0x4000>; interrupts = <33>; @@ -104,6 +104,15 @@ status = "disabled"; }; + ssi2: ssi@50014000 { + compatible = "fsl,imx53-ssi", "fsl,imx21-ssi"; + reg = <0x50014000 0x4000>; + interrupts = <30>; + fsl,fifo-depth = <15>; + fsl,ssi-dma-events = <25 24 23 22>; /* TX0 RX0 TX1 RX1 */ + status = "disabled"; + }; + esdhc@50020000 { /* ESDHC3 */ compatible = "fsl,imx53-esdhc"; reg = <0x50020000 0x4000>; @@ -173,14 +182,14 @@ status = "disabled"; }; - uart1: uart@53fbc000 { + uart1: serial@53fbc000 { compatible = "fsl,imx53-uart", "fsl,imx21-uart"; reg = <0x53fbc000 0x4000>; interrupts = <31>; status = "disabled"; }; - uart2: uart@53fc0000 { + uart2: serial@53fc0000 { compatible = "fsl,imx53-uart", "fsl,imx21-uart"; reg = <0x53fc0000 0x4000>; interrupts = <32>; @@ -226,7 +235,7 @@ status = "disabled"; }; - uart4: uart@53ff0000 { + uart4: serial@53ff0000 { compatible = "fsl,imx53-uart", "fsl,imx21-uart"; reg = <0x53ff0000 0x4000>; interrupts = <13>; @@ -241,7 +250,7 @@ reg = <0x60000000 0x10000000>; ranges; - uart5: uart@63f90000 { + uart5: serial@63f90000 { compatible = "fsl,imx53-uart", "fsl,imx21-uart"; reg = <0x63f90000 0x4000>; interrupts = <86>; @@ -290,7 +299,31 @@ status = "disabled"; }; - fec@63fec000 { + ssi1: ssi@63fcc000 { + compatible = "fsl,imx53-ssi", "fsl,imx21-ssi"; + reg = <0x63fcc000 0x4000>; + interrupts = <29>; + fsl,fifo-depth = <15>; + fsl,ssi-dma-events = <29 28 27 26>; /* TX0 RX0 TX1 RX1 */ + status = "disabled"; + }; + + audmux@63fd0000 { + compatible = "fsl,imx53-audmux", "fsl,imx31-audmux"; + reg = <0x63fd0000 0x4000>; + status = "disabled"; + }; + + ssi3: ssi@63fe8000 { + compatible = "fsl,imx53-ssi", "fsl,imx21-ssi"; + reg = <0x63fe8000 0x4000>; + interrupts = <96>; + fsl,fifo-depth = <15>; + fsl,ssi-dma-events = <47 46 45 44>; /* TX0 RX0 TX1 RX1 */ + status = "disabled"; + }; + + ethernet@63fec000 { compatible = "fsl,imx53-fec", "fsl,imx25-fec"; reg = <0x63fec000 0x4000>; interrupts = <87>; diff --git a/trunk/arch/arm/boot/dts/imx6q-arm2.dts b/trunk/arch/arm/boot/dts/imx6q-arm2.dts index ce1c8238c897..db4c6096c562 100644 --- a/trunk/arch/arm/boot/dts/imx6q-arm2.dts +++ b/trunk/arch/arm/boot/dts/imx6q-arm2.dts @@ -17,19 +17,14 @@ model = "Freescale i.MX6 Quad Armadillo2 Board"; compatible = "fsl,imx6q-arm2", "fsl,imx6q"; - chosen { - bootargs = "console=ttymxc0,115200 root=/dev/mmcblk3p3 rootwait"; - }; - memory { reg = <0x10000000 0x80000000>; }; soc { aips-bus@02100000 { /* AIPS2 */ - enet@02188000 { + ethernet@02188000 { phy-mode = "rgmii"; - local-mac-address = [00 04 9F 01 1B 61]; status = "okay"; }; @@ -37,16 +32,20 @@ cd-gpios = <&gpio6 11 0>; wp-gpios = <&gpio6 14 0>; vmmc-supply = <®_3p3v>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc3_1>; status = "okay"; }; usdhc@0219c000 { /* uSDHC4 */ - fsl,card-wired; + non-removable; vmmc-supply = <®_3p3v>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc4_1>; status = "okay"; }; - uart4: uart@021f0000 { + uart4: serial@021f0000 { status = "okay"; }; }; diff --git a/trunk/arch/arm/boot/dts/imx6q-sabrelite.dts b/trunk/arch/arm/boot/dts/imx6q-sabrelite.dts index 4663a4e5a285..e0ec92973e7e 100644 --- a/trunk/arch/arm/boot/dts/imx6q-sabrelite.dts +++ b/trunk/arch/arm/boot/dts/imx6q-sabrelite.dts @@ -22,8 +22,30 @@ }; soc { + aips-bus@02000000 { /* AIPS1 */ + spba-bus@02000000 { + ecspi@02008000 { /* eCSPI1 */ + fsl,spi-num-chipselects = <1>; + cs-gpios = <&gpio3 19 0>; + status = "okay"; + + flash: m25p80@0 { + compatible = "sst,sst25vf016b"; + spi-max-frequency = <20000000>; + reg = <0>; + }; + }; + + ssi1: ssi@02028000 { + fsl,mode = "i2s-slave"; + status = "okay"; + }; + }; + + }; + aips-bus@02100000 { /* AIPS2 */ - enet@02188000 { + ethernet@02188000 { phy-mode = "rgmii"; phy-reset-gpios = <&gpio3 23 0>; status = "okay"; @@ -43,13 +65,23 @@ status = "okay"; }; - uart2: uart@021e8000 { + audmux@021d8000 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_audmux_1>; + }; + + uart2: serial@021e8000 { status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_serial2_1>; }; i2c@021a0000 { /* I2C1 */ status = "okay"; clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1_1>; codec: sgtl5000@0a { compatible = "fsl,sgtl5000"; @@ -80,4 +112,18 @@ regulator-always-on; }; }; + + sound { + compatible = "fsl,imx6q-sabrelite-sgtl5000", + "fsl,imx-audio-sgtl5000"; + model = "imx6q-sabrelite-sgtl5000"; + ssi-controller = <&ssi1>; + audio-codec = <&codec>; + audio-routing = + "MIC_IN", "Mic Jack", + "Mic Jack", "Mic Bias", + "Headphone Jack", "HP_OUT"; + mux-int-port = <1>; + mux-ext-port = <4>; + }; }; diff --git a/trunk/arch/arm/boot/dts/imx6q-sabresd.dts b/trunk/arch/arm/boot/dts/imx6q-sabresd.dts new file mode 100644 index 000000000000..07509a181178 --- /dev/null +++ b/trunk/arch/arm/boot/dts/imx6q-sabresd.dts @@ -0,0 +1,53 @@ +/* + * Copyright 2012 Freescale Semiconductor, Inc. + * Copyright 2011 Linaro Ltd. + * + * 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 + */ + +/dts-v1/; +/include/ "imx6q.dtsi" + +/ { + model = "Freescale i.MX6Q SABRE Smart Device Board"; + compatible = "fsl,imx6q-sabresd", "fsl,imx6q"; + + memory { + reg = <0x10000000 0x40000000>; + }; + + soc { + + aips-bus@02000000 { /* AIPS1 */ + spba-bus@02000000 { + uart1: serial@02020000 { + status = "okay"; + }; + }; + }; + + aips-bus@02100000 { /* AIPS2 */ + ethernet@02188000 { + phy-mode = "rgmii"; + status = "okay"; + }; + + usdhc@02194000 { /* uSDHC2 */ + cd-gpios = <&gpio2 2 0>; + wp-gpios = <&gpio2 3 0>; + status = "okay"; + }; + + usdhc@02198000 { /* uSDHC3 */ + cd-gpios = <&gpio2 0 0>; + wp-gpios = <&gpio2 1 0>; + status = "okay"; + }; + }; + }; +}; diff --git a/trunk/arch/arm/boot/dts/imx6q.dtsi b/trunk/arch/arm/boot/dts/imx6q.dtsi index 4905f51a106f..8c90cbac945f 100644 --- a/trunk/arch/arm/boot/dts/imx6q.dtsi +++ b/trunk/arch/arm/boot/dts/imx6q.dtsi @@ -165,7 +165,7 @@ status = "disabled"; }; - uart1: uart@02020000 { + uart1: serial@02020000 { compatible = "fsl,imx6q-uart", "fsl,imx21-uart"; reg = <0x02020000 0x4000>; interrupts = <0 26 0x04>; @@ -177,19 +177,31 @@ interrupts = <0 51 0x04>; }; - ssi@02028000 { /* SSI1 */ + ssi1: ssi@02028000 { + compatible = "fsl,imx6q-ssi","fsl,imx21-ssi"; reg = <0x02028000 0x4000>; interrupts = <0 46 0x04>; + fsl,fifo-depth = <15>; + fsl,ssi-dma-events = <38 37>; + status = "disabled"; }; - ssi@0202c000 { /* SSI2 */ + ssi2: ssi@0202c000 { + compatible = "fsl,imx6q-ssi","fsl,imx21-ssi"; reg = <0x0202c000 0x4000>; interrupts = <0 47 0x04>; + fsl,fifo-depth = <15>; + fsl,ssi-dma-events = <42 41>; + status = "disabled"; }; - ssi@02030000 { /* SSI3 */ + ssi3: ssi@02030000 { + compatible = "fsl,imx6q-ssi","fsl,imx21-ssi"; reg = <0x02030000 0x4000>; interrupts = <0 48 0x04>; + fsl,fifo-depth = <15>; + fsl,ssi-dma-events = <46 45>; + status = "disabled"; }; asrc@02034000 { @@ -346,6 +358,90 @@ compatible = "fsl,imx6q-anatop"; reg = <0x020c8000 0x1000>; interrupts = <0 49 0x04 0 54 0x04 0 127 0x04>; + + regulator-1p1@110 { + compatible = "fsl,anatop-regulator"; + regulator-name = "vdd1p1"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1375000>; + regulator-always-on; + anatop-reg-offset = <0x110>; + anatop-vol-bit-shift = <8>; + anatop-vol-bit-width = <5>; + anatop-min-bit-val = <4>; + anatop-min-voltage = <800000>; + anatop-max-voltage = <1375000>; + }; + + regulator-3p0@120 { + compatible = "fsl,anatop-regulator"; + regulator-name = "vdd3p0"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <3150000>; + regulator-always-on; + anatop-reg-offset = <0x120>; + anatop-vol-bit-shift = <8>; + anatop-vol-bit-width = <5>; + anatop-min-bit-val = <0>; + anatop-min-voltage = <2625000>; + anatop-max-voltage = <3400000>; + }; + + regulator-2p5@130 { + compatible = "fsl,anatop-regulator"; + regulator-name = "vdd2p5"; + regulator-min-microvolt = <2000000>; + regulator-max-microvolt = <2750000>; + regulator-always-on; + anatop-reg-offset = <0x130>; + anatop-vol-bit-shift = <8>; + anatop-vol-bit-width = <5>; + anatop-min-bit-val = <0>; + anatop-min-voltage = <2000000>; + anatop-max-voltage = <2750000>; + }; + + regulator-vddcore@140 { + compatible = "fsl,anatop-regulator"; + regulator-name = "cpu"; + regulator-min-microvolt = <725000>; + regulator-max-microvolt = <1450000>; + regulator-always-on; + anatop-reg-offset = <0x140>; + anatop-vol-bit-shift = <0>; + anatop-vol-bit-width = <5>; + anatop-min-bit-val = <1>; + anatop-min-voltage = <725000>; + anatop-max-voltage = <1450000>; + }; + + regulator-vddpu@140 { + compatible = "fsl,anatop-regulator"; + regulator-name = "vddpu"; + regulator-min-microvolt = <725000>; + regulator-max-microvolt = <1450000>; + regulator-always-on; + anatop-reg-offset = <0x140>; + anatop-vol-bit-shift = <9>; + anatop-vol-bit-width = <5>; + anatop-min-bit-val = <1>; + anatop-min-voltage = <725000>; + anatop-max-voltage = <1450000>; + }; + + regulator-vddsoc@140 { + compatible = "fsl,anatop-regulator"; + regulator-name = "vddsoc"; + regulator-min-microvolt = <725000>; + regulator-max-microvolt = <1450000>; + regulator-always-on; + anatop-reg-offset = <0x140>; + anatop-vol-bit-shift = <18>; + anatop-vol-bit-width = <5>; + anatop-min-bit-val = <1>; + anatop-min-voltage = <725000>; + anatop-max-voltage = <1450000>; + }; }; usbphy@020c9000 { /* USBPHY1 */ @@ -386,7 +482,62 @@ }; iomuxc@020e0000 { + compatible = "fsl,imx6q-iomuxc"; reg = <0x020e0000 0x4000>; + + /* shared pinctrl settings */ + audmux { + pinctrl_audmux_1: audmux-1 { + fsl,pins = <18 0x80000000 /* MX6Q_PAD_SD2_DAT0__AUDMUX_AUD4_RXD */ + 1586 0x80000000 /* MX6Q_PAD_SD2_DAT3__AUDMUX_AUD4_TXC */ + 11 0x80000000 /* MX6Q_PAD_SD2_DAT2__AUDMUX_AUD4_TXD */ + 3 0x80000000>; /* MX6Q_PAD_SD2_DAT1__AUDMUX_AUD4_TXFS */ + }; + }; + + i2c1 { + pinctrl_i2c1_1: i2c1grp-1 { + fsl,pins = <137 0x4001b8b1 /* MX6Q_PAD_EIM_D21__I2C1_SCL */ + 196 0x4001b8b1>; /* MX6Q_PAD_EIM_D28__I2C1_SDA */ + }; + }; + + serial2 { + pinctrl_serial2_1: serial2grp-1 { + fsl,pins = <183 0x1b0b1 /* MX6Q_PAD_EIM_D26__UART2_TXD */ + 191 0x1b0b1>; /* MX6Q_PAD_EIM_D27__UART2_RXD */ + }; + }; + + usdhc3 { + pinctrl_usdhc3_1: usdhc3grp-1 { + fsl,pins = <1273 0x17059 /* MX6Q_PAD_SD3_CMD__USDHC3_CMD */ + 1281 0x10059 /* MX6Q_PAD_SD3_CLK__USDHC3_CLK */ + 1289 0x17059 /* MX6Q_PAD_SD3_DAT0__USDHC3_DAT0 */ + 1297 0x17059 /* MX6Q_PAD_SD3_DAT1__USDHC3_DAT1 */ + 1305 0x17059 /* MX6Q_PAD_SD3_DAT2__USDHC3_DAT2 */ + 1312 0x17059 /* MX6Q_PAD_SD3_DAT3__USDHC3_DAT3 */ + 1265 0x17059 /* MX6Q_PAD_SD3_DAT4__USDHC3_DAT4 */ + 1257 0x17059 /* MX6Q_PAD_SD3_DAT5__USDHC3_DAT5 */ + 1249 0x17059 /* MX6Q_PAD_SD3_DAT6__USDHC3_DAT6 */ + 1241 0x17059>; /* MX6Q_PAD_SD3_DAT7__USDHC3_DAT7 */ + }; + }; + + usdhc4 { + pinctrl_usdhc4_1: usdhc4grp-1 { + fsl,pins = <1386 0x17059 /* MX6Q_PAD_SD4_CMD__USDHC4_CMD */ + 1392 0x10059 /* MX6Q_PAD_SD4_CLK__USDHC4_CLK */ + 1462 0x17059 /* MX6Q_PAD_SD4_DAT0__USDHC4_DAT0 */ + 1470 0x17059 /* MX6Q_PAD_SD4_DAT1__USDHC4_DAT1 */ + 1478 0x17059 /* MX6Q_PAD_SD4_DAT2__USDHC4_DAT2 */ + 1486 0x17059 /* MX6Q_PAD_SD4_DAT3__USDHC4_DAT3 */ + 1493 0x17059 /* MX6Q_PAD_SD4_DAT4__USDHC4_DAT4 */ + 1501 0x17059 /* MX6Q_PAD_SD4_DAT5__USDHC4_DAT5 */ + 1509 0x17059 /* MX6Q_PAD_SD4_DAT6__USDHC4_DAT6 */ + 1517 0x17059>; /* MX6Q_PAD_SD4_DAT7__USDHC4_DAT7 */ + }; + }; }; dcic@020e4000 { /* DCIC1 */ @@ -422,7 +573,7 @@ reg = <0x0217c000 0x4000>; }; - enet@02188000 { + ethernet@02188000 { compatible = "fsl,imx6q-fec"; reg = <0x02188000 0x4000>; interrupts = <0 118 0x04 0 119 0x04>; @@ -527,7 +678,9 @@ }; audmux@021d8000 { + compatible = "fsl,imx6q-audmux", "fsl,imx31-audmux"; reg = <0x021d8000 0x4000>; + status = "disabled"; }; mipi@021dc000 { /* MIPI-CSI */ @@ -543,28 +696,28 @@ interrupts = <0 18 0x04>; }; - uart2: uart@021e8000 { + uart2: serial@021e8000 { compatible = "fsl,imx6q-uart", "fsl,imx21-uart"; reg = <0x021e8000 0x4000>; interrupts = <0 27 0x04>; status = "disabled"; }; - uart3: uart@021ec000 { + uart3: serial@021ec000 { compatible = "fsl,imx6q-uart", "fsl,imx21-uart"; reg = <0x021ec000 0x4000>; interrupts = <0 28 0x04>; status = "disabled"; }; - uart4: uart@021f0000 { + uart4: serial@021f0000 { compatible = "fsl,imx6q-uart", "fsl,imx21-uart"; reg = <0x021f0000 0x4000>; interrupts = <0 29 0x04>; status = "disabled"; }; - uart5: uart@021f4000 { + uart5: serial@021f4000 { compatible = "fsl,imx6q-uart", "fsl,imx21-uart"; reg = <0x021f4000 0x4000>; interrupts = <0 30 0x04>; diff --git a/trunk/arch/arm/boot/dts/lpc32xx.dtsi b/trunk/arch/arm/boot/dts/lpc32xx.dtsi index 2d696866f71c..3f5dad801a98 100644 --- a/trunk/arch/arm/boot/dts/lpc32xx.dtsi +++ b/trunk/arch/arm/boot/dts/lpc32xx.dtsi @@ -215,45 +215,8 @@ gpio: gpio@40028000 { compatible = "nxp,lpc3220-gpio"; reg = <0x40028000 0x1000>; - /* create a private address space for enumeration */ - #address-cells = <1>; - #size-cells = <0>; - - gpio_p0: gpio-bank@0 { - gpio-controller; - #gpio-cells = <2>; - reg = <0>; - }; - - gpio_p1: gpio-bank@1 { - gpio-controller; - #gpio-cells = <2>; - reg = <1>; - }; - - gpio_p2: gpio-bank@2 { - gpio-controller; - #gpio-cells = <2>; - reg = <2>; - }; - - gpio_p3: gpio-bank@3 { - gpio-controller; - #gpio-cells = <2>; - reg = <3>; - }; - - gpi_p3: gpio-bank@4 { - gpio-controller; - #gpio-cells = <2>; - reg = <4>; - }; - - gpo_p3: gpio-bank@5 { - gpio-controller; - #gpio-cells = <2>; - reg = <5>; - }; + gpio-controller; + #gpio-cells = <3>; /* bank, pin, flags */ }; watchdog@4003C000 { diff --git a/trunk/arch/arm/boot/dts/mmp2-brownstone.dts b/trunk/arch/arm/boot/dts/mmp2-brownstone.dts index 153a4b2d12b5..c9b4f27d191e 100644 --- a/trunk/arch/arm/boot/dts/mmp2-brownstone.dts +++ b/trunk/arch/arm/boot/dts/mmp2-brownstone.dts @@ -11,7 +11,7 @@ /include/ "mmp2.dtsi" / { - model = "Marvell MMP2 Aspenite Development Board"; + model = "Marvell MMP2 Brownstone Development Board"; compatible = "mrvl,mmp2-brownstone", "mrvl,mmp2"; chosen { @@ -19,7 +19,7 @@ }; memory { - reg = <0x00000000 0x04000000>; + reg = <0x00000000 0x08000000>; }; soc { diff --git a/trunk/arch/arm/boot/dts/omap2.dtsi b/trunk/arch/arm/boot/dts/omap2.dtsi index f2ab4ea7cc0e..581cb081cb0f 100644 --- a/trunk/arch/arm/boot/dts/omap2.dtsi +++ b/trunk/arch/arm/boot/dts/omap2.dtsi @@ -44,6 +44,8 @@ compatible = "ti,omap2-intc"; interrupt-controller; #interrupt-cells = <1>; + ti,intc-size = <96>; + reg = <0x480FE000 0x1000>; }; uart1: serial@4806a000 { diff --git a/trunk/arch/arm/boot/dts/omap3-beagle.dts b/trunk/arch/arm/boot/dts/omap3-beagle.dts index 8c756be4d7ad..5b4506c0a8c4 100644 --- a/trunk/arch/arm/boot/dts/omap3-beagle.dts +++ b/trunk/arch/arm/boot/dts/omap3-beagle.dts @@ -57,7 +57,7 @@ &mmc1 { vmmc-supply = <&vmmc1>; vmmc_aux-supply = <&vsim>; - ti,bus-width = <8>; + bus-width = <8>; }; &mmc2 { diff --git a/trunk/arch/arm/boot/dts/omap4-panda.dts b/trunk/arch/arm/boot/dts/omap4-panda.dts index e671361bc791..1efe0c587985 100644 --- a/trunk/arch/arm/boot/dts/omap4-panda.dts +++ b/trunk/arch/arm/boot/dts/omap4-panda.dts @@ -70,7 +70,7 @@ &mmc1 { vmmc-supply = <&vmmc>; - ti,bus-width = <8>; + bus-width = <8>; }; &mmc2 { @@ -87,5 +87,5 @@ &mmc5 { ti,non-removable; - ti,bus-width = <4>; + bus-width = <4>; }; diff --git a/trunk/arch/arm/boot/dts/omap4-sdp.dts b/trunk/arch/arm/boot/dts/omap4-sdp.dts index e5eeb6f9c6e6..d08c4d137280 100644 --- a/trunk/arch/arm/boot/dts/omap4-sdp.dts +++ b/trunk/arch/arm/boot/dts/omap4-sdp.dts @@ -137,12 +137,12 @@ &mmc1 { vmmc-supply = <&vmmc>; - ti,bus-width = <8>; + bus-width = <8>; }; &mmc2 { vmmc-supply = <&vaux1>; - ti,bus-width = <8>; + bus-width = <8>; ti,non-removable; }; @@ -155,6 +155,6 @@ }; &mmc5 { - ti,bus-width = <4>; + bus-width = <4>; ti,non-removable; }; diff --git a/trunk/arch/arm/boot/dts/phy3250.dts b/trunk/arch/arm/boot/dts/phy3250.dts index 0167e86314c0..c4ff6d1a018b 100644 --- a/trunk/arch/arm/boot/dts/phy3250.dts +++ b/trunk/arch/arm/boot/dts/phy3250.dts @@ -131,13 +131,13 @@ compatible = "gpio-leds"; led0 { - gpios = <&gpo_p3 1 1>; /* GPO_P3 1, GPIO 80, active low */ + gpios = <&gpio 5 1 1>; /* GPO_P3 1, GPIO 80, active low */ linux,default-trigger = "heartbeat"; default-state = "off"; }; led1 { - gpios = <&gpo_p3 14 1>; /* GPO_P3 14, GPIO 93, active low */ + gpios = <&gpio 5 14 1>; /* GPO_P3 14, GPIO 93, active low */ linux,default-trigger = "timer"; default-state = "off"; }; diff --git a/trunk/arch/arm/boot/dts/snowball.dts b/trunk/arch/arm/boot/dts/snowball.dts index d99dc04f0d91..ec3c33975110 100644 --- a/trunk/arch/arm/boot/dts/snowball.dts +++ b/trunk/arch/arm/boot/dts/snowball.dts @@ -20,6 +20,16 @@ reg = <0x00000000 0x20000000>; }; + en_3v3_reg: en_3v3 { + compatible = "regulator-fixed"; + regulator-name = "en-3v3-fixed-supply"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpios = <&gpio0 26 0x4>; // 26 + startup-delay-us = <5000>; + enable-active-high; + }; + gpio_keys { compatible = "gpio-keys"; #address-cells = <1>; @@ -30,35 +40,35 @@ wakeup = <1>; linux,code = <2>; label = "userpb"; - gpios = <&gpio1 0 0>; + gpios = <&gpio1 0 0x4>; }; button@2 { debounce_interval = <50>; wakeup = <1>; linux,code = <3>; label = "extkb1"; - gpios = <&gpio4 23 0>; + gpios = <&gpio4 23 0x4>; }; button@3 { debounce_interval = <50>; wakeup = <1>; linux,code = <4>; label = "extkb2"; - gpios = <&gpio4 24 0>; + gpios = <&gpio4 24 0x4>; }; button@4 { debounce_interval = <50>; wakeup = <1>; linux,code = <5>; label = "extkb3"; - gpios = <&gpio5 1 0>; + gpios = <&gpio5 1 0x4>; }; button@5 { debounce_interval = <50>; wakeup = <1>; linux,code = <6>; label = "extkb4"; - gpios = <&gpio5 2 0>; + gpios = <&gpio5 2 0x4>; }; }; @@ -66,12 +76,11 @@ compatible = "gpio-leds"; used-led { label = "user_led"; - gpios = <&gpio4 14>; + gpios = <&gpio4 14 0x4>; }; }; soc-u9500 { - external-bus@50000000 { status = "okay"; @@ -80,6 +89,9 @@ reg = <0 0x10000>; interrupts = <12 0x1>; interrupt-parent = <&gpio4>; + vdd33a-supply = <&en_3v3_reg>; + vddvario-supply = <&db8500_vape_reg>; + reg-shift = <1>; reg-io-width = <2>; @@ -91,11 +103,13 @@ sdi@80126000 { status = "enabled"; - cd-gpios = <&gpio6 26>; + vmmc-supply = <&ab8500_ldo_aux3_reg>; + cd-gpios = <&gpio6 26 0x4>; // 218 }; sdi@80114000 { status = "enabled"; + vmmc-supply = <&ab8500_ldo_aux2_reg>; }; uart@80120000 { @@ -114,7 +128,7 @@ tc3589x@42 { //compatible = "tc3589x"; reg = <0x42>; - interrupts = <25>; + gpios = <&gpio6 25 0x4>; interrupt-parent = <&gpio6>; }; tps61052@33 { diff --git a/trunk/arch/arm/boot/dts/spear1310-evb.dts b/trunk/arch/arm/boot/dts/spear1310-evb.dts new file mode 100644 index 000000000000..dd4358bc26e2 --- /dev/null +++ b/trunk/arch/arm/boot/dts/spear1310-evb.dts @@ -0,0 +1,292 @@ +/* + * DTS file for SPEAr1310 Evaluation Baord + * + * Copyright 2012 Viresh Kumar + * + * 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 + */ + +/dts-v1/; +/include/ "spear1310.dtsi" + +/ { + model = "ST SPEAr1310 Evaluation Board"; + compatible = "st,spear1310-evb", "st,spear1310"; + #address-cells = <1>; + #size-cells = <1>; + + memory { + reg = <0 0x40000000>; + }; + + ahb { + pinmux@e0700000 { + pinctrl-names = "default"; + pinctrl-0 = <&state_default>; + + state_default: pinmux { + i2c0-pmx { + st,pins = "i2c0_grp"; + st,function = "i2c0"; + }; + i2s1 { + st,pins = "i2s1_grp"; + st,function = "i2s1"; + }; + gpio { + st,pins = "arm_gpio_grp"; + st,function = "arm_gpio"; + }; + eth { + st,pins = "gmii_grp"; + st,function = "gmii"; + }; + ssp0 { + st,pins = "ssp0_grp"; + st,function = "ssp0"; + }; + kbd { + st,pins = "keyboard_6x6_grp"; + st,function = "keyboard"; + }; + sdhci { + st,pins = "sdhci_grp"; + st,function = "sdhci"; + }; + smi-pmx { + st,pins = "smi_2_chips_grp"; + st,function = "smi"; + }; + uart0 { + st,pins = "uart0_grp"; + st,function = "uart0"; + }; + rs485 { + st,pins = "rs485_0_1_tdm_0_1_grp"; + st,function = "rs485_0_1_tdm_0_1"; + }; + i2c1_2 { + st,pins = "i2c_1_2_grp"; + st,function = "i2c_1_2"; + }; + pci { + st,pins = "pcie0_grp","pcie1_grp", + "pcie2_grp"; + st,function = "pci"; + }; + smii { + st,pins = "smii_0_1_2_grp"; + st,function = "smii_0_1_2"; + }; + nand { + st,pins = "nand_8bit_grp", + "nand_16bit_grp"; + st,function = "nand"; + }; + }; + }; + + ahci@b1000000 { + status = "okay"; + }; + + cf@b2800000 { + status = "okay"; + }; + + dma@ea800000 { + status = "okay"; + }; + + dma@eb000000 { + status = "okay"; + }; + + fsmc: flash@b0000000 { + status = "okay"; + }; + + gmac0: eth@e2000000 { + status = "okay"; + }; + + sdhci@b3000000 { + status = "okay"; + }; + + smi: flash@ea000000 { + status = "okay"; + clock-rate=<50000000>; + + flash@e6000000 { + #address-cells = <1>; + #size-cells = <1>; + reg = <0xe6000000 0x800000>; + st,smi-fast-mode; + + partition@0 { + label = "xloader"; + reg = <0x0 0x10000>; + }; + partition@10000 { + label = "u-boot"; + reg = <0x10000 0x40000>; + }; + partition@50000 { + label = "linux"; + reg = <0x50000 0x2c0000>; + }; + partition@310000 { + label = "rootfs"; + reg = <0x310000 0x4f0000>; + }; + }; + }; + + spi0: spi@e0100000 { + status = "okay"; + }; + + ehci@e4800000 { + status = "okay"; + }; + + ehci@e5800000 { + status = "okay"; + }; + + ohci@e4000000 { + status = "okay"; + }; + + ohci@e5000000 { + status = "okay"; + }; + + apb { + adc@e0080000 { + status = "okay"; + }; + + gpio0: gpio@e0600000 { + status = "okay"; + }; + + gpio1: gpio@e0680000 { + status = "okay"; + }; + + i2c0: i2c@e0280000 { + status = "okay"; + }; + + i2c1: i2c@5cd00000 { + status = "okay"; + }; + + kbd@e0300000 { + linux,keymap = < 0x00000001 + 0x00010002 + 0x00020003 + 0x00030004 + 0x00040005 + 0x00050006 + 0x00060007 + 0x00070008 + 0x00080009 + 0x0100000a + 0x0101000c + 0x0102000d + 0x0103000e + 0x0104000f + 0x01050010 + 0x01060011 + 0x01070012 + 0x01080013 + 0x02000014 + 0x02010015 + 0x02020016 + 0x02030017 + 0x02040018 + 0x02050019 + 0x0206001a + 0x0207001b + 0x0208001c + 0x0300001d + 0x0301001e + 0x0302001f + 0x03030020 + 0x03040021 + 0x03050022 + 0x03060023 + 0x03070024 + 0x03080025 + 0x04000026 + 0x04010027 + 0x04020028 + 0x04030029 + 0x0404002a + 0x0405002b + 0x0406002c + 0x0407002d + 0x0408002e + 0x0500002f + 0x05010030 + 0x05020031 + 0x05030032 + 0x05040033 + 0x05050034 + 0x05060035 + 0x05070036 + 0x05080037 + 0x06000038 + 0x06010039 + 0x0602003a + 0x0603003b + 0x0604003c + 0x0605003d + 0x0606003e + 0x0607003f + 0x06080040 + 0x07000041 + 0x07010042 + 0x07020043 + 0x07030044 + 0x07040045 + 0x07050046 + 0x07060047 + 0x07070048 + 0x07080049 + 0x0800004a + 0x0801004b + 0x0802004c + 0x0803004d + 0x0804004e + 0x0805004f + 0x08060050 + 0x08070051 + 0x08080052 >; + autorepeat; + st,mode = <0>; + status = "okay"; + }; + + rtc@e0580000 { + status = "okay"; + }; + + serial@e0000000 { + status = "okay"; + }; + + wdt@ec800620 { + status = "okay"; + }; + }; + }; +}; diff --git a/trunk/arch/arm/boot/dts/spear1310.dtsi b/trunk/arch/arm/boot/dts/spear1310.dtsi new file mode 100644 index 000000000000..419ea7413d23 --- /dev/null +++ b/trunk/arch/arm/boot/dts/spear1310.dtsi @@ -0,0 +1,184 @@ +/* + * DTS file for all SPEAr1310 SoCs + * + * Copyright 2012 Viresh Kumar + * + * 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/ "spear13xx.dtsi" + +/ { + compatible = "st,spear1310"; + + ahb { + ahci@b1000000 { + compatible = "snps,spear-ahci"; + reg = <0xb1000000 0x10000>; + interrupts = <0 68 0x4>; + status = "disabled"; + }; + + ahci@b1800000 { + compatible = "snps,spear-ahci"; + reg = <0xb1800000 0x10000>; + interrupts = <0 69 0x4>; + status = "disabled"; + }; + + ahci@b4000000 { + compatible = "snps,spear-ahci"; + reg = <0xb4000000 0x10000>; + interrupts = <0 70 0x4>; + status = "disabled"; + }; + + gmac1: eth@5c400000 { + compatible = "st,spear600-gmac"; + reg = <0x5c400000 0x8000>; + interrupts = <0 95 0x4>; + interrupt-names = "macirq"; + status = "disabled"; + }; + + gmac2: eth@5c500000 { + compatible = "st,spear600-gmac"; + reg = <0x5c500000 0x8000>; + interrupts = <0 96 0x4>; + interrupt-names = "macirq"; + status = "disabled"; + }; + + gmac3: eth@5c600000 { + compatible = "st,spear600-gmac"; + reg = <0x5c600000 0x8000>; + interrupts = <0 97 0x4>; + interrupt-names = "macirq"; + status = "disabled"; + }; + + gmac4: eth@5c700000 { + compatible = "st,spear600-gmac"; + reg = <0x5c700000 0x8000>; + interrupts = <0 98 0x4>; + interrupt-names = "macirq"; + status = "disabled"; + }; + + spi1: spi@5d400000 { + compatible = "arm,pl022", "arm,primecell"; + reg = <0x5d400000 0x1000>; + interrupts = <0 99 0x4>; + status = "disabled"; + }; + + apb { + i2c1: i2c@5cd00000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,designware-i2c"; + reg = <0x5cd00000 0x1000>; + interrupts = <0 87 0x4>; + status = "disabled"; + }; + + i2c2: i2c@5ce00000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,designware-i2c"; + reg = <0x5ce00000 0x1000>; + interrupts = <0 88 0x4>; + status = "disabled"; + }; + + i2c3: i2c@5cf00000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,designware-i2c"; + reg = <0x5cf00000 0x1000>; + interrupts = <0 89 0x4>; + status = "disabled"; + }; + + i2c4: i2c@5d000000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,designware-i2c"; + reg = <0x5d000000 0x1000>; + interrupts = <0 90 0x4>; + status = "disabled"; + }; + + i2c5: i2c@5d100000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,designware-i2c"; + reg = <0x5d100000 0x1000>; + interrupts = <0 91 0x4>; + status = "disabled"; + }; + + i2c6: i2c@5d200000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,designware-i2c"; + reg = <0x5d200000 0x1000>; + interrupts = <0 92 0x4>; + status = "disabled"; + }; + + i2c7: i2c@5d300000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,designware-i2c"; + reg = <0x5d300000 0x1000>; + interrupts = <0 93 0x4>; + status = "disabled"; + }; + + serial@5c800000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x5c800000 0x1000>; + interrupts = <0 82 0x4>; + status = "disabled"; + }; + + serial@5c900000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x5c900000 0x1000>; + interrupts = <0 83 0x4>; + status = "disabled"; + }; + + serial@5ca00000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x5ca00000 0x1000>; + interrupts = <0 84 0x4>; + status = "disabled"; + }; + + serial@5cb00000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x5cb00000 0x1000>; + interrupts = <0 85 0x4>; + status = "disabled"; + }; + + serial@5cc00000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x5cc00000 0x1000>; + interrupts = <0 86 0x4>; + status = "disabled"; + }; + + thermal@e07008c4 { + st,thermal-flags = <0x7000>; + }; + }; + }; +}; diff --git a/trunk/arch/arm/boot/dts/spear1340-evb.dts b/trunk/arch/arm/boot/dts/spear1340-evb.dts new file mode 100644 index 000000000000..c9a54e06fb68 --- /dev/null +++ b/trunk/arch/arm/boot/dts/spear1340-evb.dts @@ -0,0 +1,308 @@ +/* + * DTS file for SPEAr1340 Evaluation Baord + * + * Copyright 2012 Viresh Kumar + * + * 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 + */ + +/dts-v1/; +/include/ "spear1340.dtsi" + +/ { + model = "ST SPEAr1340 Evaluation Board"; + compatible = "st,spear1340-evb", "st,spear1340"; + #address-cells = <1>; + #size-cells = <1>; + + memory { + reg = <0 0x40000000>; + }; + + ahb { + pinmux@e0700000 { + pinctrl-names = "default"; + pinctrl-0 = <&state_default>; + + state_default: pinmux { + pads_as_gpio { + st,pins = "pads_as_gpio_grp"; + st,function = "pads_as_gpio"; + }; + fsmc { + st,pins = "fsmc_8bit_grp"; + st,function = "fsmc"; + }; + kbd { + st,pins = "keyboard_row_col_grp", + "keyboard_col5_grp"; + st,function = "keyboard"; + }; + uart0 { + st,pins = "uart0_grp", "uart0_enh_grp"; + st,function = "uart0"; + }; + i2c0-pmx { + st,pins = "i2c0_grp"; + st,function = "i2c0"; + }; + i2c1-pmx { + st,pins = "i2c1_grp"; + st,function = "i2c1"; + }; + spdif-in { + st,pins = "spdif_in_grp"; + st,function = "spdif_in"; + }; + spdif-out { + st,pins = "spdif_out_grp"; + st,function = "spdif_out"; + }; + ssp0 { + st,pins = "ssp0_grp", "ssp0_cs1_grp", + "ssp0_cs3_grp"; + st,function = "ssp0"; + }; + pwm { + st,pins = "pwm2_grp", "pwm3_grp"; + st,function = "pwm"; + }; + smi-pmx { + st,pins = "smi_grp"; + st,function = "smi"; + }; + i2s { + st,pins = "i2s_in_grp", "i2s_out_grp"; + st,function = "i2s"; + }; + gmac { + st,pins = "gmii_grp", "rgmii_grp"; + st,function = "gmac"; + }; + cam3 { + st,pins = "cam3_grp"; + st,function = "cam3"; + }; + cec0 { + st,pins = "cec0_grp"; + st,function = "cec0"; + }; + cec1 { + st,pins = "cec1_grp"; + st,function = "cec1"; + }; + sdhci { + st,pins = "sdhci_grp"; + st,function = "sdhci"; + }; + clcd { + st,pins = "clcd_grp"; + st,function = "clcd"; + }; + sata { + st,pins = "sata_grp"; + st,function = "sata"; + }; + }; + }; + + dma@ea800000 { + status = "okay"; + }; + + dma@eb000000 { + status = "okay"; + }; + + fsmc: flash@b0000000 { + status = "okay"; + }; + + gmac0: eth@e2000000 { + status = "okay"; + }; + + sdhci@b3000000 { + status = "okay"; + }; + + smi: flash@ea000000 { + status = "okay"; + clock-rate=<50000000>; + + flash@e6000000 { + #address-cells = <1>; + #size-cells = <1>; + reg = <0xe6000000 0x800000>; + st,smi-fast-mode; + + partition@0 { + label = "xloader"; + reg = <0x0 0x10000>; + }; + partition@10000 { + label = "u-boot"; + reg = <0x10000 0x40000>; + }; + partition@50000 { + label = "linux"; + reg = <0x50000 0x2c0000>; + }; + partition@310000 { + label = "rootfs"; + reg = <0x310000 0x4f0000>; + }; + }; + }; + + spi0: spi@e0100000 { + status = "okay"; + }; + + ehci@e4800000 { + status = "okay"; + }; + + ehci@e5800000 { + status = "okay"; + }; + + ohci@e4000000 { + status = "okay"; + }; + + ohci@e5000000 { + status = "okay"; + }; + + apb { + adc@e0080000 { + status = "okay"; + }; + + gpio0: gpio@e0600000 { + status = "okay"; + }; + + gpio1: gpio@e0680000 { + status = "okay"; + }; + + i2c0: i2c@e0280000 { + status = "okay"; + }; + + i2c1: i2c@b4000000 { + status = "okay"; + }; + + kbd@e0300000 { + linux,keymap = < 0x00000001 + 0x00010002 + 0x00020003 + 0x00030004 + 0x00040005 + 0x00050006 + 0x00060007 + 0x00070008 + 0x00080009 + 0x0100000a + 0x0101000c + 0x0102000d + 0x0103000e + 0x0104000f + 0x01050010 + 0x01060011 + 0x01070012 + 0x01080013 + 0x02000014 + 0x02010015 + 0x02020016 + 0x02030017 + 0x02040018 + 0x02050019 + 0x0206001a + 0x0207001b + 0x0208001c + 0x0300001d + 0x0301001e + 0x0302001f + 0x03030020 + 0x03040021 + 0x03050022 + 0x03060023 + 0x03070024 + 0x03080025 + 0x04000026 + 0x04010027 + 0x04020028 + 0x04030029 + 0x0404002a + 0x0405002b + 0x0406002c + 0x0407002d + 0x0408002e + 0x0500002f + 0x05010030 + 0x05020031 + 0x05030032 + 0x05040033 + 0x05050034 + 0x05060035 + 0x05070036 + 0x05080037 + 0x06000038 + 0x06010039 + 0x0602003a + 0x0603003b + 0x0604003c + 0x0605003d + 0x0606003e + 0x0607003f + 0x06080040 + 0x07000041 + 0x07010042 + 0x07020043 + 0x07030044 + 0x07040045 + 0x07050046 + 0x07060047 + 0x07070048 + 0x07080049 + 0x0800004a + 0x0801004b + 0x0802004c + 0x0803004d + 0x0804004e + 0x0805004f + 0x08060050 + 0x08070051 + 0x08080052 >; + autorepeat; + st,mode = <0>; + status = "okay"; + }; + + rtc@e0580000 { + status = "okay"; + }; + + serial@e0000000 { + status = "okay"; + }; + + serial@b4100000 { + status = "okay"; + }; + + wdt@ec800620 { + status = "okay"; + }; + }; + }; +}; diff --git a/trunk/arch/arm/boot/dts/spear1340.dtsi b/trunk/arch/arm/boot/dts/spear1340.dtsi new file mode 100644 index 000000000000..d71fe2a68f09 --- /dev/null +++ b/trunk/arch/arm/boot/dts/spear1340.dtsi @@ -0,0 +1,56 @@ +/* + * DTS file for all SPEAr1340 SoCs + * + * Copyright 2012 Viresh Kumar + * + * 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/ "spear13xx.dtsi" + +/ { + compatible = "st,spear1340"; + + ahb { + ahci@b1000000 { + compatible = "snps,spear-ahci"; + reg = <0xb1000000 0x10000>; + interrupts = <0 72 0x4>; + status = "disabled"; + }; + + spi1: spi@5d400000 { + compatible = "arm,pl022", "arm,primecell"; + reg = <0x5d400000 0x1000>; + interrupts = <0 99 0x4>; + status = "disabled"; + }; + + apb { + i2c1: i2c@b4000000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,designware-i2c"; + reg = <0xb4000000 0x1000>; + interrupts = <0 104 0x4>; + status = "disabled"; + }; + + serial@b4100000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0xb4100000 0x1000>; + interrupts = <0 105 0x4>; + status = "disabled"; + }; + + thermal@e07008c4 { + st,thermal-flags = <0x2a00>; + }; + }; + }; +}; diff --git a/trunk/arch/arm/boot/dts/spear13xx.dtsi b/trunk/arch/arm/boot/dts/spear13xx.dtsi new file mode 100644 index 000000000000..10dcec7e7321 --- /dev/null +++ b/trunk/arch/arm/boot/dts/spear13xx.dtsi @@ -0,0 +1,262 @@ +/* + * DTS file for all SPEAr13xx SoCs + * + * Copyright 2012 Viresh Kumar + * + * 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/ "skeleton.dtsi" + +/ { + interrupt-parent = <&gic>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + compatible = "arm,cortex-a9"; + reg = <0>; + next-level-cache = <&L2>; + }; + + cpu@1 { + compatible = "arm,cortex-a9"; + reg = <1>; + next-level-cache = <&L2>; + }; + }; + + gic: interrupt-controller@ec801000 { + compatible = "arm,cortex-a9-gic"; + interrupt-controller; + #interrupt-cells = <3>; + reg = < 0xec801000 0x1000 >, + < 0xec800100 0x0100 >; + }; + + pmu { + compatible = "arm,cortex-a9-pmu"; + interrupts = <0 8 0x04 + 0 9 0x04>; + }; + + L2: l2-cache { + compatible = "arm,pl310-cache"; + reg = <0xed000000 0x1000>; + cache-unified; + cache-level = <2>; + }; + + memory { + name = "memory"; + device_type = "memory"; + reg = <0 0x40000000>; + }; + + chosen { + bootargs = "console=ttyAMA0,115200"; + }; + + ahb { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + ranges = <0x50000000 0x50000000 0x10000000 + 0xb0000000 0xb0000000 0x10000000 + 0xe0000000 0xe0000000 0x10000000>; + + sdhci@b3000000 { + compatible = "st,sdhci-spear"; + reg = <0xb3000000 0x100>; + interrupts = <0 28 0x4>; + status = "disabled"; + }; + + cf@b2800000 { + compatible = "arasan,cf-spear1340"; + reg = <0xb2800000 0x100>; + interrupts = <0 29 0x4>; + status = "disabled"; + }; + + dma@ea800000 { + compatible = "snps,dma-spear1340"; + reg = <0xea800000 0x1000>; + interrupts = <0 19 0x4>; + status = "disabled"; + }; + + dma@eb000000 { + compatible = "snps,dma-spear1340"; + reg = <0xeb000000 0x1000>; + interrupts = <0 59 0x4>; + status = "disabled"; + }; + + fsmc: flash@b0000000 { + compatible = "st,spear600-fsmc-nand"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xb0000000 0x1000 /* FSMC Register */ + 0xb0800000 0x0010>; /* NAND Base */ + reg-names = "fsmc_regs", "nand_data"; + interrupts = <0 20 0x4 + 0 21 0x4 + 0 22 0x4 + 0 23 0x4>; + st,ale-off = <0x20000>; + st,cle-off = <0x10000>; + status = "disabled"; + }; + + gmac0: eth@e2000000 { + compatible = "st,spear600-gmac"; + reg = <0xe2000000 0x8000>; + interrupts = <0 23 0x4 + 0 24 0x4>; + interrupt-names = "macirq", "eth_wake_irq"; + status = "disabled"; + }; + + smi: flash@ea000000 { + compatible = "st,spear600-smi"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0xea000000 0x1000>; + interrupts = <0 30 0x4>; + status = "disabled"; + }; + + spi0: spi@e0100000 { + compatible = "arm,pl022", "arm,primecell"; + reg = <0xe0100000 0x1000>; + interrupts = <0 31 0x4>; + status = "disabled"; + }; + + ehci@e4800000 { + compatible = "st,spear600-ehci", "usb-ehci"; + reg = <0xe4800000 0x1000>; + interrupts = <0 64 0x4>; + status = "disabled"; + }; + + ehci@e5800000 { + compatible = "st,spear600-ehci", "usb-ehci"; + reg = <0xe5800000 0x1000>; + interrupts = <0 66 0x4>; + status = "disabled"; + }; + + ohci@e4000000 { + compatible = "st,spear600-ohci", "usb-ohci"; + reg = <0xe4000000 0x1000>; + interrupts = <0 65 0x4>; + status = "disabled"; + }; + + ohci@e5000000 { + compatible = "st,spear600-ohci", "usb-ohci"; + reg = <0xe5000000 0x1000>; + interrupts = <0 67 0x4>; + status = "disabled"; + }; + + apb { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + ranges = <0x50000000 0x50000000 0x10000000 + 0xb0000000 0xb0000000 0x10000000 + 0xe0000000 0xe0000000 0x10000000>; + + gpio0: gpio@e0600000 { + compatible = "arm,pl061", "arm,primecell"; + reg = <0xe0600000 0x1000>; + interrupts = <0 24 0x4>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + status = "disabled"; + }; + + gpio1: gpio@e0680000 { + compatible = "arm,pl061", "arm,primecell"; + reg = <0xe0680000 0x1000>; + interrupts = <0 25 0x4>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + status = "disabled"; + }; + + kbd@e0300000 { + compatible = "st,spear300-kbd"; + reg = <0xe0300000 0x1000>; + status = "disabled"; + }; + + i2c0: i2c@e0280000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,designware-i2c"; + reg = <0xe0280000 0x1000>; + interrupts = <0 41 0x4>; + status = "disabled"; + }; + + rtc@e0580000 { + compatible = "st,spear-rtc"; + reg = <0xe0580000 0x1000>; + interrupts = <0 36 0x4>; + status = "disabled"; + }; + + serial@e0000000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0xe0000000 0x1000>; + interrupts = <0 36 0x4>; + status = "disabled"; + }; + + adc@e0080000 { + compatible = "st,spear600-adc"; + reg = <0xe0080000 0x1000>; + interrupts = <0 44 0x4>; + status = "disabled"; + }; + + timer@e0380000 { + compatible = "st,spear-timer"; + reg = <0xe0380000 0x400>; + interrupts = <0 37 0x4>; + }; + + timer@ec800600 { + compatible = "arm,cortex-a9-twd-timer"; + reg = <0xec800600 0x20>; + interrupts = <1 13 0x301>; + }; + + wdt@ec800620 { + compatible = "arm,cortex-a9-twd-wdt"; + reg = <0xec800620 0x20>; + status = "disabled"; + }; + + thermal@e07008c4 { + compatible = "st,thermal-spear1340"; + reg = <0xe07008c4 0x4>; + }; + }; + }; +}; diff --git a/trunk/arch/arm/boot/dts/spear300-evb.dts b/trunk/arch/arm/boot/dts/spear300-evb.dts index 910e264b87c0..d71b8d581e3d 100644 --- a/trunk/arch/arm/boot/dts/spear300-evb.dts +++ b/trunk/arch/arm/boot/dts/spear300-evb.dts @@ -1,7 +1,7 @@ /* * DTS file for SPEAr300 Evaluation Baord * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License @@ -87,6 +87,31 @@ smi: flash@fc000000 { status = "okay"; + clock-rate=<50000000>; + + flash@f8000000 { + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf8000000 0x800000>; + st,smi-fast-mode; + + partition@0 { + label = "xloader"; + reg = <0x0 0x10000>; + }; + partition@10000 { + label = "u-boot"; + reg = <0x10000 0x40000>; + }; + partition@50000 { + label = "linux"; + reg = <0x50000 0x2c0000>; + }; + partition@310000 { + label = "rootfs"; + reg = <0x310000 0x4f0000>; + }; + }; }; spi0: spi@d0100000 { diff --git a/trunk/arch/arm/boot/dts/spear300.dtsi b/trunk/arch/arm/boot/dts/spear300.dtsi index 01c5e358fdb2..ed3627c116cc 100644 --- a/trunk/arch/arm/boot/dts/spear300.dtsi +++ b/trunk/arch/arm/boot/dts/spear300.dtsi @@ -1,7 +1,7 @@ /* * DTS file for SPEAr300 SoC * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/trunk/arch/arm/boot/dts/spear310-evb.dts b/trunk/arch/arm/boot/dts/spear310-evb.dts index 6d95317100ad..b00544e0cd5d 100644 --- a/trunk/arch/arm/boot/dts/spear310-evb.dts +++ b/trunk/arch/arm/boot/dts/spear310-evb.dts @@ -1,7 +1,7 @@ /* * DTS file for SPEAr310 Evaluation Baord * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License @@ -103,11 +103,27 @@ clock-rate=<50000000>; flash@f8000000 { - label = "m25p64"; - reg = <0xf8000000 0x800000>; #address-cells = <1>; #size-cells = <1>; + reg = <0xf8000000 0x800000>; st,smi-fast-mode; + + partition@0 { + label = "xloader"; + reg = <0x0 0x10000>; + }; + partition@10000 { + label = "u-boot"; + reg = <0x10000 0x40000>; + }; + partition@50000 { + label = "linux"; + reg = <0x50000 0x2c0000>; + }; + partition@310000 { + label = "rootfs"; + reg = <0x310000 0x4f0000>; + }; }; }; diff --git a/trunk/arch/arm/boot/dts/spear310.dtsi b/trunk/arch/arm/boot/dts/spear310.dtsi index e47081c494d9..62fc4fb3e5f9 100644 --- a/trunk/arch/arm/boot/dts/spear310.dtsi +++ b/trunk/arch/arm/boot/dts/spear310.dtsi @@ -1,7 +1,7 @@ /* * DTS file for SPEAr310 SoC * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/trunk/arch/arm/boot/dts/spear320-evb.dts b/trunk/arch/arm/boot/dts/spear320-evb.dts index 0c6463b71a37..c13fd1f3b09f 100644 --- a/trunk/arch/arm/boot/dts/spear320-evb.dts +++ b/trunk/arch/arm/boot/dts/spear320-evb.dts @@ -1,7 +1,7 @@ /* * DTS file for SPEAr320 Evaluation Baord * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License @@ -110,6 +110,31 @@ smi: flash@fc000000 { status = "okay"; + clock-rate=<50000000>; + + flash@f8000000 { + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf8000000 0x800000>; + st,smi-fast-mode; + + partition@0 { + label = "xloader"; + reg = <0x0 0x10000>; + }; + partition@10000 { + label = "u-boot"; + reg = <0x10000 0x40000>; + }; + partition@50000 { + label = "linux"; + reg = <0x50000 0x2c0000>; + }; + partition@310000 { + label = "rootfs"; + reg = <0x310000 0x4f0000>; + }; + }; }; spi0: spi@d0100000 { diff --git a/trunk/arch/arm/boot/dts/spear320.dtsi b/trunk/arch/arm/boot/dts/spear320.dtsi index 5372ca399b1f..1f49d69595a0 100644 --- a/trunk/arch/arm/boot/dts/spear320.dtsi +++ b/trunk/arch/arm/boot/dts/spear320.dtsi @@ -1,7 +1,7 @@ /* * DTS file for SPEAr320 SoC * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/trunk/arch/arm/boot/dts/spear3xx.dtsi b/trunk/arch/arm/boot/dts/spear3xx.dtsi index 0ae7c8e86311..3a8bb5736928 100644 --- a/trunk/arch/arm/boot/dts/spear3xx.dtsi +++ b/trunk/arch/arm/boot/dts/spear3xx.dtsi @@ -1,7 +1,7 @@ /* * DTS file for all SPEAr3xx SoCs * - * Copyright 2012 Viresh Kumar + * Copyright 2012 Viresh Kumar * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License @@ -139,6 +139,12 @@ interrupts = <12>; status = "disabled"; }; + + timer@f0000000 { + compatible = "st,spear-timer"; + reg = <0xf0000000 0x400>; + interrupts = <2>; + }; }; }; }; diff --git a/trunk/arch/arm/boot/dts/spear600-evb.dts b/trunk/arch/arm/boot/dts/spear600-evb.dts index 790a7a8a5ccd..1119c22c9a82 100644 --- a/trunk/arch/arm/boot/dts/spear600-evb.dts +++ b/trunk/arch/arm/boot/dts/spear600-evb.dts @@ -33,6 +33,35 @@ status = "okay"; }; + smi: flash@fc000000 { + status = "okay"; + clock-rate=<50000000>; + + flash@f8000000 { + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf8000000 0x800000>; + st,smi-fast-mode; + + partition@0 { + label = "xloader"; + reg = <0x0 0x10000>; + }; + partition@10000 { + label = "u-boot"; + reg = <0x10000 0x40000>; + }; + partition@50000 { + label = "linux"; + reg = <0x50000 0x2c0000>; + }; + partition@310000 { + label = "rootfs"; + reg = <0x310000 0x4f0000>; + }; + }; + }; + apb { serial@d0000000 { status = "okay"; diff --git a/trunk/arch/arm/boot/dts/spear600.dtsi b/trunk/arch/arm/boot/dts/spear600.dtsi index d777e3a6f178..089f0a42c50e 100644 --- a/trunk/arch/arm/boot/dts/spear600.dtsi +++ b/trunk/arch/arm/boot/dts/spear600.dtsi @@ -177,6 +177,12 @@ interrupts = <28>; status = "disabled"; }; + + timer@f0000000 { + compatible = "st,spear-timer"; + reg = <0xf0000000 0x400>; + interrupts = <16>; + }; }; }; }; diff --git a/trunk/arch/arm/boot/dts/tegra-cardhu.dts b/trunk/arch/arm/boot/dts/tegra-cardhu.dts index 0a9f34a2c3aa..36321bceec46 100644 --- a/trunk/arch/arm/boot/dts/tegra-cardhu.dts +++ b/trunk/arch/arm/boot/dts/tegra-cardhu.dts @@ -7,10 +7,10 @@ compatible = "nvidia,cardhu", "nvidia,tegra30"; memory { - reg = < 0x80000000 0x40000000 >; + reg = <0x80000000 0x40000000>; }; - pinmux@70000000 { + pinmux { pinctrl-names = "default"; pinctrl-0 = <&state_default>; @@ -51,64 +51,122 @@ nvidia,pull = <2>; nvidia,tristate = <0>; }; + dap2_fs_pa2 { + nvidia,pins = "dap2_fs_pa2", + "dap2_sclk_pa3", + "dap2_din_pa4", + "dap2_dout_pa5"; + nvidia,function = "i2s1"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + }; }; }; serial@70006000 { - clock-frequency = < 408000000 >; - }; - - serial@70006040 { - status = "disable"; - }; - - serial@70006200 { - status = "disable"; - }; - - serial@70006300 { - status = "disable"; - }; - - serial@70006400 { - status = "disable"; + status = "okay"; + clock-frequency = <408000000>; }; i2c@7000c000 { + status = "okay"; clock-frequency = <100000>; }; i2c@7000c400 { + status = "okay"; clock-frequency = <100000>; }; i2c@7000c500 { + status = "okay"; clock-frequency = <100000>; + + /* ALS and Proximity sensor */ + isl29028@44 { + compatible = "isil,isl29028"; + reg = <0x44>; + interrupt-parent = <&gpio>; + interrupts = <88 0x04>; /*gpio PL0 */ + }; }; i2c@7000c700 { + status = "okay"; clock-frequency = <100000>; }; i2c@7000d000 { + status = "okay"; clock-frequency = <100000>; + + wm8903: wm8903@1a { + compatible = "wlf,wm8903"; + reg = <0x1a>; + interrupt-parent = <&gpio>; + interrupts = <179 0x04>; /* gpio PW3 */ + + gpio-controller; + #gpio-cells = <2>; + + micdet-cfg = <0>; + micdet-delay = <100>; + gpio-cfg = <0xffffffff 0xffffffff 0 0xffffffff 0xffffffff>; + }; + + tps62361 { + compatible = "ti,tps62361"; + reg = <0x60>; + + regulator-name = "tps62361-vout"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1500000>; + regulator-boot-on; + regulator-always-on; + ti,vsel0-state-high; + ti,vsel1-state-high; + }; + }; + + ahub { + i2s@70080400 { + status = "okay"; + }; }; sdhci@78000000 { + status = "okay"; cd-gpios = <&gpio 69 0>; /* gpio PI5 */ wp-gpios = <&gpio 155 0>; /* gpio PT3 */ power-gpios = <&gpio 31 0>; /* gpio PD7 */ + bus-width = <4>; }; - sdhci@78000200 { - status = "disable"; + sdhci@78000600 { + status = "okay"; + support-8bit; + bus-width = <8>; }; - sdhci@78000400 { - status = "disable"; - }; + sound { + compatible = "nvidia,tegra-audio-wm8903-cardhu", + "nvidia,tegra-audio-wm8903"; + nvidia,model = "NVIDIA Tegra Cardhu"; - sdhci@78000400 { - support-8bit; + nvidia,audio-routing = + "Headphone Jack", "HPOUTR", + "Headphone Jack", "HPOUTL", + "Int Spk", "ROP", + "Int Spk", "RON", + "Int Spk", "LOP", + "Int Spk", "LON", + "Mic Jack", "MICBIAS", + "IN1L", "Mic Jack"; + + nvidia,i2s-controller = <&tegra_i2s1>; + nvidia,audio-codec = <&wm8903>; + + nvidia,spkr-en-gpios = <&wm8903 2 0>; + nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */ }; }; diff --git a/trunk/arch/arm/boot/dts/tegra-harmony.dts b/trunk/arch/arm/boot/dts/tegra-harmony.dts index 1a0b1f182944..7de701365fce 100644 --- a/trunk/arch/arm/boot/dts/tegra-harmony.dts +++ b/trunk/arch/arm/boot/dts/tegra-harmony.dts @@ -6,11 +6,11 @@ model = "NVIDIA Tegra2 Harmony evaluation board"; compatible = "nvidia,harmony", "nvidia,tegra20"; - memory@0 { - reg = < 0x00000000 0x40000000 >; + memory { + reg = <0x00000000 0x40000000>; }; - pinmux@70000000 { + pinmux { pinctrl-names = "default"; pinctrl-0 = <&state_default>; @@ -167,28 +167,28 @@ }; conf_ata { nvidia,pins = "ata", "atb", "atc", "atd", "ate", - "cdev1", "dap1", "dtb", "gma", "gmb", - "gmc", "gmd", "gme", "gpu7", "gpv", - "i2cp", "pta", "rm", "slxa", "slxk", - "spia", "spib"; + "cdev1", "cdev2", "dap1", "dtb", "gma", + "gmb", "gmc", "gmd", "gme", "gpu7", + "gpv", "i2cp", "pta", "rm", "slxa", + "slxk", "spia", "spib", "uac"; nvidia,pull = <0>; nvidia,tristate = <0>; }; - conf_cdev2 { - nvidia,pins = "cdev2", "csus", "spid", "spif"; - nvidia,pull = <1>; - nvidia,tristate = <1>; - }; conf_ck32 { nvidia,pins = "ck32", "ddrc", "pmca", "pmcb", "pmcc", "pmcd", "pmce", "xm2c", "xm2d"; nvidia,pull = <0>; }; + conf_csus { + nvidia,pins = "csus", "spid", "spif"; + nvidia,pull = <1>; + nvidia,tristate = <1>; + }; conf_crtp { nvidia,pins = "crtp", "dap2", "dap3", "dap4", "dtc", "dte", "dtf", "gpu", "sdio1", "slxc", "slxd", "spdi", "spdo", "spig", - "uac", "uda"; + "uda"; nvidia,pull = <0>; nvidia,tristate = <1>; }; @@ -234,42 +234,81 @@ }; }; - pmc@7000f400 { - nvidia,invert-interrupt; + i2s@70002800 { + status = "okay"; + }; + + serial@70006300 { + status = "okay"; + clock-frequency = <216000000>; }; i2c@7000c000 { + status = "okay"; clock-frequency = <400000>; wm8903: wm8903@1a { compatible = "wlf,wm8903"; reg = <0x1a>; interrupt-parent = <&gpio>; - interrupts = < 187 0x04 >; + interrupts = <187 0x04>; gpio-controller; #gpio-cells = <2>; micdet-cfg = <0>; micdet-delay = <100>; - gpio-cfg = < 0xffffffff 0xffffffff 0 0xffffffff 0xffffffff >; + gpio-cfg = <0xffffffff 0xffffffff 0 0xffffffff 0xffffffff>; }; }; i2c@7000c400 { + status = "okay"; clock-frequency = <400000>; }; i2c@7000c500 { + status = "okay"; clock-frequency = <400000>; }; i2c@7000d000 { + status = "okay"; clock-frequency = <400000>; }; - i2s@70002a00 { - status = "disable"; + pmc { + nvidia,invert-interrupt; + }; + + usb@c5000000 { + status = "okay"; + }; + + usb@c5004000 { + status = "okay"; + nvidia,phy-reset-gpio = <&gpio 169 0>; /* gpio PV1 */ + }; + + usb@c5008000 { + status = "okay"; + }; + + sdhci@c8000200 { + status = "okay"; + cd-gpios = <&gpio 69 0>; /* gpio PI5 */ + wp-gpios = <&gpio 57 0>; /* gpio PH1 */ + power-gpios = <&gpio 155 0>; /* gpio PT3 */ + bus-width = <4>; + }; + + sdhci@c8000600 { + status = "okay"; + cd-gpios = <&gpio 58 0>; /* gpio PH2 */ + wp-gpios = <&gpio 59 0>; /* gpio PH3 */ + power-gpios = <&gpio 70 0>; /* gpio PI6 */ + support-8bit; + bus-width = <8>; }; sound { @@ -295,45 +334,4 @@ nvidia,int-mic-en-gpios = <&gpio 184 0>; /*gpio PX0 */ nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */ }; - - serial@70006000 { - status = "disable"; - }; - - serial@70006040 { - status = "disable"; - }; - - serial@70006200 { - status = "disable"; - }; - - serial@70006300 { - clock-frequency = < 216000000 >; - }; - - serial@70006400 { - status = "disable"; - }; - - sdhci@c8000000 { - status = "disable"; - }; - - sdhci@c8000200 { - cd-gpios = <&gpio 69 0>; /* gpio PI5 */ - wp-gpios = <&gpio 57 0>; /* gpio PH1 */ - power-gpios = <&gpio 155 0>; /* gpio PT3 */ - }; - - sdhci@c8000400 { - status = "disable"; - }; - - sdhci@c8000600 { - cd-gpios = <&gpio 58 0>; /* gpio PH2 */ - wp-gpios = <&gpio 59 0>; /* gpio PH3 */ - power-gpios = <&gpio 70 0>; /* gpio PI6 */ - support-8bit; - }; }; diff --git a/trunk/arch/arm/boot/dts/tegra-paz00.dts b/trunk/arch/arm/boot/dts/tegra-paz00.dts index 10943fb2561c..bfeb117d5aea 100644 --- a/trunk/arch/arm/boot/dts/tegra-paz00.dts +++ b/trunk/arch/arm/boot/dts/tegra-paz00.dts @@ -6,11 +6,11 @@ model = "Toshiba AC100 / Dynabook AZ"; compatible = "compal,paz00", "nvidia,tegra20"; - memory@0 { + memory { reg = <0x00000000 0x20000000>; }; - pinmux@70000000 { + pinmux { pinctrl-names = "default"; pinctrl-0 = <&state_default>; @@ -159,18 +159,14 @@ }; conf_ata { nvidia,pins = "ata", "atb", "atc", "atd", "ate", - "cdev1", "dap1", "dap2", "dtf", "gma", - "gmb", "gmc", "gmd", "gme", "gpu", - "gpu7", "gpv", "i2cp", "pta", "rm", - "sdio1", "slxk", "spdo", "uac", "uda"; + "cdev1", "cdev2", "dap1", "dap2", "dtf", + "gma", "gmb", "gmc", "gmd", "gme", + "gpu", "gpu7", "gpv", "i2cp", "pta", + "rm", "sdio1", "slxk", "spdo", "uac", + "uda"; nvidia,pull = <0>; nvidia,tristate = <0>; }; - conf_cdev2 { - nvidia,pins = "cdev2"; - nvidia,pull = <1>; - nvidia,tristate = <0>; - }; conf_ck32 { nvidia,pins = "ck32", "ddrc", "pmca", "pmcb", "pmcc", "pmcd", "pmce", "xm2c", "xm2d"; @@ -230,7 +226,22 @@ }; }; + i2s@70002800 { + status = "okay"; + }; + + serial@70006000 { + status = "okay"; + clock-frequency = <216000000>; + }; + + serial@70006200 { + status = "okay"; + clock-frequency = <216000000>; + }; + i2c@7000c000 { + status = "okay"; clock-frequency = <400000>; alc5632: alc5632@1e { @@ -242,25 +253,23 @@ }; i2c@7000c400 { + status = "okay"; clock-frequency = <400000>; }; - i2c@7000c500 { - status = "disable"; - }; - - nvec@7000c500 { - #address-cells = <1>; - #size-cells = <0>; + nvec { compatible = "nvidia,nvec"; - reg = <0x7000C500 0x100>; + reg = <0x7000c500 0x100>; interrupts = <0 92 0x04>; + #address-cells = <1>; + #size-cells = <0>; clock-frequency = <80000>; - request-gpios = <&gpio 170 0>; + request-gpios = <&gpio 170 0>; /* gpio PV2 */ slave-addr = <138>; }; i2c@7000d000 { + status = "okay"; clock-frequency = <400000>; adt7461@4c { @@ -269,66 +278,31 @@ }; }; - i2s@70002a00 { - status = "disable"; - }; - - sound { - compatible = "nvidia,tegra-audio-alc5632-paz00", - "nvidia,tegra-audio-alc5632"; - - nvidia,model = "Compal PAZ00"; - - nvidia,audio-routing = - "Int Spk", "SPKOUT", - "Int Spk", "SPKOUTN", - "Headset Mic", "MICBIAS1", - "MIC1", "Headset Mic", - "Headset Stereophone", "HPR", - "Headset Stereophone", "HPL", - "DMICDAT", "Digital Mic"; - - nvidia,audio-codec = <&alc5632>; - nvidia,i2s-controller = <&tegra_i2s1>; - nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */ - }; - - serial@70006000 { - clock-frequency = <216000000>; + usb@c5000000 { + status = "okay"; }; - serial@70006040 { - status = "disable"; + usb@c5004000 { + status = "okay"; + nvidia,phy-reset-gpio = <&gpio 168 0>; /* gpio PV0 */ }; - serial@70006200 { - clock-frequency = <216000000>; - }; - - serial@70006300 { - status = "disable"; - }; - - serial@70006400 { - status = "disable"; + usb@c5008000 { + status = "okay"; }; sdhci@c8000000 { + status = "okay"; cd-gpios = <&gpio 173 0>; /* gpio PV5 */ wp-gpios = <&gpio 57 0>; /* gpio PH1 */ power-gpios = <&gpio 169 0>; /* gpio PV1 */ - }; - - sdhci@c8000200 { - status = "disable"; - }; - - sdhci@c8000400 { - status = "disable"; + bus-width = <4>; }; sdhci@c8000600 { + status = "okay"; support-8bit; + bus-width = <8>; }; gpio-keys { @@ -347,8 +321,28 @@ wifi { label = "wifi-led"; - gpios = <&gpio 24 0>; + gpios = <&gpio 24 0>; /* gpio PD0 */ linux,default-trigger = "rfkill0"; }; }; + + sound { + compatible = "nvidia,tegra-audio-alc5632-paz00", + "nvidia,tegra-audio-alc5632"; + + nvidia,model = "Compal PAZ00"; + + nvidia,audio-routing = + "Int Spk", "SPKOUT", + "Int Spk", "SPKOUTN", + "Headset Mic", "MICBIAS1", + "MIC1", "Headset Mic", + "Headset Stereophone", "HPR", + "Headset Stereophone", "HPL", + "DMICDAT", "Digital Mic"; + + nvidia,audio-codec = <&alc5632>; + nvidia,i2s-controller = <&tegra_i2s1>; + nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */ + }; }; diff --git a/trunk/arch/arm/boot/dts/tegra-seaboard.dts b/trunk/arch/arm/boot/dts/tegra-seaboard.dts index ec33116f5df9..89cb7f2acd92 100644 --- a/trunk/arch/arm/boot/dts/tegra-seaboard.dts +++ b/trunk/arch/arm/boot/dts/tegra-seaboard.dts @@ -7,11 +7,10 @@ compatible = "nvidia,seaboard", "nvidia,tegra20"; memory { - device_type = "memory"; - reg = < 0x00000000 0x40000000 >; + reg = <0x00000000 0x40000000>; }; - pinmux@70000000 { + pinmux { pinctrl-names = "default"; pinctrl-0 = <&state_default>; @@ -100,7 +99,7 @@ }; hdint { nvidia,pins = "hdint", "lpw0", "lpw2", "lsc1", - "lsck", "lsda", "pta"; + "lsck", "lsda"; nvidia,function = "hdmi"; }; i2cp { @@ -134,6 +133,10 @@ nvidia,pins = "pmc"; nvidia,function = "pwr_on"; }; + pta { + nvidia,pins = "pta"; + nvidia,function = "i2c2"; + }; rm { nvidia,pins = "rm"; nvidia,function = "i2c1"; @@ -254,108 +257,148 @@ }; }; + i2s@70002800 { + status = "okay"; + }; + + serial@70006300 { + status = "okay"; + clock-frequency = <216000000>; + }; + i2c@7000c000 { + status = "okay"; clock-frequency = <400000>; wm8903: wm8903@1a { compatible = "wlf,wm8903"; reg = <0x1a>; interrupt-parent = <&gpio>; - interrupts = < 187 0x04 >; + interrupts = <187 0x04>; gpio-controller; #gpio-cells = <2>; micdet-cfg = <0>; micdet-delay = <100>; - gpio-cfg = < 0xffffffff 0xffffffff 0 0xffffffff 0xffffffff >; + gpio-cfg = <0xffffffff 0xffffffff 0 0xffffffff 0xffffffff>; + }; + + /* ALS and proximity sensor */ + isl29018@44 { + compatible = "isil,isl29018"; + reg = <0x44>; + interrupt-parent = <&gpio>; + interrupts = <202 0x04>; /* GPIO PZ2 */ + }; + + gyrometer@68 { + compatible = "invn,mpu3050"; + reg = <0x68>; + interrupt-parent = <&gpio>; + interrupts = <204 0x04>; /* gpio PZ4 */ }; }; i2c@7000c400 { - clock-frequency = <400000>; + status = "okay"; + clock-frequency = <100000>; + + smart-battery@b { + compatible = "ti,bq20z75", "smart-battery-1.1"; + reg = <0xb>; + ti,i2c-retry-count = <2>; + ti,poll-retry-count = <10>; + }; }; i2c@7000c500 { + status = "okay"; clock-frequency = <400000>; }; i2c@7000d000 { + status = "okay"; clock-frequency = <400000>; - adt7461@4c { - compatible = "adt7461"; + temperature-sensor@4c { + compatible = "nct1008"; reg = <0x4c>; }; - }; - - i2s@70002a00 { - status = "disable"; - }; - - sound { - compatible = "nvidia,tegra-audio-wm8903-seaboard", - "nvidia,tegra-audio-wm8903"; - nvidia,model = "NVIDIA Tegra Seaboard"; - - nvidia,audio-routing = - "Headphone Jack", "HPOUTR", - "Headphone Jack", "HPOUTL", - "Int Spk", "ROP", - "Int Spk", "RON", - "Int Spk", "LOP", - "Int Spk", "LON", - "Mic Jack", "MICBIAS", - "IN1R", "Mic Jack"; - - nvidia,i2s-controller = <&tegra_i2s1>; - nvidia,audio-codec = <&wm8903>; - - nvidia,spkr-en-gpios = <&wm8903 2 0>; - nvidia,hp-det-gpios = <&gpio 185 0>; /* gpio PX1 */ - }; - serial@70006000 { - status = "disable"; - }; - - serial@70006040 { - status = "disable"; + magnetometer@c { + compatible = "ak8975"; + reg = <0xc>; + interrupt-parent = <&gpio>; + interrupts = <109 0x04>; /* gpio PN5 */ + }; }; - serial@70006200 { - status = "disable"; - }; + emc { + emc-table@190000 { + reg = <190000>; + compatible = "nvidia,tegra20-emc-table"; + clock-frequency = <190000>; + nvidia,emc-registers = <0x0000000c 0x00000026 + 0x00000009 0x00000003 0x00000004 0x00000004 + 0x00000002 0x0000000c 0x00000003 0x00000003 + 0x00000002 0x00000001 0x00000004 0x00000005 + 0x00000004 0x00000009 0x0000000d 0x0000059f + 0x00000000 0x00000003 0x00000003 0x00000003 + 0x00000003 0x00000001 0x0000000b 0x000000c8 + 0x00000003 0x00000007 0x00000004 0x0000000f + 0x00000002 0x00000000 0x00000000 0x00000002 + 0x00000000 0x00000000 0x00000083 0xa06204ae + 0x007dc010 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000>; + }; - serial@70006300 { - clock-frequency = < 216000000 >; + emc-table@380000 { + reg = <380000>; + compatible = "nvidia,tegra20-emc-table"; + clock-frequency = <380000>; + nvidia,emc-registers = <0x00000017 0x0000004b + 0x00000012 0x00000006 0x00000004 0x00000005 + 0x00000003 0x0000000c 0x00000006 0x00000006 + 0x00000003 0x00000001 0x00000004 0x00000005 + 0x00000004 0x00000009 0x0000000d 0x00000b5f + 0x00000000 0x00000003 0x00000003 0x00000006 + 0x00000006 0x00000001 0x00000011 0x000000c8 + 0x00000003 0x0000000e 0x00000007 0x0000000f + 0x00000002 0x00000000 0x00000000 0x00000002 + 0x00000000 0x00000000 0x00000083 0xe044048b + 0x007d8010 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000>; + }; }; - serial@70006400 { - status = "disable"; + usb@c5000000 { + status = "okay"; + nvidia,vbus-gpio = <&gpio 24 0>; /* PD0 */ + dr_mode = "otg"; }; - sdhci@c8000000 { - status = "disable"; + usb@c5004000 { + status = "okay"; + nvidia,phy-reset-gpio = <&gpio 169 0>; /* gpio PV1 */ }; - sdhci@c8000200 { - status = "disable"; + usb@c5008000 { + status = "okay"; }; sdhci@c8000400 { + status = "okay"; cd-gpios = <&gpio 69 0>; /* gpio PI5 */ wp-gpios = <&gpio 57 0>; /* gpio PH1 */ power-gpios = <&gpio 70 0>; /* gpio PI6 */ + bus-width = <4>; }; sdhci@c8000600 { + status = "okay"; support-8bit; - }; - - usb@c5000000 { - nvidia,vbus-gpio = <&gpio 24 0>; /* PD0 */ - dr_mode = "otg"; + bus-width = <8>; }; gpio-keys { @@ -378,41 +421,25 @@ }; }; - emc@7000f400 { - emc-table@190000 { - reg = < 190000 >; - compatible = "nvidia,tegra20-emc-table"; - clock-frequency = < 190000 >; - nvidia,emc-registers = < 0x0000000c 0x00000026 - 0x00000009 0x00000003 0x00000004 0x00000004 - 0x00000002 0x0000000c 0x00000003 0x00000003 - 0x00000002 0x00000001 0x00000004 0x00000005 - 0x00000004 0x00000009 0x0000000d 0x0000059f - 0x00000000 0x00000003 0x00000003 0x00000003 - 0x00000003 0x00000001 0x0000000b 0x000000c8 - 0x00000003 0x00000007 0x00000004 0x0000000f - 0x00000002 0x00000000 0x00000000 0x00000002 - 0x00000000 0x00000000 0x00000083 0xa06204ae - 0x007dc010 0x00000000 0x00000000 0x00000000 - 0x00000000 0x00000000 0x00000000 0x00000000 >; - }; + sound { + compatible = "nvidia,tegra-audio-wm8903-seaboard", + "nvidia,tegra-audio-wm8903"; + nvidia,model = "NVIDIA Tegra Seaboard"; - emc-table@380000 { - reg = < 380000 >; - compatible = "nvidia,tegra20-emc-table"; - clock-frequency = < 380000 >; - nvidia,emc-registers = < 0x00000017 0x0000004b - 0x00000012 0x00000006 0x00000004 0x00000005 - 0x00000003 0x0000000c 0x00000006 0x00000006 - 0x00000003 0x00000001 0x00000004 0x00000005 - 0x00000004 0x00000009 0x0000000d 0x00000b5f - 0x00000000 0x00000003 0x00000003 0x00000006 - 0x00000006 0x00000001 0x00000011 0x000000c8 - 0x00000003 0x0000000e 0x00000007 0x0000000f - 0x00000002 0x00000000 0x00000000 0x00000002 - 0x00000000 0x00000000 0x00000083 0xe044048b - 0x007d8010 0x00000000 0x00000000 0x00000000 - 0x00000000 0x00000000 0x00000000 0x00000000 >; - }; + nvidia,audio-routing = + "Headphone Jack", "HPOUTR", + "Headphone Jack", "HPOUTL", + "Int Spk", "ROP", + "Int Spk", "RON", + "Int Spk", "LOP", + "Int Spk", "LON", + "Mic Jack", "MICBIAS", + "IN1R", "Mic Jack"; + + nvidia,i2s-controller = <&tegra_i2s1>; + nvidia,audio-codec = <&wm8903>; + + nvidia,spkr-en-gpios = <&wm8903 2 0>; + nvidia,hp-det-gpios = <&gpio 185 0>; /* gpio PX1 */ }; }; diff --git a/trunk/arch/arm/boot/dts/tegra-trimslice.dts b/trunk/arch/arm/boot/dts/tegra-trimslice.dts index 98efd5b0d7f9..9de5636023f6 100644 --- a/trunk/arch/arm/boot/dts/tegra-trimslice.dts +++ b/trunk/arch/arm/boot/dts/tegra-trimslice.dts @@ -6,11 +6,11 @@ model = "Compulab TrimSlice board"; compatible = "compulab,trimslice", "nvidia,tegra20"; - memory@0 { - reg = < 0x00000000 0x40000000 >; + memory { + reg = <0x00000000 0x40000000>; }; - pinmux@70000000 { + pinmux { pinctrl-names = "default"; pinctrl-0 = <&state_default>; @@ -182,23 +182,23 @@ nvidia,tristate = <1>; }; conf_atb { - nvidia,pins = "atb", "cdev1", "dap1", "gma", - "gmc", "gmd", "gpu", "gpu7", "gpv", - "sdio1", "slxa", "slxk", "uac"; + nvidia,pins = "atb", "cdev1", "cdev2", "dap1", + "gma", "gmc", "gmd", "gpu", "gpu7", + "gpv", "sdio1", "slxa", "slxk", "uac"; nvidia,pull = <0>; nvidia,tristate = <0>; }; - conf_cdev2 { - nvidia,pins = "cdev2", "csus", "spia", "spib", - "spid", "spif"; - nvidia,pull = <1>; - nvidia,tristate = <1>; - }; conf_ck32 { nvidia,pins = "ck32", "ddrc", "pmca", "pmcb", "pmcc", "pmcd", "pmce", "xm2c", "xm2d"; nvidia,pull = <0>; }; + conf_csus { + nvidia,pins = "csus", "spia", "spib", + "spid", "spif"; + nvidia,pull = <1>; + nvidia,tristate = <1>; + }; conf_ddc { nvidia,pins = "ddc", "dtf", "rm", "sdc", "sdd"; nvidia,pull = <2>; @@ -240,68 +240,67 @@ }; }; + i2s@70002800 { + status = "okay"; + }; + + serial@70006000 { + status = "okay"; + clock-frequency = <216000000>; + }; + i2c@7000c000 { + status = "okay"; clock-frequency = <400000>; }; i2c@7000c400 { + status = "okay"; clock-frequency = <400000>; }; i2c@7000c500 { + status = "okay"; clock-frequency = <400000>; - }; - - i2c@7000d000 { - status = "disable"; - }; - - i2s@70002800 { - status = "disable"; - }; - - i2s@70002a00 { - status = "disable"; - }; - - das@70000c00 { - status = "disable"; - }; - serial@70006000 { - clock-frequency = < 216000000 >; - }; + codec: codec@1a { + compatible = "ti,tlv320aic23"; + reg = <0x1a>; + }; - serial@70006040 { - status = "disable"; + rtc@56 { + compatible = "emmicro,em3027"; + reg = <0x56>; + }; }; - serial@70006200 { - status = "disable"; + usb@c5000000 { + status = "okay"; }; - serial@70006300 { - status = "disable"; + usb@c5004000 { + nvidia,phy-reset-gpio = <&gpio 168 0>; /* gpio PV0 */ }; - serial@70006400 { - status = "disable"; + usb@c5008000 { + status = "okay"; }; sdhci@c8000000 { - status = "disable"; + status = "okay"; + bus-width = <4>; }; - sdhci@c8000200 { - status = "disable"; - }; - - sdhci@c8000400 { - status = "disable"; + sdhci@c8000600 { + status = "okay"; + cd-gpios = <&gpio 121 0>; /* gpio PP1 */ + wp-gpios = <&gpio 122 0>; /* gpio PP2 */ + bus-width = <4>; }; - sdhci@c8000600 { - cd-gpios = <&gpio 121 0>; - wp-gpios = <&gpio 122 0>; + sound { + compatible = "nvidia,tegra-audio-trimslice"; + nvidia,i2s-controller = <&tegra_i2s1>; + nvidia,audio-codec = <&codec>; }; }; diff --git a/trunk/arch/arm/boot/dts/tegra-ventana.dts b/trunk/arch/arm/boot/dts/tegra-ventana.dts index 71eb2e50a668..445343b0fbdd 100644 --- a/trunk/arch/arm/boot/dts/tegra-ventana.dts +++ b/trunk/arch/arm/boot/dts/tegra-ventana.dts @@ -7,10 +7,10 @@ compatible = "nvidia,ventana", "nvidia,tegra20"; memory { - reg = < 0x00000000 0x40000000 >; + reg = <0x00000000 0x40000000>; }; - pinmux@70000000 { + pinmux { pinctrl-names = "default"; pinctrl-0 = <&state_default>; @@ -240,38 +240,82 @@ }; }; + i2s@70002800 { + status = "okay"; + }; + + serial@70006300 { + status = "okay"; + clock-frequency = <216000000>; + }; + i2c@7000c000 { + status = "okay"; clock-frequency = <400000>; wm8903: wm8903@1a { compatible = "wlf,wm8903"; reg = <0x1a>; interrupt-parent = <&gpio>; - interrupts = < 187 0x04 >; + interrupts = <187 0x04>; gpio-controller; #gpio-cells = <2>; micdet-cfg = <0>; micdet-delay = <100>; - gpio-cfg = < 0xffffffff 0xffffffff 0 0xffffffff 0xffffffff >; + gpio-cfg = <0xffffffff 0xffffffff 0 0xffffffff 0xffffffff>; + }; + + /* ALS and proximity sensor */ + isl29018@44 { + compatible = "isil,isl29018"; + reg = <0x44>; + interrupt-parent = <&gpio>; + interrupts = <202 0x04>; /*gpio PZ2 */ }; }; i2c@7000c400 { + status = "okay"; clock-frequency = <400000>; }; i2c@7000c500 { + status = "okay"; clock-frequency = <400000>; }; i2c@7000d000 { + status = "okay"; clock-frequency = <400000>; }; - i2s@70002a00 { - status = "disable"; + usb@c5000000 { + status = "okay"; + }; + + usb@c5004000 { + status = "okay"; + nvidia,phy-reset-gpio = <&gpio 169 0>; /* gpio PV1 */ + }; + + usb@c5008000 { + status = "okay"; + }; + + sdhci@c8000400 { + status = "okay"; + cd-gpios = <&gpio 69 0>; /* gpio PI5 */ + wp-gpios = <&gpio 57 0>; /* gpio PH1 */ + power-gpios = <&gpio 70 0>; /* gpio PI6 */ + bus-width = <4>; + }; + + sdhci@c8000600 { + status = "okay"; + support-8bit; + bus-width = <8>; }; sound { @@ -294,45 +338,7 @@ nvidia,spkr-en-gpios = <&wm8903 2 0>; nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */ - nvidia,int-mic-en-gpios = <&gpio 184 0>; /*gpio PX0 */ + nvidia,int-mic-en-gpios = <&gpio 184 0>; /* gpio PX0 */ nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */ }; - - serial@70006000 { - status = "disable"; - }; - - serial@70006040 { - status = "disable"; - }; - - serial@70006200 { - status = "disable"; - }; - - serial@70006300 { - clock-frequency = < 216000000 >; - }; - - serial@70006400 { - status = "disable"; - }; - - sdhci@c8000000 { - status = "disable"; - }; - - sdhci@c8000200 { - status = "disable"; - }; - - sdhci@c8000400 { - cd-gpios = <&gpio 69 0>; /* gpio PI5 */ - wp-gpios = <&gpio 57 0>; /* gpio PH1 */ - power-gpios = <&gpio 70 0>; /* gpio PI6 */ - }; - - sdhci@c8000600 { - support-8bit; - }; }; diff --git a/trunk/arch/arm/boot/dts/tegra20.dtsi b/trunk/arch/arm/boot/dts/tegra20.dtsi index 108e894a8926..c417d67e9027 100644 --- a/trunk/arch/arm/boot/dts/tegra20.dtsi +++ b/trunk/arch/arm/boot/dts/tegra20.dtsi @@ -4,207 +4,242 @@ compatible = "nvidia,tegra20"; interrupt-parent = <&intc>; - pmc@7000f400 { - compatible = "nvidia,tegra20-pmc"; - reg = <0x7000e400 0x400>; - }; - - intc: interrupt-controller@50041000 { + intc: interrupt-controller { compatible = "arm,cortex-a9-gic"; + reg = <0x50041000 0x1000 + 0x50040100 0x0100>; interrupt-controller; #interrupt-cells = <3>; - reg = < 0x50041000 0x1000 >, - < 0x50040100 0x0100 >; }; - pmu { - compatible = "arm,cortex-a9-pmu"; - interrupts = <0 56 0x04 - 0 57 0x04>; - }; - - apbdma: dma@6000a000 { + apbdma: dma { compatible = "nvidia,tegra20-apbdma"; reg = <0x6000a000 0x1200>; - 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 >; - }; - - i2c@7000c000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "nvidia,tegra20-i2c"; - reg = <0x7000C000 0x100>; - interrupts = < 0 38 0x04 >; - }; - - i2c@7000c400 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "nvidia,tegra20-i2c"; - reg = <0x7000C400 0x100>; - interrupts = < 0 84 0x04 >; + 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>; + }; + + ahb { + compatible = "nvidia,tegra20-ahb"; + reg = <0x6000c004 0x10c>; /* AHB Arbitration + Gizmo Controller */ + }; + + gpio: gpio { + compatible = "nvidia,tegra20-gpio"; + reg = <0x6000d000 0x1000>; + interrupts = <0 32 0x04 + 0 33 0x04 + 0 34 0x04 + 0 35 0x04 + 0 55 0x04 + 0 87 0x04 + 0 89 0x04>; + #gpio-cells = <2>; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; }; - i2c@7000c500 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "nvidia,tegra20-i2c"; - reg = <0x7000C500 0x100>; - interrupts = < 0 92 0x04 >; + pinmux: pinmux { + compatible = "nvidia,tegra20-pinmux"; + reg = <0x70000014 0x10 /* Tri-state registers */ + 0x70000080 0x20 /* Mux registers */ + 0x700000a0 0x14 /* Pull-up/down registers */ + 0x70000868 0xa8>; /* Pad control registers */ }; - i2c@7000d000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "nvidia,tegra20-i2c-dvc"; - reg = <0x7000D000 0x200>; - interrupts = < 0 53 0x04 >; + das { + compatible = "nvidia,tegra20-das"; + reg = <0x70000c00 0x80>; }; tegra_i2s1: i2s@70002800 { compatible = "nvidia,tegra20-i2s"; reg = <0x70002800 0x200>; - interrupts = < 0 13 0x04 >; - nvidia,dma-request-selector = < &apbdma 2 >; + interrupts = <0 13 0x04>; + nvidia,dma-request-selector = <&apbdma 2>; + status = "disable"; }; tegra_i2s2: i2s@70002a00 { compatible = "nvidia,tegra20-i2s"; reg = <0x70002a00 0x200>; - interrupts = < 0 3 0x04 >; - nvidia,dma-request-selector = < &apbdma 1 >; - }; - - das@70000c00 { - compatible = "nvidia,tegra20-das"; - reg = <0x70000c00 0x80>; - }; - - gpio: gpio@6000d000 { - compatible = "nvidia,tegra20-gpio"; - reg = < 0x6000d000 0x1000 >; - interrupts = < 0 32 0x04 - 0 33 0x04 - 0 34 0x04 - 0 35 0x04 - 0 55 0x04 - 0 87 0x04 - 0 89 0x04 >; - #gpio-cells = <2>; - gpio-controller; - #interrupt-cells = <2>; - interrupt-controller; - }; - - pinmux: pinmux@70000000 { - compatible = "nvidia,tegra20-pinmux"; - reg = < 0x70000014 0x10 /* Tri-state registers */ - 0x70000080 0x20 /* Mux registers */ - 0x700000a0 0x14 /* Pull-up/down registers */ - 0x70000868 0xa8 >; /* Pad control registers */ + interrupts = <0 3 0x04>; + nvidia,dma-request-selector = <&apbdma 1>; + status = "disable"; }; serial@70006000 { compatible = "nvidia,tegra20-uart"; reg = <0x70006000 0x40>; reg-shift = <2>; - interrupts = < 0 36 0x04 >; + interrupts = <0 36 0x04>; + status = "disable"; }; serial@70006040 { compatible = "nvidia,tegra20-uart"; reg = <0x70006040 0x40>; reg-shift = <2>; - interrupts = < 0 37 0x04 >; + interrupts = <0 37 0x04>; + status = "disable"; }; serial@70006200 { compatible = "nvidia,tegra20-uart"; reg = <0x70006200 0x100>; reg-shift = <2>; - interrupts = < 0 46 0x04 >; + interrupts = <0 46 0x04>; + status = "disable"; }; serial@70006300 { compatible = "nvidia,tegra20-uart"; reg = <0x70006300 0x100>; reg-shift = <2>; - interrupts = < 0 90 0x04 >; + interrupts = <0 90 0x04>; + status = "disable"; }; serial@70006400 { compatible = "nvidia,tegra20-uart"; reg = <0x70006400 0x100>; reg-shift = <2>; - interrupts = < 0 91 0x04 >; + interrupts = <0 91 0x04>; + status = "disable"; }; - emc@7000f400 { + i2c@7000c000 { + compatible = "nvidia,tegra20-i2c"; + reg = <0x7000c000 0x100>; + interrupts = <0 38 0x04>; #address-cells = <1>; #size-cells = <0>; - compatible = "nvidia,tegra20-emc"; - reg = <0x7000f400 0x200>; + status = "disable"; }; - sdhci@c8000000 { - compatible = "nvidia,tegra20-sdhci"; - reg = <0xc8000000 0x200>; - interrupts = < 0 14 0x04 >; + i2c@7000c400 { + compatible = "nvidia,tegra20-i2c"; + reg = <0x7000c400 0x100>; + interrupts = <0 84 0x04>; + #address-cells = <1>; + #size-cells = <0>; + status = "disable"; }; - sdhci@c8000200 { - compatible = "nvidia,tegra20-sdhci"; - reg = <0xc8000200 0x200>; - interrupts = < 0 15 0x04 >; + i2c@7000c500 { + compatible = "nvidia,tegra20-i2c"; + reg = <0x7000c500 0x100>; + interrupts = <0 92 0x04>; + #address-cells = <1>; + #size-cells = <0>; + status = "disable"; }; - sdhci@c8000400 { - compatible = "nvidia,tegra20-sdhci"; - reg = <0xc8000400 0x200>; - interrupts = < 0 19 0x04 >; + i2c@7000d000 { + compatible = "nvidia,tegra20-i2c-dvc"; + reg = <0x7000d000 0x200>; + interrupts = <0 53 0x04>; + #address-cells = <1>; + #size-cells = <0>; + status = "disable"; }; - sdhci@c8000600 { - compatible = "nvidia,tegra20-sdhci"; - reg = <0xc8000600 0x200>; - interrupts = < 0 31 0x04 >; + pmc { + compatible = "nvidia,tegra20-pmc"; + reg = <0x7000e400 0x400>; + }; + + mc { + compatible = "nvidia,tegra20-mc"; + reg = <0x7000f000 0x024 + 0x7000f03c 0x3c4>; + interrupts = <0 77 0x04>; + }; + + gart { + compatible = "nvidia,tegra20-gart"; + reg = <0x7000f024 0x00000018 /* controller registers */ + 0x58000000 0x02000000>; /* GART aperture */ + }; + + emc { + compatible = "nvidia,tegra20-emc"; + reg = <0x7000f400 0x200>; + #address-cells = <1>; + #size-cells = <0>; }; usb@c5000000 { compatible = "nvidia,tegra20-ehci", "usb-ehci"; reg = <0xc5000000 0x4000>; - interrupts = < 0 20 0x04 >; + interrupts = <0 20 0x04>; phy_type = "utmi"; nvidia,has-legacy-mode; + status = "disable"; }; usb@c5004000 { compatible = "nvidia,tegra20-ehci", "usb-ehci"; reg = <0xc5004000 0x4000>; - interrupts = < 0 21 0x04 >; + interrupts = <0 21 0x04>; phy_type = "ulpi"; + status = "disable"; }; usb@c5008000 { compatible = "nvidia,tegra20-ehci", "usb-ehci"; reg = <0xc5008000 0x4000>; - interrupts = < 0 97 0x04 >; + interrupts = <0 97 0x04>; phy_type = "utmi"; + status = "disable"; + }; + + sdhci@c8000000 { + compatible = "nvidia,tegra20-sdhci"; + reg = <0xc8000000 0x200>; + interrupts = <0 14 0x04>; + status = "disable"; }; -}; + sdhci@c8000200 { + compatible = "nvidia,tegra20-sdhci"; + reg = <0xc8000200 0x200>; + interrupts = <0 15 0x04>; + status = "disable"; + }; + + sdhci@c8000400 { + compatible = "nvidia,tegra20-sdhci"; + reg = <0xc8000400 0x200>; + interrupts = <0 19 0x04>; + status = "disable"; + }; + + sdhci@c8000600 { + compatible = "nvidia,tegra20-sdhci"; + reg = <0xc8000600 0x200>; + interrupts = <0 31 0x04>; + status = "disable"; + }; + + pmu { + compatible = "arm,cortex-a9-pmu"; + interrupts = <0 56 0x04 + 0 57 0x04>; + }; +}; diff --git a/trunk/arch/arm/boot/dts/tegra30.dtsi b/trunk/arch/arm/boot/dts/tegra30.dtsi index 62a7b39f1c9a..2dcc09e784b5 100644 --- a/trunk/arch/arm/boot/dts/tegra30.dtsi +++ b/trunk/arch/arm/boot/dts/tegra30.dtsi @@ -4,183 +4,268 @@ compatible = "nvidia,tegra30"; interrupt-parent = <&intc>; - pmc@7000f400 { - compatible = "nvidia,tegra20-pmc", "nvidia,tegra30-pmc"; - reg = <0x7000e400 0x400>; - }; - - intc: interrupt-controller@50041000 { + intc: interrupt-controller { compatible = "arm,cortex-a9-gic"; + reg = <0x50041000 0x1000 + 0x50040100 0x0100>; interrupt-controller; #interrupt-cells = <3>; - reg = < 0x50041000 0x1000 >, - < 0x50040100 0x0100 >; }; - pmu { - compatible = "arm,cortex-a9-pmu"; - interrupts = <0 144 0x04 - 0 145 0x04 - 0 146 0x04 - 0 147 0x04>; - }; - - apbdma: dma@6000a000 { + apbdma: dma { compatible = "nvidia,tegra30-apbdma", "nvidia,tegra20-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 >; - }; - - i2c@7000c000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c"; - reg = <0x7000C000 0x100>; - interrupts = < 0 38 0x04 >; - }; - - i2c@7000c400 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c"; - reg = <0x7000C400 0x100>; - interrupts = < 0 84 0x04 >; - }; - - i2c@7000c500 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c"; - reg = <0x7000C500 0x100>; - interrupts = < 0 92 0x04 >; + 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>; }; - i2c@7000c700 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c"; - reg = <0x7000c700 0x100>; - interrupts = < 0 120 0x04 >; + ahb: ahb { + compatible = "nvidia,tegra30-ahb"; + reg = <0x6000c004 0x14c>; /* AHB Arbitration + Gizmo Controller */ }; - i2c@7000d000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c"; - reg = <0x7000D000 0x100>; - interrupts = < 0 53 0x04 >; - }; - - gpio: gpio@6000d000 { + gpio: gpio { compatible = "nvidia,tegra30-gpio", "nvidia,tegra20-gpio"; - reg = < 0x6000d000 0x1000 >; - interrupts = < 0 32 0x04 - 0 33 0x04 - 0 34 0x04 - 0 35 0x04 - 0 55 0x04 - 0 87 0x04 - 0 89 0x04 - 0 125 0x04 >; + reg = <0x6000d000 0x1000>; + interrupts = <0 32 0x04 + 0 33 0x04 + 0 34 0x04 + 0 35 0x04 + 0 55 0x04 + 0 87 0x04 + 0 89 0x04 + 0 125 0x04>; #gpio-cells = <2>; gpio-controller; #interrupt-cells = <2>; interrupt-controller; }; + pinmux: pinmux { + compatible = "nvidia,tegra30-pinmux"; + reg = <0x70000868 0xd0 /* Pad control registers */ + 0x70003000 0x3e0>; /* Mux registers */ + }; + serial@70006000 { compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart"; reg = <0x70006000 0x40>; reg-shift = <2>; - interrupts = < 0 36 0x04 >; + interrupts = <0 36 0x04>; + status = "disable"; }; serial@70006040 { compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart"; reg = <0x70006040 0x40>; reg-shift = <2>; - interrupts = < 0 37 0x04 >; + interrupts = <0 37 0x04>; + status = "disable"; }; serial@70006200 { compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart"; reg = <0x70006200 0x100>; reg-shift = <2>; - interrupts = < 0 46 0x04 >; + interrupts = <0 46 0x04>; + status = "disable"; }; serial@70006300 { compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart"; reg = <0x70006300 0x100>; reg-shift = <2>; - interrupts = < 0 90 0x04 >; + interrupts = <0 90 0x04>; + status = "disable"; }; serial@70006400 { compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart"; reg = <0x70006400 0x100>; reg-shift = <2>; - interrupts = < 0 91 0x04 >; + interrupts = <0 91 0x04>; + status = "disable"; + }; + + i2c@7000c000 { + compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c"; + reg = <0x7000c000 0x100>; + interrupts = <0 38 0x04>; + #address-cells = <1>; + #size-cells = <0>; + status = "disable"; + }; + + i2c@7000c400 { + compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c"; + reg = <0x7000c400 0x100>; + interrupts = <0 84 0x04>; + #address-cells = <1>; + #size-cells = <0>; + status = "disable"; + }; + + i2c@7000c500 { + compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c"; + reg = <0x7000c500 0x100>; + interrupts = <0 92 0x04>; + #address-cells = <1>; + #size-cells = <0>; + status = "disable"; + }; + + i2c@7000c700 { + compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c"; + reg = <0x7000c700 0x100>; + interrupts = <0 120 0x04>; + #address-cells = <1>; + #size-cells = <0>; + status = "disable"; + }; + + i2c@7000d000 { + compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c"; + reg = <0x7000d000 0x100>; + interrupts = <0 53 0x04>; + #address-cells = <1>; + #size-cells = <0>; + status = "disable"; + }; + + pmc { + compatible = "nvidia,tegra20-pmc", "nvidia,tegra30-pmc"; + reg = <0x7000e400 0x400>; + }; + + mc { + compatible = "nvidia,tegra30-mc"; + reg = <0x7000f000 0x010 + 0x7000f03c 0x1b4 + 0x7000f200 0x028 + 0x7000f284 0x17c>; + interrupts = <0 77 0x04>; + }; + + smmu { + compatible = "nvidia,tegra30-smmu"; + reg = <0x7000f010 0x02c + 0x7000f1f0 0x010 + 0x7000f228 0x05c>; + nvidia,#asids = <4>; /* # of ASIDs */ + dma-window = <0 0x40000000>; /* IOVA start & length */ + nvidia,ahb = <&ahb>; + }; + + ahub { + compatible = "nvidia,tegra30-ahub"; + reg = <0x70080000 0x200 + 0x70080200 0x100>; + interrupts = <0 103 0x04>; + nvidia,dma-request-selector = <&apbdma 1>; + + ranges; + #address-cells = <1>; + #size-cells = <1>; + + tegra_i2s0: i2s@70080300 { + compatible = "nvidia,tegra30-i2s"; + reg = <0x70080300 0x100>; + nvidia,ahub-cif-ids = <4 4>; + status = "disable"; + }; + + tegra_i2s1: i2s@70080400 { + compatible = "nvidia,tegra30-i2s"; + reg = <0x70080400 0x100>; + nvidia,ahub-cif-ids = <5 5>; + status = "disable"; + }; + + tegra_i2s2: i2s@70080500 { + compatible = "nvidia,tegra30-i2s"; + reg = <0x70080500 0x100>; + nvidia,ahub-cif-ids = <6 6>; + status = "disable"; + }; + + tegra_i2s3: i2s@70080600 { + compatible = "nvidia,tegra30-i2s"; + reg = <0x70080600 0x100>; + nvidia,ahub-cif-ids = <7 7>; + status = "disable"; + }; + + tegra_i2s4: i2s@70080700 { + compatible = "nvidia,tegra30-i2s"; + reg = <0x70080700 0x100>; + nvidia,ahub-cif-ids = <8 8>; + status = "disable"; + }; }; sdhci@78000000 { compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci"; reg = <0x78000000 0x200>; - interrupts = < 0 14 0x04 >; + interrupts = <0 14 0x04>; + status = "disable"; }; sdhci@78000200 { compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci"; reg = <0x78000200 0x200>; - interrupts = < 0 15 0x04 >; + interrupts = <0 15 0x04>; + status = "disable"; }; sdhci@78000400 { compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci"; reg = <0x78000400 0x200>; - interrupts = < 0 19 0x04 >; + interrupts = <0 19 0x04>; + status = "disable"; }; sdhci@78000600 { compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci"; reg = <0x78000600 0x200>; - interrupts = < 0 31 0x04 >; + interrupts = <0 31 0x04>; + status = "disable"; }; - pinmux: pinmux@70000000 { - compatible = "nvidia,tegra30-pinmux"; - reg = < 0x70000868 0xd0 /* Pad control registers */ - 0x70003000 0x3e0 >; /* Mux registers */ + pmu { + compatible = "arm,cortex-a9-pmu"; + interrupts = <0 144 0x04 + 0 145 0x04 + 0 146 0x04 + 0 147 0x04>; }; }; diff --git a/trunk/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts b/trunk/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts index 941b161ab78c..7e1091d91af8 100644 --- a/trunk/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts +++ b/trunk/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts @@ -73,7 +73,10 @@ #address-cells = <0>; interrupt-controller; reg = <0x2c001000 0x1000>, - <0x2c002000 0x100>; + <0x2c002000 0x1000>, + <0x2c004000 0x2000>, + <0x2c006000 0x2000>; + interrupts = <1 9 0xf04>; }; memory-controller@7ffd0000 { @@ -93,6 +96,14 @@ <0 91 4>; }; + timer { + compatible = "arm,armv7-timer"; + interrupts = <1 13 0xf08>, + <1 14 0xf08>, + <1 11 0xf08>, + <1 10 0xf08>; + }; + pmu { compatible = "arm,cortex-a15-pmu", "arm,cortex-a9-pmu"; interrupts = <0 68 4>, diff --git a/trunk/arch/arm/boot/dts/vexpress-v2p-ca5s.dts b/trunk/arch/arm/boot/dts/vexpress-v2p-ca5s.dts index 6905e66d4748..18917a0f8604 100644 --- a/trunk/arch/arm/boot/dts/vexpress-v2p-ca5s.dts +++ b/trunk/arch/arm/boot/dts/vexpress-v2p-ca5s.dts @@ -77,13 +77,18 @@ timer@2c000600 { compatible = "arm,cortex-a5-twd-timer"; - reg = <0x2c000600 0x38>; - interrupts = <1 2 0x304>, - <1 3 0x304>; + reg = <0x2c000600 0x20>; + interrupts = <1 13 0x304>; + }; + + watchdog@2c000620 { + compatible = "arm,cortex-a5-twd-wdt"; + reg = <0x2c000620 0x20>; + interrupts = <1 14 0x304>; }; gic: interrupt-controller@2c001000 { - compatible = "arm,corex-a5-gic", "arm,cortex-a9-gic"; + compatible = "arm,cortex-a5-gic", "arm,cortex-a9-gic"; #interrupt-cells = <3>; #address-cells = <0>; interrupt-controller; diff --git a/trunk/arch/arm/boot/dts/vexpress-v2p-ca9.dts b/trunk/arch/arm/boot/dts/vexpress-v2p-ca9.dts index da778693be54..3f0c736d31d6 100644 --- a/trunk/arch/arm/boot/dts/vexpress-v2p-ca9.dts +++ b/trunk/arch/arm/boot/dts/vexpress-v2p-ca9.dts @@ -105,8 +105,13 @@ timer@1e000600 { compatible = "arm,cortex-a9-twd-timer"; reg = <0x1e000600 0x20>; - interrupts = <1 2 0xf04>, - <1 3 0xf04>; + interrupts = <1 13 0xf04>; + }; + + watchdog@1e000620 { + compatible = "arm,cortex-a9-twd-wdt"; + reg = <0x1e000620 0x20>; + interrupts = <1 14 0xf04>; }; gic: interrupt-controller@1e001000 { diff --git a/trunk/arch/arm/common/dmabounce.c b/trunk/arch/arm/common/dmabounce.c index 595ecd290ebf..aa07f5938f05 100644 --- a/trunk/arch/arm/common/dmabounce.c +++ b/trunk/arch/arm/common/dmabounce.c @@ -173,7 +173,8 @@ find_safe_buffer(struct dmabounce_device_info *device_info, dma_addr_t safe_dma_ read_lock_irqsave(&device_info->lock, flags); list_for_each_entry(b, &device_info->safe_buffers, node) - if (b->safe_dma_addr == safe_dma_addr) { + if (b->safe_dma_addr <= safe_dma_addr && + b->safe_dma_addr + b->size > safe_dma_addr) { rb = b; break; } @@ -254,7 +255,7 @@ static inline dma_addr_t map_single(struct device *dev, void *ptr, size_t size, if (buf == NULL) { dev_err(dev, "%s: unable to map unsafe buffer %p!\n", __func__, ptr); - return ~0; + return DMA_ERROR_CODE; } dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n", @@ -307,8 +308,9 @@ static inline void unmap_single(struct device *dev, struct safe_buffer *buf, * substitute the safe buffer for the unsafe one. * (basically move the buffer from an unsafe area to a safe one) */ -dma_addr_t __dma_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, enum dma_data_direction dir) +static dma_addr_t dmabounce_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, enum dma_data_direction dir, + struct dma_attrs *attrs) { dma_addr_t dma_addr; int ret; @@ -320,21 +322,20 @@ dma_addr_t __dma_map_page(struct device *dev, struct page *page, ret = needs_bounce(dev, dma_addr, size); if (ret < 0) - return ~0; + return DMA_ERROR_CODE; if (ret == 0) { - __dma_page_cpu_to_dev(page, offset, size, dir); + arm_dma_ops.sync_single_for_device(dev, dma_addr, size, dir); return dma_addr; } if (PageHighMem(page)) { dev_err(dev, "DMA buffer bouncing of HIGHMEM pages is not supported\n"); - return ~0; + return DMA_ERROR_CODE; } return map_single(dev, page_address(page) + offset, size, dir); } -EXPORT_SYMBOL(__dma_map_page); /* * see if a mapped address was really a "safe" buffer and if so, copy @@ -342,8 +343,8 @@ EXPORT_SYMBOL(__dma_map_page); * the safe buffer. (basically return things back to the way they * should be) */ -void __dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size, - enum dma_data_direction dir) +static void dmabounce_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size, + enum dma_data_direction dir, struct dma_attrs *attrs) { struct safe_buffer *buf; @@ -352,31 +353,32 @@ void __dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size, buf = find_safe_buffer_dev(dev, dma_addr, __func__); if (!buf) { - __dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, dma_addr)), - dma_addr & ~PAGE_MASK, size, dir); + arm_dma_ops.sync_single_for_cpu(dev, dma_addr, size, dir); return; } unmap_single(dev, buf, size, dir); } -EXPORT_SYMBOL(__dma_unmap_page); -int dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr, - unsigned long off, size_t sz, enum dma_data_direction dir) +static int __dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr, + size_t sz, enum dma_data_direction dir) { struct safe_buffer *buf; + unsigned long off; - dev_dbg(dev, "%s(dma=%#x,off=%#lx,sz=%zx,dir=%x)\n", - __func__, addr, off, sz, dir); + dev_dbg(dev, "%s(dma=%#x,sz=%zx,dir=%x)\n", + __func__, addr, sz, dir); buf = find_safe_buffer_dev(dev, addr, __func__); if (!buf) return 1; + off = addr - buf->safe_dma_addr; + BUG_ON(buf->direction != dir); - dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n", - __func__, buf->ptr, virt_to_dma(dev, buf->ptr), + dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x off=%#lx) mapped to %p (dma=%#x)\n", + __func__, buf->ptr, virt_to_dma(dev, buf->ptr), off, buf->safe, buf->safe_dma_addr); DO_STATS(dev->archdata.dmabounce->bounce_count++); @@ -388,24 +390,35 @@ int dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr, } return 0; } -EXPORT_SYMBOL(dmabounce_sync_for_cpu); -int dmabounce_sync_for_device(struct device *dev, dma_addr_t addr, - unsigned long off, size_t sz, enum dma_data_direction dir) +static void dmabounce_sync_for_cpu(struct device *dev, + dma_addr_t handle, size_t size, enum dma_data_direction dir) +{ + if (!__dmabounce_sync_for_cpu(dev, handle, size, dir)) + return; + + arm_dma_ops.sync_single_for_cpu(dev, handle, size, dir); +} + +static int __dmabounce_sync_for_device(struct device *dev, dma_addr_t addr, + size_t sz, enum dma_data_direction dir) { struct safe_buffer *buf; + unsigned long off; - dev_dbg(dev, "%s(dma=%#x,off=%#lx,sz=%zx,dir=%x)\n", - __func__, addr, off, sz, dir); + dev_dbg(dev, "%s(dma=%#x,sz=%zx,dir=%x)\n", + __func__, addr, sz, dir); buf = find_safe_buffer_dev(dev, addr, __func__); if (!buf) return 1; + off = addr - buf->safe_dma_addr; + BUG_ON(buf->direction != dir); - dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n", - __func__, buf->ptr, virt_to_dma(dev, buf->ptr), + dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x off=%#lx) mapped to %p (dma=%#x)\n", + __func__, buf->ptr, virt_to_dma(dev, buf->ptr), off, buf->safe, buf->safe_dma_addr); DO_STATS(dev->archdata.dmabounce->bounce_count++); @@ -417,7 +430,38 @@ int dmabounce_sync_for_device(struct device *dev, dma_addr_t addr, } return 0; } -EXPORT_SYMBOL(dmabounce_sync_for_device); + +static void dmabounce_sync_for_device(struct device *dev, + dma_addr_t handle, size_t size, enum dma_data_direction dir) +{ + if (!__dmabounce_sync_for_device(dev, handle, size, dir)) + return; + + arm_dma_ops.sync_single_for_device(dev, handle, size, dir); +} + +static int dmabounce_set_mask(struct device *dev, u64 dma_mask) +{ + if (dev->archdata.dmabounce) + return 0; + + return arm_dma_ops.set_dma_mask(dev, dma_mask); +} + +static struct dma_map_ops dmabounce_ops = { + .alloc = arm_dma_alloc, + .free = arm_dma_free, + .mmap = arm_dma_mmap, + .map_page = dmabounce_map_page, + .unmap_page = dmabounce_unmap_page, + .sync_single_for_cpu = dmabounce_sync_for_cpu, + .sync_single_for_device = dmabounce_sync_for_device, + .map_sg = arm_dma_map_sg, + .unmap_sg = arm_dma_unmap_sg, + .sync_sg_for_cpu = arm_dma_sync_sg_for_cpu, + .sync_sg_for_device = arm_dma_sync_sg_for_device, + .set_dma_mask = dmabounce_set_mask, +}; static int dmabounce_init_pool(struct dmabounce_pool *pool, struct device *dev, const char *name, unsigned long size) @@ -479,6 +523,7 @@ int dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size, #endif dev->archdata.dmabounce = device_info; + set_dma_ops(dev, &dmabounce_ops); dev_info(dev, "dmabounce: registered device\n"); @@ -497,6 +542,7 @@ void dmabounce_unregister_dev(struct device *dev) struct dmabounce_device_info *device_info = dev->archdata.dmabounce; dev->archdata.dmabounce = NULL; + set_dma_ops(dev, NULL); if (!device_info) { dev_warn(dev, diff --git a/trunk/arch/arm/configs/imx_v4_v5_defconfig b/trunk/arch/arm/configs/imx_v4_v5_defconfig index 09a02963cf58..e05a2f1665a7 100644 --- a/trunk/arch/arm/configs/imx_v4_v5_defconfig +++ b/trunk/arch/arm/configs/imx_v4_v5_defconfig @@ -33,6 +33,7 @@ CONFIG_MACH_IMX27LITE=y CONFIG_MACH_PCA100=y CONFIG_MACH_MXT_TD60=y CONFIG_MACH_IMX27IPCAM=y +CONFIG_MACH_IMX27_DT=y CONFIG_MXC_IRQ_PRIOR=y CONFIG_MXC_PWM=y CONFIG_NO_HZ=y @@ -172,7 +173,7 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_PCF8563=y CONFIG_RTC_DRV_IMXDI=y -CONFIG_RTC_MXC=y +CONFIG_RTC_DRV_MXC=y CONFIG_DMADEVICES=y CONFIG_IMX_SDMA=y CONFIG_IMX_DMA=y diff --git a/trunk/arch/arm/configs/imx_v6_v7_defconfig b/trunk/arch/arm/configs/imx_v6_v7_defconfig index dc6f6411bbf5..b1d3675df72c 100644 --- a/trunk/arch/arm/configs/imx_v6_v7_defconfig +++ b/trunk/arch/arm/configs/imx_v6_v7_defconfig @@ -64,6 +64,12 @@ CONFIG_IPV6=y # CONFIG_WIRELESS is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y +CONFIG_MTD=y +CONFIG_MTD_OF_PARTS=y +CONFIG_MTD_CHAR=y +CONFIG_MTD_DATAFLASH=y +CONFIG_MTD_M25P80=y +CONFIG_MTD_SST25L=y # CONFIG_STANDALONE is not set CONFIG_CONNECTOR=y CONFIG_BLK_DEV_LOOP=y @@ -172,7 +178,7 @@ CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y CONFIG_RTC_CLASS=y CONFIG_RTC_INTF_DEV_UIE_EMUL=y -CONFIG_RTC_MXC=y +CONFIG_RTC_DRV_MXC=y CONFIG_DMADEVICES=y CONFIG_IMX_SDMA=y CONFIG_EXT2_FS=y diff --git a/trunk/arch/arm/configs/mxs_defconfig b/trunk/arch/arm/configs/mxs_defconfig index 1ebbf451c48d..5406c23a02e3 100644 --- a/trunk/arch/arm/configs/mxs_defconfig +++ b/trunk/arch/arm/configs/mxs_defconfig @@ -22,6 +22,7 @@ CONFIG_BLK_DEV_INTEGRITY=y # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set CONFIG_ARCH_MXS=y +CONFIG_MACH_MXS_DT=y CONFIG_MACH_MX23EVK=y CONFIG_MACH_MX28EVK=y CONFIG_MACH_STMP378X_DEVB=y diff --git a/trunk/arch/arm/configs/prima2_defconfig b/trunk/arch/arm/configs/prima2_defconfig new file mode 100644 index 000000000000..c328ac65479a --- /dev/null +++ b/trunk/arch/arm/configs/prima2_defconfig @@ -0,0 +1,69 @@ +CONFIG_EXPERIMENTAL=y +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_KALLSYMS_ALL=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_BLK_DEV_BSG is not set +CONFIG_PARTITION_ADVANCED=y +CONFIG_BSD_DISKLABEL=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_ARCH_PRIMA2=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_PREEMPT=y +CONFIG_AEABI=y +CONFIG_KEXEC=y +CONFIG_BINFMT_MISC=y +CONFIG_PM_RUNTIME=y +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_SG=y +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_SERIAL_SIRFSOC=y +CONFIG_SERIAL_SIRFSOC_CONSOLE=y +CONFIG_HW_RANDOM=y +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_SIRF=y +CONFIG_SPI=y +CONFIG_SPI_SIRF=y +CONFIG_SPI_SPIDEV=y +# CONFIG_HWMON is not set +# CONFIG_HID_SUPPORT is not set +CONFIG_USB_GADGET=y +CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m +CONFIG_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_DMADEVICES=y +CONFIG_DMADEVICES_DEBUG=y +CONFIG_DMADEVICES_VDEBUG=y +CONFIG_SIRF_DMA=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_EXT2_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_CRAMFS=y +CONFIG_ROMFS_FS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_SECTION_MISMATCH=y +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_PREEMPT is not set +CONFIG_DEBUG_RT_MUTEXES=y +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_MUTEXES=y +CONFIG_DEBUG_INFO=y +CONFIG_CRC_CCITT=y diff --git a/trunk/arch/arm/configs/spear13xx_defconfig b/trunk/arch/arm/configs/spear13xx_defconfig new file mode 100644 index 000000000000..1fdb82694ca2 --- /dev/null +++ b/trunk/arch/arm/configs/spear13xx_defconfig @@ -0,0 +1,95 @@ +CONFIG_EXPERIMENTAL=y +CONFIG_SYSVIPC=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_PLAT_SPEAR=y +CONFIG_ARCH_SPEAR13XX=y +CONFIG_MACH_SPEAR1310=y +CONFIG_MACH_SPEAR1340=y +# CONFIG_SWP_EMULATE is not set +CONFIG_SMP=y +# CONFIG_SMP_ON_UP is not set +# CONFIG_ARM_CPU_TOPOLOGY is not set +CONFIG_ARM_APPENDED_DTB=y +CONFIG_ARM_ATAG_DTB_COMPAT=y +CONFIG_BINFMT_MISC=y +CONFIG_NET=y +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_MTD=y +CONFIG_MTD_OF_PARTS=y +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_FSMC=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=16384 +CONFIG_ATA=y +# CONFIG_SATA_PMP is not set +CONFIG_SATA_AHCI_PLATFORM=y +CONFIG_PATA_ARASAN_CF=y +CONFIG_NETDEVICES=y +# 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_MICREL is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SMSC is not set +CONFIG_STMMAC_ETH=y +# CONFIG_WLAN is not set +CONFIG_INPUT_FF_MEMLESS=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +# CONFIG_KEYBOARD_ATKBD is not set +CONFIG_KEYBOARD_SPEAR=y +# CONFIG_INPUT_MOUSE is not set +# CONFIG_LEGACY_PTYS is not set +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +# CONFIG_HW_RANDOM is not set +CONFIG_RAW_DRIVER=y +CONFIG_MAX_RAW_DEVS=8192 +CONFIG_I2C=y +CONFIG_I2C_DESIGNWARE_PLATFORM=y +CONFIG_SPI=y +CONFIG_SPI_PL022=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_PL061=y +# CONFIG_HWMON is not set +CONFIG_WATCHDOG=y +CONFIG_MPCORE_WATCHDOG=y +# CONFIG_HID_SUPPORT is not set +CONFIG_USB=y +# CONFIG_USB_DEVICE_CLASS is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_OHCI_HCD=y +CONFIG_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_SPEAR=y +CONFIG_RTC_CLASS=y +CONFIG_DMADEVICES=y +CONFIG_DW_DMAC=y +CONFIG_DMATEST=m +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_AUTOFS4_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +CONFIG_TMPFS=y +CONFIG_JFFS2_FS=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ASCII=m +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_FS=y +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_INFO=y diff --git a/trunk/arch/arm/configs/spear3xx_defconfig b/trunk/arch/arm/configs/spear3xx_defconfig index 7ed42912d69a..865980c5f212 100644 --- a/trunk/arch/arm/configs/spear3xx_defconfig +++ b/trunk/arch/arm/configs/spear3xx_defconfig @@ -14,6 +14,9 @@ CONFIG_BINFMT_MISC=y CONFIG_NET=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y +CONFIG_MTD_OF_PARTS=y +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y CONFIG_MTD_NAND=y CONFIG_MTD_NAND_FSMC=y CONFIG_BLK_DEV_RAM=y @@ -73,6 +76,7 @@ CONFIG_MSDOS_FS=m CONFIG_VFAT_FS=m CONFIG_FAT_DEFAULT_IOCHARSET="ascii" CONFIG_TMPFS=y +CONFIG_JFFS2_FS=y CONFIG_NLS_DEFAULT="utf8" CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ASCII=m diff --git a/trunk/arch/arm/configs/spear6xx_defconfig b/trunk/arch/arm/configs/spear6xx_defconfig index cf94bc73a0e0..a2a1265f86b6 100644 --- a/trunk/arch/arm/configs/spear6xx_defconfig +++ b/trunk/arch/arm/configs/spear6xx_defconfig @@ -8,11 +8,13 @@ CONFIG_MODVERSIONS=y CONFIG_PARTITION_ADVANCED=y CONFIG_PLAT_SPEAR=y CONFIG_ARCH_SPEAR6XX=y -CONFIG_BOARD_SPEAR600_DT=y CONFIG_BINFMT_MISC=y CONFIG_NET=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y +CONFIG_MTD_OF_PARTS=y +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y CONFIG_MTD_NAND=y CONFIG_MTD_NAND_FSMC=y CONFIG_BLK_DEV_RAM=y @@ -64,6 +66,7 @@ CONFIG_MSDOS_FS=m CONFIG_VFAT_FS=m CONFIG_FAT_DEFAULT_IOCHARSET="ascii" CONFIG_TMPFS=y +CONFIG_JFFS2_FS=y CONFIG_NLS_DEFAULT="utf8" CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ASCII=m diff --git a/trunk/arch/arm/configs/tegra_defconfig b/trunk/arch/arm/configs/tegra_defconfig index 351d6708c3ae..1198dd61c7c4 100644 --- a/trunk/arch/arm/configs/tegra_defconfig +++ b/trunk/arch/arm/configs/tegra_defconfig @@ -45,6 +45,7 @@ CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y CONFIG_CPU_IDLE=y CONFIG_VFP=y +CONFIG_PM_RUNTIME=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y @@ -91,6 +92,8 @@ CONFIG_USB_NET_SMSC75XX=y CONFIG_USB_NET_SMSC95XX=y # CONFIG_WLAN is not set CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_MISC=y +CONFIG_INPUT_MPU3050=y # CONFIG_VT is not set # CONFIG_LEGACY_PTYS is not set # CONFIG_DEVKMEM is not set @@ -103,12 +106,15 @@ CONFIG_I2C=y CONFIG_I2C_TEGRA=y CONFIG_SPI=y CONFIG_SPI_TEGRA=y +CONFIG_POWER_SUPPLY=y +CONFIG_BATTERY_SBS=y CONFIG_SENSORS_LM90=y CONFIG_MFD_TPS6586X=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_VIRTUAL_CONSUMER=y CONFIG_REGULATOR_GPIO=y +CONFIG_REGULATOR_TPS62360=y CONFIG_REGULATOR_TPS6586X=y CONFIG_SOUND=y CONFIG_SND=y @@ -133,16 +139,19 @@ CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_TEGRA=y CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_EM3027=y CONFIG_RTC_DRV_TEGRA=y CONFIG_STAGING=y -CONFIG_IIO=y CONFIG_SENSORS_ISL29018=y +CONFIG_SENSORS_ISL29028=y CONFIG_SENSORS_AK8975=y CONFIG_MFD_NVEC=y CONFIG_KEYBOARD_NVEC=y CONFIG_SERIO_NVEC_PS2=y CONFIG_TEGRA_IOMMU_GART=y CONFIG_TEGRA_IOMMU_SMMU=y +CONFIG_MEMORY=y +CONFIG_IIO=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y diff --git a/trunk/arch/arm/configs/u8500_defconfig b/trunk/arch/arm/configs/u8500_defconfig index 7e84f453e8a6..2d4f661d1cf6 100644 --- a/trunk/arch/arm/configs/u8500_defconfig +++ b/trunk/arch/arm/configs/u8500_defconfig @@ -75,6 +75,7 @@ CONFIG_AB5500_CORE=y CONFIG_AB8500_CORE=y CONFIG_REGULATOR=y CONFIG_REGULATOR_AB8500=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y # CONFIG_HID_SUPPORT is not set CONFIG_USB_GADGET=y CONFIG_AB8500_USB=y diff --git a/trunk/arch/arm/include/asm/device.h b/trunk/arch/arm/include/asm/device.h index 7aa368003b05..b69c0d3285f8 100644 --- a/trunk/arch/arm/include/asm/device.h +++ b/trunk/arch/arm/include/asm/device.h @@ -7,12 +7,16 @@ #define ASMARM_DEVICE_H struct dev_archdata { + struct dma_map_ops *dma_ops; #ifdef CONFIG_DMABOUNCE struct dmabounce_device_info *dmabounce; #endif #ifdef CONFIG_IOMMU_API void *iommu; /* private IOMMU data */ #endif +#ifdef CONFIG_ARM_DMA_USE_IOMMU + struct dma_iommu_mapping *mapping; +#endif }; struct omap_device; diff --git a/trunk/arch/arm/include/asm/dma-contiguous.h b/trunk/arch/arm/include/asm/dma-contiguous.h new file mode 100644 index 000000000000..3ed37b4d93da --- /dev/null +++ b/trunk/arch/arm/include/asm/dma-contiguous.h @@ -0,0 +1,15 @@ +#ifndef ASMARM_DMA_CONTIGUOUS_H +#define ASMARM_DMA_CONTIGUOUS_H + +#ifdef __KERNEL__ +#ifdef CONFIG_CMA + +#include +#include + +void dma_contiguous_early_fixup(phys_addr_t base, unsigned long size); + +#endif +#endif + +#endif diff --git a/trunk/arch/arm/include/asm/dma-iommu.h b/trunk/arch/arm/include/asm/dma-iommu.h new file mode 100644 index 000000000000..799b09409fad --- /dev/null +++ b/trunk/arch/arm/include/asm/dma-iommu.h @@ -0,0 +1,34 @@ +#ifndef ASMARM_DMA_IOMMU_H +#define ASMARM_DMA_IOMMU_H + +#ifdef __KERNEL__ + +#include +#include +#include +#include + +struct dma_iommu_mapping { + /* iommu specific data */ + struct iommu_domain *domain; + + void *bitmap; + size_t bits; + unsigned int order; + dma_addr_t base; + + spinlock_t lock; + struct kref kref; +}; + +struct dma_iommu_mapping * +arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, size_t size, + int order); + +void arm_iommu_release_mapping(struct dma_iommu_mapping *mapping); + +int arm_iommu_attach_device(struct device *dev, + struct dma_iommu_mapping *mapping); + +#endif /* __KERNEL__ */ +#endif diff --git a/trunk/arch/arm/include/asm/dma-mapping.h b/trunk/arch/arm/include/asm/dma-mapping.h index cb3b7c981c4b..bbef15d04890 100644 --- a/trunk/arch/arm/include/asm/dma-mapping.h +++ b/trunk/arch/arm/include/asm/dma-mapping.h @@ -5,11 +5,35 @@ #include #include +#include #include #include #include +#define DMA_ERROR_CODE (~0) +extern struct dma_map_ops arm_dma_ops; + +static inline struct dma_map_ops *get_dma_ops(struct device *dev) +{ + if (dev && dev->archdata.dma_ops) + return dev->archdata.dma_ops; + return &arm_dma_ops; +} + +static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops) +{ + BUG_ON(!dev); + dev->archdata.dma_ops = ops; +} + +#include + +static inline int dma_set_mask(struct device *dev, u64 mask) +{ + return get_dma_ops(dev)->set_dma_mask(dev, mask); +} + #ifdef __arch_page_to_dma #error Please update to __arch_pfn_to_dma #endif @@ -61,69 +85,12 @@ static inline dma_addr_t virt_to_dma(struct device *dev, void *addr) } #endif -/* - * The DMA API is built upon the notion of "buffer ownership". A buffer - * is either exclusively owned by the CPU (and therefore may be accessed - * by it) or exclusively owned by the DMA device. These helper functions - * represent the transitions between these two ownership states. - * - * Note, however, that on later ARMs, this notion does not work due to - * speculative prefetches. We model our approach on the assumption that - * the CPU does do speculative prefetches, which means we clean caches - * before transfers and delay cache invalidation until transfer completion. - * - * Private support functions: these are not part of the API and are - * liable to change. Drivers must not use these. - */ -static inline void __dma_single_cpu_to_dev(const void *kaddr, size_t size, - enum dma_data_direction dir) -{ - extern void ___dma_single_cpu_to_dev(const void *, size_t, - enum dma_data_direction); - - if (!arch_is_coherent()) - ___dma_single_cpu_to_dev(kaddr, size, dir); -} - -static inline void __dma_single_dev_to_cpu(const void *kaddr, size_t size, - enum dma_data_direction dir) -{ - extern void ___dma_single_dev_to_cpu(const void *, size_t, - enum dma_data_direction); - - if (!arch_is_coherent()) - ___dma_single_dev_to_cpu(kaddr, size, dir); -} - -static inline void __dma_page_cpu_to_dev(struct page *page, unsigned long off, - size_t size, enum dma_data_direction dir) -{ - extern void ___dma_page_cpu_to_dev(struct page *, unsigned long, - size_t, enum dma_data_direction); - - if (!arch_is_coherent()) - ___dma_page_cpu_to_dev(page, off, size, dir); -} - -static inline void __dma_page_dev_to_cpu(struct page *page, unsigned long off, - size_t size, enum dma_data_direction dir) -{ - extern void ___dma_page_dev_to_cpu(struct page *, unsigned long, - size_t, enum dma_data_direction); - - if (!arch_is_coherent()) - ___dma_page_dev_to_cpu(page, off, size, dir); -} - -extern int dma_supported(struct device *, u64); -extern int dma_set_mask(struct device *, u64); - /* * DMA errors are defined by all-bits-set in the DMA address. */ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { - return dma_addr == ~0; + return dma_addr == DMA_ERROR_CODE; } /* @@ -141,69 +108,118 @@ static inline void dma_free_noncoherent(struct device *dev, size_t size, { } +extern int dma_supported(struct device *dev, u64 mask); + /** - * dma_alloc_coherent - allocate consistent memory for DMA + * arm_dma_alloc - allocate consistent memory for DMA * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices * @size: required memory size * @handle: bus-specific DMA address + * @attrs: optinal attributes that specific mapping properties * - * Allocate some uncached, unbuffered memory for a device for - * performing DMA. This function allocates pages, and will - * return the CPU-viewed address, and sets @handle to be the - * device-viewed address. + * Allocate some memory for a device for performing DMA. This function + * allocates pages, and will return the CPU-viewed address, and sets @handle + * to be the device-viewed address. */ -extern void *dma_alloc_coherent(struct device *, size_t, dma_addr_t *, gfp_t); +extern void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, + gfp_t gfp, struct dma_attrs *attrs); + +#define dma_alloc_coherent(d, s, h, f) dma_alloc_attrs(d, s, h, f, NULL) + +static inline void *dma_alloc_attrs(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag, + struct dma_attrs *attrs) +{ + struct dma_map_ops *ops = get_dma_ops(dev); + void *cpu_addr; + BUG_ON(!ops); + + cpu_addr = ops->alloc(dev, size, dma_handle, flag, attrs); + debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr); + return cpu_addr; +} /** - * dma_free_coherent - free memory allocated by dma_alloc_coherent + * arm_dma_free - free memory allocated by arm_dma_alloc * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices * @size: size of memory originally requested in dma_alloc_coherent * @cpu_addr: CPU-view address returned from dma_alloc_coherent * @handle: device-view address returned from dma_alloc_coherent + * @attrs: optinal attributes that specific mapping properties * * Free (and unmap) a DMA buffer previously allocated by - * dma_alloc_coherent(). + * arm_dma_alloc(). * * References to memory and mappings associated with cpu_addr/handle * during and after this call executing are illegal. */ -extern void dma_free_coherent(struct device *, size_t, void *, dma_addr_t); +extern void arm_dma_free(struct device *dev, size_t size, void *cpu_addr, + dma_addr_t handle, struct dma_attrs *attrs); + +#define dma_free_coherent(d, s, c, h) dma_free_attrs(d, s, c, h, NULL) + +static inline void dma_free_attrs(struct device *dev, size_t size, + void *cpu_addr, dma_addr_t dma_handle, + struct dma_attrs *attrs) +{ + struct dma_map_ops *ops = get_dma_ops(dev); + BUG_ON(!ops); + + debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); + ops->free(dev, size, cpu_addr, dma_handle, attrs); +} /** - * dma_mmap_coherent - map a coherent DMA allocation into user space + * arm_dma_mmap - map a coherent DMA allocation into user space * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices * @vma: vm_area_struct describing requested user mapping * @cpu_addr: kernel CPU-view address returned from dma_alloc_coherent * @handle: device-view address returned from dma_alloc_coherent * @size: size of memory originally requested in dma_alloc_coherent + * @attrs: optinal attributes that specific mapping properties * * Map a coherent DMA buffer previously allocated by dma_alloc_coherent * into user space. The coherent DMA buffer must not be freed by the * driver until the user space mapping has been released. */ -int dma_mmap_coherent(struct device *, struct vm_area_struct *, - void *, dma_addr_t, size_t); +extern int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma, + void *cpu_addr, dma_addr_t dma_addr, size_t size, + struct dma_attrs *attrs); +#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, NULL) -/** - * dma_alloc_writecombine - allocate writecombining memory for DMA - * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices - * @size: required memory size - * @handle: bus-specific DMA address - * - * Allocate some uncached, buffered memory for a device for - * performing DMA. This function allocates pages, and will - * return the CPU-viewed address, and sets @handle to be the - * device-viewed address. - */ -extern void *dma_alloc_writecombine(struct device *, size_t, dma_addr_t *, - gfp_t); +static inline int dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, + void *cpu_addr, dma_addr_t dma_addr, + size_t size, struct dma_attrs *attrs) +{ + struct dma_map_ops *ops = get_dma_ops(dev); + BUG_ON(!ops); + return ops->mmap(dev, vma, cpu_addr, dma_addr, size, attrs); +} + +static inline void *dma_alloc_writecombine(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag) +{ + DEFINE_DMA_ATTRS(attrs); + dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs); + return dma_alloc_attrs(dev, size, dma_handle, flag, &attrs); +} -#define dma_free_writecombine(dev,size,cpu_addr,handle) \ - dma_free_coherent(dev,size,cpu_addr,handle) +static inline void dma_free_writecombine(struct device *dev, size_t size, + void *cpu_addr, dma_addr_t dma_handle) +{ + DEFINE_DMA_ATTRS(attrs); + dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs); + return dma_free_attrs(dev, size, cpu_addr, dma_handle, &attrs); +} -int dma_mmap_writecombine(struct device *, struct vm_area_struct *, - void *, dma_addr_t, size_t); +static inline int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma, + void *cpu_addr, dma_addr_t dma_addr, size_t size) +{ + DEFINE_DMA_ATTRS(attrs); + dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs); + return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size, &attrs); +} /* * This can be called during boot to increase the size of the consistent @@ -212,8 +228,6 @@ int dma_mmap_writecombine(struct device *, struct vm_area_struct *, */ extern void __init init_consistent_dma_size(unsigned long size); - -#ifdef CONFIG_DMABOUNCE /* * For SA-1111, IXP425, and ADI systems the dma-mapping functions are "magic" * and utilize bounce buffers as needed to work around limited DMA windows. @@ -253,222 +267,19 @@ extern int dmabounce_register_dev(struct device *, unsigned long, */ extern void dmabounce_unregister_dev(struct device *); -/* - * The DMA API, implemented by dmabounce.c. See below for descriptions. - */ -extern dma_addr_t __dma_map_page(struct device *, struct page *, - unsigned long, size_t, enum dma_data_direction); -extern void __dma_unmap_page(struct device *, dma_addr_t, size_t, - enum dma_data_direction); - -/* - * Private functions - */ -int dmabounce_sync_for_cpu(struct device *, dma_addr_t, unsigned long, - size_t, enum dma_data_direction); -int dmabounce_sync_for_device(struct device *, dma_addr_t, unsigned long, - size_t, enum dma_data_direction); -#else -static inline int dmabounce_sync_for_cpu(struct device *d, dma_addr_t addr, - unsigned long offset, size_t size, enum dma_data_direction dir) -{ - return 1; -} -static inline int dmabounce_sync_for_device(struct device *d, dma_addr_t addr, - unsigned long offset, size_t size, enum dma_data_direction dir) -{ - return 1; -} - - -static inline dma_addr_t __dma_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, enum dma_data_direction dir) -{ - __dma_page_cpu_to_dev(page, offset, size, dir); - return pfn_to_dma(dev, page_to_pfn(page)) + offset; -} - -static inline void __dma_unmap_page(struct device *dev, dma_addr_t handle, - size_t size, enum dma_data_direction dir) -{ - __dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, handle)), - handle & ~PAGE_MASK, size, dir); -} -#endif /* CONFIG_DMABOUNCE */ - -/** - * dma_map_single - map a single buffer for streaming DMA - * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices - * @cpu_addr: CPU direct mapped address of buffer - * @size: size of buffer to map - * @dir: DMA transfer direction - * - * Ensure that any data held in the cache is appropriately discarded - * or written back. - * - * The device owns this memory once this call has completed. The CPU - * can regain ownership by calling dma_unmap_single() or - * dma_sync_single_for_cpu(). - */ -static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, - size_t size, enum dma_data_direction dir) -{ - unsigned long offset; - struct page *page; - dma_addr_t addr; - - BUG_ON(!virt_addr_valid(cpu_addr)); - BUG_ON(!virt_addr_valid(cpu_addr + size - 1)); - BUG_ON(!valid_dma_direction(dir)); - - page = virt_to_page(cpu_addr); - offset = (unsigned long)cpu_addr & ~PAGE_MASK; - addr = __dma_map_page(dev, page, offset, size, dir); - debug_dma_map_page(dev, page, offset, size, dir, addr, true); - - return addr; -} - -/** - * dma_map_page - map a portion of a page for streaming DMA - * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices - * @page: page that buffer resides in - * @offset: offset into page for start of buffer - * @size: size of buffer to map - * @dir: DMA transfer direction - * - * Ensure that any data held in the cache is appropriately discarded - * or written back. - * - * The device owns this memory once this call has completed. The CPU - * can regain ownership by calling dma_unmap_page(). - */ -static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, enum dma_data_direction dir) -{ - dma_addr_t addr; - - BUG_ON(!valid_dma_direction(dir)); - - addr = __dma_map_page(dev, page, offset, size, dir); - debug_dma_map_page(dev, page, offset, size, dir, addr, false); - - return addr; -} - -/** - * dma_unmap_single - unmap a single buffer previously mapped - * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices - * @handle: DMA address of buffer - * @size: size of buffer (same as passed to dma_map_single) - * @dir: DMA transfer direction (same as passed to dma_map_single) - * - * Unmap a single streaming mode DMA translation. The handle and size - * must match what was provided in the previous dma_map_single() call. - * All other usages are undefined. - * - * After this call, reads by the CPU to the buffer are guaranteed to see - * whatever the device wrote there. - */ -static inline void dma_unmap_single(struct device *dev, dma_addr_t handle, - size_t size, enum dma_data_direction dir) -{ - debug_dma_unmap_page(dev, handle, size, dir, true); - __dma_unmap_page(dev, handle, size, dir); -} - -/** - * dma_unmap_page - unmap a buffer previously mapped through dma_map_page() - * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices - * @handle: DMA address of buffer - * @size: size of buffer (same as passed to dma_map_page) - * @dir: DMA transfer direction (same as passed to dma_map_page) - * - * Unmap a page streaming mode DMA translation. The handle and size - * must match what was provided in the previous dma_map_page() call. - * All other usages are undefined. - * - * After this call, reads by the CPU to the buffer are guaranteed to see - * whatever the device wrote there. - */ -static inline void dma_unmap_page(struct device *dev, dma_addr_t handle, - size_t size, enum dma_data_direction dir) -{ - debug_dma_unmap_page(dev, handle, size, dir, false); - __dma_unmap_page(dev, handle, size, dir); -} - -/** - * dma_sync_single_range_for_cpu - * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices - * @handle: DMA address of buffer - * @offset: offset of region to start sync - * @size: size of region to sync - * @dir: DMA transfer direction (same as passed to dma_map_single) - * - * Make physical memory consistent for a single streaming mode DMA - * translation after a transfer. - * - * If you perform a dma_map_single() but wish to interrogate the - * buffer using the cpu, yet do not wish to teardown the PCI dma - * mapping, you must call this function before doing so. At the - * next point you give the PCI dma address back to the card, you - * must first the perform a dma_sync_for_device, and then the - * device again owns the buffer. - */ -static inline void dma_sync_single_range_for_cpu(struct device *dev, - dma_addr_t handle, unsigned long offset, size_t size, - enum dma_data_direction dir) -{ - BUG_ON(!valid_dma_direction(dir)); - - debug_dma_sync_single_for_cpu(dev, handle + offset, size, dir); - - if (!dmabounce_sync_for_cpu(dev, handle, offset, size, dir)) - return; - - __dma_single_dev_to_cpu(dma_to_virt(dev, handle) + offset, size, dir); -} - -static inline void dma_sync_single_range_for_device(struct device *dev, - dma_addr_t handle, unsigned long offset, size_t size, - enum dma_data_direction dir) -{ - BUG_ON(!valid_dma_direction(dir)); - - debug_dma_sync_single_for_device(dev, handle + offset, size, dir); - - if (!dmabounce_sync_for_device(dev, handle, offset, size, dir)) - return; - - __dma_single_cpu_to_dev(dma_to_virt(dev, handle) + offset, size, dir); -} - -static inline void dma_sync_single_for_cpu(struct device *dev, - dma_addr_t handle, size_t size, enum dma_data_direction dir) -{ - dma_sync_single_range_for_cpu(dev, handle, 0, size, dir); -} - -static inline void dma_sync_single_for_device(struct device *dev, - dma_addr_t handle, size_t size, enum dma_data_direction dir) -{ - dma_sync_single_range_for_device(dev, handle, 0, size, dir); -} /* * The scatter list versions of the above methods. */ -extern int dma_map_sg(struct device *, struct scatterlist *, int, - enum dma_data_direction); -extern void dma_unmap_sg(struct device *, struct scatterlist *, int, +extern int arm_dma_map_sg(struct device *, struct scatterlist *, int, + enum dma_data_direction, struct dma_attrs *attrs); +extern void arm_dma_unmap_sg(struct device *, struct scatterlist *, int, + enum dma_data_direction, struct dma_attrs *attrs); +extern void arm_dma_sync_sg_for_cpu(struct device *, struct scatterlist *, int, enum dma_data_direction); -extern void dma_sync_sg_for_cpu(struct device *, struct scatterlist *, int, +extern void arm_dma_sync_sg_for_device(struct device *, struct scatterlist *, int, enum dma_data_direction); -extern void dma_sync_sg_for_device(struct device *, struct scatterlist *, int, - enum dma_data_direction); - #endif /* __KERNEL__ */ #endif diff --git a/trunk/arch/arm/include/asm/futex.h b/trunk/arch/arm/include/asm/futex.h index 7be54690aeec..e42cf597f6e6 100644 --- a/trunk/arch/arm/include/asm/futex.h +++ b/trunk/arch/arm/include/asm/futex.h @@ -19,6 +19,7 @@ " .long 1b, 4f, 2b, 4f\n" \ " .popsection\n" \ " .pushsection .fixup,\"ax\"\n" \ + " .align 2\n" \ "4: mov %0, " err_reg "\n" \ " b 3b\n" \ " .popsection" diff --git a/trunk/arch/arm/include/asm/hardware/pl080.h b/trunk/arch/arm/include/asm/hardware/pl080.h index 33c78d7af2e1..4eea2107214b 100644 --- a/trunk/arch/arm/include/asm/hardware/pl080.h +++ b/trunk/arch/arm/include/asm/hardware/pl080.h @@ -102,6 +102,8 @@ #define PL080_WIDTH_16BIT (0x1) #define PL080_WIDTH_32BIT (0x2) +#define PL080N_CONFIG_ITPROT (1 << 20) +#define PL080N_CONFIG_SECPROT (1 << 19) #define PL080_CONFIG_HALT (1 << 18) #define PL080_CONFIG_ACTIVE (1 << 17) /* RO */ #define PL080_CONFIG_LOCK (1 << 16) diff --git a/trunk/arch/arm/include/asm/hardware/sp810.h b/trunk/arch/arm/include/asm/hardware/sp810.h index e0d1c0cfa548..6b9b077d86b3 100644 --- a/trunk/arch/arm/include/asm/hardware/sp810.h +++ b/trunk/arch/arm/include/asm/hardware/sp810.h @@ -4,7 +4,7 @@ * ARM PrimeXsys System Controller SP810 header file * * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar + * Viresh Kumar * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/trunk/arch/arm/include/asm/io.h b/trunk/arch/arm/include/asm/io.h index 9af5563dd3eb..815c669fec0a 100644 --- a/trunk/arch/arm/include/asm/io.h +++ b/trunk/arch/arm/include/asm/io.h @@ -47,9 +47,9 @@ extern void __raw_readsb(const void __iomem *addr, void *data, int bytelen); extern void __raw_readsw(const void __iomem *addr, void *data, int wordlen); extern void __raw_readsl(const void __iomem *addr, void *data, int longlen); -#define __raw_writeb(v,a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a) = (v)) -#define __raw_writew(v,a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v)) -#define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a) = (v)) +#define __raw_writeb(v,a) ((void)(__chk_io_ptr(a), *(volatile unsigned char __force *)(a) = (v))) +#define __raw_writew(v,a) ((void)(__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v))) +#define __raw_writel(v,a) ((void)(__chk_io_ptr(a), *(volatile unsigned int __force *)(a) = (v))) #define __raw_readb(a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a)) #define __raw_readw(a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a)) @@ -229,11 +229,9 @@ extern void _memset_io(volatile void __iomem *, int, size_t); #define readl_relaxed(c) ({ u32 __r = le32_to_cpu((__force __le32) \ __raw_readl(c)); __r; }) -#define writeb_relaxed(v,c) ((void)__raw_writeb(v,c)) -#define writew_relaxed(v,c) ((void)__raw_writew((__force u16) \ - cpu_to_le16(v),c)) -#define writel_relaxed(v,c) ((void)__raw_writel((__force u32) \ - cpu_to_le32(v),c)) +#define writeb_relaxed(v,c) __raw_writeb(v,c) +#define writew_relaxed(v,c) __raw_writew((__force u16) cpu_to_le16(v),c) +#define writel_relaxed(v,c) __raw_writel((__force u32) cpu_to_le32(v),c) #define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(); __v; }) #define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(); __v; }) @@ -281,12 +279,12 @@ extern void _memset_io(volatile void __iomem *, int, size_t); #define ioread16be(p) ({ unsigned int __v = be16_to_cpu((__force __be16)__raw_readw(p)); __iormb(); __v; }) #define ioread32be(p) ({ unsigned int __v = be32_to_cpu((__force __be32)__raw_readl(p)); __iormb(); __v; }) -#define iowrite8(v,p) ({ __iowmb(); (void)__raw_writeb(v, p); }) -#define iowrite16(v,p) ({ __iowmb(); (void)__raw_writew((__force __u16)cpu_to_le16(v), p); }) -#define iowrite32(v,p) ({ __iowmb(); (void)__raw_writel((__force __u32)cpu_to_le32(v), p); }) +#define iowrite8(v,p) ({ __iowmb(); __raw_writeb(v, p); }) +#define iowrite16(v,p) ({ __iowmb(); __raw_writew((__force __u16)cpu_to_le16(v), p); }) +#define iowrite32(v,p) ({ __iowmb(); __raw_writel((__force __u32)cpu_to_le32(v), p); }) -#define iowrite16be(v,p) ({ __iowmb(); (void)__raw_writew((__force __u16)cpu_to_be16(v), p); }) -#define iowrite32be(v,p) ({ __iowmb(); (void)__raw_writel((__force __u32)cpu_to_be32(v), p); }) +#define iowrite16be(v,p) ({ __iowmb(); __raw_writew((__force __u16)cpu_to_be16(v), p); }) +#define iowrite32be(v,p) ({ __iowmb(); __raw_writel((__force __u32)cpu_to_be32(v), p); }) #define ioread8_rep(p,d,c) __raw_readsb(p,d,c) #define ioread16_rep(p,d,c) __raw_readsw(p,d,c) diff --git a/trunk/arch/arm/include/asm/mach/arch.h b/trunk/arch/arm/include/asm/mach/arch.h index d7692cafde7f..0b1c94b8c652 100644 --- a/trunk/arch/arm/include/asm/mach/arch.h +++ b/trunk/arch/arm/include/asm/mach/arch.h @@ -43,6 +43,7 @@ struct machine_desc { void (*init_irq)(void); struct sys_timer *timer; /* system tick timer */ void (*init_machine)(void); + void (*init_late)(void); #ifdef CONFIG_MULTI_IRQ_HANDLER void (*handle_irq)(struct pt_regs *); #endif diff --git a/trunk/arch/arm/include/asm/mach/map.h b/trunk/arch/arm/include/asm/mach/map.h index b36f3654bf54..a6efcdd6fd25 100644 --- a/trunk/arch/arm/include/asm/mach/map.h +++ b/trunk/arch/arm/include/asm/mach/map.h @@ -30,6 +30,7 @@ struct map_desc { #define MT_MEMORY_DTCM 12 #define MT_MEMORY_ITCM 13 #define MT_MEMORY_SO 14 +#define MT_MEMORY_DMA_READY 15 #ifdef CONFIG_MMU extern void iotable_init(struct map_desc *, int); diff --git a/trunk/arch/arm/include/asm/posix_types.h b/trunk/arch/arm/include/asm/posix_types.h index efdf99045d87..d2de9cbbcd9b 100644 --- a/trunk/arch/arm/include/asm/posix_types.h +++ b/trunk/arch/arm/include/asm/posix_types.h @@ -22,9 +22,6 @@ typedef unsigned short __kernel_mode_t; #define __kernel_mode_t __kernel_mode_t -typedef unsigned short __kernel_nlink_t; -#define __kernel_nlink_t __kernel_nlink_t - typedef unsigned short __kernel_ipc_pid_t; #define __kernel_ipc_pid_t __kernel_ipc_pid_t diff --git a/trunk/arch/arm/include/asm/thread_info.h b/trunk/arch/arm/include/asm/thread_info.h index 68388eb4946b..b79f8e97f775 100644 --- a/trunk/arch/arm/include/asm/thread_info.h +++ b/trunk/arch/arm/include/asm/thread_info.h @@ -148,6 +148,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, #define TIF_NOTIFY_RESUME 2 /* callback before returning to user */ #define TIF_SYSCALL_TRACE 8 #define TIF_SYSCALL_AUDIT 9 +#define TIF_SYSCALL_RESTARTSYS 10 #define TIF_POLLING_NRFLAG 16 #define TIF_USING_IWMMXT 17 #define TIF_MEMDIE 18 /* is terminating due to OOM killer */ @@ -162,16 +163,17 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT) -#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) #define _TIF_SECCOMP (1 << TIF_SECCOMP) +#define _TIF_SYSCALL_RESTARTSYS (1 << TIF_SYSCALL_RESTARTSYS) /* Checks for any syscall work in entry-common.S */ -#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT) +#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \ + _TIF_SYSCALL_RESTARTSYS) /* * Change these and you break ASM code in entry-common.S */ -#define _TIF_WORK_MASK 0x000000ff +#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | _TIF_NOTIFY_RESUME) #endif /* __KERNEL__ */ #endif /* __ASM_ARM_THREAD_INFO_H */ diff --git a/trunk/arch/arm/kernel/entry-armv.S b/trunk/arch/arm/kernel/entry-armv.S index 437f0c426517..0d1851ca6eb9 100644 --- a/trunk/arch/arm/kernel/entry-armv.S +++ b/trunk/arch/arm/kernel/entry-armv.S @@ -495,6 +495,7 @@ ENDPROC(__und_usr) * The out of line fixup for the ldrt above. */ .pushsection .fixup, "ax" + .align 2 4: mov pc, r9 .popsection .pushsection __ex_table,"a" diff --git a/trunk/arch/arm/kernel/entry-common.S b/trunk/arch/arm/kernel/entry-common.S index 7bd2d3cb8957..4afed88d250a 100644 --- a/trunk/arch/arm/kernel/entry-common.S +++ b/trunk/arch/arm/kernel/entry-common.S @@ -53,9 +53,13 @@ fast_work_pending: work_pending: tst r1, #_TIF_NEED_RESCHED bne work_resched - tst r1, #_TIF_SIGPENDING|_TIF_NOTIFY_RESUME - beq no_work_pending + /* + * TIF_SIGPENDING or TIF_NOTIFY_RESUME must've been set if we got here + */ + ldr r2, [sp, #S_PSR] mov r0, sp @ 'regs' + tst r2, #15 @ are we returning to user mode? + bne no_work_pending @ no? just leave, then... mov r2, why @ 'syscall' tst r1, #_TIF_SIGPENDING @ delivering a signal? movne why, #0 @ prevent further restarts diff --git a/trunk/arch/arm/kernel/kprobes-thumb.c b/trunk/arch/arm/kernel/kprobes-thumb.c index 8f96ec778e8d..6123daf397a7 100644 --- a/trunk/arch/arm/kernel/kprobes-thumb.c +++ b/trunk/arch/arm/kernel/kprobes-thumb.c @@ -660,7 +660,7 @@ static const union decode_item t32_table_1111_100x[] = { /* LDRSB (literal) 1111 1001 x001 1111 xxxx xxxx xxxx xxxx */ /* LDRH (literal) 1111 1000 x011 1111 xxxx xxxx xxxx xxxx */ /* LDRSH (literal) 1111 1001 x011 1111 xxxx xxxx xxxx xxxx */ - DECODE_EMULATEX (0xfe5f0000, 0xf81f0000, t32_simulate_ldr_literal, + DECODE_SIMULATEX(0xfe5f0000, 0xf81f0000, t32_simulate_ldr_literal, REGS(PC, NOSPPCX, 0, 0, 0)), /* STRB (immediate) 1111 1000 0000 xxxx xxxx 1xxx xxxx xxxx */ diff --git a/trunk/arch/arm/kernel/ptrace.c b/trunk/arch/arm/kernel/ptrace.c index 14e38261cd31..5700a7ae7f0b 100644 --- a/trunk/arch/arm/kernel/ptrace.c +++ b/trunk/arch/arm/kernel/ptrace.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -917,6 +918,8 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno) audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, regs->ARM_r1, regs->ARM_r2, regs->ARM_r3); + if (why == 0 && test_and_clear_thread_flag(TIF_SYSCALL_RESTARTSYS)) + scno = __NR_restart_syscall - __NR_SYSCALL_BASE; if (!test_thread_flag(TIF_SYSCALL_TRACE)) return scno; diff --git a/trunk/arch/arm/kernel/setup.c b/trunk/arch/arm/kernel/setup.c index ebfac782593f..e15d83bb4ea3 100644 --- a/trunk/arch/arm/kernel/setup.c +++ b/trunk/arch/arm/kernel/setup.c @@ -81,6 +81,7 @@ __setup("fpe=", fpe_setup); extern void paging_init(struct machine_desc *desc); extern void sanity_check_meminfo(void); extern void reboot_setup(char *str); +extern void setup_dma_zone(struct machine_desc *desc); unsigned int processor_id; EXPORT_SYMBOL(processor_id); @@ -800,6 +801,14 @@ static int __init customize_machine(void) } arch_initcall(customize_machine); +static int __init init_machine_late(void) +{ + if (machine_desc->init_late) + machine_desc->init_late(); + return 0; +} +late_initcall(init_machine_late); + #ifdef CONFIG_KEXEC static inline unsigned long long get_total_mem(void) { @@ -939,12 +948,8 @@ void __init setup_arch(char **cmdline_p) machine_desc = mdesc; machine_name = mdesc->name; -#ifdef CONFIG_ZONE_DMA - if (mdesc->dma_zone_size) { - extern unsigned long arm_dma_zone_size; - arm_dma_zone_size = mdesc->dma_zone_size; - } -#endif + setup_dma_zone(mdesc); + if (mdesc->restart_mode) reboot_setup(&mdesc->restart_mode); diff --git a/trunk/arch/arm/kernel/signal.c b/trunk/arch/arm/kernel/signal.c index 4e5fdd9bd9e3..fd2392a17ac1 100644 --- a/trunk/arch/arm/kernel/signal.c +++ b/trunk/arch/arm/kernel/signal.c @@ -22,14 +22,11 @@ #include "signal.h" -#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) - /* * For ARM syscalls, we encode the syscall number into the instruction. */ #define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE)) #define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE)) -#define SWI_SYS_RESTART (0xef000000|__NR_restart_syscall|__NR_OABI_SYSCALL_BASE) /* * With EABI, the syscall number has to be loaded into r7. @@ -49,18 +46,6 @@ const unsigned long sigreturn_codes[7] = { MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN, }; -/* - * Either we support OABI only, or we have EABI with the OABI - * compat layer enabled. In the later case we don't know if - * user space is EABI or not, and if not we must not clobber r7. - * Always using the OABI syscall solves that issue and works for - * all those cases. - */ -const unsigned long syscall_restart_code[2] = { - SWI_SYS_RESTART, /* swi __NR_restart_syscall */ - 0xe49df004, /* ldr pc, [sp], #4 */ -}; - /* * atomically swap in the new signal mask, and wait for a signal. */ @@ -82,10 +67,10 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, old_sigset_t mask; if (!access_ok(VERIFY_READ, act, sizeof(*act)) || __get_user(new_ka.sa.sa_handler, &act->sa_handler) || - __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) + __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) || + __get_user(new_ka.sa.sa_flags, &act->sa_flags) || + __get_user(mask, &act->sa_mask)) return -EFAULT; - __get_user(new_ka.sa.sa_flags, &act->sa_flags); - __get_user(mask, &act->sa_mask); siginitset(&new_ka.sa.sa_mask, mask); } @@ -94,10 +79,10 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, if (!ret && oact) { if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || - __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) + __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) || + __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) return -EFAULT; - __put_user(old_ka.sa.sa_flags, &oact->sa_flags); - __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); } return ret; @@ -223,10 +208,8 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf) int err; err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); - if (err == 0) { - sigdelsetmask(&set, ~_BLOCKABLE); + if (err == 0) set_current_blocked(&set); - } __get_user_error(regs->ARM_r0, &sf->uc.uc_mcontext.arm_r0, err); __get_user_error(regs->ARM_r1, &sf->uc.uc_mcontext.arm_r1, err); @@ -541,13 +524,13 @@ setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info, /* * OK, we're invoking a handler */ -static int +static void handle_signal(unsigned long sig, struct k_sigaction *ka, - siginfo_t *info, sigset_t *oldset, - struct pt_regs * regs) + siginfo_t *info, struct pt_regs *regs) { struct thread_info *thread = current_thread_info(); struct task_struct *tsk = current; + sigset_t *oldset = sigmask_to_save(); int usig = sig; int ret; @@ -572,17 +555,9 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, if (ret != 0) { force_sigsegv(sig, tsk); - return ret; + return; } - - /* - * Block the signal if we were successful. - */ - block_sigmask(ka, sig); - - tracehook_signal_handler(sig, info, ka, regs, 0); - - return 0; + signal_delivered(sig, info, ka, regs, 0); } /* @@ -601,15 +576,6 @@ static void do_signal(struct pt_regs *regs, int syscall) siginfo_t info; int signr; - /* - * We want the common case to go fast, which - * is why we may in certain cases get here from - * kernel mode. Just return without doing anything - * if so. - */ - if (!user_mode(regs)) - return; - /* * If we were from a system call, check for system call restarting... */ @@ -626,58 +592,39 @@ static void do_signal(struct pt_regs *regs, int syscall) case -ERESTARTNOHAND: case -ERESTARTSYS: case -ERESTARTNOINTR: + case -ERESTART_RESTARTBLOCK: regs->ARM_r0 = regs->ARM_ORIG_r0; regs->ARM_pc = restart_addr; break; - case -ERESTART_RESTARTBLOCK: - regs->ARM_r0 = -EINTR; - break; } } - if (try_to_freeze()) - goto no_signal; - /* * Get the signal to deliver. When running under ptrace, at this * point the debugger may change all our registers ... */ signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { - sigset_t *oldset; - /* * Depending on the signal settings we may need to revert the * decision to restart the system call. But skip this if a * debugger has chosen to restart at a different PC. */ if (regs->ARM_pc == restart_addr) { - if (retval == -ERESTARTNOHAND + if (retval == -ERESTARTNOHAND || + retval == -ERESTART_RESTARTBLOCK || (retval == -ERESTARTSYS && !(ka.sa.sa_flags & SA_RESTART))) { regs->ARM_r0 = -EINTR; regs->ARM_pc = continue_addr; } + clear_thread_flag(TIF_SYSCALL_RESTARTSYS); } - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - oldset = ¤t->saved_sigmask; - else - oldset = ¤t->blocked; - if (handle_signal(signr, &ka, &info, oldset, regs) == 0) { - /* - * A signal was successfully delivered; the saved - * sigmask will have been stored in the signal frame, - * and will be restored by sigreturn, so we can simply - * clear the TIF_RESTORE_SIGMASK flag. - */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - clear_thread_flag(TIF_RESTORE_SIGMASK); - } + handle_signal(signr, &ka, &info, regs); return; } - no_signal: if (syscall) { /* * Handle restarting a different system call. As above, @@ -685,38 +632,11 @@ static void do_signal(struct pt_regs *regs, int syscall) * ignore the restart. */ if (retval == -ERESTART_RESTARTBLOCK - && regs->ARM_pc == continue_addr) { - if (thumb_mode(regs)) { - regs->ARM_r7 = __NR_restart_syscall - __NR_SYSCALL_BASE; - regs->ARM_pc -= 2; - } else { -#if defined(CONFIG_AEABI) && !defined(CONFIG_OABI_COMPAT) - regs->ARM_r7 = __NR_restart_syscall; - regs->ARM_pc -= 4; -#else - u32 __user *usp; - - regs->ARM_sp -= 4; - usp = (u32 __user *)regs->ARM_sp; - - if (put_user(regs->ARM_pc, usp) == 0) { - regs->ARM_pc = KERN_RESTART_CODE; - } else { - regs->ARM_sp += 4; - force_sigsegv(0, current); - } -#endif - } - } - - /* If there's no signal to deliver, we just put the saved sigmask - * back. - */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { - clear_thread_flag(TIF_RESTORE_SIGMASK); - sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); - } + && regs->ARM_pc == restart_addr) + set_thread_flag(TIF_SYSCALL_RESTARTSYS); } + + restore_saved_sigmask(); } asmlinkage void @@ -728,7 +648,5 @@ do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall) if (thread_flags & _TIF_NOTIFY_RESUME) { clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); - if (current->replacement_session_keyring) - key_replace_session_keyring(); } } diff --git a/trunk/arch/arm/kernel/signal.h b/trunk/arch/arm/kernel/signal.h index 6fcfe8398aa4..5ff067b7c752 100644 --- a/trunk/arch/arm/kernel/signal.h +++ b/trunk/arch/arm/kernel/signal.h @@ -8,7 +8,5 @@ * published by the Free Software Foundation. */ #define KERN_SIGRETURN_CODE (CONFIG_VECTORS_BASE + 0x00000500) -#define KERN_RESTART_CODE (KERN_SIGRETURN_CODE + sizeof(sigreturn_codes)) extern const unsigned long sigreturn_codes[7]; -extern const unsigned long syscall_restart_code[2]; diff --git a/trunk/arch/arm/kernel/smp.c b/trunk/arch/arm/kernel/smp.c index b735521a4a54..2c7217d971db 100644 --- a/trunk/arch/arm/kernel/smp.c +++ b/trunk/arch/arm/kernel/smp.c @@ -109,7 +109,6 @@ static void percpu_timer_stop(void); int __cpu_disable(void) { unsigned int cpu = smp_processor_id(); - struct task_struct *p; int ret; ret = platform_cpu_disable(cpu); @@ -139,12 +138,7 @@ int __cpu_disable(void) flush_cache_all(); local_flush_tlb_all(); - read_lock(&tasklist_lock); - for_each_process(p) { - if (p->mm) - cpumask_clear_cpu(cpu, mm_cpumask(p->mm)); - } - read_unlock(&tasklist_lock); + clear_tasks_mm_cpumask(cpu); return 0; } diff --git a/trunk/arch/arm/kernel/traps.c b/trunk/arch/arm/kernel/traps.c index 3647170e9a16..4928d89758f4 100644 --- a/trunk/arch/arm/kernel/traps.c +++ b/trunk/arch/arm/kernel/traps.c @@ -820,8 +820,6 @@ void __init early_trap_init(void *vectors_base) */ memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE), sigreturn_codes, sizeof(sigreturn_codes)); - memcpy((void *)(vectors + KERN_RESTART_CODE - CONFIG_VECTORS_BASE), - syscall_restart_code, sizeof(syscall_restart_code)); flush_icache_range(vectors, vectors + PAGE_SIZE); modify_domain(DOMAIN_USER, DOMAIN_CLIENT); diff --git a/trunk/arch/arm/mach-at91/at91sam9g45_devices.c b/trunk/arch/arm/mach-at91/at91sam9g45_devices.c index f6747246d649..933fc9afe7d0 100644 --- a/trunk/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9g45_devices.c @@ -436,7 +436,6 @@ void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) atslave->dma_dev = &at_hdmac_device.dev; atslave->cfg = ATC_FIFOCFG_HALFFIFO | ATC_SRC_H2SEL_HW | ATC_DST_H2SEL_HW; - atslave->ctrla = ATC_SCSIZE_16 | ATC_DCSIZE_16; if (mmc_id == 0) /* MCI0 */ atslave->cfg |= ATC_SRC_PER(AT_DMA_ID_MCI0) | ATC_DST_PER(AT_DMA_ID_MCI0); diff --git a/trunk/arch/arm/mach-at91/include/mach/at_hdmac.h b/trunk/arch/arm/mach-at91/include/mach/at_hdmac.h index fff48d1a0f4e..cab0997be3de 100644 --- a/trunk/arch/arm/mach-at91/include/mach/at_hdmac.h +++ b/trunk/arch/arm/mach-at91/include/mach/at_hdmac.h @@ -26,18 +26,11 @@ struct at_dma_platform_data { /** * struct at_dma_slave - Controller-specific information about a slave * @dma_dev: required DMA master device - * @tx_reg: physical address of data register used for - * memory-to-peripheral transfers - * @rx_reg: physical address of data register used for - * peripheral-to-memory transfers - * @reg_width: peripheral register width * @cfg: Platform-specific initializer for the CFG register - * @ctrla: Platform-specific initializer for the CTRLA register */ struct at_dma_slave { struct device *dma_dev; u32 cfg; - u32 ctrla; }; @@ -64,24 +57,5 @@ struct at_dma_slave { #define ATC_FIFOCFG_HALFFIFO (0x1 << 28) #define ATC_FIFOCFG_ENOUGHSPACE (0x2 << 28) -/* Platform-configurable bits in CTRLA */ -#define ATC_SCSIZE_MASK (0x7 << 16) /* Source Chunk Transfer Size */ -#define ATC_SCSIZE_1 (0x0 << 16) -#define ATC_SCSIZE_4 (0x1 << 16) -#define ATC_SCSIZE_8 (0x2 << 16) -#define ATC_SCSIZE_16 (0x3 << 16) -#define ATC_SCSIZE_32 (0x4 << 16) -#define ATC_SCSIZE_64 (0x5 << 16) -#define ATC_SCSIZE_128 (0x6 << 16) -#define ATC_SCSIZE_256 (0x7 << 16) -#define ATC_DCSIZE_MASK (0x7 << 20) /* Destination Chunk Transfer Size */ -#define ATC_DCSIZE_1 (0x0 << 20) -#define ATC_DCSIZE_4 (0x1 << 20) -#define ATC_DCSIZE_8 (0x2 << 20) -#define ATC_DCSIZE_16 (0x3 << 20) -#define ATC_DCSIZE_32 (0x4 << 20) -#define ATC_DCSIZE_64 (0x5 << 20) -#define ATC_DCSIZE_128 (0x6 << 20) -#define ATC_DCSIZE_256 (0x7 << 20) #endif /* AT_HDMAC_H */ diff --git a/trunk/arch/arm/mach-davinci/board-da830-evm.c b/trunk/arch/arm/mach-davinci/board-da830-evm.c index dc1afe5be20c..0031864e7f11 100644 --- a/trunk/arch/arm/mach-davinci/board-da830-evm.c +++ b/trunk/arch/arm/mach-davinci/board-da830-evm.c @@ -681,6 +681,7 @@ MACHINE_START(DAVINCI_DA830_EVM, "DaVinci DA830/OMAP-L137/AM17x EVM") .init_irq = cp_intc_init, .timer = &davinci_timer, .init_machine = da830_evm_init, + .init_late = davinci_init_late, .dma_zone_size = SZ_128M, .restart = da8xx_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-davinci/board-da850-evm.c b/trunk/arch/arm/mach-davinci/board-da850-evm.c index 09f61073c8d9..0149fb453be3 100644 --- a/trunk/arch/arm/mach-davinci/board-da850-evm.c +++ b/trunk/arch/arm/mach-davinci/board-da850-evm.c @@ -1411,6 +1411,7 @@ MACHINE_START(DAVINCI_DA850_EVM, "DaVinci DA850/OMAP-L138/AM18x EVM") .init_irq = cp_intc_init, .timer = &davinci_timer, .init_machine = da850_evm_init, + .init_late = davinci_init_late, .dma_zone_size = SZ_128M, .restart = da8xx_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-davinci/board-dm355-evm.c b/trunk/arch/arm/mach-davinci/board-dm355-evm.c index 82ed753fb360..1c7b1f46a8f3 100644 --- a/trunk/arch/arm/mach-davinci/board-dm355-evm.c +++ b/trunk/arch/arm/mach-davinci/board-dm355-evm.c @@ -357,6 +357,7 @@ MACHINE_START(DAVINCI_DM355_EVM, "DaVinci DM355 EVM") .init_irq = davinci_irq_init, .timer = &davinci_timer, .init_machine = dm355_evm_init, + .init_late = davinci_init_late, .dma_zone_size = SZ_128M, .restart = davinci_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-davinci/board-dm355-leopard.c b/trunk/arch/arm/mach-davinci/board-dm355-leopard.c index d74a8b3445fb..8e7703213b08 100644 --- a/trunk/arch/arm/mach-davinci/board-dm355-leopard.c +++ b/trunk/arch/arm/mach-davinci/board-dm355-leopard.c @@ -276,6 +276,7 @@ MACHINE_START(DM355_LEOPARD, "DaVinci DM355 leopard") .init_irq = davinci_irq_init, .timer = &davinci_timer, .init_machine = dm355_leopard_init, + .init_late = davinci_init_late, .dma_zone_size = SZ_128M, .restart = davinci_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-davinci/board-dm365-evm.c b/trunk/arch/arm/mach-davinci/board-dm365-evm.c index 5bce2b83bb4f..688a9c556dc9 100644 --- a/trunk/arch/arm/mach-davinci/board-dm365-evm.c +++ b/trunk/arch/arm/mach-davinci/board-dm365-evm.c @@ -618,6 +618,7 @@ MACHINE_START(DAVINCI_DM365_EVM, "DaVinci DM365 EVM") .init_irq = davinci_irq_init, .timer = &davinci_timer, .init_machine = dm365_evm_init, + .init_late = davinci_init_late, .dma_zone_size = SZ_128M, .restart = davinci_restart, 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 3683306e0245..d34ed55912b2 100644 --- a/trunk/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/trunk/arch/arm/mach-davinci/board-dm644x-evm.c @@ -825,6 +825,7 @@ MACHINE_START(DAVINCI_EVM, "DaVinci DM644x EVM") .init_irq = davinci_irq_init, .timer = &davinci_timer, .init_machine = davinci_evm_init, + .init_late = davinci_init_late, .dma_zone_size = SZ_128M, .restart = davinci_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-davinci/board-dm646x-evm.c b/trunk/arch/arm/mach-davinci/board-dm646x-evm.c index d72ab948d630..958679a20e13 100644 --- a/trunk/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/trunk/arch/arm/mach-davinci/board-dm646x-evm.c @@ -788,6 +788,7 @@ MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM") .init_irq = davinci_irq_init, .timer = &davinci_timer, .init_machine = evm_init, + .init_late = davinci_init_late, .dma_zone_size = SZ_128M, .restart = davinci_restart, MACHINE_END @@ -798,6 +799,7 @@ MACHINE_START(DAVINCI_DM6467TEVM, "DaVinci DM6467T EVM") .init_irq = davinci_irq_init, .timer = &davinci_timer, .init_machine = evm_init, + .init_late = davinci_init_late, .dma_zone_size = SZ_128M, .restart = davinci_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-davinci/board-mityomapl138.c b/trunk/arch/arm/mach-davinci/board-mityomapl138.c index 672d820e2aa4..beecde3a1d2f 100644 --- a/trunk/arch/arm/mach-davinci/board-mityomapl138.c +++ b/trunk/arch/arm/mach-davinci/board-mityomapl138.c @@ -572,6 +572,7 @@ MACHINE_START(MITYOMAPL138, "MityDSP-L138/MityARM-1808") .init_irq = cp_intc_init, .timer = &davinci_timer, .init_machine = mityomapl138_init, + .init_late = davinci_init_late, .dma_zone_size = SZ_128M, .restart = da8xx_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-davinci/board-neuros-osd2.c b/trunk/arch/arm/mach-davinci/board-neuros-osd2.c index a772bb45570a..5de69f2fcca9 100644 --- a/trunk/arch/arm/mach-davinci/board-neuros-osd2.c +++ b/trunk/arch/arm/mach-davinci/board-neuros-osd2.c @@ -278,6 +278,7 @@ MACHINE_START(NEUROS_OSD2, "Neuros OSD2") .init_irq = davinci_irq_init, .timer = &davinci_timer, .init_machine = davinci_ntosd2_init, + .init_late = davinci_init_late, .dma_zone_size = SZ_128M, .restart = davinci_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-davinci/board-omapl138-hawk.c b/trunk/arch/arm/mach-davinci/board-omapl138-hawk.c index 45e815760a27..dc1208e9e664 100644 --- a/trunk/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/trunk/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -343,6 +343,7 @@ MACHINE_START(OMAPL138_HAWKBOARD, "AM18x/OMAP-L138 Hawkboard") .init_irq = cp_intc_init, .timer = &davinci_timer, .init_machine = omapl138_hawk_init, + .init_late = davinci_init_late, .dma_zone_size = SZ_128M, .restart = da8xx_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-davinci/board-sffsdr.c b/trunk/arch/arm/mach-davinci/board-sffsdr.c index 76e675096104..9078acf94bac 100644 --- a/trunk/arch/arm/mach-davinci/board-sffsdr.c +++ b/trunk/arch/arm/mach-davinci/board-sffsdr.c @@ -157,6 +157,7 @@ MACHINE_START(SFFSDR, "Lyrtech SFFSDR") .init_irq = davinci_irq_init, .timer = &davinci_timer, .init_machine = davinci_sffsdr_init, + .init_late = davinci_init_late, .dma_zone_size = SZ_128M, .restart = davinci_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-davinci/board-tnetv107x-evm.c b/trunk/arch/arm/mach-davinci/board-tnetv107x-evm.c index 5f14e30b00d8..ac4e003ad863 100644 --- a/trunk/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/trunk/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -282,6 +282,7 @@ MACHINE_START(TNETV107X, "TNETV107X EVM") .init_irq = cp_intc_init, .timer = &davinci_timer, .init_machine = tnetv107x_evm_board_init, + .init_late = davinci_init_late, .dma_zone_size = SZ_128M, .restart = tnetv107x_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-davinci/clock.c b/trunk/arch/arm/mach-davinci/clock.c index 008772e3b843..34668ead53c7 100644 --- a/trunk/arch/arm/mach-davinci/clock.c +++ b/trunk/arch/arm/mach-davinci/clock.c @@ -213,7 +213,7 @@ EXPORT_SYMBOL(clk_unregister); /* * Disable any unused clocks left on by the bootloader */ -static int __init clk_disable_unused(void) +int __init davinci_clk_disable_unused(void) { struct clk *ck; @@ -237,7 +237,6 @@ static int __init clk_disable_unused(void) return 0; } -late_initcall(clk_disable_unused); #endif static unsigned long clk_sysclk_recalc(struct clk *clk) diff --git a/trunk/arch/arm/mach-davinci/common.c b/trunk/arch/arm/mach-davinci/common.c index cb9b2e47510c..64b0f65a8639 100644 --- a/trunk/arch/arm/mach-davinci/common.c +++ b/trunk/arch/arm/mach-davinci/common.c @@ -117,3 +117,10 @@ void __init davinci_common_init(struct davinci_soc_info *soc_info) err: panic("davinci_common_init: SoC Initialization failed\n"); } + +void __init davinci_init_late(void) +{ + davinci_cpufreq_init(); + davinci_pm_init(); + davinci_clk_disable_unused(); +} diff --git a/trunk/arch/arm/mach-davinci/cpufreq.c b/trunk/arch/arm/mach-davinci/cpufreq.c index 031048fec9f5..4729eaab0f40 100644 --- a/trunk/arch/arm/mach-davinci/cpufreq.c +++ b/trunk/arch/arm/mach-davinci/cpufreq.c @@ -240,10 +240,9 @@ static struct platform_driver davinci_cpufreq_driver = { .remove = __exit_p(davinci_cpufreq_remove), }; -static int __init davinci_cpufreq_init(void) +int __init davinci_cpufreq_init(void) { return platform_driver_probe(&davinci_cpufreq_driver, davinci_cpufreq_probe); } -late_initcall(davinci_cpufreq_init); diff --git a/trunk/arch/arm/mach-davinci/dma.c b/trunk/arch/arm/mach-davinci/dma.c index 95ce019c9b98..a685e9706b7b 100644 --- a/trunk/arch/arm/mach-davinci/dma.c +++ b/trunk/arch/arm/mach-davinci/dma.c @@ -353,9 +353,10 @@ static int irq2ctlr(int irq) *****************************************************************************/ static irqreturn_t dma_irq_handler(int irq, void *data) { - int i; int ctlr; - unsigned int cnt = 0; + u32 sh_ier; + u32 sh_ipr; + u32 bank; ctlr = irq2ctlr(irq); if (ctlr < 0) @@ -363,41 +364,39 @@ static irqreturn_t dma_irq_handler(int irq, void *data) dev_dbg(data, "dma_irq_handler\n"); - if ((edma_shadow0_read_array(ctlr, SH_IPR, 0) == 0) && - (edma_shadow0_read_array(ctlr, SH_IPR, 1) == 0)) - return IRQ_NONE; + sh_ipr = edma_shadow0_read_array(ctlr, SH_IPR, 0); + if (!sh_ipr) { + sh_ipr = edma_shadow0_read_array(ctlr, SH_IPR, 1); + if (!sh_ipr) + return IRQ_NONE; + sh_ier = edma_shadow0_read_array(ctlr, SH_IER, 1); + bank = 1; + } else { + sh_ier = edma_shadow0_read_array(ctlr, SH_IER, 0); + bank = 0; + } - while (1) { - int j; - if (edma_shadow0_read_array(ctlr, SH_IPR, 0) & - edma_shadow0_read_array(ctlr, SH_IER, 0)) - j = 0; - else if (edma_shadow0_read_array(ctlr, SH_IPR, 1) & - edma_shadow0_read_array(ctlr, SH_IER, 1)) - j = 1; - else - break; - dev_dbg(data, "IPR%d %08x\n", j, - edma_shadow0_read_array(ctlr, SH_IPR, j)); - for (i = 0; i < 32; i++) { - int k = (j << 5) + i; - if ((edma_shadow0_read_array(ctlr, SH_IPR, j) & BIT(i)) - && (edma_shadow0_read_array(ctlr, - SH_IER, j) & BIT(i))) { - /* Clear the corresponding IPR bits */ - edma_shadow0_write_array(ctlr, SH_ICR, j, - BIT(i)); - if (edma_cc[ctlr]->intr_data[k].callback) - edma_cc[ctlr]->intr_data[k].callback( - k, DMA_COMPLETE, - edma_cc[ctlr]->intr_data[k]. - data); - } + do { + u32 slot; + u32 channel; + + dev_dbg(data, "IPR%d %08x\n", bank, sh_ipr); + + slot = __ffs(sh_ipr); + sh_ipr &= ~(BIT(slot)); + + if (sh_ier & BIT(slot)) { + channel = (bank << 5) | slot; + /* Clear the corresponding IPR bits */ + edma_shadow0_write_array(ctlr, SH_ICR, bank, + BIT(slot)); + if (edma_cc[ctlr]->intr_data[channel].callback) + edma_cc[ctlr]->intr_data[channel].callback( + channel, DMA_COMPLETE, + edma_cc[ctlr]->intr_data[channel].data); } - cnt++; - if (cnt > 10) - break; - } + } while (sh_ipr); + edma_shadow0_write(ctlr, SH_IEVAL, 1); return IRQ_HANDLED; } diff --git a/trunk/arch/arm/mach-davinci/include/mach/common.h b/trunk/arch/arm/mach-davinci/include/mach/common.h index 5cd39a4e0c96..bdc4aa8e672a 100644 --- a/trunk/arch/arm/mach-davinci/include/mach/common.h +++ b/trunk/arch/arm/mach-davinci/include/mach/common.h @@ -84,6 +84,25 @@ extern struct davinci_soc_info davinci_soc_info; extern void davinci_common_init(struct davinci_soc_info *soc_info); extern void davinci_init_ide(void); void davinci_restart(char mode, const char *cmd); +void davinci_init_late(void); + +#ifdef CONFIG_DAVINCI_RESET_CLOCKS +int davinci_clk_disable_unused(void); +#else +static inline int davinci_clk_disable_unused(void) { return 0; } +#endif + +#ifdef CONFIG_CPU_FREQ +int davinci_cpufreq_init(void); +#else +static inline int davinci_cpufreq_init(void) { return 0; } +#endif + +#ifdef CONFIG_SUSPEND +int davinci_pm_init(void); +#else +static inline int davinci_pm_init(void) { return 0; } +#endif /* standard place to map on-chip SRAMs; they *may* support DMA */ #define SRAM_VIRT 0xfffe0000 diff --git a/trunk/arch/arm/mach-davinci/include/mach/debug-macro.S b/trunk/arch/arm/mach-davinci/include/mach/debug-macro.S index cf94552d5274..34290d14754b 100644 --- a/trunk/arch/arm/mach-davinci/include/mach/debug-macro.S +++ b/trunk/arch/arm/mach-davinci/include/mach/debug-macro.S @@ -22,46 +22,28 @@ #define UART_SHIFT 2 - .pushsection .data -davinci_uart_phys: .word 0 -davinci_uart_virt: .word 0 - .popsection - - .macro addruart, rp, rv, tmp - - /* Use davinci_uart_phys/virt if already configured */ -10: adr \rp, 99f @ get effective addr of 99f - ldr \rv, [\rp] @ get absolute addr of 99f - sub \rv, \rv, \rp @ offset between the two - ldr \rp, [\rp, #4] @ abs addr of omap_uart_phys - sub \tmp, \rp, \rv @ make it effective - ldr \rp, [\tmp, #0] @ davinci_uart_phys - ldr \rv, [\tmp, #4] @ davinci_uart_virt - cmp \rp, #0 @ is port configured? - cmpne \rv, #0 - bne 100f @ already configured - - /* Check the debug UART address set in uncompress.h */ - and \rp, pc, #0xff000000 - ldr \rv, =DAVINCI_UART_INFO_OFS - add \rp, \rp, \rv - - /* Copy uart phys address from decompressor uart info */ - ldr \rv, [\rp, #0] - str \rv, [\tmp, #0] - - /* Copy uart virt address from decompressor uart info */ - ldr \rv, [\rp, #4] - str \rv, [\tmp, #4] - - b 10b +#if defined(CONFIG_DEBUG_DAVINCI_DMx_UART0) +#define UART_BASE DAVINCI_UART0_BASE +#elif defined(CONFIG_DEBUG_DAVINCI_DA8XX_UART0) +#define UART_BASE DA8XX_UART0_BASE +#elif defined(CONFIG_DEBUG_DAVINCI_DA8XX_UART1) +#define UART_BASE DA8XX_UART1_BASE +#elif defined(CONFIG_DEBUG_DAVINCI_DA8XX_UART2) +#define UART_BASE DA8XX_UART2_BASE +#elif defined(CONFIG_DEBUG_DAVINCI_TNETV107X_UART1) +#define UART_BASE TNETV107X_UART2_BASE +#define UART_VIRTBASE TNETV107X_UART2_VIRT +#else +#error "Select a specifc port for DEBUG_LL" +#endif - .align -99: .word . - .word davinci_uart_phys - .ltorg +#ifndef UART_VIRTBASE +#define UART_VIRTBASE IO_ADDRESS(UART_BASE) +#endif -100: + .macro addruart, rp, rv, tmp + ldr \rp, =UART_BASE + ldr \rv, =UART_VIRTBASE .endm .macro senduart,rd,rx diff --git a/trunk/arch/arm/mach-davinci/include/mach/hardware.h b/trunk/arch/arm/mach-davinci/include/mach/hardware.h index 2184691ebc2f..16bb42291d39 100644 --- a/trunk/arch/arm/mach-davinci/include/mach/hardware.h +++ b/trunk/arch/arm/mach-davinci/include/mach/hardware.h @@ -22,7 +22,7 @@ /* * I/O mapping */ -#define IO_PHYS 0x01c00000UL +#define IO_PHYS UL(0x01c00000) #define IO_OFFSET 0xfd000000 /* Virtual IO = 0xfec00000 */ #define IO_SIZE 0x00400000 #define IO_VIRT (IO_PHYS + IO_OFFSET) diff --git a/trunk/arch/arm/mach-davinci/include/mach/serial.h b/trunk/arch/arm/mach-davinci/include/mach/serial.h index e347d88fef91..46b3cd11c3c2 100644 --- a/trunk/arch/arm/mach-davinci/include/mach/serial.h +++ b/trunk/arch/arm/mach-davinci/include/mach/serial.h @@ -15,16 +15,6 @@ #include -/* - * Stolen area that contains debug uart physical and virtual addresses. These - * addresses are filled in by the uncompress.h code, and are used by the debug - * macros in debug-macro.S. - * - * This area sits just below the page tables (see arch/arm/kernel/head.S). - * We define it as a relative offset from start of usable RAM. - */ -#define DAVINCI_UART_INFO_OFS 0x3ff8 - #define DAVINCI_UART0_BASE (IO_PHYS + 0x20000) #define DAVINCI_UART1_BASE (IO_PHYS + 0x20400) #define DAVINCI_UART2_BASE (IO_PHYS + 0x20800) diff --git a/trunk/arch/arm/mach-davinci/include/mach/uncompress.h b/trunk/arch/arm/mach-davinci/include/mach/uncompress.h index da2fb2c2155a..18cfd4977155 100644 --- a/trunk/arch/arm/mach-davinci/include/mach/uncompress.h +++ b/trunk/arch/arm/mach-davinci/include/mach/uncompress.h @@ -43,37 +43,27 @@ static inline void flush(void) barrier(); } -static inline void set_uart_info(u32 phys, void * __iomem virt) +static inline void set_uart_info(u32 phys) { - /* - * Get address of some.bss variable and round it down - * a la CONFIG_AUTO_ZRELADDR. - */ - u32 ram_start = (u32)&uart & 0xf8000000; - u32 *uart_info = (u32 *)(ram_start + DAVINCI_UART_INFO_OFS); - uart = (u32 *)phys; - uart_info[0] = phys; - uart_info[1] = (u32)virt; } -#define _DEBUG_LL_ENTRY(machine, phys, virt) \ - if (machine_is_##machine()) { \ - set_uart_info(phys, virt); \ - break; \ +#define _DEBUG_LL_ENTRY(machine, phys) \ + { \ + if (machine_is_##machine()) { \ + set_uart_info(phys); \ + break; \ + } \ } #define DEBUG_LL_DAVINCI(machine, port) \ - _DEBUG_LL_ENTRY(machine, DAVINCI_UART##port##_BASE, \ - IO_ADDRESS(DAVINCI_UART##port##_BASE)) + _DEBUG_LL_ENTRY(machine, DAVINCI_UART##port##_BASE) #define DEBUG_LL_DA8XX(machine, port) \ - _DEBUG_LL_ENTRY(machine, DA8XX_UART##port##_BASE, \ - IO_ADDRESS(DA8XX_UART##port##_BASE)) + _DEBUG_LL_ENTRY(machine, DA8XX_UART##port##_BASE) #define DEBUG_LL_TNETV107X(machine, port) \ - _DEBUG_LL_ENTRY(machine, TNETV107X_UART##port##_BASE, \ - TNETV107X_UART##port##_VIRT) + _DEBUG_LL_ENTRY(machine, TNETV107X_UART##port##_BASE) static inline void __arch_decomp_setup(unsigned long arch_id) { diff --git a/trunk/arch/arm/mach-davinci/pm.c b/trunk/arch/arm/mach-davinci/pm.c index 04c49f7543ef..eb8360b33aa9 100644 --- a/trunk/arch/arm/mach-davinci/pm.c +++ b/trunk/arch/arm/mach-davinci/pm.c @@ -152,8 +152,7 @@ static struct platform_driver davinci_pm_driver = { .remove = __exit_p(davinci_pm_remove), }; -static int __init davinci_pm_init(void) +int __init davinci_pm_init(void) { return platform_driver_probe(&davinci_pm_driver, davinci_pm_probe); } -late_initcall(davinci_pm_init); diff --git a/trunk/arch/arm/mach-dove/common.c b/trunk/arch/arm/mach-dove/common.c index 42ab1e7c4ecc..9493076fc594 100644 --- a/trunk/arch/arm/mach-dove/common.c +++ b/trunk/arch/arm/mach-dove/common.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include @@ -67,6 +67,19 @@ void __init dove_map_io(void) iotable_init(dove_io_desc, ARRAY_SIZE(dove_io_desc)); } +/***************************************************************************** + * CLK tree + ****************************************************************************/ +static struct clk *tclk; + +static void __init clk_init(void) +{ + tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT, + get_tclk()); + + orion_clkdev_init(tclk); +} + /***************************************************************************** * EHCI0 ****************************************************************************/ @@ -89,8 +102,7 @@ void __init dove_ehci1_init(void) void __init dove_ge00_init(struct mv643xx_eth_platform_data *eth_data) { orion_ge00_init(eth_data, - DOVE_GE00_PHYS_BASE, IRQ_DOVE_GE00_SUM, - 0, get_tclk()); + DOVE_GE00_PHYS_BASE, IRQ_DOVE_GE00_SUM, 0); } /***************************************************************************** @@ -116,7 +128,7 @@ void __init dove_sata_init(struct mv_sata_platform_data *sata_data) void __init dove_uart0_init(void) { orion_uart0_init(DOVE_UART0_VIRT_BASE, DOVE_UART0_PHYS_BASE, - IRQ_DOVE_UART_0, get_tclk()); + IRQ_DOVE_UART_0, tclk); } /***************************************************************************** @@ -125,7 +137,7 @@ void __init dove_uart0_init(void) void __init dove_uart1_init(void) { orion_uart1_init(DOVE_UART1_VIRT_BASE, DOVE_UART1_PHYS_BASE, - IRQ_DOVE_UART_1, get_tclk()); + IRQ_DOVE_UART_1, tclk); } /***************************************************************************** @@ -134,7 +146,7 @@ void __init dove_uart1_init(void) void __init dove_uart2_init(void) { orion_uart2_init(DOVE_UART2_VIRT_BASE, DOVE_UART2_PHYS_BASE, - IRQ_DOVE_UART_2, get_tclk()); + IRQ_DOVE_UART_2, tclk); } /***************************************************************************** @@ -143,7 +155,7 @@ void __init dove_uart2_init(void) void __init dove_uart3_init(void) { orion_uart3_init(DOVE_UART3_VIRT_BASE, DOVE_UART3_PHYS_BASE, - IRQ_DOVE_UART_3, get_tclk()); + IRQ_DOVE_UART_3, tclk); } /***************************************************************************** @@ -151,12 +163,12 @@ void __init dove_uart3_init(void) ****************************************************************************/ void __init dove_spi0_init(void) { - orion_spi_init(DOVE_SPI0_PHYS_BASE, get_tclk()); + orion_spi_init(DOVE_SPI0_PHYS_BASE); } void __init dove_spi1_init(void) { - orion_spi_1_init(DOVE_SPI1_PHYS_BASE, get_tclk()); + orion_spi_1_init(DOVE_SPI1_PHYS_BASE); } /***************************************************************************** @@ -272,18 +284,17 @@ void __init dove_sdio1_init(void) void __init dove_init(void) { - int tclk; - - tclk = get_tclk(); - printk(KERN_INFO "Dove 88AP510 SoC, "); - printk(KERN_INFO "TCLK = %dMHz\n", (tclk + 499999) / 1000000); + printk(KERN_INFO "TCLK = %dMHz\n", (get_tclk() + 499999) / 1000000); #ifdef CONFIG_CACHE_TAUROS2 tauros2_init(); #endif dove_setup_cpu_mbus(); + /* Setup root of clk tree */ + clk_init(); + /* internal devices that every board has */ dove_rtc_init(); dove_xor0_init(); diff --git a/trunk/arch/arm/mach-dove/dove-db-setup.c b/trunk/arch/arm/mach-dove/dove-db-setup.c index ea77ae430b2d..bc2867f11346 100644 --- a/trunk/arch/arm/mach-dove/dove-db-setup.c +++ b/trunk/arch/arm/mach-dove/dove-db-setup.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/arm/mach-ep93xx/adssphere.c b/trunk/arch/arm/mach-ep93xx/adssphere.c index 2d45947a3034..a472777e9eba 100644 --- a/trunk/arch/arm/mach-ep93xx/adssphere.c +++ b/trunk/arch/arm/mach-ep93xx/adssphere.c @@ -41,5 +41,6 @@ MACHINE_START(ADSSPHERE, "ADS Sphere board") .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = adssphere_init_machine, + .init_late = ep93xx_init_late, .restart = ep93xx_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-ep93xx/core.c b/trunk/arch/arm/mach-ep93xx/core.c index 66b1494f23a6..4dd07a0e3604 100644 --- a/trunk/arch/arm/mach-ep93xx/core.c +++ b/trunk/arch/arm/mach-ep93xx/core.c @@ -675,7 +675,7 @@ int ep93xx_keypad_acquire_gpio(struct platform_device *pdev) fail_gpio_d: gpio_free(EP93XX_GPIO_LINE_C(i)); fail_gpio_c: - for ( ; i >= 0; --i) { + for (--i; i >= 0; --i) { gpio_free(EP93XX_GPIO_LINE_C(i)); gpio_free(EP93XX_GPIO_LINE_D(i)); } @@ -834,3 +834,8 @@ void ep93xx_restart(char mode, const char *cmd) while (1) ; } + +void __init ep93xx_init_late(void) +{ + crunch_init(); +} diff --git a/trunk/arch/arm/mach-ep93xx/crunch.c b/trunk/arch/arm/mach-ep93xx/crunch.c index 74753e2df603..a4a2ab9648c9 100644 --- a/trunk/arch/arm/mach-ep93xx/crunch.c +++ b/trunk/arch/arm/mach-ep93xx/crunch.c @@ -79,12 +79,10 @@ static struct notifier_block crunch_notifier_block = { .notifier_call = crunch_do, }; -static int __init crunch_init(void) +int __init crunch_init(void) { thread_register_notifier(&crunch_notifier_block); elf_hwcap |= HWCAP_CRUNCH; return 0; } - -late_initcall(crunch_init); diff --git a/trunk/arch/arm/mach-ep93xx/edb93xx.c b/trunk/arch/arm/mach-ep93xx/edb93xx.c index da9047d726f0..d74c5cddb98b 100644 --- a/trunk/arch/arm/mach-ep93xx/edb93xx.c +++ b/trunk/arch/arm/mach-ep93xx/edb93xx.c @@ -255,6 +255,7 @@ MACHINE_START(EDB9301, "Cirrus Logic EDB9301 Evaluation Board") .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = edb93xx_init_machine, + .init_late = ep93xx_init_late, .restart = ep93xx_restart, MACHINE_END #endif @@ -268,6 +269,7 @@ MACHINE_START(EDB9302, "Cirrus Logic EDB9302 Evaluation Board") .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = edb93xx_init_machine, + .init_late = ep93xx_init_late, .restart = ep93xx_restart, MACHINE_END #endif @@ -281,6 +283,7 @@ MACHINE_START(EDB9302A, "Cirrus Logic EDB9302A Evaluation Board") .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = edb93xx_init_machine, + .init_late = ep93xx_init_late, .restart = ep93xx_restart, MACHINE_END #endif @@ -294,6 +297,7 @@ MACHINE_START(EDB9307, "Cirrus Logic EDB9307 Evaluation Board") .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = edb93xx_init_machine, + .init_late = ep93xx_init_late, .restart = ep93xx_restart, MACHINE_END #endif @@ -307,6 +311,7 @@ MACHINE_START(EDB9307A, "Cirrus Logic EDB9307A Evaluation Board") .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = edb93xx_init_machine, + .init_late = ep93xx_init_late, .restart = ep93xx_restart, MACHINE_END #endif @@ -320,6 +325,7 @@ MACHINE_START(EDB9312, "Cirrus Logic EDB9312 Evaluation Board") .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = edb93xx_init_machine, + .init_late = ep93xx_init_late, .restart = ep93xx_restart, MACHINE_END #endif @@ -333,6 +339,7 @@ MACHINE_START(EDB9315, "Cirrus Logic EDB9315 Evaluation Board") .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = edb93xx_init_machine, + .init_late = ep93xx_init_late, .restart = ep93xx_restart, MACHINE_END #endif @@ -346,6 +353,7 @@ MACHINE_START(EDB9315A, "Cirrus Logic EDB9315A Evaluation Board") .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = edb93xx_init_machine, + .init_late = ep93xx_init_late, .restart = ep93xx_restart, MACHINE_END #endif diff --git a/trunk/arch/arm/mach-ep93xx/gesbc9312.c b/trunk/arch/arm/mach-ep93xx/gesbc9312.c index fcdffbe49dcc..437c34111155 100644 --- a/trunk/arch/arm/mach-ep93xx/gesbc9312.c +++ b/trunk/arch/arm/mach-ep93xx/gesbc9312.c @@ -41,5 +41,6 @@ MACHINE_START(GESBC9312, "Glomation GESBC-9312-sx") .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = gesbc9312_init_machine, + .init_late = ep93xx_init_late, .restart = ep93xx_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-ep93xx/include/mach/platform.h b/trunk/arch/arm/mach-ep93xx/include/mach/platform.h index 602bd87fd0ab..1ecb040d98bf 100644 --- a/trunk/arch/arm/mach-ep93xx/include/mach/platform.h +++ b/trunk/arch/arm/mach-ep93xx/include/mach/platform.h @@ -53,5 +53,12 @@ void ep93xx_init_devices(void); extern struct sys_timer ep93xx_timer; void ep93xx_restart(char, const char *); +void ep93xx_init_late(void); + +#ifdef CONFIG_CRUNCH +int crunch_init(void); +#else +static inline int crunch_init(void) { return 0; } +#endif #endif diff --git a/trunk/arch/arm/mach-ep93xx/micro9.c b/trunk/arch/arm/mach-ep93xx/micro9.c index dc431c5f04ce..3d7cdab725b2 100644 --- a/trunk/arch/arm/mach-ep93xx/micro9.c +++ b/trunk/arch/arm/mach-ep93xx/micro9.c @@ -85,6 +85,7 @@ MACHINE_START(MICRO9, "Contec Micro9-High") .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = micro9_init_machine, + .init_late = ep93xx_init_late, .restart = ep93xx_restart, MACHINE_END #endif @@ -98,6 +99,7 @@ MACHINE_START(MICRO9M, "Contec Micro9-Mid") .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = micro9_init_machine, + .init_late = ep93xx_init_late, .restart = ep93xx_restart, MACHINE_END #endif @@ -111,6 +113,7 @@ MACHINE_START(MICRO9L, "Contec Micro9-Lite") .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = micro9_init_machine, + .init_late = ep93xx_init_late, .restart = ep93xx_restart, MACHINE_END #endif @@ -124,6 +127,7 @@ MACHINE_START(MICRO9S, "Contec Micro9-Slim") .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = micro9_init_machine, + .init_late = ep93xx_init_late, .restart = ep93xx_restart, MACHINE_END #endif diff --git a/trunk/arch/arm/mach-ep93xx/simone.c b/trunk/arch/arm/mach-ep93xx/simone.c index f40c2987e545..33dc07917417 100644 --- a/trunk/arch/arm/mach-ep93xx/simone.c +++ b/trunk/arch/arm/mach-ep93xx/simone.c @@ -86,5 +86,6 @@ MACHINE_START(SIM_ONE, "Simplemachines Sim.One Board") .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = simone_init_machine, + .init_late = ep93xx_init_late, .restart = ep93xx_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-ep93xx/snappercl15.c b/trunk/arch/arm/mach-ep93xx/snappercl15.c index 0c00852ef160..01abd3516a77 100644 --- a/trunk/arch/arm/mach-ep93xx/snappercl15.c +++ b/trunk/arch/arm/mach-ep93xx/snappercl15.c @@ -82,8 +82,6 @@ static int snappercl15_nand_dev_ready(struct mtd_info *mtd) return !!(__raw_readw(NAND_CTRL_ADDR(chip)) & SNAPPERCL15_NAND_RDY); } -static const char *snappercl15_nand_part_probes[] = {"cmdlinepart", NULL}; - static struct mtd_partition snappercl15_nand_parts[] = { { .name = "Kernel", @@ -100,10 +98,8 @@ static struct mtd_partition snappercl15_nand_parts[] = { static struct platform_nand_data snappercl15_nand_data = { .chip = { .nr_chips = 1, - .part_probe_types = snappercl15_nand_part_probes, .partitions = snappercl15_nand_parts, .nr_partitions = ARRAY_SIZE(snappercl15_nand_parts), - .options = NAND_NO_AUTOINCR, .chip_delay = 25, }, .ctrl = { @@ -183,5 +179,6 @@ MACHINE_START(SNAPPER_CL15, "Bluewater Systems Snapper CL15") .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = snappercl15_init_machine, + .init_late = ep93xx_init_late, .restart = ep93xx_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-ep93xx/ts72xx.c b/trunk/arch/arm/mach-ep93xx/ts72xx.c index 5ea790942e94..75cab2d7ec73 100644 --- a/trunk/arch/arm/mach-ep93xx/ts72xx.c +++ b/trunk/arch/arm/mach-ep93xx/ts72xx.c @@ -105,8 +105,6 @@ static int ts72xx_nand_device_ready(struct mtd_info *mtd) return !!(__raw_readb(addr) & 0x20); } -static const char *ts72xx_nand_part_probes[] = { "cmdlinepart", NULL }; - #define TS72XX_BOOTROM_PART_SIZE (SZ_16K) #define TS72XX_REDBOOT_PART_SIZE (SZ_2M + SZ_1M) @@ -134,7 +132,6 @@ static struct platform_nand_data ts72xx_nand_data = { .nr_chips = 1, .chip_offset = 0, .chip_delay = 15, - .part_probe_types = ts72xx_nand_part_probes, .partitions = ts72xx_nand_parts, .nr_partitions = ARRAY_SIZE(ts72xx_nand_parts), }, @@ -252,5 +249,6 @@ MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC") .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = ts72xx_init_machine, + .init_late = ep93xx_init_late, .restart = ep93xx_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-ep93xx/vision_ep9307.c b/trunk/arch/arm/mach-ep93xx/vision_ep9307.c index ba156eb225e8..2905a4929bdc 100644 --- a/trunk/arch/arm/mach-ep93xx/vision_ep9307.c +++ b/trunk/arch/arm/mach-ep93xx/vision_ep9307.c @@ -367,5 +367,6 @@ MACHINE_START(VISION_EP9307, "Vision Engraving Systems EP9307") .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = vision_init_machine, + .init_late = ep93xx_init_late, .restart = ep93xx_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-exynos/Kconfig b/trunk/arch/arm/mach-exynos/Kconfig index 15b05b89cc39..6f6d13f91e4c 100644 --- a/trunk/arch/arm/mach-exynos/Kconfig +++ b/trunk/arch/arm/mach-exynos/Kconfig @@ -61,6 +61,9 @@ config SOC_EXYNOS5250 bool "SAMSUNG EXYNOS5250" default y depends on ARCH_EXYNOS5 + select SAMSUNG_DMADEV + select S5P_PM if PM + select S5P_SLEEP if PM help Enable EXYNOS5250 SoC support @@ -70,7 +73,7 @@ config EXYNOS4_MCT help Use MCT (Multi Core Timer) as kernel timers -config EXYNOS4_DEV_DMA +config EXYNOS_DEV_DMA bool help Compile in amba device definitions for DMA controller @@ -80,15 +83,20 @@ config EXYNOS4_DEV_AHCI help Compile in platform device definitions for AHCI +config EXYNOS_DEV_DRM + bool + help + Compile in platform device definitions for core DRM device + config EXYNOS4_SETUP_FIMD0 bool help Common setup code for FIMD0. -config EXYNOS4_DEV_SYSMMU +config EXYNOS_DEV_SYSMMU bool help - Common setup code for SYSTEM MMU in EXYNOS4 + Common setup code for SYSTEM MMU in EXYNOS platforms config EXYNOS4_DEV_DWMCI bool @@ -161,7 +169,7 @@ config EXYNOS4_SETUP_USB_PHY help Common setup code for USB PHY controller -config EXYNOS4_SETUP_SPI +config EXYNOS_SETUP_SPI bool help Common setup code for SPI GPIO configurations. @@ -201,12 +209,12 @@ config MACH_SMDKV310 select S3C_DEV_HSMMC3 select SAMSUNG_DEV_BACKLIGHT select EXYNOS_DEV_DRM + select EXYNOS_DEV_SYSMMU select EXYNOS4_DEV_AHCI select SAMSUNG_DEV_KEYPAD - select EXYNOS4_DEV_DMA + select EXYNOS_DEV_DMA select SAMSUNG_DEV_PWM select EXYNOS4_DEV_USB_OHCI - select EXYNOS4_DEV_SYSMMU select EXYNOS4_SETUP_FIMD0 select EXYNOS4_SETUP_I2C1 select EXYNOS4_SETUP_KEYPAD @@ -224,8 +232,7 @@ config MACH_ARMLEX4210 select S3C_DEV_HSMMC2 select S3C_DEV_HSMMC3 select EXYNOS4_DEV_AHCI - select EXYNOS4_DEV_DMA - select EXYNOS4_DEV_SYSMMU + select EXYNOS_DEV_DMA select EXYNOS4_SETUP_SDHCI help Machine support for Samsung ARMLEX4210 based on EXYNOS4210 @@ -256,7 +263,8 @@ config MACH_UNIVERSAL_C210 select S5P_DEV_MFC select S5P_DEV_ONENAND select S5P_DEV_TV - select EXYNOS4_DEV_DMA + select EXYNOS_DEV_SYSMMU + select EXYNOS_DEV_DMA select EXYNOS_DEV_DRM select EXYNOS4_SETUP_FIMD0 select EXYNOS4_SETUP_I2C1 @@ -295,7 +303,7 @@ config MACH_NURI select S5P_DEV_MFC select S5P_DEV_USB_EHCI select S5P_SETUP_MIPIPHY - select EXYNOS4_DEV_DMA + select EXYNOS_DEV_DMA select EXYNOS_DEV_DRM select EXYNOS4_SETUP_FIMC select EXYNOS4_SETUP_FIMD0 @@ -332,7 +340,8 @@ config MACH_ORIGEN select SAMSUNG_DEV_BACKLIGHT select SAMSUNG_DEV_PWM select EXYNOS_DEV_DRM - select EXYNOS4_DEV_DMA + select EXYNOS_DEV_SYSMMU + select EXYNOS_DEV_DMA select EXYNOS4_DEV_USB_OHCI select EXYNOS4_SETUP_FIMD0 select EXYNOS4_SETUP_SDHCI @@ -360,7 +369,8 @@ config MACH_SMDK4212 select SAMSUNG_DEV_BACKLIGHT select SAMSUNG_DEV_KEYPAD select SAMSUNG_DEV_PWM - select EXYNOS4_DEV_DMA + select EXYNOS_DEV_SYSMMU + select EXYNOS_DEV_DMA select EXYNOS4_SETUP_I2C1 select EXYNOS4_SETUP_I2C3 select EXYNOS4_SETUP_I2C7 diff --git a/trunk/arch/arm/mach-exynos/Makefile b/trunk/arch/arm/mach-exynos/Makefile index 8631840d1b5e..9b58024f7d43 100644 --- a/trunk/arch/arm/mach-exynos/Makefile +++ b/trunk/arch/arm/mach-exynos/Makefile @@ -22,7 +22,7 @@ obj-$(CONFIG_PM) += pm.o obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o -obj-$(CONFIG_ARCH_EXYNOS4) += pmu.o +obj-$(CONFIG_ARCH_EXYNOS) += pmu.o obj-$(CONFIG_SMP) += platsmp.o headsmp.o @@ -50,10 +50,11 @@ obj-$(CONFIG_MACH_EXYNOS5_DT) += mach-exynos5-dt.o obj-y += dev-uart.o obj-$(CONFIG_ARCH_EXYNOS4) += dev-audio.o obj-$(CONFIG_EXYNOS4_DEV_AHCI) += dev-ahci.o -obj-$(CONFIG_EXYNOS4_DEV_SYSMMU) += dev-sysmmu.o obj-$(CONFIG_EXYNOS4_DEV_DWMCI) += dev-dwmci.o -obj-$(CONFIG_EXYNOS4_DEV_DMA) += dma.o +obj-$(CONFIG_EXYNOS_DEV_DMA) += dma.o obj-$(CONFIG_EXYNOS4_DEV_USB_OHCI) += dev-ohci.o +obj-$(CONFIG_EXYNOS_DEV_DRM) += dev-drm.o +obj-$(CONFIG_EXYNOS_DEV_SYSMMU) += dev-sysmmu.o obj-$(CONFIG_ARCH_EXYNOS) += setup-i2c0.o obj-$(CONFIG_EXYNOS4_SETUP_FIMC) += setup-fimc.o @@ -68,4 +69,4 @@ obj-$(CONFIG_EXYNOS4_SETUP_I2C7) += setup-i2c7.o obj-$(CONFIG_EXYNOS4_SETUP_KEYPAD) += setup-keypad.o obj-$(CONFIG_EXYNOS4_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o obj-$(CONFIG_EXYNOS4_SETUP_USB_PHY) += setup-usb-phy.o -obj-$(CONFIG_EXYNOS4_SETUP_SPI) += setup-spi.o +obj-$(CONFIG_EXYNOS_SETUP_SPI) += setup-spi.o diff --git a/trunk/arch/arm/mach-exynos/Makefile.boot b/trunk/arch/arm/mach-exynos/Makefile.boot index b9862e22bf10..31bd181b0514 100644 --- a/trunk/arch/arm/mach-exynos/Makefile.boot +++ b/trunk/arch/arm/mach-exynos/Makefile.boot @@ -1,2 +1,5 @@ zreladdr-y += 0x40008000 params_phys-y := 0x40000100 + +dtb-$(CONFIG_MACH_EXYNOS4_DT) += exynos4210-origen.dtb exynos4210-smdkv310.dtb +dtb-$(CONFIG_MACH_EXYNOS5_DT) += exynos5250-smdk5250.dtb diff --git a/trunk/arch/arm/mach-exynos/clock-exynos4.c b/trunk/arch/arm/mach-exynos/clock-exynos4.c index 6efd1e5919fd..bcb7db453145 100644 --- a/trunk/arch/arm/mach-exynos/clock-exynos4.c +++ b/trunk/arch/arm/mach-exynos/clock-exynos4.c @@ -168,7 +168,7 @@ static int exynos4_clk_ip_tv_ctrl(struct clk *clk, int enable) return s5p_gatectrl(EXYNOS4_CLKGATE_IP_TV, clk, enable); } -static int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable) +int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable) { return s5p_gatectrl(EXYNOS4_CLKGATE_IP_IMAGE, clk, enable); } @@ -198,6 +198,11 @@ 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); @@ -678,61 +683,55 @@ static struct clk exynos4_init_clocks_off[] = { .enable = exynos4_clk_ip_peril_ctrl, .ctrlbit = (1 << 14), }, { - .name = "SYSMMU_MDMA", + .name = SYSMMU_CLOCK_NAME, + .devname = SYSMMU_CLOCK_DEVNAME(mfc_l, 0), + .enable = exynos4_clk_ip_mfc_ctrl, + .ctrlbit = (1 << 1), + }, { + .name = SYSMMU_CLOCK_NAME, + .devname = SYSMMU_CLOCK_DEVNAME(mfc_r, 1), + .enable = exynos4_clk_ip_mfc_ctrl, + .ctrlbit = (1 << 2), + }, { + .name = SYSMMU_CLOCK_NAME, + .devname = SYSMMU_CLOCK_DEVNAME(tv, 2), + .enable = exynos4_clk_ip_tv_ctrl, + .ctrlbit = (1 << 4), + }, { + .name = SYSMMU_CLOCK_NAME, + .devname = SYSMMU_CLOCK_DEVNAME(jpeg, 3), + .enable = exynos4_clk_ip_cam_ctrl, + .ctrlbit = (1 << 11), + }, { + .name = SYSMMU_CLOCK_NAME, + .devname = SYSMMU_CLOCK_DEVNAME(rot, 4), .enable = exynos4_clk_ip_image_ctrl, - .ctrlbit = (1 << 5), + .ctrlbit = (1 << 4), }, { - .name = "SYSMMU_FIMC0", + .name = SYSMMU_CLOCK_NAME, + .devname = SYSMMU_CLOCK_DEVNAME(fimc0, 5), .enable = exynos4_clk_ip_cam_ctrl, .ctrlbit = (1 << 7), }, { - .name = "SYSMMU_FIMC1", + .name = SYSMMU_CLOCK_NAME, + .devname = SYSMMU_CLOCK_DEVNAME(fimc1, 6), .enable = exynos4_clk_ip_cam_ctrl, .ctrlbit = (1 << 8), }, { - .name = "SYSMMU_FIMC2", + .name = SYSMMU_CLOCK_NAME, + .devname = SYSMMU_CLOCK_DEVNAME(fimc2, 7), .enable = exynos4_clk_ip_cam_ctrl, .ctrlbit = (1 << 9), }, { - .name = "SYSMMU_FIMC3", + .name = SYSMMU_CLOCK_NAME, + .devname = SYSMMU_CLOCK_DEVNAME(fimc3, 8), .enable = exynos4_clk_ip_cam_ctrl, .ctrlbit = (1 << 10), }, { - .name = "SYSMMU_JPEG", - .enable = exynos4_clk_ip_cam_ctrl, - .ctrlbit = (1 << 11), - }, { - .name = "SYSMMU_FIMD0", + .name = SYSMMU_CLOCK_NAME, + .devname = SYSMMU_CLOCK_DEVNAME(fimd0, 10), .enable = exynos4_clk_ip_lcd0_ctrl, .ctrlbit = (1 << 4), - }, { - .name = "SYSMMU_FIMD1", - .enable = exynos4_clk_ip_lcd1_ctrl, - .ctrlbit = (1 << 4), - }, { - .name = "SYSMMU_PCIe", - .enable = exynos4_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 18), - }, { - .name = "SYSMMU_G2D", - .enable = exynos4_clk_ip_image_ctrl, - .ctrlbit = (1 << 3), - }, { - .name = "SYSMMU_ROTATOR", - .enable = exynos4_clk_ip_image_ctrl, - .ctrlbit = (1 << 4), - }, { - .name = "SYSMMU_TV", - .enable = exynos4_clk_ip_tv_ctrl, - .ctrlbit = (1 << 4), - }, { - .name = "SYSMMU_MFC_L", - .enable = exynos4_clk_ip_mfc_ctrl, - .ctrlbit = (1 << 1), - }, { - .name = "SYSMMU_MFC_R", - .enable = exynos4_clk_ip_mfc_ctrl, - .ctrlbit = (1 << 2), } }; diff --git a/trunk/arch/arm/mach-exynos/clock-exynos4.h b/trunk/arch/arm/mach-exynos/clock-exynos4.h index cb71c29c14d1..28a119701182 100644 --- a/trunk/arch/arm/mach-exynos/clock-exynos4.h +++ b/trunk/arch/arm/mach-exynos/clock-exynos4.h @@ -26,5 +26,7 @@ extern struct clk *exynos4_clkset_group_list[]; 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 index 3b131e4b6ef5..b8689ff60baf 100644 --- a/trunk/arch/arm/mach-exynos/clock-exynos4210.c +++ b/trunk/arch/arm/mach-exynos/clock-exynos4210.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "common.h" #include "clock-exynos4.h" @@ -94,6 +95,16 @@ static struct clk init_clocks_off[] = { .devname = "exynos4-fb.1", .enable = exynos4_clk_ip_lcd1_ctrl, .ctrlbit = (1 << 0), + }, { + .name = SYSMMU_CLOCK_NAME, + .devname = SYSMMU_CLOCK_DEVNAME(2d, 14), + .enable = exynos4_clk_ip_image_ctrl, + .ctrlbit = (1 << 3), + }, { + .name = SYSMMU_CLOCK_NAME, + .devname = SYSMMU_CLOCK_DEVNAME(fimd1, 11), + .enable = exynos4_clk_ip_lcd1_ctrl, + .ctrlbit = (1 << 4), }, }; diff --git a/trunk/arch/arm/mach-exynos/clock-exynos4212.c b/trunk/arch/arm/mach-exynos/clock-exynos4212.c index 3ecc01e06f74..da397d21bbcf 100644 --- a/trunk/arch/arm/mach-exynos/clock-exynos4212.c +++ b/trunk/arch/arm/mach-exynos/clock-exynos4212.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "common.h" #include "clock-exynos4.h" @@ -39,6 +40,16 @@ static struct sleep_save exynos4212_clock_save[] = { }; #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, @@ -66,7 +77,32 @@ static struct clksrc_clk clksrcs[] = { }; static struct clk init_clocks_off[] = { - /* nothing here yet */ + { + .name = SYSMMU_CLOCK_NAME, + .devname = SYSMMU_CLOCK_DEVNAME(2d, 14), + .enable = exynos4_clk_ip_dmc_ctrl, + .ctrlbit = (1 << 24), + }, { + .name = SYSMMU_CLOCK_NAME, + .devname = SYSMMU_CLOCK_DEVNAME(isp, 9), + .enable = exynos4212_clk_ip_isp0_ctrl, + .ctrlbit = (7 << 8), + }, { + .name = SYSMMU_CLOCK_NAME2, + .devname = SYSMMU_CLOCK_DEVNAME(isp, 9), + .enable = exynos4212_clk_ip_isp1_ctrl, + .ctrlbit = (1 << 4), + }, { + .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), + } }; #ifdef CONFIG_PM_SLEEP diff --git a/trunk/arch/arm/mach-exynos/clock-exynos5.c b/trunk/arch/arm/mach-exynos/clock-exynos5.c index 7ac6ff4c46bd..fefa336be2b4 100644 --- a/trunk/arch/arm/mach-exynos/clock-exynos5.c +++ b/trunk/arch/arm/mach-exynos/clock-exynos5.c @@ -30,7 +30,56 @@ #ifdef CONFIG_PM_SLEEP static struct sleep_save exynos5_clock_save[] = { - /* will be implemented */ + 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), }; #endif @@ -82,6 +131,11 @@ static int exynos5_clksrc_mask_peric0_ctrl(struct clk *clk, int enable) return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_PERIC0, 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); @@ -127,6 +181,21 @@ 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); +} + /* Core list of CMU_CPU side */ static struct clksrc_clk exynos5_clk_mout_apll = { @@ -145,11 +214,29 @@ static struct clksrc_clk exynos5_clk_sclk_apll = { .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 = &clk_src_bpll, + .sources = &exynos5_clk_src_bpll, .reg_src = { .reg = EXYNOS5_CLKSRC_CDREX, .shift = 0, .size = 1 }, }; @@ -187,11 +274,29 @@ static struct clksrc_clk exynos5_clk_mout_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), +}; + struct clksrc_clk exynos5_clk_mout_mpll = { .clk = { .name = "mout_mpll", }, - .sources = &clk_src_mpll, + .sources = &exynos5_clk_src_mpll, .reg_src = { .reg = EXYNOS5_CLKSRC_CORE1, .shift = 8, .size = 1 }, }; @@ -453,6 +558,11 @@ static struct clk exynos5_init_clocks_off[] = { .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 = "hsmmc", .devname = "exynos4-sdhci.0", @@ -630,6 +740,76 @@ static struct clk exynos5_init_clocks_off[] = { .parent = &exynos5_clk_aclk_66.clk, .enable = exynos5_clk_ip_peric_ctrl, .ctrlbit = (1 << 14), + }, { + .name = SYSMMU_CLOCK_NAME, + .devname = SYSMMU_CLOCK_DEVNAME(mfc_l, 0), + .enable = &exynos5_clk_ip_mfc_ctrl, + .ctrlbit = (1 << 1), + }, { + .name = SYSMMU_CLOCK_NAME, + .devname = SYSMMU_CLOCK_DEVNAME(mfc_r, 1), + .enable = &exynos5_clk_ip_mfc_ctrl, + .ctrlbit = (1 << 2), + }, { + .name = SYSMMU_CLOCK_NAME, + .devname = SYSMMU_CLOCK_DEVNAME(tv, 2), + .enable = &exynos5_clk_ip_disp1_ctrl, + .ctrlbit = (1 << 9) + }, { + .name = SYSMMU_CLOCK_NAME, + .devname = SYSMMU_CLOCK_DEVNAME(jpeg, 3), + .enable = &exynos5_clk_ip_gen_ctrl, + .ctrlbit = (1 << 7), + }, { + .name = SYSMMU_CLOCK_NAME, + .devname = SYSMMU_CLOCK_DEVNAME(rot, 4), + .enable = &exynos5_clk_ip_gen_ctrl, + .ctrlbit = (1 << 6) + }, { + .name = SYSMMU_CLOCK_NAME, + .devname = SYSMMU_CLOCK_DEVNAME(gsc0, 5), + .enable = &exynos5_clk_ip_gscl_ctrl, + .ctrlbit = (1 << 7), + }, { + .name = SYSMMU_CLOCK_NAME, + .devname = SYSMMU_CLOCK_DEVNAME(gsc1, 6), + .enable = &exynos5_clk_ip_gscl_ctrl, + .ctrlbit = (1 << 8), + }, { + .name = SYSMMU_CLOCK_NAME, + .devname = SYSMMU_CLOCK_DEVNAME(gsc2, 7), + .enable = &exynos5_clk_ip_gscl_ctrl, + .ctrlbit = (1 << 9), + }, { + .name = SYSMMU_CLOCK_NAME, + .devname = SYSMMU_CLOCK_DEVNAME(gsc3, 8), + .enable = &exynos5_clk_ip_gscl_ctrl, + .ctrlbit = (1 << 10), + }, { + .name = SYSMMU_CLOCK_NAME, + .devname = SYSMMU_CLOCK_DEVNAME(isp, 9), + .enable = &exynos5_clk_ip_isp0_ctrl, + .ctrlbit = (0x3F << 8), + }, { + .name = SYSMMU_CLOCK_NAME2, + .devname = SYSMMU_CLOCK_DEVNAME(isp, 9), + .enable = &exynos5_clk_ip_isp1_ctrl, + .ctrlbit = (0xF << 4), + }, { + .name = SYSMMU_CLOCK_NAME, + .devname = SYSMMU_CLOCK_DEVNAME(camif0, 12), + .enable = &exynos5_clk_ip_gscl_ctrl, + .ctrlbit = (1 << 11), + }, { + .name = SYSMMU_CLOCK_NAME, + .devname = SYSMMU_CLOCK_DEVNAME(camif1, 13), + .enable = &exynos5_clk_ip_gscl_ctrl, + .ctrlbit = (1 << 12), + }, { + .name = SYSMMU_CLOCK_NAME, + .devname = SYSMMU_CLOCK_DEVNAME(2d, 14), + .enable = &exynos5_clk_ip_acp_ctrl, + .ctrlbit = (1 << 7) } }; @@ -941,10 +1121,12 @@ 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, @@ -1008,7 +1190,9 @@ 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, }; @@ -1173,8 +1357,10 @@ void __init_or_cpufreq exynos5_setup_clocks(void) 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; diff --git a/trunk/arch/arm/mach-exynos/common.c b/trunk/arch/arm/mach-exynos/common.c index 5ccd6e80a607..742edd3bbec3 100644 --- a/trunk/arch/arm/mach-exynos/common.c +++ b/trunk/arch/arm/mach-exynos/common.c @@ -19,6 +19,9 @@ #include #include #include +#include +#include +#include #include #include @@ -265,12 +268,12 @@ static struct map_desc exynos5_iodesc[] __initdata = { }, { .virtual = (unsigned long)S5P_VA_GIC_CPU, .pfn = __phys_to_pfn(EXYNOS5_PA_GIC_CPU), - .length = SZ_64K, + .length = SZ_8K, .type = MT_DEVICE, }, { .virtual = (unsigned long)S5P_VA_GIC_DIST, .pfn = __phys_to_pfn(EXYNOS5_PA_GIC_DIST), - .length = SZ_64K, + .length = SZ_4K, .type = MT_DEVICE, }, }; @@ -285,6 +288,11 @@ void exynos5_restart(char mode, const char *cmd) __raw_writel(0x1, EXYNOS_SWRESET); } +void __init exynos_init_late(void) +{ + exynos_pm_late_initcall(); +} + /* * exynos_map_io * @@ -399,6 +407,7 @@ struct combiner_chip_data { void __iomem *base; }; +static struct irq_domain *combiner_irq_domain; static struct combiner_chip_data combiner_data[MAX_COMBINER_NR]; static inline void __iomem *combiner_base(struct irq_data *data) @@ -411,14 +420,14 @@ static inline void __iomem *combiner_base(struct irq_data *data) static void combiner_mask_irq(struct irq_data *data) { - u32 mask = 1 << (data->irq % 32); + u32 mask = 1 << (data->hwirq % 32); __raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_CLEAR); } static void combiner_unmask_irq(struct irq_data *data) { - u32 mask = 1 << (data->irq % 32); + u32 mask = 1 << (data->hwirq % 32); __raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_SET); } @@ -474,49 +483,131 @@ static void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int i irq_set_chained_handler(irq, combiner_handle_cascade_irq); } -static void __init combiner_init(unsigned int combiner_nr, void __iomem *base, - unsigned int irq_start) +static void __init combiner_init_one(unsigned int combiner_nr, + void __iomem *base) { - unsigned int i; - unsigned int max_nr; - - if (soc_is_exynos5250()) - max_nr = EXYNOS5_MAX_COMBINER_NR; - else - max_nr = EXYNOS4_MAX_COMBINER_NR; - - if (combiner_nr >= max_nr) - BUG(); - combiner_data[combiner_nr].base = base; - combiner_data[combiner_nr].irq_offset = irq_start; + combiner_data[combiner_nr].irq_offset = irq_find_mapping( + combiner_irq_domain, combiner_nr * MAX_IRQ_IN_COMBINER); combiner_data[combiner_nr].irq_mask = 0xff << ((combiner_nr % 4) << 3); /* Disable all interrupts */ - __raw_writel(combiner_data[combiner_nr].irq_mask, base + COMBINER_ENABLE_CLEAR); +} + +#ifdef CONFIG_OF +static int combiner_irq_domain_xlate(struct irq_domain *d, + struct device_node *controller, + const u32 *intspec, unsigned int intsize, + unsigned long *out_hwirq, + unsigned int *out_type) +{ + if (d->of_node != controller) + return -EINVAL; + + if (intsize < 2) + return -EINVAL; + + *out_hwirq = intspec[0] * MAX_IRQ_IN_COMBINER + intspec[1]; + *out_type = 0; + + return 0; +} +#else +static int combiner_irq_domain_xlate(struct irq_domain *d, + struct device_node *controller, + const u32 *intspec, unsigned int intsize, + unsigned long *out_hwirq, + unsigned int *out_type) +{ + return -EINVAL; +} +#endif + +static int combiner_irq_domain_map(struct irq_domain *d, unsigned int irq, + irq_hw_number_t hw) +{ + irq_set_chip_and_handler(irq, &combiner_chip, handle_level_irq); + irq_set_chip_data(irq, &combiner_data[hw >> 3]); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + + return 0; +} + +static struct irq_domain_ops combiner_irq_domain_ops = { + .xlate = combiner_irq_domain_xlate, + .map = combiner_irq_domain_map, +}; + +void __init combiner_init(void __iomem *combiner_base, struct device_node *np) +{ + int i, irq, irq_base; + unsigned int max_nr, nr_irq; + + if (np) { + if (of_property_read_u32(np, "samsung,combiner-nr", &max_nr)) { + pr_warning("%s: number of combiners not specified, " + "setting default as %d.\n", + __func__, EXYNOS4_MAX_COMBINER_NR); + max_nr = EXYNOS4_MAX_COMBINER_NR; + } + } else { + max_nr = soc_is_exynos5250() ? EXYNOS5_MAX_COMBINER_NR : + EXYNOS4_MAX_COMBINER_NR; + } + nr_irq = max_nr * MAX_IRQ_IN_COMBINER; - /* Setup the Linux IRQ subsystem */ + irq_base = irq_alloc_descs(COMBINER_IRQ(0, 0), 1, nr_irq, 0); + if (IS_ERR_VALUE(irq_base)) { + irq_base = COMBINER_IRQ(0, 0); + pr_warning("%s: irq desc alloc failed. Continuing with %d as linux irq base\n", __func__, irq_base); + } - for (i = irq_start; i < combiner_data[combiner_nr].irq_offset - + MAX_IRQ_IN_COMBINER; i++) { - irq_set_chip_and_handler(i, &combiner_chip, handle_level_irq); - irq_set_chip_data(i, &combiner_data[combiner_nr]); - set_irq_flags(i, IRQF_VALID | IRQF_PROBE); + combiner_irq_domain = irq_domain_add_legacy(np, nr_irq, irq_base, 0, + &combiner_irq_domain_ops, &combiner_data); + if (WARN_ON(!combiner_irq_domain)) { + pr_warning("%s: irq domain init failed\n", __func__); + return; + } + + for (i = 0; i < max_nr; i++) { + combiner_init_one(i, combiner_base + (i >> 2) * 0x10); + irq = IRQ_SPI(i); +#ifdef CONFIG_OF + if (np) + irq = irq_of_parse_and_map(np, i); +#endif + combiner_cascade_irq(i, irq); } } #ifdef CONFIG_OF +int __init combiner_of_init(struct device_node *np, struct device_node *parent) +{ + void __iomem *combiner_base; + + combiner_base = of_iomap(np, 0); + if (!combiner_base) { + pr_err("%s: failed to map combiner registers\n", __func__); + return -ENXIO; + } + + combiner_init(combiner_base, np); + + return 0; +} + static const struct of_device_id exynos4_dt_irq_match[] = { { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, }, + { .compatible = "samsung,exynos4210-combiner", + .data = combiner_of_init, }, {}, }; #endif void __init exynos4_init_irq(void) { - int irq; unsigned int gic_bank_offset; gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000; @@ -528,12 +619,8 @@ void __init exynos4_init_irq(void) of_irq_init(exynos4_dt_irq_match); #endif - for (irq = 0; irq < EXYNOS4_MAX_COMBINER_NR; irq++) { - - combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq), - COMBINER_IRQ(irq, 0)); - combiner_cascade_irq(irq, IRQ_SPI(irq)); - } + if (!of_have_populated_dt()) + combiner_init(S5P_VA_COMBINER_BASE, NULL); /* * The parameters of s5p_init_irq() are for VIC init. @@ -545,18 +632,9 @@ void __init exynos4_init_irq(void) void __init exynos5_init_irq(void) { - int irq; - #ifdef CONFIG_OF of_irq_init(exynos4_dt_irq_match); #endif - - for (irq = 0; irq < EXYNOS5_MAX_COMBINER_NR; irq++) { - combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq), - COMBINER_IRQ(irq, 0)); - combiner_cascade_irq(irq, IRQ_SPI(irq)); - } - /* * The parameters of s5p_init_irq() are for VIC init. * Theses parameters should be NULL and 0 because EXYNOS4 @@ -565,30 +643,18 @@ void __init exynos5_init_irq(void) s5p_init_irq(NULL, 0); } -struct bus_type exynos4_subsys = { - .name = "exynos4-core", - .dev_name = "exynos4-core", -}; - -struct bus_type exynos5_subsys = { - .name = "exynos5-core", - .dev_name = "exynos5-core", +struct bus_type exynos_subsys = { + .name = "exynos-core", + .dev_name = "exynos-core", }; static struct device exynos4_dev = { - .bus = &exynos4_subsys, -}; - -static struct device exynos5_dev = { - .bus = &exynos5_subsys, + .bus = &exynos_subsys, }; static int __init exynos_core_init(void) { - if (soc_is_exynos5250()) - return subsys_system_register(&exynos5_subsys, NULL); - else - return subsys_system_register(&exynos4_subsys, NULL); + return subsys_system_register(&exynos_subsys, NULL); } core_initcall(exynos_core_init); @@ -675,10 +741,7 @@ static int __init exynos_init(void) { printk(KERN_INFO "EXYNOS: Initializing architecture\n"); - if (soc_is_exynos5250()) - return device_register(&exynos5_dev); - else - return device_register(&exynos4_dev); + return device_register(&exynos4_dev); } /* uart registration process */ diff --git a/trunk/arch/arm/mach-exynos/common.h b/trunk/arch/arm/mach-exynos/common.h index 677b5467df18..aed2eeb06517 100644 --- a/trunk/arch/arm/mach-exynos/common.h +++ b/trunk/arch/arm/mach-exynos/common.h @@ -19,6 +19,13 @@ void exynos4_init_irq(void); void exynos5_init_irq(void); void exynos4_restart(char mode, const char *cmd); void exynos5_restart(char mode, const char *cmd); +void exynos_init_late(void); + +#ifdef CONFIG_PM_GENERIC_DOMAINS +int exynos_pm_late_initcall(void); +#else +static int exynos_pm_late_initcall(void) { return 0; } +#endif #ifdef CONFIG_ARCH_EXYNOS4 void exynos4_register_clocks(void); diff --git a/trunk/arch/arm/mach-exynos/cpuidle.c b/trunk/arch/arm/mach-exynos/cpuidle.c index 26dac2893b8e..cff0595d0d35 100644 --- a/trunk/arch/arm/mach-exynos/cpuidle.c +++ b/trunk/arch/arm/mach-exynos/cpuidle.c @@ -100,7 +100,7 @@ static int exynos4_enter_core0_aftr(struct cpuidle_device *dev, exynos4_set_wakeupmask(); /* Set value of power down register for aftr mode */ - exynos4_sys_powerdown_conf(SYS_AFTR); + exynos_sys_powerdown_conf(SYS_AFTR); __raw_writel(virt_to_phys(s3c_cpu_resume), REG_DIRECTGO_ADDR); __raw_writel(S5P_CHECK_AFTR, REG_DIRECTGO_FLAG); diff --git a/trunk/arch/arm/mach-exynos/dev-drm.c b/trunk/arch/arm/mach-exynos/dev-drm.c new file mode 100644 index 000000000000..17c9c6ecc2e0 --- /dev/null +++ b/trunk/arch/arm/mach-exynos/dev-drm.c @@ -0,0 +1,29 @@ +/* + * linux/arch/arm/mach-exynos/dev-drm.c + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * EXYNOS - core DRM device + * + * 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 + +static u64 exynos_drm_dma_mask = DMA_BIT_MASK(32); + +struct platform_device exynos_device_drm = { + .name = "exynos-drm", + .dev = { + .dma_mask = &exynos_drm_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + } +}; diff --git a/trunk/arch/arm/mach-exynos/dev-sysmmu.c b/trunk/arch/arm/mach-exynos/dev-sysmmu.c index 781563fcb156..c5b1ea301df0 100644 --- a/trunk/arch/arm/mach-exynos/dev-sysmmu.c +++ b/trunk/arch/arm/mach-exynos/dev-sysmmu.c @@ -1,9 +1,9 @@ -/* linux/arch/arm/mach-exynos4/dev-sysmmu.c +/* linux/arch/arm/mach-exynos/dev-sysmmu.c * - * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd. * http://www.samsung.com * - * EXYNOS4 - System MMU support + * EXYNOS - System MMU 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 @@ -12,222 +12,263 @@ #include #include -#include + +#include #include #include #include -#include - -/* These names must be equal to the clock names in mach-exynos4/clock.c */ -const char *sysmmu_ips_name[EXYNOS4_SYSMMU_TOTAL_IPNUM] = { - "SYSMMU_MDMA" , - "SYSMMU_SSS" , - "SYSMMU_FIMC0" , - "SYSMMU_FIMC1" , - "SYSMMU_FIMC2" , - "SYSMMU_FIMC3" , - "SYSMMU_JPEG" , - "SYSMMU_FIMD0" , - "SYSMMU_FIMD1" , - "SYSMMU_PCIe" , - "SYSMMU_G2D" , - "SYSMMU_ROTATOR", - "SYSMMU_MDMA2" , - "SYSMMU_TV" , - "SYSMMU_MFC_L" , - "SYSMMU_MFC_R" , -}; -static struct resource exynos4_sysmmu_resource[] = { - [0] = { - .start = EXYNOS4_PA_SYSMMU_MDMA, - .end = EXYNOS4_PA_SYSMMU_MDMA + SZ_64K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_SYSMMU_MDMA0_0, - .end = IRQ_SYSMMU_MDMA0_0, - .flags = IORESOURCE_IRQ, - }, - [2] = { - .start = EXYNOS4_PA_SYSMMU_SSS, - .end = EXYNOS4_PA_SYSMMU_SSS + SZ_64K - 1, - .flags = IORESOURCE_MEM, - }, - [3] = { - .start = IRQ_SYSMMU_SSS_0, - .end = IRQ_SYSMMU_SSS_0, - .flags = IORESOURCE_IRQ, - }, - [4] = { - .start = EXYNOS4_PA_SYSMMU_FIMC0, - .end = EXYNOS4_PA_SYSMMU_FIMC0 + SZ_64K - 1, - .flags = IORESOURCE_MEM, - }, - [5] = { - .start = IRQ_SYSMMU_FIMC0_0, - .end = IRQ_SYSMMU_FIMC0_0, - .flags = IORESOURCE_IRQ, - }, - [6] = { - .start = EXYNOS4_PA_SYSMMU_FIMC1, - .end = EXYNOS4_PA_SYSMMU_FIMC1 + SZ_64K - 1, - .flags = IORESOURCE_MEM, - }, - [7] = { - .start = IRQ_SYSMMU_FIMC1_0, - .end = IRQ_SYSMMU_FIMC1_0, - .flags = IORESOURCE_IRQ, - }, - [8] = { - .start = EXYNOS4_PA_SYSMMU_FIMC2, - .end = EXYNOS4_PA_SYSMMU_FIMC2 + SZ_64K - 1, - .flags = IORESOURCE_MEM, - }, - [9] = { - .start = IRQ_SYSMMU_FIMC2_0, - .end = IRQ_SYSMMU_FIMC2_0, - .flags = IORESOURCE_IRQ, - }, - [10] = { - .start = EXYNOS4_PA_SYSMMU_FIMC3, - .end = EXYNOS4_PA_SYSMMU_FIMC3 + SZ_64K - 1, - .flags = IORESOURCE_MEM, - }, - [11] = { - .start = IRQ_SYSMMU_FIMC3_0, - .end = IRQ_SYSMMU_FIMC3_0, - .flags = IORESOURCE_IRQ, - }, - [12] = { - .start = EXYNOS4_PA_SYSMMU_JPEG, - .end = EXYNOS4_PA_SYSMMU_JPEG + SZ_64K - 1, - .flags = IORESOURCE_MEM, - }, - [13] = { - .start = IRQ_SYSMMU_JPEG_0, - .end = IRQ_SYSMMU_JPEG_0, - .flags = IORESOURCE_IRQ, - }, - [14] = { - .start = EXYNOS4_PA_SYSMMU_FIMD0, - .end = EXYNOS4_PA_SYSMMU_FIMD0 + SZ_64K - 1, - .flags = IORESOURCE_MEM, - }, - [15] = { - .start = IRQ_SYSMMU_LCD0_M0_0, - .end = IRQ_SYSMMU_LCD0_M0_0, - .flags = IORESOURCE_IRQ, - }, - [16] = { - .start = EXYNOS4_PA_SYSMMU_FIMD1, - .end = EXYNOS4_PA_SYSMMU_FIMD1 + SZ_64K - 1, - .flags = IORESOURCE_MEM, - }, - [17] = { - .start = IRQ_SYSMMU_LCD1_M1_0, - .end = IRQ_SYSMMU_LCD1_M1_0, - .flags = IORESOURCE_IRQ, - }, - [18] = { - .start = EXYNOS4_PA_SYSMMU_PCIe, - .end = EXYNOS4_PA_SYSMMU_PCIe + SZ_64K - 1, - .flags = IORESOURCE_MEM, - }, - [19] = { - .start = IRQ_SYSMMU_PCIE_0, - .end = IRQ_SYSMMU_PCIE_0, - .flags = IORESOURCE_IRQ, - }, - [20] = { - .start = EXYNOS4_PA_SYSMMU_G2D, - .end = EXYNOS4_PA_SYSMMU_G2D + SZ_64K - 1, - .flags = IORESOURCE_MEM, - }, - [21] = { - .start = IRQ_SYSMMU_2D_0, - .end = IRQ_SYSMMU_2D_0, - .flags = IORESOURCE_IRQ, - }, - [22] = { - .start = EXYNOS4_PA_SYSMMU_ROTATOR, - .end = EXYNOS4_PA_SYSMMU_ROTATOR + SZ_64K - 1, - .flags = IORESOURCE_MEM, - }, - [23] = { - .start = IRQ_SYSMMU_ROTATOR_0, - .end = IRQ_SYSMMU_ROTATOR_0, - .flags = IORESOURCE_IRQ, - }, - [24] = { - .start = EXYNOS4_PA_SYSMMU_MDMA2, - .end = EXYNOS4_PA_SYSMMU_MDMA2 + SZ_64K - 1, - .flags = IORESOURCE_MEM, - }, - [25] = { - .start = IRQ_SYSMMU_MDMA1_0, - .end = IRQ_SYSMMU_MDMA1_0, - .flags = IORESOURCE_IRQ, - }, - [26] = { - .start = EXYNOS4_PA_SYSMMU_TV, - .end = EXYNOS4_PA_SYSMMU_TV + SZ_64K - 1, - .flags = IORESOURCE_MEM, - }, - [27] = { - .start = IRQ_SYSMMU_TV_M0_0, - .end = IRQ_SYSMMU_TV_M0_0, - .flags = IORESOURCE_IRQ, - }, - [28] = { - .start = EXYNOS4_PA_SYSMMU_MFC_L, - .end = EXYNOS4_PA_SYSMMU_MFC_L + SZ_64K - 1, - .flags = IORESOURCE_MEM, - }, - [29] = { - .start = IRQ_SYSMMU_MFC_M0_0, - .end = IRQ_SYSMMU_MFC_M0_0, - .flags = IORESOURCE_IRQ, - }, - [30] = { - .start = EXYNOS4_PA_SYSMMU_MFC_R, - .end = EXYNOS4_PA_SYSMMU_MFC_R + SZ_64K - 1, - .flags = IORESOURCE_MEM, - }, - [31] = { - .start = IRQ_SYSMMU_MFC_M1_0, - .end = IRQ_SYSMMU_MFC_M1_0, - .flags = IORESOURCE_IRQ, - }, -}; +static u64 exynos_sysmmu_dma_mask = DMA_BIT_MASK(32); + +#define SYSMMU_PLATFORM_DEVICE(ipname, devid) \ +static struct sysmmu_platform_data platdata_##ipname = { \ + .dbgname = #ipname, \ +}; \ +struct platform_device SYSMMU_PLATDEV(ipname) = \ +{ \ + .name = SYSMMU_DEVNAME_BASE, \ + .id = devid, \ + .dev = { \ + .dma_mask = &exynos_sysmmu_dma_mask, \ + .coherent_dma_mask = DMA_BIT_MASK(32), \ + .platform_data = &platdata_##ipname, \ + }, \ +} + +SYSMMU_PLATFORM_DEVICE(mfc_l, 0); +SYSMMU_PLATFORM_DEVICE(mfc_r, 1); +SYSMMU_PLATFORM_DEVICE(tv, 2); +SYSMMU_PLATFORM_DEVICE(jpeg, 3); +SYSMMU_PLATFORM_DEVICE(rot, 4); +SYSMMU_PLATFORM_DEVICE(fimc0, 5); /* fimc* and gsc* exist exclusively */ +SYSMMU_PLATFORM_DEVICE(fimc1, 6); +SYSMMU_PLATFORM_DEVICE(fimc2, 7); +SYSMMU_PLATFORM_DEVICE(fimc3, 8); +SYSMMU_PLATFORM_DEVICE(gsc0, 5); +SYSMMU_PLATFORM_DEVICE(gsc1, 6); +SYSMMU_PLATFORM_DEVICE(gsc2, 7); +SYSMMU_PLATFORM_DEVICE(gsc3, 8); +SYSMMU_PLATFORM_DEVICE(isp, 9); +SYSMMU_PLATFORM_DEVICE(fimd0, 10); +SYSMMU_PLATFORM_DEVICE(fimd1, 11); +SYSMMU_PLATFORM_DEVICE(camif0, 12); +SYSMMU_PLATFORM_DEVICE(camif1, 13); +SYSMMU_PLATFORM_DEVICE(2d, 14); + +#define SYSMMU_RESOURCE_NAME(core, ipname) sysmmures_##core##_##ipname + +#define SYSMMU_RESOURCE(core, ipname) \ + static struct resource SYSMMU_RESOURCE_NAME(core, ipname)[] __initdata = + +#define DEFINE_SYSMMU_RESOURCE(core, mem, irq) \ + DEFINE_RES_MEM_NAMED(core##_PA_SYSMMU_##mem, SZ_4K, #mem), \ + DEFINE_RES_IRQ_NAMED(core##_IRQ_SYSMMU_##irq##_0, #mem) + +#define SYSMMU_RESOURCE_DEFINE(core, ipname, mem, irq) \ + SYSMMU_RESOURCE(core, ipname) { \ + DEFINE_SYSMMU_RESOURCE(core, mem, irq) \ + } -struct platform_device exynos4_device_sysmmu = { - .name = "s5p-sysmmu", - .id = 32, - .num_resources = ARRAY_SIZE(exynos4_sysmmu_resource), - .resource = exynos4_sysmmu_resource, +struct sysmmu_resource_map { + struct platform_device *pdev; + struct resource *res; + u32 rnum; + struct device *pdd; + char *clocknames; }; -EXPORT_SYMBOL(exynos4_device_sysmmu); -static struct clk *sysmmu_clk[S5P_SYSMMU_TOTAL_IPNUM]; -void sysmmu_clk_init(struct device *dev, sysmmu_ips ips) -{ - sysmmu_clk[ips] = clk_get(dev, sysmmu_ips_name[ips]); - if (IS_ERR(sysmmu_clk[ips])) - sysmmu_clk[ips] = NULL; - else - clk_put(sysmmu_clk[ips]); +#define SYSMMU_RESOURCE_MAPPING(core, ipname, resname) { \ + .pdev = &SYSMMU_PLATDEV(ipname), \ + .res = SYSMMU_RESOURCE_NAME(EXYNOS##core, resname), \ + .rnum = ARRAY_SIZE(SYSMMU_RESOURCE_NAME(EXYNOS##core, resname)),\ + .clocknames = SYSMMU_CLOCK_NAME, \ } -void sysmmu_clk_enable(sysmmu_ips ips) -{ - if (sysmmu_clk[ips]) - clk_enable(sysmmu_clk[ips]); +#define SYSMMU_RESOURCE_MAPPING_MC(core, ipname, resname, pdata) { \ + .pdev = &SYSMMU_PLATDEV(ipname), \ + .res = SYSMMU_RESOURCE_NAME(EXYNOS##core, resname), \ + .rnum = ARRAY_SIZE(SYSMMU_RESOURCE_NAME(EXYNOS##core, resname)),\ + .clocknames = SYSMMU_CLOCK_NAME "," SYSMMU_CLOCK_NAME2, \ +} + +#ifdef CONFIG_EXYNOS_DEV_PD +#define SYSMMU_RESOURCE_MAPPING_PD(core, ipname, resname, pd) { \ + .pdev = &SYSMMU_PLATDEV(ipname), \ + .res = &SYSMMU_RESOURCE_NAME(EXYNOS##core, resname), \ + .rnum = ARRAY_SIZE(SYSMMU_RESOURCE_NAME(EXYNOS##core, resname)),\ + .clocknames = SYSMMU_CLOCK_NAME, \ + .pdd = &exynos##core##_device_pd[pd].dev, \ +} + +#define SYSMMU_RESOURCE_MAPPING_MCPD(core, ipname, resname, pd, pdata) {\ + .pdev = &SYSMMU_PLATDEV(ipname), \ + .res = &SYSMMU_RESOURCE_NAME(EXYNOS##core, resname), \ + .rnum = ARRAY_SIZE(SYSMMU_RESOURCE_NAME(EXYNOS##core, resname)),\ + .clocknames = SYSMMU_CLOCK_NAME "," SYSMMU_CLOCK_NAME2, \ + .pdd = &exynos##core##_device_pd[pd].dev, \ } +#else +#define SYSMMU_RESOURCE_MAPPING_PD(core, ipname, resname, pd) \ + SYSMMU_RESOURCE_MAPPING(core, ipname, resname) +#define SYSMMU_RESOURCE_MAPPING_MCPD(core, ipname, resname, pd, pdata) \ + SYSMMU_RESOURCE_MAPPING_MC(core, ipname, resname, pdata) + +#endif /* CONFIG_EXYNOS_DEV_PD */ + +#ifdef CONFIG_ARCH_EXYNOS4 +SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimc0, FIMC0, FIMC0); +SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimc1, FIMC1, FIMC1); +SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimc2, FIMC2, FIMC2); +SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimc3, FIMC3, FIMC3); +SYSMMU_RESOURCE_DEFINE(EXYNOS4, jpeg, JPEG, JPEG); +SYSMMU_RESOURCE_DEFINE(EXYNOS4, 2d, G2D, 2D); +SYSMMU_RESOURCE_DEFINE(EXYNOS4, tv, TV, TV_M0); +SYSMMU_RESOURCE_DEFINE(EXYNOS4, 2d_acp, 2D_ACP, 2D); +SYSMMU_RESOURCE_DEFINE(EXYNOS4, rot, ROTATOR, ROTATOR); +SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimd0, FIMD0, LCD0_M0); +SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimd1, FIMD1, LCD1_M1); +SYSMMU_RESOURCE_DEFINE(EXYNOS4, flite0, FIMC_LITE0, FIMC_LITE0); +SYSMMU_RESOURCE_DEFINE(EXYNOS4, flite1, FIMC_LITE1, FIMC_LITE1); +SYSMMU_RESOURCE_DEFINE(EXYNOS4, mfc_r, MFC_R, MFC_M0); +SYSMMU_RESOURCE_DEFINE(EXYNOS4, mfc_l, MFC_L, MFC_M1); +SYSMMU_RESOURCE(EXYNOS4, isp) { + DEFINE_SYSMMU_RESOURCE(EXYNOS4, FIMC_ISP, FIMC_ISP), + DEFINE_SYSMMU_RESOURCE(EXYNOS4, FIMC_DRC, FIMC_DRC), + DEFINE_SYSMMU_RESOURCE(EXYNOS4, FIMC_FD, FIMC_FD), + DEFINE_SYSMMU_RESOURCE(EXYNOS4, ISPCPU, FIMC_CX), +}; + +static struct sysmmu_resource_map sysmmu_resmap4[] __initdata = { + SYSMMU_RESOURCE_MAPPING_PD(4, fimc0, fimc0, PD_CAM), + SYSMMU_RESOURCE_MAPPING_PD(4, fimc1, fimc1, PD_CAM), + SYSMMU_RESOURCE_MAPPING_PD(4, fimc2, fimc2, PD_CAM), + SYSMMU_RESOURCE_MAPPING_PD(4, fimc3, fimc3, PD_CAM), + SYSMMU_RESOURCE_MAPPING_PD(4, tv, tv, PD_TV), + SYSMMU_RESOURCE_MAPPING_PD(4, mfc_r, mfc_r, PD_MFC), + SYSMMU_RESOURCE_MAPPING_PD(4, mfc_l, mfc_l, PD_MFC), + SYSMMU_RESOURCE_MAPPING_PD(4, rot, rot, PD_LCD0), + SYSMMU_RESOURCE_MAPPING_PD(4, jpeg, jpeg, PD_CAM), + SYSMMU_RESOURCE_MAPPING_PD(4, fimd0, fimd0, PD_LCD0), +}; + +static struct sysmmu_resource_map sysmmu_resmap4210[] __initdata = { + SYSMMU_RESOURCE_MAPPING_PD(4, 2d, 2d, PD_LCD0), + SYSMMU_RESOURCE_MAPPING_PD(4, fimd1, fimd1, PD_LCD1), +}; + +static struct sysmmu_resource_map sysmmu_resmap4212[] __initdata = { + SYSMMU_RESOURCE_MAPPING(4, 2d, 2d_acp), + SYSMMU_RESOURCE_MAPPING_PD(4, camif0, flite0, PD_ISP), + SYSMMU_RESOURCE_MAPPING_PD(4, camif1, flite1, PD_ISP), + SYSMMU_RESOURCE_MAPPING_PD(4, isp, isp, PD_ISP), +}; +#endif /* CONFIG_ARCH_EXYNOS4 */ -void sysmmu_clk_disable(sysmmu_ips ips) +#ifdef CONFIG_ARCH_EXYNOS5 +SYSMMU_RESOURCE_DEFINE(EXYNOS5, jpeg, JPEG, JPEG); +SYSMMU_RESOURCE_DEFINE(EXYNOS5, fimd1, FIMD1, FIMD1); +SYSMMU_RESOURCE_DEFINE(EXYNOS5, 2d, 2D, 2D); +SYSMMU_RESOURCE_DEFINE(EXYNOS5, rot, ROTATOR, ROTATOR); +SYSMMU_RESOURCE_DEFINE(EXYNOS5, tv, TV, TV); +SYSMMU_RESOURCE_DEFINE(EXYNOS5, flite0, LITE0, LITE0); +SYSMMU_RESOURCE_DEFINE(EXYNOS5, flite1, LITE1, LITE1); +SYSMMU_RESOURCE_DEFINE(EXYNOS5, gsc0, GSC0, GSC0); +SYSMMU_RESOURCE_DEFINE(EXYNOS5, gsc1, GSC1, GSC1); +SYSMMU_RESOURCE_DEFINE(EXYNOS5, gsc2, GSC2, GSC2); +SYSMMU_RESOURCE_DEFINE(EXYNOS5, gsc3, GSC3, GSC3); +SYSMMU_RESOURCE_DEFINE(EXYNOS5, mfc_r, MFC_R, MFC_R); +SYSMMU_RESOURCE_DEFINE(EXYNOS5, mfc_l, MFC_L, MFC_L); +SYSMMU_RESOURCE(EXYNOS5, isp) { + DEFINE_SYSMMU_RESOURCE(EXYNOS5, ISP, ISP), + DEFINE_SYSMMU_RESOURCE(EXYNOS5, DRC, DRC), + DEFINE_SYSMMU_RESOURCE(EXYNOS5, FD, FD), + DEFINE_SYSMMU_RESOURCE(EXYNOS5, ISPCPU, MCUISP), + DEFINE_SYSMMU_RESOURCE(EXYNOS5, SCALERC, SCALERCISP), + DEFINE_SYSMMU_RESOURCE(EXYNOS5, SCALERP, SCALERPISP), + DEFINE_SYSMMU_RESOURCE(EXYNOS5, ODC, ODC), + DEFINE_SYSMMU_RESOURCE(EXYNOS5, DIS0, DIS0), + DEFINE_SYSMMU_RESOURCE(EXYNOS5, DIS1, DIS1), + DEFINE_SYSMMU_RESOURCE(EXYNOS5, 3DNR, 3DNR), +}; + +static struct sysmmu_resource_map sysmmu_resmap5[] __initdata = { + SYSMMU_RESOURCE_MAPPING(5, jpeg, jpeg), + SYSMMU_RESOURCE_MAPPING(5, fimd1, fimd1), + SYSMMU_RESOURCE_MAPPING(5, 2d, 2d), + SYSMMU_RESOURCE_MAPPING(5, rot, rot), + SYSMMU_RESOURCE_MAPPING_PD(5, tv, tv, PD_DISP1), + SYSMMU_RESOURCE_MAPPING_PD(5, camif0, flite0, PD_GSCL), + SYSMMU_RESOURCE_MAPPING_PD(5, camif1, flite1, PD_GSCL), + SYSMMU_RESOURCE_MAPPING_PD(5, gsc0, gsc0, PD_GSCL), + SYSMMU_RESOURCE_MAPPING_PD(5, gsc1, gsc1, PD_GSCL), + SYSMMU_RESOURCE_MAPPING_PD(5, gsc2, gsc2, PD_GSCL), + SYSMMU_RESOURCE_MAPPING_PD(5, gsc3, gsc3, PD_GSCL), + SYSMMU_RESOURCE_MAPPING_PD(5, mfc_r, mfc_r, PD_MFC), + SYSMMU_RESOURCE_MAPPING_PD(5, mfc_l, mfc_l, PD_MFC), + SYSMMU_RESOURCE_MAPPING_MCPD(5, isp, isp, PD_ISP, mc_platdata), +}; +#endif /* CONFIG_ARCH_EXYNOS5 */ + +static int __init init_sysmmu_platform_device(void) { - if (sysmmu_clk[ips]) - clk_disable(sysmmu_clk[ips]); + int i, j; + struct sysmmu_resource_map *resmap[2] = {NULL, NULL}; + int nmap[2] = {0, 0}; + +#ifdef CONFIG_ARCH_EXYNOS5 + if (soc_is_exynos5250()) { + resmap[0] = sysmmu_resmap5; + nmap[0] = ARRAY_SIZE(sysmmu_resmap5); + nmap[1] = 0; + } +#endif + +#ifdef CONFIG_ARCH_EXYNOS4 + if (resmap[0] == NULL) { + resmap[0] = sysmmu_resmap4; + nmap[0] = ARRAY_SIZE(sysmmu_resmap4); + } + + if (soc_is_exynos4210()) { + resmap[1] = sysmmu_resmap4210; + nmap[1] = ARRAY_SIZE(sysmmu_resmap4210); + } + + if (soc_is_exynos4412() || soc_is_exynos4212()) { + resmap[1] = sysmmu_resmap4212; + nmap[1] = ARRAY_SIZE(sysmmu_resmap4212); + } +#endif + + for (j = 0; j < 2; j++) { + for (i = 0; i < nmap[j]; i++) { + struct sysmmu_resource_map *map; + struct sysmmu_platform_data *platdata; + + map = &resmap[j][i]; + + map->pdev->dev.parent = map->pdd; + + platdata = map->pdev->dev.platform_data; + platdata->clockname = map->clocknames; + + if (platform_device_add_resources(map->pdev, map->res, + map->rnum)) { + pr_err("%s: Failed to add device resources for " + "%s.%d\n", __func__, + map->pdev->name, map->pdev->id); + continue; + } + + if (platform_device_register(map->pdev)) { + pr_err("%s: Failed to register %s.%d\n", + __func__, map->pdev->name, + map->pdev->id); + } + } + } + + return 0; } +arch_initcall(init_sysmmu_platform_device); diff --git a/trunk/arch/arm/mach-exynos/dma.c b/trunk/arch/arm/mach-exynos/dma.c index 69aaa4503205..f60b66dbcf84 100644 --- a/trunk/arch/arm/mach-exynos/dma.c +++ b/trunk/arch/arm/mach-exynos/dma.c @@ -103,10 +103,45 @@ static u8 exynos4212_pdma0_peri[] = { DMACH_MIPI_HSI5, }; -struct dma_pl330_platdata exynos4_pdma0_pdata; +static u8 exynos5250_pdma0_peri[] = { + DMACH_PCM0_RX, + DMACH_PCM0_TX, + DMACH_PCM2_RX, + DMACH_PCM2_TX, + DMACH_SPI0_RX, + DMACH_SPI0_TX, + DMACH_SPI2_RX, + DMACH_SPI2_TX, + DMACH_I2S0S_TX, + DMACH_I2S0_RX, + DMACH_I2S0_TX, + DMACH_I2S2_RX, + DMACH_I2S2_TX, + DMACH_UART0_RX, + DMACH_UART0_TX, + DMACH_UART2_RX, + DMACH_UART2_TX, + DMACH_UART4_RX, + DMACH_UART4_TX, + DMACH_SLIMBUS0_RX, + DMACH_SLIMBUS0_TX, + DMACH_SLIMBUS2_RX, + DMACH_SLIMBUS2_TX, + DMACH_SLIMBUS4_RX, + DMACH_SLIMBUS4_TX, + DMACH_AC97_MICIN, + DMACH_AC97_PCMIN, + DMACH_AC97_PCMOUT, + DMACH_MIPI_HSI0, + DMACH_MIPI_HSI2, + DMACH_MIPI_HSI4, + DMACH_MIPI_HSI6, +}; + +static struct dma_pl330_platdata exynos_pdma0_pdata; -static AMBA_AHB_DEVICE(exynos4_pdma0, "dma-pl330.0", 0x00041330, - EXYNOS4_PA_PDMA0, {EXYNOS4_IRQ_PDMA0}, &exynos4_pdma0_pdata); +static AMBA_AHB_DEVICE(exynos_pdma0, "dma-pl330.0", 0x00041330, + EXYNOS4_PA_PDMA0, {EXYNOS4_IRQ_PDMA0}, &exynos_pdma0_pdata); static u8 exynos4210_pdma1_peri[] = { DMACH_PCM0_RX, @@ -169,10 +204,45 @@ static u8 exynos4212_pdma1_peri[] = { DMACH_MIPI_HSI7, }; -static struct dma_pl330_platdata exynos4_pdma1_pdata; +static u8 exynos5250_pdma1_peri[] = { + DMACH_PCM0_RX, + DMACH_PCM0_TX, + DMACH_PCM1_RX, + DMACH_PCM1_TX, + DMACH_SPI1_RX, + DMACH_SPI1_TX, + DMACH_PWM, + DMACH_SPDIF, + DMACH_I2S0S_TX, + DMACH_I2S0_RX, + DMACH_I2S0_TX, + DMACH_I2S1_RX, + DMACH_I2S1_TX, + DMACH_UART0_RX, + DMACH_UART0_TX, + DMACH_UART1_RX, + DMACH_UART1_TX, + DMACH_UART3_RX, + DMACH_UART3_TX, + DMACH_SLIMBUS1_RX, + DMACH_SLIMBUS1_TX, + DMACH_SLIMBUS3_RX, + DMACH_SLIMBUS3_TX, + DMACH_SLIMBUS5_RX, + DMACH_SLIMBUS5_TX, + DMACH_SLIMBUS0AUX_RX, + DMACH_SLIMBUS0AUX_TX, + DMACH_DISP1, + DMACH_MIPI_HSI1, + DMACH_MIPI_HSI3, + DMACH_MIPI_HSI5, + DMACH_MIPI_HSI7, +}; -static AMBA_AHB_DEVICE(exynos4_pdma1, "dma-pl330.1", 0x00041330, - EXYNOS4_PA_PDMA1, {EXYNOS4_IRQ_PDMA1}, &exynos4_pdma1_pdata); +static struct dma_pl330_platdata exynos_pdma1_pdata; + +static AMBA_AHB_DEVICE(exynos_pdma1, "dma-pl330.1", 0x00041330, + EXYNOS4_PA_PDMA1, {EXYNOS4_IRQ_PDMA1}, &exynos_pdma1_pdata); static u8 mdma_peri[] = { DMACH_MTOM_0, @@ -185,46 +255,63 @@ static u8 mdma_peri[] = { DMACH_MTOM_7, }; -static struct dma_pl330_platdata exynos4_mdma1_pdata = { +static struct dma_pl330_platdata exynos_mdma1_pdata = { .nr_valid_peri = ARRAY_SIZE(mdma_peri), .peri_id = mdma_peri, }; -static AMBA_AHB_DEVICE(exynos4_mdma1, "dma-pl330.2", 0x00041330, - EXYNOS4_PA_MDMA1, {EXYNOS4_IRQ_MDMA1}, &exynos4_mdma1_pdata); +static AMBA_AHB_DEVICE(exynos_mdma1, "dma-pl330.2", 0x00041330, + EXYNOS4_PA_MDMA1, {EXYNOS4_IRQ_MDMA1}, &exynos_mdma1_pdata); -static int __init exynos4_dma_init(void) +static int __init exynos_dma_init(void) { if (of_have_populated_dt()) return 0; if (soc_is_exynos4210()) { - exynos4_pdma0_pdata.nr_valid_peri = + exynos_pdma0_pdata.nr_valid_peri = ARRAY_SIZE(exynos4210_pdma0_peri); - exynos4_pdma0_pdata.peri_id = exynos4210_pdma0_peri; - exynos4_pdma1_pdata.nr_valid_peri = + exynos_pdma0_pdata.peri_id = exynos4210_pdma0_peri; + exynos_pdma1_pdata.nr_valid_peri = ARRAY_SIZE(exynos4210_pdma1_peri); - exynos4_pdma1_pdata.peri_id = exynos4210_pdma1_peri; + exynos_pdma1_pdata.peri_id = exynos4210_pdma1_peri; } else if (soc_is_exynos4212() || soc_is_exynos4412()) { - exynos4_pdma0_pdata.nr_valid_peri = + exynos_pdma0_pdata.nr_valid_peri = ARRAY_SIZE(exynos4212_pdma0_peri); - exynos4_pdma0_pdata.peri_id = exynos4212_pdma0_peri; - exynos4_pdma1_pdata.nr_valid_peri = + exynos_pdma0_pdata.peri_id = exynos4212_pdma0_peri; + exynos_pdma1_pdata.nr_valid_peri = ARRAY_SIZE(exynos4212_pdma1_peri); - exynos4_pdma1_pdata.peri_id = exynos4212_pdma1_peri; + exynos_pdma1_pdata.peri_id = exynos4212_pdma1_peri; + } else if (soc_is_exynos5250()) { + exynos_pdma0_pdata.nr_valid_peri = + ARRAY_SIZE(exynos5250_pdma0_peri); + exynos_pdma0_pdata.peri_id = exynos5250_pdma0_peri; + exynos_pdma1_pdata.nr_valid_peri = + ARRAY_SIZE(exynos5250_pdma1_peri); + exynos_pdma1_pdata.peri_id = exynos5250_pdma1_peri; + + exynos_pdma0_device.res.start = EXYNOS5_PA_PDMA0; + exynos_pdma0_device.res.end = EXYNOS5_PA_PDMA0 + SZ_4K; + exynos_pdma0_device.irq[0] = EXYNOS5_IRQ_PDMA0; + exynos_pdma1_device.res.start = EXYNOS5_PA_PDMA1; + exynos_pdma1_device.res.end = EXYNOS5_PA_PDMA1 + SZ_4K; + exynos_pdma0_device.irq[0] = EXYNOS5_IRQ_PDMA1; + exynos_mdma1_device.res.start = EXYNOS5_PA_MDMA1; + exynos_mdma1_device.res.end = EXYNOS5_PA_MDMA1 + SZ_4K; + exynos_pdma0_device.irq[0] = EXYNOS5_IRQ_MDMA1; } - dma_cap_set(DMA_SLAVE, exynos4_pdma0_pdata.cap_mask); - dma_cap_set(DMA_CYCLIC, exynos4_pdma0_pdata.cap_mask); - amba_device_register(&exynos4_pdma0_device, &iomem_resource); + dma_cap_set(DMA_SLAVE, exynos_pdma0_pdata.cap_mask); + dma_cap_set(DMA_CYCLIC, exynos_pdma0_pdata.cap_mask); + amba_device_register(&exynos_pdma0_device, &iomem_resource); - dma_cap_set(DMA_SLAVE, exynos4_pdma1_pdata.cap_mask); - dma_cap_set(DMA_CYCLIC, exynos4_pdma1_pdata.cap_mask); - amba_device_register(&exynos4_pdma1_device, &iomem_resource); + dma_cap_set(DMA_SLAVE, exynos_pdma1_pdata.cap_mask); + dma_cap_set(DMA_CYCLIC, exynos_pdma1_pdata.cap_mask); + amba_device_register(&exynos_pdma1_device, &iomem_resource); - dma_cap_set(DMA_MEMCPY, exynos4_mdma1_pdata.cap_mask); - amba_device_register(&exynos4_mdma1_device, &iomem_resource); + dma_cap_set(DMA_MEMCPY, exynos_mdma1_pdata.cap_mask); + amba_device_register(&exynos_mdma1_device, &iomem_resource); return 0; } -arch_initcall(exynos4_dma_init); +arch_initcall(exynos_dma_init); diff --git a/trunk/arch/arm/mach-exynos/include/mach/gpio.h b/trunk/arch/arm/mach-exynos/include/mach/gpio.h index d7498afe036a..eb24f1eb8e3b 100644 --- a/trunk/arch/arm/mach-exynos/include/mach/gpio.h +++ b/trunk/arch/arm/mach-exynos/include/mach/gpio.h @@ -153,10 +153,11 @@ enum exynos4_gpio_number { #define EXYNOS5_GPIO_B2_NR (4) #define EXYNOS5_GPIO_B3_NR (4) #define EXYNOS5_GPIO_C0_NR (7) -#define EXYNOS5_GPIO_C1_NR (7) +#define EXYNOS5_GPIO_C1_NR (4) #define EXYNOS5_GPIO_C2_NR (7) #define EXYNOS5_GPIO_C3_NR (7) -#define EXYNOS5_GPIO_D0_NR (8) +#define EXYNOS5_GPIO_C4_NR (7) +#define EXYNOS5_GPIO_D0_NR (4) #define EXYNOS5_GPIO_D1_NR (8) #define EXYNOS5_GPIO_Y0_NR (6) #define EXYNOS5_GPIO_Y1_NR (4) @@ -199,7 +200,8 @@ enum exynos5_gpio_number { EXYNOS5_GPIO_C1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C0), EXYNOS5_GPIO_C2_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C1), EXYNOS5_GPIO_C3_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C2), - EXYNOS5_GPIO_D0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C3), + EXYNOS5_GPIO_C4_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C3), + EXYNOS5_GPIO_D0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C4), EXYNOS5_GPIO_D1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_D0), EXYNOS5_GPIO_Y0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_D1), EXYNOS5_GPIO_Y1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y0), @@ -242,6 +244,7 @@ enum exynos5_gpio_number { #define EXYNOS5_GPC1(_nr) (EXYNOS5_GPIO_C1_START + (_nr)) #define EXYNOS5_GPC2(_nr) (EXYNOS5_GPIO_C2_START + (_nr)) #define EXYNOS5_GPC3(_nr) (EXYNOS5_GPIO_C3_START + (_nr)) +#define EXYNOS5_GPC4(_nr) (EXYNOS5_GPIO_C4_START + (_nr)) #define EXYNOS5_GPD0(_nr) (EXYNOS5_GPIO_D0_START + (_nr)) #define EXYNOS5_GPD1(_nr) (EXYNOS5_GPIO_D1_START + (_nr)) #define EXYNOS5_GPY0(_nr) (EXYNOS5_GPIO_Y0_START + (_nr)) diff --git a/trunk/arch/arm/mach-exynos/include/mach/irqs.h b/trunk/arch/arm/mach-exynos/include/mach/irqs.h index c02dae7bf4a3..7a4b4789eb72 100644 --- a/trunk/arch/arm/mach-exynos/include/mach/irqs.h +++ b/trunk/arch/arm/mach-exynos/include/mach/irqs.h @@ -154,6 +154,13 @@ #define EXYNOS4_IRQ_SYSMMU_MFC_M1_0 COMBINER_IRQ(5, 6) #define EXYNOS4_IRQ_SYSMMU_PCIE_0 COMBINER_IRQ(5, 7) +#define EXYNOS4_IRQ_SYSMMU_FIMC_LITE0_0 COMBINER_IRQ(16, 0) +#define EXYNOS4_IRQ_SYSMMU_FIMC_LITE1_0 COMBINER_IRQ(16, 1) +#define EXYNOS4_IRQ_SYSMMU_FIMC_ISP_0 COMBINER_IRQ(16, 2) +#define EXYNOS4_IRQ_SYSMMU_FIMC_DRC_0 COMBINER_IRQ(16, 3) +#define EXYNOS4_IRQ_SYSMMU_FIMC_FD_0 COMBINER_IRQ(16, 4) +#define EXYNOS4_IRQ_SYSMMU_FIMC_CX_0 COMBINER_IRQ(16, 5) + #define EXYNOS4_IRQ_FIMD0_FIFO COMBINER_IRQ(11, 0) #define EXYNOS4_IRQ_FIMD0_VSYNC COMBINER_IRQ(11, 1) #define EXYNOS4_IRQ_FIMD0_SYSTEM COMBINER_IRQ(11, 2) @@ -221,24 +228,6 @@ #define IRQ_KEYPAD EXYNOS4_IRQ_KEYPAD #define IRQ_PMU EXYNOS4_IRQ_PMU -#define IRQ_SYSMMU_MDMA0_0 EXYNOS4_IRQ_SYSMMU_MDMA0_0 -#define IRQ_SYSMMU_SSS_0 EXYNOS4_IRQ_SYSMMU_SSS_0 -#define IRQ_SYSMMU_FIMC0_0 EXYNOS4_IRQ_SYSMMU_FIMC0_0 -#define IRQ_SYSMMU_FIMC1_0 EXYNOS4_IRQ_SYSMMU_FIMC1_0 -#define IRQ_SYSMMU_FIMC2_0 EXYNOS4_IRQ_SYSMMU_FIMC2_0 -#define IRQ_SYSMMU_FIMC3_0 EXYNOS4_IRQ_SYSMMU_FIMC3_0 -#define IRQ_SYSMMU_JPEG_0 EXYNOS4_IRQ_SYSMMU_JPEG_0 -#define IRQ_SYSMMU_2D_0 EXYNOS4_IRQ_SYSMMU_2D_0 - -#define IRQ_SYSMMU_ROTATOR_0 EXYNOS4_IRQ_SYSMMU_ROTATOR_0 -#define IRQ_SYSMMU_MDMA1_0 EXYNOS4_IRQ_SYSMMU_MDMA1_0 -#define IRQ_SYSMMU_LCD0_M0_0 EXYNOS4_IRQ_SYSMMU_LCD0_M0_0 -#define IRQ_SYSMMU_LCD1_M1_0 EXYNOS4_IRQ_SYSMMU_LCD1_M1_0 -#define IRQ_SYSMMU_TV_M0_0 EXYNOS4_IRQ_SYSMMU_TV_M0_0 -#define IRQ_SYSMMU_MFC_M0_0 EXYNOS4_IRQ_SYSMMU_MFC_M0_0 -#define IRQ_SYSMMU_MFC_M1_0 EXYNOS4_IRQ_SYSMMU_MFC_M1_0 -#define IRQ_SYSMMU_PCIE_0 EXYNOS4_IRQ_SYSMMU_PCIE_0 - #define IRQ_FIMD0_FIFO EXYNOS4_IRQ_FIMD0_FIFO #define IRQ_FIMD0_VSYNC EXYNOS4_IRQ_FIMD0_VSYNC #define IRQ_FIMD0_SYSTEM EXYNOS4_IRQ_FIMD0_SYSTEM @@ -298,6 +287,7 @@ #define EXYNOS5_IRQ_MIPICSI1 IRQ_SPI(80) #define EXYNOS5_IRQ_EFNFCON_DMA_ABORT IRQ_SPI(81) #define EXYNOS5_IRQ_MIPIDSI0 IRQ_SPI(82) +#define EXYNOS5_IRQ_WDT_IOP IRQ_SPI(83) #define EXYNOS5_IRQ_ROTATOR IRQ_SPI(84) #define EXYNOS5_IRQ_GSC0 IRQ_SPI(85) #define EXYNOS5_IRQ_GSC1 IRQ_SPI(86) @@ -306,8 +296,8 @@ #define EXYNOS5_IRQ_JPEG IRQ_SPI(89) #define EXYNOS5_IRQ_EFNFCON_DMA IRQ_SPI(90) #define EXYNOS5_IRQ_2D IRQ_SPI(91) -#define EXYNOS5_IRQ_SFMC0 IRQ_SPI(92) -#define EXYNOS5_IRQ_SFMC1 IRQ_SPI(93) +#define EXYNOS5_IRQ_EFNFCON_0 IRQ_SPI(92) +#define EXYNOS5_IRQ_EFNFCON_1 IRQ_SPI(93) #define EXYNOS5_IRQ_MIXER IRQ_SPI(94) #define EXYNOS5_IRQ_HDMI IRQ_SPI(95) #define EXYNOS5_IRQ_MFC IRQ_SPI(96) @@ -321,7 +311,7 @@ #define EXYNOS5_IRQ_PCM2 IRQ_SPI(104) #define EXYNOS5_IRQ_SPDIF IRQ_SPI(105) #define EXYNOS5_IRQ_ADC0 IRQ_SPI(106) - +#define EXYNOS5_IRQ_ADC1 IRQ_SPI(107) #define EXYNOS5_IRQ_SATA_PHY IRQ_SPI(108) #define EXYNOS5_IRQ_SATA_PMEMREQ IRQ_SPI(109) #define EXYNOS5_IRQ_CAM_C IRQ_SPI(110) @@ -330,8 +320,9 @@ #define EXYNOS5_IRQ_DP1_INTP1 IRQ_SPI(113) #define EXYNOS5_IRQ_CEC IRQ_SPI(114) #define EXYNOS5_IRQ_SATA IRQ_SPI(115) -#define EXYNOS5_IRQ_NFCON IRQ_SPI(116) +#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) @@ -339,7 +330,6 @@ #define EXYNOS5_IRQ_RP_TIMER IRQ_SPI(127) #define EXYNOS5_IRQ_PMU COMBINER_IRQ(1, 2) -#define EXYNOS5_IRQ_PMU_CPU1 COMBINER_IRQ(1, 6) #define EXYNOS5_IRQ_SYSMMU_GSC0_0 COMBINER_IRQ(2, 0) #define EXYNOS5_IRQ_SYSMMU_GSC0_1 COMBINER_IRQ(2, 1) @@ -350,6 +340,8 @@ #define EXYNOS5_IRQ_SYSMMU_GSC3_0 COMBINER_IRQ(2, 6) #define EXYNOS5_IRQ_SYSMMU_GSC3_1 COMBINER_IRQ(2, 7) +#define EXYNOS5_IRQ_SYSMMU_LITE2_0 COMBINER_IRQ(3, 0) +#define EXYNOS5_IRQ_SYSMMU_LITE2_1 COMBINER_IRQ(3, 1) #define EXYNOS5_IRQ_SYSMMU_FIMD1_0 COMBINER_IRQ(3, 2) #define EXYNOS5_IRQ_SYSMMU_FIMD1_1 COMBINER_IRQ(3, 3) #define EXYNOS5_IRQ_SYSMMU_LITE0_0 COMBINER_IRQ(3, 4) @@ -373,8 +365,8 @@ #define EXYNOS5_IRQ_SYSMMU_ARM_0 COMBINER_IRQ(6, 0) #define EXYNOS5_IRQ_SYSMMU_ARM_1 COMBINER_IRQ(6, 1) -#define EXYNOS5_IRQ_SYSMMU_MFC_L_0 COMBINER_IRQ(6, 2) -#define EXYNOS5_IRQ_SYSMMU_MFC_L_1 COMBINER_IRQ(6, 3) +#define EXYNOS5_IRQ_SYSMMU_MFC_R_0 COMBINER_IRQ(6, 2) +#define EXYNOS5_IRQ_SYSMMU_MFC_R_1 COMBINER_IRQ(6, 3) #define EXYNOS5_IRQ_SYSMMU_RTIC_0 COMBINER_IRQ(6, 4) #define EXYNOS5_IRQ_SYSMMU_RTIC_1 COMBINER_IRQ(6, 5) #define EXYNOS5_IRQ_SYSMMU_SSS_0 COMBINER_IRQ(6, 6) @@ -386,11 +378,9 @@ #define EXYNOS5_IRQ_SYSMMU_MDMA1_1 COMBINER_IRQ(7, 3) #define EXYNOS5_IRQ_SYSMMU_TV_0 COMBINER_IRQ(7, 4) #define EXYNOS5_IRQ_SYSMMU_TV_1 COMBINER_IRQ(7, 5) -#define EXYNOS5_IRQ_SYSMMU_GPSX_0 COMBINER_IRQ(7, 6) -#define EXYNOS5_IRQ_SYSMMU_GPSX_1 COMBINER_IRQ(7, 7) -#define EXYNOS5_IRQ_SYSMMU_MFC_R_0 COMBINER_IRQ(8, 5) -#define EXYNOS5_IRQ_SYSMMU_MFC_R_1 COMBINER_IRQ(8, 6) +#define EXYNOS5_IRQ_SYSMMU_MFC_L_0 COMBINER_IRQ(8, 5) +#define EXYNOS5_IRQ_SYSMMU_MFC_L_1 COMBINER_IRQ(8, 6) #define EXYNOS5_IRQ_SYSMMU_DIS1_0 COMBINER_IRQ(9, 4) #define EXYNOS5_IRQ_SYSMMU_DIS1_1 COMBINER_IRQ(9, 5) @@ -406,17 +396,24 @@ #define EXYNOS5_IRQ_SYSMMU_DRC_0 COMBINER_IRQ(11, 6) #define EXYNOS5_IRQ_SYSMMU_DRC_1 COMBINER_IRQ(11, 7) +#define EXYNOS5_IRQ_MDMA1_ABORT COMBINER_IRQ(13, 1) + +#define EXYNOS5_IRQ_MDMA0_ABORT COMBINER_IRQ(15, 3) + #define EXYNOS5_IRQ_FIMD1_FIFO COMBINER_IRQ(18, 4) #define EXYNOS5_IRQ_FIMD1_VSYNC COMBINER_IRQ(18, 5) #define EXYNOS5_IRQ_FIMD1_SYSTEM COMBINER_IRQ(18, 6) +#define EXYNOS5_IRQ_ARMIOP_GIC COMBINER_IRQ(19, 0) +#define EXYNOS5_IRQ_ARMISP_GIC COMBINER_IRQ(19, 1) +#define EXYNOS5_IRQ_IOP_GIC COMBINER_IRQ(19, 3) +#define EXYNOS5_IRQ_ISP_GIC COMBINER_IRQ(19, 4) + +#define EXYNOS5_IRQ_PMU_CPU1 COMBINER_IRQ(22, 4) + #define EXYNOS5_IRQ_EINT0 COMBINER_IRQ(23, 0) -#define EXYNOS5_IRQ_MCT_L0 COMBINER_IRQ(23, 1) -#define EXYNOS5_IRQ_MCT_L1 COMBINER_IRQ(23, 2) #define EXYNOS5_IRQ_MCT_G0 COMBINER_IRQ(23, 3) #define EXYNOS5_IRQ_MCT_G1 COMBINER_IRQ(23, 4) -#define EXYNOS5_IRQ_MCT_G2 COMBINER_IRQ(23, 5) -#define EXYNOS5_IRQ_MCT_G3 COMBINER_IRQ(23, 6) #define EXYNOS5_IRQ_EINT1 COMBINER_IRQ(24, 0) #define EXYNOS5_IRQ_SYSMMU_LITE1_0 COMBINER_IRQ(24, 1) @@ -447,7 +444,7 @@ #define EXYNOS5_MAX_COMBINER_NR 32 -#define EXYNOS5_IRQ_GPIO1_NR_GROUPS 13 +#define EXYNOS5_IRQ_GPIO1_NR_GROUPS 14 #define EXYNOS5_IRQ_GPIO2_NR_GROUPS 9 #define EXYNOS5_IRQ_GPIO3_NR_GROUPS 5 #define EXYNOS5_IRQ_GPIO4_NR_GROUPS 1 diff --git a/trunk/arch/arm/mach-exynos/include/mach/map.h b/trunk/arch/arm/mach-exynos/include/mach/map.h index e009a66477f4..ca4aa89aa46b 100644 --- a/trunk/arch/arm/mach-exynos/include/mach/map.h +++ b/trunk/arch/arm/mach-exynos/include/mach/map.h @@ -34,6 +34,9 @@ #define EXYNOS4_PA_JPEG 0x11840000 +/* x = 0...1 */ +#define EXYNOS4_PA_FIMC_LITE(x) (0x12390000 + ((x) * 0x10000)) + #define EXYNOS4_PA_G2D 0x12800000 #define EXYNOS4_PA_I2S0 0x03830000 @@ -78,8 +81,8 @@ #define EXYNOS4_PA_GIC_CPU 0x10480000 #define EXYNOS4_PA_GIC_DIST 0x10490000 -#define EXYNOS5_PA_GIC_CPU 0x10480000 -#define EXYNOS5_PA_GIC_DIST 0x10490000 +#define EXYNOS5_PA_GIC_CPU 0x10482000 +#define EXYNOS5_PA_GIC_DIST 0x10481000 #define EXYNOS4_PA_COREPERI 0x10500000 #define EXYNOS4_PA_TWD 0x10500600 @@ -95,6 +98,7 @@ #define EXYNOS5_PA_PDMA1 0x121B0000 #define EXYNOS4_PA_SYSMMU_MDMA 0x10A40000 +#define EXYNOS4_PA_SYSMMU_2D_ACP 0x10A40000 #define EXYNOS4_PA_SYSMMU_SSS 0x10A50000 #define EXYNOS4_PA_SYSMMU_FIMC0 0x11A20000 #define EXYNOS4_PA_SYSMMU_FIMC1 0x11A30000 @@ -103,6 +107,12 @@ #define EXYNOS4_PA_SYSMMU_JPEG 0x11A60000 #define EXYNOS4_PA_SYSMMU_FIMD0 0x11E20000 #define EXYNOS4_PA_SYSMMU_FIMD1 0x12220000 +#define EXYNOS4_PA_SYSMMU_FIMC_ISP 0x12260000 +#define EXYNOS4_PA_SYSMMU_FIMC_DRC 0x12270000 +#define EXYNOS4_PA_SYSMMU_FIMC_FD 0x122A0000 +#define EXYNOS4_PA_SYSMMU_ISPCPU 0x122B0000 +#define EXYNOS4_PA_SYSMMU_FIMC_LITE0 0x123B0000 +#define EXYNOS4_PA_SYSMMU_FIMC_LITE1 0x123C0000 #define EXYNOS4_PA_SYSMMU_PCIe 0x12620000 #define EXYNOS4_PA_SYSMMU_G2D 0x12A20000 #define EXYNOS4_PA_SYSMMU_ROTATOR 0x12A30000 @@ -110,6 +120,37 @@ #define EXYNOS4_PA_SYSMMU_TV 0x12E20000 #define EXYNOS4_PA_SYSMMU_MFC_L 0x13620000 #define EXYNOS4_PA_SYSMMU_MFC_R 0x13630000 + +#define EXYNOS5_PA_SYSMMU_MDMA1 0x10A40000 +#define EXYNOS5_PA_SYSMMU_SSS 0x10A50000 +#define EXYNOS5_PA_SYSMMU_2D 0x10A60000 +#define EXYNOS5_PA_SYSMMU_MFC_L 0x11200000 +#define EXYNOS5_PA_SYSMMU_MFC_R 0x11210000 +#define EXYNOS5_PA_SYSMMU_ROTATOR 0x11D40000 +#define EXYNOS5_PA_SYSMMU_MDMA2 0x11D50000 +#define EXYNOS5_PA_SYSMMU_JPEG 0x11F20000 +#define EXYNOS5_PA_SYSMMU_IOP 0x12360000 +#define EXYNOS5_PA_SYSMMU_RTIC 0x12370000 +#define EXYNOS5_PA_SYSMMU_GPS 0x12630000 +#define EXYNOS5_PA_SYSMMU_ISP 0x13260000 +#define EXYNOS5_PA_SYSMMU_DRC 0x12370000 +#define EXYNOS5_PA_SYSMMU_SCALERC 0x13280000 +#define EXYNOS5_PA_SYSMMU_SCALERP 0x13290000 +#define EXYNOS5_PA_SYSMMU_FD 0x132A0000 +#define EXYNOS5_PA_SYSMMU_ISPCPU 0x132B0000 +#define EXYNOS5_PA_SYSMMU_ODC 0x132C0000 +#define EXYNOS5_PA_SYSMMU_DIS0 0x132D0000 +#define EXYNOS5_PA_SYSMMU_DIS1 0x132E0000 +#define EXYNOS5_PA_SYSMMU_3DNR 0x132F0000 +#define EXYNOS5_PA_SYSMMU_LITE0 0x13C40000 +#define EXYNOS5_PA_SYSMMU_LITE1 0x13C50000 +#define EXYNOS5_PA_SYSMMU_GSC0 0x13E80000 +#define EXYNOS5_PA_SYSMMU_GSC1 0x13E90000 +#define EXYNOS5_PA_SYSMMU_GSC2 0x13EA0000 +#define EXYNOS5_PA_SYSMMU_GSC3 0x13EB0000 +#define EXYNOS5_PA_SYSMMU_FIMD1 0x14640000 +#define EXYNOS5_PA_SYSMMU_TV 0x14650000 + #define EXYNOS4_PA_SPI0 0x13920000 #define EXYNOS4_PA_SPI1 0x13930000 #define EXYNOS4_PA_SPI2 0x13940000 diff --git a/trunk/arch/arm/mach-exynos/include/mach/pm-core.h b/trunk/arch/arm/mach-exynos/include/mach/pm-core.h index 9d8da51e35ca..a67ecfaf1216 100644 --- a/trunk/arch/arm/mach-exynos/include/mach/pm-core.h +++ b/trunk/arch/arm/mach-exynos/include/mach/pm-core.h @@ -33,7 +33,7 @@ static inline void s3c_pm_arch_prepare_irqs(void) __raw_writel(tmp, S5P_WAKEUP_MASK); __raw_writel(s3c_irqwake_intmask, S5P_WAKEUP_MASK); - __raw_writel(s3c_irqwake_eintmask, S5P_EINT_WAKEUP_MASK); + __raw_writel(s3c_irqwake_eintmask & 0xFFFFFFFE, S5P_EINT_WAKEUP_MASK); } static inline void s3c_pm_arch_stop_clocks(void) diff --git a/trunk/arch/arm/mach-exynos/include/mach/pmu.h b/trunk/arch/arm/mach-exynos/include/mach/pmu.h index e76b7faba66b..7c27c2d4bf44 100644 --- a/trunk/arch/arm/mach-exynos/include/mach/pmu.h +++ b/trunk/arch/arm/mach-exynos/include/mach/pmu.h @@ -23,12 +23,12 @@ enum sys_powerdown { }; extern unsigned long l2x0_regs_phys; -struct exynos4_pmu_conf { +struct exynos_pmu_conf { void __iomem *reg; unsigned int val[NUM_SYS_POWERDOWN]; }; -extern void exynos4_sys_powerdown_conf(enum sys_powerdown mode); +extern void exynos_sys_powerdown_conf(enum sys_powerdown mode); extern void s3c_cpu_resume(void); #endif /* __ASM_ARCH_PMU_H */ diff --git a/trunk/arch/arm/mach-exynos/include/mach/regs-clock.h b/trunk/arch/arm/mach-exynos/include/mach/regs-clock.h index d9578a58ae7f..8c9b38c9c504 100644 --- a/trunk/arch/arm/mach-exynos/include/mach/regs-clock.h +++ b/trunk/arch/arm/mach-exynos/include/mach/regs-clock.h @@ -135,6 +135,9 @@ #define EXYNOS4_CLKGATE_SCLKCPU EXYNOS_CLKREG(0x14800) #define EXYNOS4_CLKGATE_IP_CPU EXYNOS_CLKREG(0x14900) +#define EXYNOS4_CLKGATE_IP_ISP0 EXYNOS_CLKREG(0x18800) +#define EXYNOS4_CLKGATE_IP_ISP1 EXYNOS_CLKREG(0x18804) + #define EXYNOS4_APLL_LOCKTIME (0x1C20) /* 300us */ #define EXYNOS4_APLLCON0_ENABLE_SHIFT (31) @@ -271,41 +274,59 @@ #define EXYNOS5_CLKDIV_ACP EXYNOS_CLKREG(0x08500) -#define EXYNOS5_CLKSRC_TOP2 EXYNOS_CLKREG(0x10218) #define EXYNOS5_EPLL_CON0 EXYNOS_CLKREG(0x10130) #define EXYNOS5_EPLL_CON1 EXYNOS_CLKREG(0x10134) +#define EXYNOS5_EPLL_CON2 EXYNOS_CLKREG(0x10138) #define EXYNOS5_VPLL_CON0 EXYNOS_CLKREG(0x10140) #define EXYNOS5_VPLL_CON1 EXYNOS_CLKREG(0x10144) +#define EXYNOS5_VPLL_CON2 EXYNOS_CLKREG(0x10148) #define EXYNOS5_CPLL_CON0 EXYNOS_CLKREG(0x10120) #define EXYNOS5_CLKSRC_TOP0 EXYNOS_CLKREG(0x10210) +#define EXYNOS5_CLKSRC_TOP1 EXYNOS_CLKREG(0x10214) +#define EXYNOS5_CLKSRC_TOP2 EXYNOS_CLKREG(0x10218) #define EXYNOS5_CLKSRC_TOP3 EXYNOS_CLKREG(0x1021C) #define EXYNOS5_CLKSRC_GSCL EXYNOS_CLKREG(0x10220) #define EXYNOS5_CLKSRC_DISP1_0 EXYNOS_CLKREG(0x1022C) +#define EXYNOS5_CLKSRC_MAUDIO EXYNOS_CLKREG(0x10240) #define EXYNOS5_CLKSRC_FSYS EXYNOS_CLKREG(0x10244) #define EXYNOS5_CLKSRC_PERIC0 EXYNOS_CLKREG(0x10250) +#define EXYNOS5_CLKSRC_PERIC1 EXYNOS_CLKREG(0x10254) +#define EXYNOS5_SCLK_SRC_ISP EXYNOS_CLKREG(0x10270) #define EXYNOS5_CLKSRC_MASK_TOP EXYNOS_CLKREG(0x10310) #define EXYNOS5_CLKSRC_MASK_GSCL EXYNOS_CLKREG(0x10320) #define EXYNOS5_CLKSRC_MASK_DISP1_0 EXYNOS_CLKREG(0x1032C) +#define EXYNOS5_CLKSRC_MASK_MAUDIO EXYNOS_CLKREG(0x10334) #define EXYNOS5_CLKSRC_MASK_FSYS EXYNOS_CLKREG(0x10340) #define EXYNOS5_CLKSRC_MASK_PERIC0 EXYNOS_CLKREG(0x10350) +#define EXYNOS5_CLKSRC_MASK_PERIC1 EXYNOS_CLKREG(0x10354) #define EXYNOS5_CLKDIV_TOP0 EXYNOS_CLKREG(0x10510) #define EXYNOS5_CLKDIV_TOP1 EXYNOS_CLKREG(0x10514) #define EXYNOS5_CLKDIV_GSCL EXYNOS_CLKREG(0x10520) #define EXYNOS5_CLKDIV_DISP1_0 EXYNOS_CLKREG(0x1052C) #define EXYNOS5_CLKDIV_GEN EXYNOS_CLKREG(0x1053C) +#define EXYNOS5_CLKDIV_MAUDIO EXYNOS_CLKREG(0x10544) #define EXYNOS5_CLKDIV_FSYS0 EXYNOS_CLKREG(0x10548) #define EXYNOS5_CLKDIV_FSYS1 EXYNOS_CLKREG(0x1054C) #define EXYNOS5_CLKDIV_FSYS2 EXYNOS_CLKREG(0x10550) #define EXYNOS5_CLKDIV_FSYS3 EXYNOS_CLKREG(0x10554) #define EXYNOS5_CLKDIV_PERIC0 EXYNOS_CLKREG(0x10558) +#define EXYNOS5_CLKDIV_PERIC1 EXYNOS_CLKREG(0x1055C) +#define EXYNOS5_CLKDIV_PERIC2 EXYNOS_CLKREG(0x10560) +#define EXYNOS5_CLKDIV_PERIC3 EXYNOS_CLKREG(0x10564) +#define EXYNOS5_CLKDIV_PERIC4 EXYNOS_CLKREG(0x10568) +#define EXYNOS5_CLKDIV_PERIC5 EXYNOS_CLKREG(0x1056C) +#define EXYNOS5_SCLK_DIV_ISP EXYNOS_CLKREG(0x10580) #define EXYNOS5_CLKGATE_IP_ACP EXYNOS_CLKREG(0x08800) +#define EXYNOS5_CLKGATE_IP_ISP0 EXYNOS_CLKREG(0x0C800) +#define EXYNOS5_CLKGATE_IP_ISP1 EXYNOS_CLKREG(0x0C804) #define EXYNOS5_CLKGATE_IP_GSCL EXYNOS_CLKREG(0x10920) #define EXYNOS5_CLKGATE_IP_DISP1 EXYNOS_CLKREG(0x10928) #define EXYNOS5_CLKGATE_IP_MFC EXYNOS_CLKREG(0x1092C) +#define EXYNOS5_CLKGATE_IP_G3D EXYNOS_CLKREG(0x10930) #define EXYNOS5_CLKGATE_IP_GEN EXYNOS_CLKREG(0x10934) #define EXYNOS5_CLKGATE_IP_FSYS EXYNOS_CLKREG(0x10944) #define EXYNOS5_CLKGATE_IP_GPS EXYNOS_CLKREG(0x1094C) @@ -317,6 +338,8 @@ #define EXYNOS5_CLKSRC_CDREX EXYNOS_CLKREG(0x20200) #define EXYNOS5_CLKDIV_CDREX EXYNOS_CLKREG(0x20500) +#define EXYNOS5_PLL_DIV2_SEL EXYNOS_CLKREG(0x20A24) + #define EXYNOS5_EPLL_LOCK EXYNOS_CLKREG(0x10030) #define EXYNOS5_EPLLCON0_LOCKED_SHIFT (29) 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 d457d052a420..43a99e6f56ab 100644 --- a/trunk/arch/arm/mach-exynos/include/mach/regs-pmu.h +++ b/trunk/arch/arm/mach-exynos/include/mach/regs-pmu.h @@ -1,9 +1,8 @@ -/* linux/arch/arm/mach-exynos4/include/mach/regs-pmu.h - * - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. +/* + * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd. * http://www.samsung.com * - * EXYNOS4 - Power management unit definition + * EXYNOS - Power management unit definition * * 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 @@ -180,7 +179,7 @@ #define S5P_PMU_LCD1_CONF S5P_PMUREG(0x3CA0) -/* Only for EXYNOS4212 */ +/* Only for EXYNOS4x12 */ #define S5P_ISP_ARM_LOWPWR S5P_PMUREG(0x1050) #define S5P_DIS_IRQ_ISP_ARM_LOCAL_LOWPWR S5P_PMUREG(0x1054) #define S5P_DIS_IRQ_ISP_ARM_CENTRAL_LOWPWR S5P_PMUREG(0x1058) @@ -221,4 +220,146 @@ #define S5P_SECSS_MEM_OPTION S5P_PMUREG(0x2EC8) #define S5P_ROTATOR_MEM_OPTION S5P_PMUREG(0x2F48) +/* Only for EXYNOS4412 */ +#define S5P_ARM_CORE2_LOWPWR S5P_PMUREG(0x1020) +#define S5P_DIS_IRQ_CORE2 S5P_PMUREG(0x1024) +#define S5P_DIS_IRQ_CENTRAL2 S5P_PMUREG(0x1028) +#define S5P_ARM_CORE3_LOWPWR S5P_PMUREG(0x1030) +#define S5P_DIS_IRQ_CORE3 S5P_PMUREG(0x1034) +#define S5P_DIS_IRQ_CENTRAL3 S5P_PMUREG(0x1038) + +/* For EXYNOS5 */ + +#define EXYNOS5_USB_CFG S5P_PMUREG(0x0230) + +#define EXYNOS5_ARM_CORE0_SYS_PWR_REG S5P_PMUREG(0x1000) +#define EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG S5P_PMUREG(0x1004) +#define EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG S5P_PMUREG(0x1008) +#define EXYNOS5_ARM_CORE1_SYS_PWR_REG S5P_PMUREG(0x1010) +#define EXYNOS5_DIS_IRQ_ARM_CORE1_LOCAL_SYS_PWR_REG S5P_PMUREG(0x1014) +#define EXYNOS5_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG S5P_PMUREG(0x1018) +#define EXYNOS5_FSYS_ARM_SYS_PWR_REG S5P_PMUREG(0x1040) +#define EXYNOS5_DIS_IRQ_FSYS_ARM_CENTRAL_SYS_PWR_REG S5P_PMUREG(0x1048) +#define EXYNOS5_ISP_ARM_SYS_PWR_REG S5P_PMUREG(0x1050) +#define EXYNOS5_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG S5P_PMUREG(0x1054) +#define EXYNOS5_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG S5P_PMUREG(0x1058) +#define EXYNOS5_ARM_COMMON_SYS_PWR_REG S5P_PMUREG(0x1080) +#define EXYNOS5_ARM_L2_SYS_PWR_REG S5P_PMUREG(0x10C0) +#define EXYNOS5_CMU_ACLKSTOP_SYS_PWR_REG S5P_PMUREG(0x1100) +#define EXYNOS5_CMU_SCLKSTOP_SYS_PWR_REG S5P_PMUREG(0x1104) +#define EXYNOS5_CMU_RESET_SYS_PWR_REG S5P_PMUREG(0x110C) +#define EXYNOS5_CMU_ACLKSTOP_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x1120) +#define EXYNOS5_CMU_SCLKSTOP_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x1124) +#define EXYNOS5_CMU_RESET_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x112C) +#define EXYNOS5_DRAM_FREQ_DOWN_SYS_PWR_REG S5P_PMUREG(0x1130) +#define EXYNOS5_DDRPHY_DLLOFF_SYS_PWR_REG S5P_PMUREG(0x1134) +#define EXYNOS5_DDRPHY_DLLLOCK_SYS_PWR_REG S5P_PMUREG(0x1138) +#define EXYNOS5_APLL_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x1140) +#define EXYNOS5_MPLL_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x1144) +#define EXYNOS5_VPLL_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x1148) +#define EXYNOS5_EPLL_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x114C) +#define EXYNOS5_BPLL_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x1150) +#define EXYNOS5_CPLL_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x1154) +#define EXYNOS5_MPLLUSER_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x1164) +#define EXYNOS5_BPLLUSER_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x1170) +#define EXYNOS5_TOP_BUS_SYS_PWR_REG S5P_PMUREG(0x1180) +#define EXYNOS5_TOP_RETENTION_SYS_PWR_REG S5P_PMUREG(0x1184) +#define EXYNOS5_TOP_PWR_SYS_PWR_REG S5P_PMUREG(0x1188) +#define EXYNOS5_TOP_BUS_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x1190) +#define EXYNOS5_TOP_RETENTION_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x1194) +#define EXYNOS5_TOP_PWR_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x1198) +#define EXYNOS5_LOGIC_RESET_SYS_PWR_REG S5P_PMUREG(0x11A0) +#define EXYNOS5_OSCCLK_GATE_SYS_PWR_REG S5P_PMUREG(0x11A4) +#define EXYNOS5_LOGIC_RESET_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x11B0) +#define EXYNOS5_OSCCLK_GATE_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x11B4) +#define EXYNOS5_USBOTG_MEM_SYS_PWR_REG S5P_PMUREG(0x11C0) +#define EXYNOS5_G2D_MEM_SYS_PWR_REG S5P_PMUREG(0x11C8) +#define EXYNOS5_USBDRD_MEM_SYS_PWR_REG S5P_PMUREG(0x11CC) +#define EXYNOS5_SDMMC_MEM_SYS_PWR_REG S5P_PMUREG(0x11D0) +#define EXYNOS5_CSSYS_MEM_SYS_PWR_REG S5P_PMUREG(0x11D4) +#define EXYNOS5_SECSS_MEM_SYS_PWR_REG S5P_PMUREG(0x11D8) +#define EXYNOS5_ROTATOR_MEM_SYS_PWR_REG S5P_PMUREG(0x11DC) +#define EXYNOS5_INTRAM_MEM_SYS_PWR_REG S5P_PMUREG(0x11E0) +#define EXYNOS5_INTROM_MEM_SYS_PWR_REG S5P_PMUREG(0x11E4) +#define EXYNOS5_JPEG_MEM_SYS_PWR_REG S5P_PMUREG(0x11E8) +#define EXYNOS5_HSI_MEM_SYS_PWR_REG S5P_PMUREG(0x11EC) +#define EXYNOS5_MCUIOP_MEM_SYS_PWR_REG S5P_PMUREG(0x11F4) +#define EXYNOS5_SATA_MEM_SYS_PWR_REG S5P_PMUREG(0x11FC) +#define EXYNOS5_PAD_RETENTION_DRAM_SYS_PWR_REG S5P_PMUREG(0x1200) +#define EXYNOS5_PAD_RETENTION_MAU_SYS_PWR_REG S5P_PMUREG(0x1204) +#define EXYNOS5_PAD_RETENTION_EFNAND_SYS_PWR_REG S5P_PMUREG(0x1208) +#define EXYNOS5_PAD_RETENTION_GPIO_SYS_PWR_REG S5P_PMUREG(0x1220) +#define EXYNOS5_PAD_RETENTION_UART_SYS_PWR_REG S5P_PMUREG(0x1224) +#define EXYNOS5_PAD_RETENTION_MMCA_SYS_PWR_REG S5P_PMUREG(0x1228) +#define EXYNOS5_PAD_RETENTION_MMCB_SYS_PWR_REG S5P_PMUREG(0x122C) +#define EXYNOS5_PAD_RETENTION_EBIA_SYS_PWR_REG S5P_PMUREG(0x1230) +#define EXYNOS5_PAD_RETENTION_EBIB_SYS_PWR_REG S5P_PMUREG(0x1234) +#define EXYNOS5_PAD_RETENTION_SPI_SYS_PWR_REG S5P_PMUREG(0x1238) +#define EXYNOS5_PAD_RETENTION_GPIO_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x123C) +#define EXYNOS5_PAD_ISOLATION_SYS_PWR_REG S5P_PMUREG(0x1240) +#define EXYNOS5_PAD_ISOLATION_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x1250) +#define EXYNOS5_PAD_ALV_SEL_SYS_PWR_REG S5P_PMUREG(0x1260) +#define EXYNOS5_XUSBXTI_SYS_PWR_REG S5P_PMUREG(0x1280) +#define EXYNOS5_XXTI_SYS_PWR_REG S5P_PMUREG(0x1284) +#define EXYNOS5_EXT_REGULATOR_SYS_PWR_REG S5P_PMUREG(0x12C0) +#define EXYNOS5_GPIO_MODE_SYS_PWR_REG S5P_PMUREG(0x1300) +#define EXYNOS5_GPIO_MODE_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x1320) +#define EXYNOS5_GPIO_MODE_MAU_SYS_PWR_REG S5P_PMUREG(0x1340) +#define EXYNOS5_TOP_ASB_RESET_SYS_PWR_REG S5P_PMUREG(0x1344) +#define EXYNOS5_TOP_ASB_ISOLATION_SYS_PWR_REG S5P_PMUREG(0x1348) +#define EXYNOS5_GSCL_SYS_PWR_REG S5P_PMUREG(0x1400) +#define EXYNOS5_ISP_SYS_PWR_REG S5P_PMUREG(0x1404) +#define EXYNOS5_MFC_SYS_PWR_REG S5P_PMUREG(0x1408) +#define EXYNOS5_G3D_SYS_PWR_REG S5P_PMUREG(0x140C) +#define EXYNOS5_DISP1_SYS_PWR_REG S5P_PMUREG(0x1414) +#define EXYNOS5_MAU_SYS_PWR_REG S5P_PMUREG(0x1418) +#define EXYNOS5_CMU_CLKSTOP_GSCL_SYS_PWR_REG S5P_PMUREG(0x1480) +#define EXYNOS5_CMU_CLKSTOP_ISP_SYS_PWR_REG S5P_PMUREG(0x1484) +#define EXYNOS5_CMU_CLKSTOP_MFC_SYS_PWR_REG S5P_PMUREG(0x1488) +#define EXYNOS5_CMU_CLKSTOP_G3D_SYS_PWR_REG S5P_PMUREG(0x148C) +#define EXYNOS5_CMU_CLKSTOP_DISP1_SYS_PWR_REG S5P_PMUREG(0x1494) +#define EXYNOS5_CMU_CLKSTOP_MAU_SYS_PWR_REG S5P_PMUREG(0x1498) +#define EXYNOS5_CMU_SYSCLK_GSCL_SYS_PWR_REG S5P_PMUREG(0x14C0) +#define EXYNOS5_CMU_SYSCLK_ISP_SYS_PWR_REG S5P_PMUREG(0x14C4) +#define EXYNOS5_CMU_SYSCLK_MFC_SYS_PWR_REG S5P_PMUREG(0x14C8) +#define EXYNOS5_CMU_SYSCLK_G3D_SYS_PWR_REG S5P_PMUREG(0x14CC) +#define EXYNOS5_CMU_SYSCLK_DISP1_SYS_PWR_REG S5P_PMUREG(0x14D4) +#define EXYNOS5_CMU_SYSCLK_MAU_SYS_PWR_REG S5P_PMUREG(0x14D8) +#define EXYNOS5_CMU_RESET_GSCL_SYS_PWR_REG S5P_PMUREG(0x1580) +#define EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG S5P_PMUREG(0x1584) +#define EXYNOS5_CMU_RESET_MFC_SYS_PWR_REG S5P_PMUREG(0x1588) +#define EXYNOS5_CMU_RESET_G3D_SYS_PWR_REG S5P_PMUREG(0x158C) +#define EXYNOS5_CMU_RESET_DISP1_SYS_PWR_REG S5P_PMUREG(0x1594) +#define EXYNOS5_CMU_RESET_MAU_SYS_PWR_REG S5P_PMUREG(0x1598) + +#define EXYNOS5_ARM_CORE0_OPTION S5P_PMUREG(0x2008) +#define EXYNOS5_ARM_CORE1_OPTION S5P_PMUREG(0x2088) +#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_TOP_PWR_OPTION S5P_PMUREG(0x2C48) +#define EXYNOS5_TOP_PWR_SYSMEM_OPTION S5P_PMUREG(0x2CC8) +#define EXYNOS5_JPEG_MEM_OPTION S5P_PMUREG(0x2F48) +#define EXYNOS5_GSCL_STATUS S5P_PMUREG(0x4004) +#define EXYNOS5_ISP_STATUS S5P_PMUREG(0x4024) +#define EXYNOS5_GSCL_OPTION S5P_PMUREG(0x4008) +#define EXYNOS5_ISP_OPTION S5P_PMUREG(0x4028) +#define EXYNOS5_MFC_OPTION S5P_PMUREG(0x4048) +#define EXYNOS5_G3D_CONFIGURATION S5P_PMUREG(0x4060) +#define EXYNOS5_G3D_STATUS S5P_PMUREG(0x4064) +#define EXYNOS5_G3D_OPTION S5P_PMUREG(0x4068) +#define EXYNOS5_DISP1_OPTION S5P_PMUREG(0x40A8) +#define EXYNOS5_MAU_OPTION S5P_PMUREG(0x40C8) + +#define EXYNOS5_USE_SC_FEEDBACK (1 << 1) +#define EXYNOS5_USE_SC_COUNTER (1 << 0) + +#define EXYNOS5_MANUAL_L2RSTDISABLE_CONTROL (1 << 2) +#define EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN (1 << 7) + +#define EXYNOS5_OPTION_USE_STANDBYWFE (1 << 24) +#define EXYNOS5_OPTION_USE_STANDBYWFI (1 << 16) + +#define EXYNOS5_OPTION_USE_RETENTION (1 << 4) + #endif /* __ASM_ARCH_REGS_PMU_H */ diff --git a/trunk/arch/arm/mach-exynos/include/mach/regs-sysmmu.h b/trunk/arch/arm/mach-exynos/include/mach/regs-sysmmu.h deleted file mode 100644 index 68ff6ad08a2b..000000000000 --- a/trunk/arch/arm/mach-exynos/include/mach/regs-sysmmu.h +++ /dev/null @@ -1,28 +0,0 @@ -/* linux/arch/arm/mach-exynos4/include/mach/regs-sysmmu.h - * - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * EXYNOS4 - System MMU register - * - * 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_SYSMMU_H -#define __ASM_ARCH_REGS_SYSMMU_H __FILE__ - -#define S5P_MMU_CTRL 0x000 -#define S5P_MMU_CFG 0x004 -#define S5P_MMU_STATUS 0x008 -#define S5P_MMU_FLUSH 0x00C -#define S5P_PT_BASE_ADDR 0x014 -#define S5P_INT_STATUS 0x018 -#define S5P_INT_CLEAR 0x01C -#define S5P_PAGE_FAULT_ADDR 0x024 -#define S5P_AW_FAULT_ADDR 0x028 -#define S5P_AR_FAULT_ADDR 0x02C -#define S5P_DEFAULT_SLAVE_ADDR 0x030 - -#endif /* __ASM_ARCH_REGS_SYSMMU_H */ diff --git a/trunk/arch/arm/mach-exynos/include/mach/spi-clocks.h b/trunk/arch/arm/mach-exynos/include/mach/spi-clocks.h index 576efdf6d091..c71a5fba6a84 100644 --- a/trunk/arch/arm/mach-exynos/include/mach/spi-clocks.h +++ b/trunk/arch/arm/mach-exynos/include/mach/spi-clocks.h @@ -11,6 +11,6 @@ #define __ASM_ARCH_SPI_CLKS_H __FILE__ /* Must source from SCLK_SPI */ -#define EXYNOS4_SPI_SRCCLK_SCLK 0 +#define EXYNOS_SPI_SRCCLK_SCLK 0 #endif /* __ASM_ARCH_SPI_CLKS_H */ diff --git a/trunk/arch/arm/mach-exynos/include/mach/sysmmu.h b/trunk/arch/arm/mach-exynos/include/mach/sysmmu.h index 6a5fbb534e82..998daf2add92 100644 --- a/trunk/arch/arm/mach-exynos/include/mach/sysmmu.h +++ b/trunk/arch/arm/mach-exynos/include/mach/sysmmu.h @@ -1,46 +1,66 @@ -/* linux/arch/arm/mach-exynos4/include/mach/sysmmu.h - * - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. +/* + * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd. * http://www.samsung.com * - * Samsung sysmmu driver for EXYNOS4 + * EXYNOS - System MMU 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_ARM_ARCH_SYSMMU_H -#define __ASM_ARM_ARCH_SYSMMU_H __FILE__ - -enum exynos4_sysmmu_ips { - SYSMMU_MDMA, - SYSMMU_SSS, - SYSMMU_FIMC0, - SYSMMU_FIMC1, - SYSMMU_FIMC2, - SYSMMU_FIMC3, - SYSMMU_JPEG, - SYSMMU_FIMD0, - SYSMMU_FIMD1, - SYSMMU_PCIe, - SYSMMU_G2D, - SYSMMU_ROTATOR, - SYSMMU_MDMA2, - SYSMMU_TV, - SYSMMU_MFC_L, - SYSMMU_MFC_R, - EXYNOS4_SYSMMU_TOTAL_IPNUM, + */ + +#ifndef _ARM_MACH_EXYNOS_SYSMMU_H_ +#define _ARM_MACH_EXYNOS_SYSMMU_H_ + +struct sysmmu_platform_data { + char *dbgname; + /* comma(,) separated list of clock names for clock gating */ + char *clockname; }; -#define S5P_SYSMMU_TOTAL_IPNUM EXYNOS4_SYSMMU_TOTAL_IPNUM +#define SYSMMU_DEVNAME_BASE "exynos-sysmmu" + +#define SYSMMU_CLOCK_NAME "sysmmu" +#define SYSMMU_CLOCK_NAME2 "sysmmu_mc" + +#ifdef CONFIG_EXYNOS_DEV_SYSMMU +#include +struct platform_device; + +#define SYSMMU_PLATDEV(ipname) exynos_device_sysmmu_##ipname + +extern struct platform_device SYSMMU_PLATDEV(mfc_l); +extern struct platform_device SYSMMU_PLATDEV(mfc_r); +extern struct platform_device SYSMMU_PLATDEV(tv); +extern struct platform_device SYSMMU_PLATDEV(jpeg); +extern struct platform_device SYSMMU_PLATDEV(rot); +extern struct platform_device SYSMMU_PLATDEV(fimc0); +extern struct platform_device SYSMMU_PLATDEV(fimc1); +extern struct platform_device SYSMMU_PLATDEV(fimc2); +extern struct platform_device SYSMMU_PLATDEV(fimc3); +extern struct platform_device SYSMMU_PLATDEV(gsc0); +extern struct platform_device SYSMMU_PLATDEV(gsc1); +extern struct platform_device SYSMMU_PLATDEV(gsc2); +extern struct platform_device SYSMMU_PLATDEV(gsc3); +extern struct platform_device SYSMMU_PLATDEV(isp); +extern struct platform_device SYSMMU_PLATDEV(fimd0); +extern struct platform_device SYSMMU_PLATDEV(fimd1); +extern struct platform_device SYSMMU_PLATDEV(camif0); +extern struct platform_device SYSMMU_PLATDEV(camif1); +extern struct platform_device SYSMMU_PLATDEV(2d); -extern const char *sysmmu_ips_name[EXYNOS4_SYSMMU_TOTAL_IPNUM]; +#ifdef CONFIG_IOMMU_API +static inline void platform_set_sysmmu( + struct device *sysmmu, struct device *dev) +{ + dev->archdata.iommu = sysmmu; +} +#endif -typedef enum exynos4_sysmmu_ips sysmmu_ips; +#else /* !CONFIG_EXYNOS_DEV_SYSMMU */ +#define platform_set_sysmmu(dev, sysmmu) do { } while (0) +#endif -void sysmmu_clk_init(struct device *dev, sysmmu_ips ips); -void sysmmu_clk_enable(sysmmu_ips ips); -void sysmmu_clk_disable(sysmmu_ips ips); +#define SYSMMU_CLOCK_DEVNAME(ipname, id) (SYSMMU_DEVNAME_BASE "." #id) -#endif /* __ASM_ARM_ARCH_SYSMMU_H */ +#endif /* _ARM_MACH_EXYNOS_SYSMMU_H_ */ diff --git a/trunk/arch/arm/mach-exynos/mach-armlex4210.c b/trunk/arch/arm/mach-exynos/mach-armlex4210.c index fed7116418eb..5a3daa0168d8 100644 --- a/trunk/arch/arm/mach-exynos/mach-armlex4210.c +++ b/trunk/arch/arm/mach-exynos/mach-armlex4210.c @@ -147,7 +147,6 @@ static struct platform_device *armlex4210_devices[] __initdata = { &s3c_device_hsmmc3, &s3c_device_rtc, &s3c_device_wdt, - &exynos4_device_sysmmu, &samsung_asoc_dma, &armlex4210_smsc911x, &exynos4_device_ahci, @@ -204,6 +203,7 @@ MACHINE_START(ARMLEX4210, "ARMLEX4210") .map_io = armlex4210_map_io, .handle_irq = gic_handle_irq, .init_machine = armlex4210_machine_init, + .init_late = exynos_init_late, .timer = &exynos4_timer, .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 8245f1c761d9..e7e9743543ac 100644 --- a/trunk/arch/arm/mach-exynos/mach-exynos4-dt.c +++ b/trunk/arch/arm/mach-exynos/mach-exynos4-dt.c @@ -83,6 +83,7 @@ DT_MACHINE_START(EXYNOS4210_DT, "Samsung Exynos4 (Flattened Device Tree)") .map_io = exynos4210_dt_map_io, .handle_irq = gic_handle_irq, .init_machine = exynos4210_dt_machine_init, + .init_late = exynos_init_late, .timer = &exynos4_timer, .dt_compat = exynos4210_dt_compat, .restart = exynos4_restart, diff --git a/trunk/arch/arm/mach-exynos/mach-exynos5-dt.c b/trunk/arch/arm/mach-exynos/mach-exynos5-dt.c index 4711c8920e37..7b1e11a228cc 100644 --- a/trunk/arch/arm/mach-exynos/mach-exynos5-dt.c +++ b/trunk/arch/arm/mach-exynos/mach-exynos5-dt.c @@ -43,6 +43,10 @@ static const struct of_dev_auxdata exynos5250_auxdata_lookup[] __initconst = { "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("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), @@ -72,6 +76,7 @@ DT_MACHINE_START(EXYNOS5_DT, "SAMSUNG EXYNOS5 (Flattened Device Tree)") .map_io = exynos5250_dt_map_io, .handle_irq = gic_handle_irq, .init_machine = exynos5250_dt_machine_init, + .init_late = exynos_init_late, .timer = &exynos4_timer, .dt_compat = exynos5250_dt_compat, .restart = exynos5_restart, diff --git a/trunk/arch/arm/mach-exynos/mach-nuri.c b/trunk/arch/arm/mach-exynos/mach-nuri.c index 6c31f2ad765d..656f8fc9addd 100644 --- a/trunk/arch/arm/mach-exynos/mach-nuri.c +++ b/trunk/arch/arm/mach-exynos/mach-nuri.c @@ -237,25 +237,29 @@ static struct exynos_drm_fimd_pdata drm_fimd_pdata = { #else /* Frame Buffer */ static struct s3c_fb_pd_win nuri_fb_win0 = { - .win_mode = { - .left_margin = 64, - .right_margin = 16, - .upper_margin = 64, - .lower_margin = 1, - .hsync_len = 48, - .vsync_len = 3, - .xres = 1024, - .yres = 600, - .refresh = 60, - }, .max_bpp = 24, .default_bpp = 16, + .xres = 1024, + .yres = 600, .virtual_x = 1024, .virtual_y = 2 * 600, }; +static struct fb_videomode nuri_lcd_timing = { + .left_margin = 64, + .right_margin = 16, + .upper_margin = 64, + .lower_margin = 1, + .hsync_len = 48, + .vsync_len = 3, + .xres = 1024, + .yres = 600, + .refresh = 60, +}; + static struct s3c_fb_platdata nuri_fb_pdata __initdata = { .win[0] = &nuri_fb_win0, + .vtiming = &nuri_lcd_timing, .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB | VIDCON0_CLKSEL_LCD, .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, @@ -1389,6 +1393,7 @@ MACHINE_START(NURI, "NURI") .map_io = nuri_map_io, .handle_irq = gic_handle_irq, .init_machine = nuri_machine_init, + .init_late = exynos_init_late, .timer = &exynos4_timer, .reserve = &nuri_reserve, .restart = exynos4_restart, diff --git a/trunk/arch/arm/mach-exynos/mach-origen.c b/trunk/arch/arm/mach-exynos/mach-origen.c index 26124a38bcbd..f5572be9d7bf 100644 --- a/trunk/arch/arm/mach-exynos/mach-origen.c +++ b/trunk/arch/arm/mach-exynos/mach-origen.c @@ -604,24 +604,28 @@ static struct exynos_drm_fimd_pdata drm_fimd_pdata = { }; #else static struct s3c_fb_pd_win origen_fb_win0 = { - .win_mode = { - .left_margin = 64, - .right_margin = 16, - .upper_margin = 64, - .lower_margin = 16, - .hsync_len = 48, - .vsync_len = 3, - .xres = 1024, - .yres = 600, - }, + .xres = 1024, + .yres = 600, .max_bpp = 32, .default_bpp = 24, .virtual_x = 1024, .virtual_y = 2 * 600, }; +static struct fb_videomode origen_lcd_timing = { + .left_margin = 64, + .right_margin = 16, + .upper_margin = 64, + .lower_margin = 16, + .hsync_len = 48, + .vsync_len = 3, + .xres = 1024, + .yres = 600, +}; + static struct s3c_fb_platdata origen_lcd_pdata __initdata = { .win[0] = &origen_fb_win0, + .vtiming = &origen_lcd_timing, .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC | VIDCON1_INV_VCLK, @@ -766,6 +770,7 @@ MACHINE_START(ORIGEN, "ORIGEN") .map_io = origen_map_io, .handle_irq = gic_handle_irq, .init_machine = origen_machine_init, + .init_late = exynos_init_late, .timer = &exynos4_timer, .reserve = &origen_reserve, .restart = exynos4_restart, diff --git a/trunk/arch/arm/mach-exynos/mach-smdk4x12.c b/trunk/arch/arm/mach-exynos/mach-smdk4x12.c index fe772d893cc9..fb09c70e195a 100644 --- a/trunk/arch/arm/mach-exynos/mach-smdk4x12.c +++ b/trunk/arch/arm/mach-exynos/mach-smdk4x12.c @@ -316,6 +316,7 @@ MACHINE_START(SMDK4412, "SMDK4412") .map_io = smdk4x12_map_io, .handle_irq = gic_handle_irq, .init_machine = smdk4x12_machine_init, + .init_late = exynos_init_late, .timer = &exynos4_timer, .restart = exynos4_restart, .reserve = &smdk4x12_reserve, diff --git a/trunk/arch/arm/mach-exynos/mach-smdkv310.c b/trunk/arch/arm/mach-exynos/mach-smdkv310.c index 5af96064ca51..262e9e446a96 100644 --- a/trunk/arch/arm/mach-exynos/mach-smdkv310.c +++ b/trunk/arch/arm/mach-exynos/mach-smdkv310.c @@ -178,22 +178,26 @@ static struct exynos_drm_fimd_pdata drm_fimd_pdata = { }; #else static struct s3c_fb_pd_win smdkv310_fb_win0 = { - .win_mode = { - .left_margin = 13, - .right_margin = 8, - .upper_margin = 7, - .lower_margin = 5, - .hsync_len = 3, - .vsync_len = 1, - .xres = 800, - .yres = 480, - }, - .max_bpp = 32, - .default_bpp = 24, + .max_bpp = 32, + .default_bpp = 24, + .xres = 800, + .yres = 480, +}; + +static struct fb_videomode smdkv310_lcd_timing = { + .left_margin = 13, + .right_margin = 8, + .upper_margin = 7, + .lower_margin = 5, + .hsync_len = 3, + .vsync_len = 1, + .xres = 800, + .yres = 480, }; static struct s3c_fb_platdata smdkv310_lcd0_pdata __initdata = { .win[0] = &smdkv310_fb_win0, + .vtiming = &smdkv310_lcd_timing, .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, .setup_gpio = exynos4_fimd0_gpio_setup_24bpp, @@ -295,7 +299,6 @@ static struct platform_device *smdkv310_devices[] __initdata = { &s5p_device_mfc_l, &s5p_device_mfc_r, &exynos4_device_spdif, - &exynos4_device_sysmmu, &samsung_asoc_dma, &samsung_asoc_idma, &s5p_device_fimd0, @@ -412,6 +415,7 @@ MACHINE_START(SMDKC210, "SMDKC210") .map_io = smdkv310_map_io, .handle_irq = gic_handle_irq, .init_machine = smdkv310_machine_init, + .init_late = exynos_init_late, .timer = &exynos4_timer, .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 6b731b863275..cd92fa86ba41 100644 --- a/trunk/arch/arm/mach-exynos/mach-universal_c210.c +++ b/trunk/arch/arm/mach-exynos/mach-universal_c210.c @@ -843,25 +843,29 @@ static struct exynos_drm_fimd_pdata drm_fimd_pdata = { #else /* Frame Buffer */ static struct s3c_fb_pd_win universal_fb_win0 = { - .win_mode = { - .left_margin = 16, - .right_margin = 16, - .upper_margin = 2, - .lower_margin = 28, - .hsync_len = 2, - .vsync_len = 1, - .xres = 480, - .yres = 800, - .refresh = 55, - }, .max_bpp = 32, .default_bpp = 16, + .xres = 480, + .yres = 800, .virtual_x = 480, .virtual_y = 2 * 800, }; +static struct fb_videomode universal_lcd_timing = { + .left_margin = 16, + .right_margin = 16, + .upper_margin = 2, + .lower_margin = 28, + .hsync_len = 2, + .vsync_len = 1, + .xres = 480, + .yres = 800, + .refresh = 55, +}; + static struct s3c_fb_platdata universal_lcd_pdata __initdata = { .win[0] = &universal_fb_win0, + .vtiming = &universal_lcd_timing, .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB | VIDCON0_CLKSEL_LCD, .vidcon1 = VIDCON1_INV_VCLK | VIDCON1_INV_VDEN @@ -1157,6 +1161,7 @@ MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210") .map_io = universal_map_io, .handle_irq = gic_handle_irq, .init_machine = universal_machine_init, + .init_late = exynos_init_late, .timer = &s5p_timer, .reserve = &universal_reserve, .restart = exynos4_restart, diff --git a/trunk/arch/arm/mach-exynos/mct.c b/trunk/arch/arm/mach-exynos/mct.c index 897d9a9cf226..b601fb8a408b 100644 --- a/trunk/arch/arm/mach-exynos/mct.c +++ b/trunk/arch/arm/mach-exynos/mct.c @@ -388,6 +388,7 @@ static int __cpuinit exynos4_local_timer_setup(struct clock_event_device *evt) { struct mct_clock_event_device *mevt; unsigned int cpu = smp_processor_id(); + int mct_lx_irq; mevt = this_cpu_ptr(&percpu_mct_tick); mevt->evt = evt; @@ -414,14 +415,18 @@ static int __cpuinit exynos4_local_timer_setup(struct clock_event_device *evt) if (mct_int_type == MCT_INT_SPI) { if (cpu == 0) { + mct_lx_irq = soc_is_exynos4210() ? EXYNOS4_IRQ_MCT_L0 : + EXYNOS5_IRQ_MCT_L0; mct_tick0_event_irq.dev_id = mevt; - evt->irq = EXYNOS4_IRQ_MCT_L0; - setup_irq(EXYNOS4_IRQ_MCT_L0, &mct_tick0_event_irq); + evt->irq = mct_lx_irq; + setup_irq(mct_lx_irq, &mct_tick0_event_irq); } else { + mct_lx_irq = soc_is_exynos4210() ? EXYNOS4_IRQ_MCT_L1 : + EXYNOS5_IRQ_MCT_L1; mct_tick1_event_irq.dev_id = mevt; - evt->irq = EXYNOS4_IRQ_MCT_L1; - setup_irq(EXYNOS4_IRQ_MCT_L1, &mct_tick1_event_irq); - irq_set_affinity(EXYNOS4_IRQ_MCT_L1, cpumask_of(1)); + evt->irq = mct_lx_irq; + setup_irq(mct_lx_irq, &mct_tick1_event_irq); + irq_set_affinity(mct_lx_irq, cpumask_of(1)); } } else { enable_percpu_irq(EXYNOS_IRQ_MCT_LOCALTIMER, 0); @@ -473,7 +478,7 @@ static void __init exynos4_timer_resources(void) static void __init exynos4_timer_init(void) { - if (soc_is_exynos4210()) + if ((soc_is_exynos4210()) || (soc_is_exynos5250())) mct_int_type = MCT_INT_SPI; else mct_int_type = MCT_INT_PPI; diff --git a/trunk/arch/arm/mach-exynos/pm.c b/trunk/arch/arm/mach-exynos/pm.c index 428cfeb57724..c06c992943a1 100644 --- a/trunk/arch/arm/mach-exynos/pm.c +++ b/trunk/arch/arm/mach-exynos/pm.c @@ -1,9 +1,8 @@ -/* linux/arch/arm/mach-exynos4/pm.c - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. +/* + * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd. * http://www.samsung.com * - * EXYNOS4210 - Power Management support + * EXYNOS - Power Management support * * Based on arch/arm/mach-s3c2410/pm.c * Copyright (c) 2006 Simtec Electronics @@ -63,90 +62,7 @@ static struct sleep_save exynos4_vpll_save[] = { SAVE_ITEM(EXYNOS4_VPLL_CON1), }; -static struct sleep_save exynos4_core_save[] = { - /* GIC side */ - SAVE_ITEM(S5P_VA_GIC_CPU + 0x000), - SAVE_ITEM(S5P_VA_GIC_CPU + 0x004), - SAVE_ITEM(S5P_VA_GIC_CPU + 0x008), - SAVE_ITEM(S5P_VA_GIC_CPU + 0x00C), - SAVE_ITEM(S5P_VA_GIC_CPU + 0x014), - SAVE_ITEM(S5P_VA_GIC_CPU + 0x018), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x000), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x004), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x100), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x104), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x108), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x300), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x304), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x308), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x400), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x404), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x408), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x40C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x410), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x414), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x418), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x41C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x420), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x424), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x428), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x42C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x430), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x434), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x438), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x43C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x440), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x444), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x448), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x44C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x450), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x454), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x458), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x45C), - - SAVE_ITEM(S5P_VA_GIC_DIST + 0x800), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x804), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x808), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x80C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x810), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x814), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x818), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x81C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x820), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x824), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x828), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x82C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x830), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x834), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x838), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x83C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x840), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x844), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x848), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x84C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x850), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x854), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x858), - SAVE_ITEM(S5P_VA_GIC_DIST + 0x85C), - - SAVE_ITEM(S5P_VA_GIC_DIST + 0xC00), - SAVE_ITEM(S5P_VA_GIC_DIST + 0xC04), - SAVE_ITEM(S5P_VA_GIC_DIST + 0xC08), - SAVE_ITEM(S5P_VA_GIC_DIST + 0xC0C), - SAVE_ITEM(S5P_VA_GIC_DIST + 0xC10), - SAVE_ITEM(S5P_VA_GIC_DIST + 0xC14), - - SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x000), - SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x010), - SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x020), - SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x030), - SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x040), - SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x050), - SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x060), - SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x070), - SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x080), - SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x090), - +static struct sleep_save exynos_core_save[] = { /* SROM side */ SAVE_ITEM(S5P_SROM_BW), SAVE_ITEM(S5P_SROM_BC0), @@ -159,9 +75,11 @@ static struct sleep_save exynos4_core_save[] = { /* For Cortex-A9 Diagnostic and Power control register */ static unsigned int save_arm_register[2]; -static int exynos4_cpu_suspend(unsigned long arg) +static int exynos_cpu_suspend(unsigned long arg) { +#ifdef CONFIG_CACHE_L2X0 outer_flush_all(); +#endif /* issue the standby signal into the pm unit. */ cpu_do_idle(); @@ -170,19 +88,25 @@ static int exynos4_cpu_suspend(unsigned long arg) panic("sleep resumed to originator?"); } -static void exynos4_pm_prepare(void) +static void exynos_pm_prepare(void) { - u32 tmp; + unsigned int tmp; - s3c_pm_do_save(exynos4_core_save, ARRAY_SIZE(exynos4_core_save)); - s3c_pm_do_save(exynos4_epll_save, ARRAY_SIZE(exynos4_epll_save)); - s3c_pm_do_save(exynos4_vpll_save, ARRAY_SIZE(exynos4_vpll_save)); + s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save)); - tmp = __raw_readl(S5P_INFORM1); + if (!soc_is_exynos5250()) { + s3c_pm_do_save(exynos4_epll_save, ARRAY_SIZE(exynos4_epll_save)); + s3c_pm_do_save(exynos4_vpll_save, ARRAY_SIZE(exynos4_vpll_save)); + } else { + /* Disable USE_RETENTION of JPEG_MEM_OPTION */ + tmp = __raw_readl(EXYNOS5_JPEG_MEM_OPTION); + tmp &= ~EXYNOS5_OPTION_USE_RETENTION; + __raw_writel(tmp, EXYNOS5_JPEG_MEM_OPTION); + } /* Set value of power down register for sleep mode */ - exynos4_sys_powerdown_conf(SYS_SLEEP); + exynos_sys_powerdown_conf(SYS_SLEEP); __raw_writel(S5P_CHECK_SLEEP, S5P_INFORM1); /* ensure at least INFORM0 has the resume address */ @@ -191,17 +115,18 @@ static void exynos4_pm_prepare(void) /* Before enter central sequence mode, clock src register have to set */ - s3c_pm_do_restore_core(exynos4_set_clksrc, ARRAY_SIZE(exynos4_set_clksrc)); + if (!soc_is_exynos5250()) + s3c_pm_do_restore_core(exynos4_set_clksrc, ARRAY_SIZE(exynos4_set_clksrc)); if (soc_is_exynos4210()) s3c_pm_do_restore_core(exynos4210_set_clksrc, ARRAY_SIZE(exynos4210_set_clksrc)); } -static int exynos4_pm_add(struct device *dev, struct subsys_interface *sif) +static int exynos_pm_add(struct device *dev, struct subsys_interface *sif) { - pm_cpu_prep = exynos4_pm_prepare; - pm_cpu_sleep = exynos4_cpu_suspend; + pm_cpu_prep = exynos_pm_prepare; + pm_cpu_sleep = exynos_cpu_suspend; return 0; } @@ -273,13 +198,13 @@ static void exynos4_restore_pll(void) } while (epll_wait || vpll_wait); } -static struct subsys_interface exynos4_pm_interface = { - .name = "exynos4_pm", - .subsys = &exynos4_subsys, - .add_dev = exynos4_pm_add, +static struct subsys_interface exynos_pm_interface = { + .name = "exynos_pm", + .subsys = &exynos_subsys, + .add_dev = exynos_pm_add, }; -static __init int exynos4_pm_drvinit(void) +static __init int exynos_pm_drvinit(void) { struct clk *pll_base; unsigned int tmp; @@ -292,18 +217,20 @@ static __init int exynos4_pm_drvinit(void) tmp |= ((0xFF << 8) | (0x1F << 1)); __raw_writel(tmp, S5P_WAKEUP_MASK); - pll_base = clk_get(NULL, "xtal"); + if (!soc_is_exynos5250()) { + pll_base = clk_get(NULL, "xtal"); - if (!IS_ERR(pll_base)) { - pll_base_rate = clk_get_rate(pll_base); - clk_put(pll_base); + if (!IS_ERR(pll_base)) { + pll_base_rate = clk_get_rate(pll_base); + clk_put(pll_base); + } } - return subsys_interface_register(&exynos4_pm_interface); + return subsys_interface_register(&exynos_pm_interface); } -arch_initcall(exynos4_pm_drvinit); +arch_initcall(exynos_pm_drvinit); -static int exynos4_pm_suspend(void) +static int exynos_pm_suspend(void) { unsigned long tmp; @@ -313,27 +240,27 @@ static int exynos4_pm_suspend(void) tmp &= ~S5P_CENTRAL_LOWPWR_CFG; __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION); - if (soc_is_exynos4212()) { - tmp = __raw_readl(S5P_CENTRAL_SEQ_OPTION); - tmp &= ~(S5P_USE_STANDBYWFI_ISP_ARM | - S5P_USE_STANDBYWFE_ISP_ARM); - __raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION); - } + /* Setting SEQ_OPTION register */ + + tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0); + __raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION); - /* Save Power control register */ - asm ("mrc p15, 0, %0, c15, c0, 0" - : "=r" (tmp) : : "cc"); - save_arm_register[0] = tmp; + if (!soc_is_exynos5250()) { + /* Save Power control register */ + asm ("mrc p15, 0, %0, c15, c0, 0" + : "=r" (tmp) : : "cc"); + save_arm_register[0] = tmp; - /* Save Diagnostic register */ - asm ("mrc p15, 0, %0, c15, c0, 1" - : "=r" (tmp) : : "cc"); - save_arm_register[1] = tmp; + /* Save Diagnostic register */ + asm ("mrc p15, 0, %0, c15, c0, 1" + : "=r" (tmp) : : "cc"); + save_arm_register[1] = tmp; + } return 0; } -static void exynos4_pm_resume(void) +static void exynos_pm_resume(void) { unsigned long tmp; @@ -350,17 +277,19 @@ static void exynos4_pm_resume(void) /* No need to perform below restore code */ goto early_wakeup; } - /* Restore Power control register */ - tmp = save_arm_register[0]; - asm volatile ("mcr p15, 0, %0, c15, c0, 0" - : : "r" (tmp) - : "cc"); - - /* Restore Diagnostic register */ - tmp = save_arm_register[1]; - asm volatile ("mcr p15, 0, %0, c15, c0, 1" - : : "r" (tmp) - : "cc"); + if (!soc_is_exynos5250()) { + /* Restore Power control register */ + tmp = save_arm_register[0]; + asm volatile ("mcr p15, 0, %0, c15, c0, 0" + : : "r" (tmp) + : "cc"); + + /* Restore Diagnostic register */ + tmp = save_arm_register[1]; + asm volatile ("mcr p15, 0, %0, c15, c0, 1" + : : "r" (tmp) + : "cc"); + } /* For release retention */ @@ -372,26 +301,28 @@ static void exynos4_pm_resume(void) __raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION); __raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION); - s3c_pm_do_restore_core(exynos4_core_save, ARRAY_SIZE(exynos4_core_save)); + s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save)); - exynos4_restore_pll(); + if (!soc_is_exynos5250()) { + exynos4_restore_pll(); #ifdef CONFIG_SMP - scu_enable(S5P_VA_SCU); + scu_enable(S5P_VA_SCU); #endif + } early_wakeup: return; } -static struct syscore_ops exynos4_pm_syscore_ops = { - .suspend = exynos4_pm_suspend, - .resume = exynos4_pm_resume, +static struct syscore_ops exynos_pm_syscore_ops = { + .suspend = exynos_pm_suspend, + .resume = exynos_pm_resume, }; -static __init int exynos4_pm_syscore_init(void) +static __init int exynos_pm_syscore_init(void) { - register_syscore_ops(&exynos4_pm_syscore_ops); + register_syscore_ops(&exynos_pm_syscore_ops); return 0; } -arch_initcall(exynos4_pm_syscore_init); +arch_initcall(exynos_pm_syscore_init); diff --git a/trunk/arch/arm/mach-exynos/pm_domains.c b/trunk/arch/arm/mach-exynos/pm_domains.c index 13b306808b42..e9fafcf163de 100644 --- a/trunk/arch/arm/mach-exynos/pm_domains.c +++ b/trunk/arch/arm/mach-exynos/pm_domains.c @@ -193,9 +193,8 @@ static __init int exynos4_pm_init_power_domain(void) } arch_initcall(exynos4_pm_init_power_domain); -static __init int exynos_pm_late_initcall(void) +int __init exynos_pm_late_initcall(void) { pm_genpd_poweroff_unused(); return 0; } -late_initcall(exynos_pm_late_initcall); diff --git a/trunk/arch/arm/mach-exynos/pmu.c b/trunk/arch/arm/mach-exynos/pmu.c index bba48f5c3e8f..4aacb66f7161 100644 --- a/trunk/arch/arm/mach-exynos/pmu.c +++ b/trunk/arch/arm/mach-exynos/pmu.c @@ -1,9 +1,8 @@ -/* linux/arch/arm/mach-exynos4/pmu.c - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. +/* + * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd. * http://www.samsung.com/ * - * EXYNOS4210 - CPU PMU(Power Management Unit) support + * EXYNOS - CPU PMU(Power Management Unit) 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 @@ -12,13 +11,14 @@ #include #include +#include #include #include -static struct exynos4_pmu_conf *exynos4_pmu_config; +static struct exynos_pmu_conf *exynos_pmu_config; -static struct exynos4_pmu_conf exynos4210_pmu_config[] = { +static struct exynos_pmu_conf exynos4210_pmu_config[] = { /* { .reg = address, .val = { AFTR, LPA, SLEEP } */ { S5P_ARM_CORE0_LOWPWR, { 0x0, 0x0, 0x2 } }, { S5P_DIS_IRQ_CORE0, { 0x0, 0x0, 0x0 } }, @@ -94,7 +94,7 @@ static struct exynos4_pmu_conf exynos4210_pmu_config[] = { { PMU_TABLE_END,}, }; -static struct exynos4_pmu_conf exynos4212_pmu_config[] = { +static struct exynos_pmu_conf exynos4x12_pmu_config[] = { { S5P_ARM_CORE0_LOWPWR, { 0x0, 0x0, 0x2 } }, { S5P_DIS_IRQ_CORE0, { 0x0, 0x0, 0x0 } }, { S5P_DIS_IRQ_CENTRAL0, { 0x0, 0x0, 0x0 } }, @@ -202,29 +202,209 @@ static struct exynos4_pmu_conf exynos4212_pmu_config[] = { { PMU_TABLE_END,}, }; -void exynos4_sys_powerdown_conf(enum sys_powerdown mode) +static struct exynos_pmu_conf exynos4412_pmu_config[] = { + { S5P_ARM_CORE2_LOWPWR, { 0x0, 0x0, 0x2 } }, + { S5P_DIS_IRQ_CORE2, { 0x0, 0x0, 0x0 } }, + { S5P_DIS_IRQ_CENTRAL2, { 0x0, 0x0, 0x0 } }, + { S5P_ARM_CORE3_LOWPWR, { 0x0, 0x0, 0x2 } }, + { S5P_DIS_IRQ_CORE3, { 0x0, 0x0, 0x0 } }, + { S5P_DIS_IRQ_CENTRAL3, { 0x0, 0x0, 0x0 } }, + { PMU_TABLE_END,}, +}; + +static struct exynos_pmu_conf exynos5250_pmu_config[] = { + /* { .reg = address, .val = { AFTR, LPA, SLEEP } */ + { EXYNOS5_ARM_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x2} }, + { EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_ARM_CORE1_SYS_PWR_REG, { 0x0, 0x0, 0x2} }, + { EXYNOS5_DIS_IRQ_ARM_CORE1_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { EXYNOS5_FSYS_ARM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_DIS_IRQ_FSYS_ARM_CENTRAL_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, + { EXYNOS5_ISP_ARM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, + { 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_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} }, + { EXYNOS5_CMU_ACLKSTOP_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, + { EXYNOS5_CMU_SCLKSTOP_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, + { EXYNOS5_CMU_RESET_SYSMEM_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_DRAM_FREQ_DOWN_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, + { EXYNOS5_DDRPHY_DLLOFF_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, + { EXYNOS5_DDRPHY_DLLLOCK_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, + { EXYNOS5_APLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_MPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_VPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_EPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_BPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_MPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_BPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_TOP_BUS_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_TOP_RETENTION_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, + { EXYNOS5_TOP_PWR_SYS_PWR_REG, { 0x3, 0x0, 0x3} }, + { EXYNOS5_TOP_BUS_SYSMEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_TOP_RETENTION_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, + { EXYNOS5_TOP_PWR_SYSMEM_SYS_PWR_REG, { 0x3, 0x0, 0x3} }, + { EXYNOS5_LOGIC_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_OSCCLK_GATE_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, + { EXYNOS5_LOGIC_RESET_SYSMEM_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_OSCCLK_GATE_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, + { EXYNOS5_USBOTG_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_G2D_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_USBDRD_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_SDMMC_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_CSSYS_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_SECSS_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_ROTATOR_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_INTRAM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_INTROM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_JPEG_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_HSI_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_MCUIOP_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_SATA_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, + { EXYNOS5_PAD_RETENTION_DRAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_PAD_RETENTION_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_PAD_RETENTION_GPIO_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_PAD_RETENTION_UART_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_PAD_RETENTION_MMCA_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_PAD_RETENTION_MMCB_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_PAD_RETENTION_EBIA_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_PAD_RETENTION_EBIB_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_PAD_RETENTION_SPI_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_PAD_RETENTION_GPIO_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_PAD_ISOLATION_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_PAD_ISOLATION_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_PAD_ALV_SEL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_XUSBXTI_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, + { EXYNOS5_XXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_EXT_REGULATOR_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_GPIO_MODE_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_GPIO_MODE_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_GPIO_MODE_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_TOP_ASB_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, + { EXYNOS5_TOP_ASB_ISOLATION_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, + { EXYNOS5_GSCL_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5_ISP_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5_MFC_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5_G3D_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5_DISP1_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, + { EXYNOS5_MAU_SYS_PWR_REG, { 0x7, 0x7, 0x0} }, + { EXYNOS5_CMU_CLKSTOP_GSCL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_CLKSTOP_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_CLKSTOP_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_CLKSTOP_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_CLKSTOP_DISP1_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_CLKSTOP_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_CMU_SYSCLK_GSCL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_SYSCLK_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_SYSCLK_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_SYSCLK_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_SYSCLK_DISP1_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_SYSCLK_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { EXYNOS5_CMU_RESET_GSCL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_RESET_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_RESET_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_RESET_DISP1_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, + { EXYNOS5_CMU_RESET_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, + { PMU_TABLE_END,}, +}; + +void __iomem *exynos5_list_both_cnt_feed[] = { + EXYNOS5_ARM_CORE0_OPTION, + EXYNOS5_ARM_CORE1_OPTION, + EXYNOS5_ARM_COMMON_OPTION, + EXYNOS5_GSCL_OPTION, + EXYNOS5_ISP_OPTION, + EXYNOS5_MFC_OPTION, + EXYNOS5_G3D_OPTION, + EXYNOS5_DISP1_OPTION, + EXYNOS5_MAU_OPTION, + EXYNOS5_TOP_PWR_OPTION, + EXYNOS5_TOP_PWR_SYSMEM_OPTION, +}; + +void __iomem *exynos5_list_diable_wfi_wfe[] = { + EXYNOS5_ARM_CORE1_OPTION, + EXYNOS5_FSYS_ARM_OPTION, + EXYNOS5_ISP_ARM_OPTION, +}; + +static void exynos5_init_pmu(void) { unsigned int i; + unsigned int tmp; - for (i = 0; (exynos4_pmu_config[i].reg != PMU_TABLE_END) ; i++) - __raw_writel(exynos4_pmu_config[i].val[mode], - exynos4_pmu_config[i].reg); + /* + * Enable both SC_FEEDBACK and SC_COUNTER + */ + for (i = 0 ; i < ARRAY_SIZE(exynos5_list_both_cnt_feed) ; i++) { + tmp = __raw_readl(exynos5_list_both_cnt_feed[i]); + tmp |= (EXYNOS5_USE_SC_FEEDBACK | + EXYNOS5_USE_SC_COUNTER); + __raw_writel(tmp, exynos5_list_both_cnt_feed[i]); + } + + /* + * 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); + __raw_writel(tmp, EXYNOS5_ARM_COMMON_OPTION); + + /* + * Disable WFI/WFE on XXX_OPTION + */ + for (i = 0 ; i < ARRAY_SIZE(exynos5_list_diable_wfi_wfe) ; i++) { + tmp = __raw_readl(exynos5_list_diable_wfi_wfe[i]); + tmp &= ~(EXYNOS5_OPTION_USE_STANDBYWFE | + EXYNOS5_OPTION_USE_STANDBYWFI); + __raw_writel(tmp, exynos5_list_diable_wfi_wfe[i]); + } +} + +void exynos_sys_powerdown_conf(enum sys_powerdown mode) +{ + unsigned int i; + + if (soc_is_exynos5250()) + exynos5_init_pmu(); + + for (i = 0; (exynos_pmu_config[i].reg != PMU_TABLE_END) ; i++) + __raw_writel(exynos_pmu_config[i].val[mode], + exynos_pmu_config[i].reg); + + if (soc_is_exynos4412()) { + for (i = 0; exynos4412_pmu_config[i].reg != PMU_TABLE_END ; i++) + __raw_writel(exynos4412_pmu_config[i].val[mode], + exynos4412_pmu_config[i].reg); + } } -static int __init exynos4_pmu_init(void) +static int __init exynos_pmu_init(void) { - exynos4_pmu_config = exynos4210_pmu_config; + exynos_pmu_config = exynos4210_pmu_config; if (soc_is_exynos4210()) { - exynos4_pmu_config = exynos4210_pmu_config; + exynos_pmu_config = exynos4210_pmu_config; pr_info("EXYNOS4210 PMU Initialize\n"); - } else if (soc_is_exynos4212()) { - exynos4_pmu_config = exynos4212_pmu_config; - pr_info("EXYNOS4212 PMU Initialize\n"); + } else if (soc_is_exynos4212() || soc_is_exynos4412()) { + exynos_pmu_config = exynos4x12_pmu_config; + pr_info("EXYNOS4x12 PMU Initialize\n"); + } else if (soc_is_exynos5250()) { + exynos_pmu_config = exynos5250_pmu_config; + pr_info("EXYNOS5250 PMU Initialize\n"); } else { - pr_info("EXYNOS4: PMU not supported\n"); + pr_info("EXYNOS: PMU not supported\n"); } return 0; } -arch_initcall(exynos4_pmu_init); +arch_initcall(exynos_pmu_init); diff --git a/trunk/arch/arm/mach-highbank/Makefile b/trunk/arch/arm/mach-highbank/Makefile index f8437dd238c2..ded4652ada80 100644 --- a/trunk/arch/arm/mach-highbank/Makefile +++ b/trunk/arch/arm/mach-highbank/Makefile @@ -1,4 +1,8 @@ -obj-y := clock.o highbank.o system.o +obj-y := clock.o highbank.o system.o smc.o + +plus_sec := $(call as-instr,.arch_extension sec,+sec) +AFLAGS_smc.o :=-Wa,-march=armv7-a$(plus_sec) + obj-$(CONFIG_DEBUG_HIGHBANK_UART) += lluart.o obj-$(CONFIG_SMP) += platsmp.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o diff --git a/trunk/arch/arm/mach-highbank/core.h b/trunk/arch/arm/mach-highbank/core.h index d8e2d0be64ac..141ed5171826 100644 --- a/trunk/arch/arm/mach-highbank/core.h +++ b/trunk/arch/arm/mach-highbank/core.h @@ -8,3 +8,4 @@ extern void highbank_lluart_map_io(void); static inline void highbank_lluart_map_io(void) {} #endif +extern void highbank_smc1(int fn, int arg); diff --git a/trunk/arch/arm/mach-highbank/highbank.c b/trunk/arch/arm/mach-highbank/highbank.c index 410a112bb52e..8777612b1a42 100644 --- a/trunk/arch/arm/mach-highbank/highbank.c +++ b/trunk/arch/arm/mach-highbank/highbank.c @@ -85,10 +85,24 @@ const static struct of_device_id irq_match[] = { {} }; +#ifdef CONFIG_CACHE_L2X0 +static void highbank_l2x0_disable(void) +{ + /* Disable PL310 L2 Cache controller */ + highbank_smc1(0x102, 0x0); +} +#endif + static void __init highbank_init_irq(void) { of_irq_init(irq_match); + +#ifdef CONFIG_CACHE_L2X0 + /* Enable PL310 L2 Cache controller */ + highbank_smc1(0x102, 0x1); l2x0_of_init(0, ~0UL); + outer_cache.disable = highbank_l2x0_disable; +#endif } static void __init highbank_timer_init(void) diff --git a/trunk/arch/arm/mach-highbank/smc.S b/trunk/arch/arm/mach-highbank/smc.S new file mode 100644 index 000000000000..407d17baaaa9 --- /dev/null +++ b/trunk/arch/arm/mach-highbank/smc.S @@ -0,0 +1,27 @@ +/* + * Copied from omap44xx-smc.S Copyright (C) 2010 Texas Instruments, Inc. + * Copyright 2012 Calxeda, 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 + +/* + * This is common routine to manage secure monitor API + * used to modify the PL310 secure registers. + * 'r0' contains the value to be modified and 'r12' contains + * the monitor API number. + * Function signature : void highbank_smc1(u32 fn, u32 arg) + */ + +ENTRY(highbank_smc1) + stmfd sp!, {r4-r11, lr} + mov r12, r0 + mov r0, r1 + dsb + smc #0 + ldmfd sp!, {r4-r11, pc} +ENDPROC(highbank_smc1) diff --git a/trunk/arch/arm/mach-imx/Kconfig b/trunk/arch/arm/mach-imx/Kconfig index cca8c0c74794..eff4db5de0dd 100644 --- a/trunk/arch/arm/mach-imx/Kconfig +++ b/trunk/arch/arm/mach-imx/Kconfig @@ -34,6 +34,7 @@ config ARCH_MX53 config SOC_IMX1 bool select ARCH_MX1 + select COMMON_CLK select CPU_ARM920T select IMX_HAVE_IOMUX_V1 select MXC_AVIC @@ -42,12 +43,14 @@ config SOC_IMX21 bool select MACH_MX21 select CPU_ARM926T + select COMMON_CLK select IMX_HAVE_IOMUX_V1 select MXC_AVIC config SOC_IMX25 bool select ARCH_MX25 + select COMMON_CLK select CPU_ARM926T select ARCH_MXC_IOMUX_V3 select MXC_AVIC @@ -56,6 +59,7 @@ config SOC_IMX27 bool select MACH_MX27 select CPU_ARM926T + select COMMON_CLK select IMX_HAVE_IOMUX_V1 select MXC_AVIC @@ -64,12 +68,14 @@ config SOC_IMX31 select CPU_V6 select IMX_HAVE_PLATFORM_MXC_RNGA select MXC_AVIC + select COMMON_CLK select SMP_ON_UP if SMP config SOC_IMX35 bool select CPU_V6 select ARCH_MXC_IOMUX_V3 + select COMMON_CLK select HAVE_EPIT select MXC_AVIC select SMP_ON_UP if SMP @@ -77,6 +83,7 @@ config SOC_IMX35 config SOC_IMX5 select CPU_V7 select MXC_TZIC + select COMMON_CLK select ARCH_MXC_IOMUX_V3 select ARCH_HAS_CPUFREQ select ARCH_MX5 @@ -470,6 +477,7 @@ config MACH_MX31_3DS select IMX_HAVE_PLATFORM_IMX2_WDT select IMX_HAVE_PLATFORM_IMX_I2C select IMX_HAVE_PLATFORM_IMX_KEYPAD + select IMX_HAVE_PLATFORM_IMX_SSI select IMX_HAVE_PLATFORM_IMX_UART select IMX_HAVE_PLATFORM_IPU_CORE select IMX_HAVE_PLATFORM_MXC_EHCI @@ -815,6 +823,7 @@ config SOC_IMX6Q bool "i.MX6 Quad support" select ARM_CPU_SUSPEND if PM select ARM_GIC + select COMMON_CLK select CPU_V7 select HAVE_ARM_SCU select HAVE_IMX_GPC diff --git a/trunk/arch/arm/mach-imx/Makefile b/trunk/arch/arm/mach-imx/Makefile index 4937c070a57e..ff29421414f2 100644 --- a/trunk/arch/arm/mach-imx/Makefile +++ b/trunk/arch/arm/mach-imx/Makefile @@ -1,15 +1,18 @@ -obj-$(CONFIG_SOC_IMX1) += clock-imx1.o mm-imx1.o -obj-$(CONFIG_SOC_IMX21) += clock-imx21.o mm-imx21.o +obj-$(CONFIG_SOC_IMX1) += clk-imx1.o mm-imx1.o +obj-$(CONFIG_SOC_IMX21) += clk-imx21.o mm-imx21.o -obj-$(CONFIG_SOC_IMX25) += clock-imx25.o mm-imx25.o ehci-imx25.o cpu-imx25.o +obj-$(CONFIG_SOC_IMX25) += clk-imx25.o mm-imx25.o ehci-imx25.o cpu-imx25.o obj-$(CONFIG_SOC_IMX27) += cpu-imx27.o pm-imx27.o -obj-$(CONFIG_SOC_IMX27) += clock-imx27.o mm-imx27.o ehci-imx27.o +obj-$(CONFIG_SOC_IMX27) += clk-imx27.o mm-imx27.o ehci-imx27.o -obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clock-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o -obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clock-imx35.o ehci-imx35.o pm-imx3.o +obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clk-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o +obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clk-imx35.o ehci-imx35.o pm-imx3.o -obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clock-mx51-mx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o +obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clk-imx51-imx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o + +obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \ + clk-pfd.o clk-busy.o # Support for CMOS sensor interface obj-$(CONFIG_MX1_VIDEO) += mx1-camera-fiq.o mx1-camera-fiq-ksym.o @@ -70,7 +73,7 @@ obj-$(CONFIG_CPU_V7) += head-v7.o AFLAGS_head-v7.o :=-Wa,-march=armv7-a obj-$(CONFIG_SMP) += platsmp.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o -obj-$(CONFIG_SOC_IMX6Q) += clock-imx6q.o mach-imx6q.o +obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o mach-imx6q.o ifeq ($(CONFIG_PM),y) obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o diff --git a/trunk/arch/arm/mach-imx/Makefile.boot b/trunk/arch/arm/mach-imx/Makefile.boot index 3851d8a27875..05541cf4a878 100644 --- a/trunk/arch/arm/mach-imx/Makefile.boot +++ b/trunk/arch/arm/mach-imx/Makefile.boot @@ -42,4 +42,5 @@ dtb-$(CONFIG_MACH_IMX51_DT) += imx51-babbage.dtb dtb-$(CONFIG_MACH_IMX53_DT) += imx53-ard.dtb imx53-evk.dtb \ imx53-qsb.dtb imx53-smd.dtb dtb-$(CONFIG_SOC_IMX6Q) += imx6q-arm2.dtb \ - imx6q-sabrelite.dtb + imx6q-sabrelite.dtb \ + imx6q-sabresd.dtb \ diff --git a/trunk/arch/arm/mach-imx/clk-busy.c b/trunk/arch/arm/mach-imx/clk-busy.c new file mode 100644 index 000000000000..1a7a8dd045a1 --- /dev/null +++ b/trunk/arch/arm/mach-imx/clk-busy.c @@ -0,0 +1,189 @@ +/* + * Copyright 2012 Freescale Semiconductor, Inc. + * Copyright 2012 Linaro Ltd. + * + * 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 "clk.h" + +static int clk_busy_wait(void __iomem *reg, u8 shift) +{ + unsigned long timeout = jiffies + msecs_to_jiffies(10); + + while (readl_relaxed(reg) & (1 << shift)) + if (time_after(jiffies, timeout)) + return -ETIMEDOUT; + + return 0; +} + +struct clk_busy_divider { + struct clk_divider div; + const struct clk_ops *div_ops; + void __iomem *reg; + u8 shift; +}; + +static inline struct clk_busy_divider *to_clk_busy_divider(struct clk_hw *hw) +{ + struct clk_divider *div = container_of(hw, struct clk_divider, hw); + + return container_of(div, struct clk_busy_divider, div); +} + +static unsigned long clk_busy_divider_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_busy_divider *busy = to_clk_busy_divider(hw); + + return busy->div_ops->recalc_rate(&busy->div.hw, parent_rate); +} + +static long clk_busy_divider_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + struct clk_busy_divider *busy = to_clk_busy_divider(hw); + + return busy->div_ops->round_rate(&busy->div.hw, rate, prate); +} + +static int clk_busy_divider_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_busy_divider *busy = to_clk_busy_divider(hw); + int ret; + + ret = busy->div_ops->set_rate(&busy->div.hw, rate, parent_rate); + if (!ret) + ret = clk_busy_wait(busy->reg, busy->shift); + + return ret; +} + +static struct clk_ops clk_busy_divider_ops = { + .recalc_rate = clk_busy_divider_recalc_rate, + .round_rate = clk_busy_divider_round_rate, + .set_rate = clk_busy_divider_set_rate, +}; + +struct clk *imx_clk_busy_divider(const char *name, const char *parent_name, + void __iomem *reg, u8 shift, u8 width, + void __iomem *busy_reg, u8 busy_shift) +{ + struct clk_busy_divider *busy; + struct clk *clk; + struct clk_init_data init; + + busy = kzalloc(sizeof(*busy), GFP_KERNEL); + if (!busy) + return ERR_PTR(-ENOMEM); + + busy->reg = busy_reg; + busy->shift = busy_shift; + + busy->div.reg = reg; + busy->div.shift = shift; + busy->div.width = width; + busy->div.lock = &imx_ccm_lock; + busy->div_ops = &clk_divider_ops; + + init.name = name; + init.ops = &clk_busy_divider_ops; + init.flags = CLK_SET_RATE_PARENT; + init.parent_names = &parent_name; + init.num_parents = 1; + + busy->div.hw.init = &init; + + clk = clk_register(NULL, &busy->div.hw); + if (!clk) + kfree(busy); + + return clk; +} + +struct clk_busy_mux { + struct clk_mux mux; + const struct clk_ops *mux_ops; + void __iomem *reg; + u8 shift; +}; + +static inline struct clk_busy_mux *to_clk_busy_mux(struct clk_hw *hw) +{ + struct clk_mux *mux = container_of(hw, struct clk_mux, hw); + + return container_of(mux, struct clk_busy_mux, mux); +} + +static u8 clk_busy_mux_get_parent(struct clk_hw *hw) +{ + struct clk_busy_mux *busy = to_clk_busy_mux(hw); + + return busy->mux_ops->get_parent(&busy->mux.hw); +} + +static int clk_busy_mux_set_parent(struct clk_hw *hw, u8 index) +{ + struct clk_busy_mux *busy = to_clk_busy_mux(hw); + int ret; + + ret = busy->mux_ops->set_parent(&busy->mux.hw, index); + if (!ret) + ret = clk_busy_wait(busy->reg, busy->shift); + + return ret; +} + +struct clk_ops clk_busy_mux_ops = { + .get_parent = clk_busy_mux_get_parent, + .set_parent = clk_busy_mux_set_parent, +}; + +struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift, + u8 width, void __iomem *busy_reg, u8 busy_shift, + const char **parent_names, int num_parents) +{ + struct clk_busy_mux *busy; + struct clk *clk; + struct clk_init_data init; + + busy = kzalloc(sizeof(*busy), GFP_KERNEL); + if (!busy) + return ERR_PTR(-ENOMEM); + + busy->reg = busy_reg; + busy->shift = busy_shift; + + busy->mux.reg = reg; + busy->mux.shift = shift; + busy->mux.width = width; + busy->mux.lock = &imx_ccm_lock; + busy->mux_ops = &clk_mux_ops; + + init.name = name; + init.ops = &clk_busy_mux_ops; + init.flags = 0; + init.parent_names = parent_names; + init.num_parents = num_parents; + + busy->mux.hw.init = &init; + + clk = clk_register(NULL, &busy->mux.hw); + if (IS_ERR(clk)) + kfree(busy); + + return clk; +} diff --git a/trunk/arch/arm/mach-imx/clk-gate2.c b/trunk/arch/arm/mach-imx/clk-gate2.c new file mode 100644 index 000000000000..3c1b8ff9a0a6 --- /dev/null +++ b/trunk/arch/arm/mach-imx/clk-gate2.c @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2010-2011 Canonical Ltd + * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd + * + * 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. + * + * Gated clock implementation + */ + +#include +#include +#include +#include +#include +#include + +/** + * DOC: basic gatable clock which can gate and ungate it's ouput + * + * Traits of this clock: + * prepare - clk_(un)prepare only ensures parent is (un)prepared + * enable - clk_enable and clk_disable are functional & control gating + * rate - inherits rate from parent. No clk_set_rate support + * parent - fixed parent. No clk_set_parent support + */ + +#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) + +static int clk_gate2_enable(struct clk_hw *hw) +{ + struct clk_gate *gate = to_clk_gate(hw); + u32 reg; + unsigned long flags = 0; + + if (gate->lock) + spin_lock_irqsave(gate->lock, flags); + + reg = readl(gate->reg); + reg |= 3 << gate->bit_idx; + writel(reg, gate->reg); + + if (gate->lock) + spin_unlock_irqrestore(gate->lock, flags); + + return 0; +} + +static void clk_gate2_disable(struct clk_hw *hw) +{ + struct clk_gate *gate = to_clk_gate(hw); + u32 reg; + unsigned long flags = 0; + + if (gate->lock) + spin_lock_irqsave(gate->lock, flags); + + reg = readl(gate->reg); + reg &= ~(3 << gate->bit_idx); + writel(reg, gate->reg); + + if (gate->lock) + spin_unlock_irqrestore(gate->lock, flags); +} + +static int clk_gate2_is_enabled(struct clk_hw *hw) +{ + u32 reg; + struct clk_gate *gate = to_clk_gate(hw); + + reg = readl(gate->reg); + + if (((reg >> gate->bit_idx) & 3) == 3) + return 1; + + return 0; +} + +static struct clk_ops clk_gate2_ops = { + .enable = clk_gate2_enable, + .disable = clk_gate2_disable, + .is_enabled = clk_gate2_is_enabled, +}; + +struct clk *clk_register_gate2(struct device *dev, const char *name, + const char *parent_name, unsigned long flags, + void __iomem *reg, u8 bit_idx, + u8 clk_gate2_flags, spinlock_t *lock) +{ + struct clk_gate *gate; + struct clk *clk; + struct clk_init_data init; + + gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); + if (!gate) + return ERR_PTR(-ENOMEM); + + /* struct clk_gate assignments */ + gate->reg = reg; + gate->bit_idx = bit_idx; + gate->flags = clk_gate2_flags; + gate->lock = lock; + + init.name = name; + init.ops = &clk_gate2_ops; + init.flags = flags; + init.parent_names = parent_name ? &parent_name : NULL; + init.num_parents = parent_name ? 1 : 0; + + gate->hw.init = &init; + + clk = clk_register(dev, &gate->hw); + if (IS_ERR(clk)) + kfree(clk); + + return clk; +} diff --git a/trunk/arch/arm/mach-imx/clk-imx1.c b/trunk/arch/arm/mach-imx/clk-imx1.c new file mode 100644 index 000000000000..516ddee1948e --- /dev/null +++ b/trunk/arch/arm/mach-imx/clk-imx1.c @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2008 Sascha Hauer , Pengutronix + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include "clk.h" + +/* CCM register addresses */ +#define IO_ADDR_CCM(off) (MX1_IO_ADDRESS(MX1_CCM_BASE_ADDR + (off))) + +#define CCM_CSCR IO_ADDR_CCM(0x0) +#define CCM_MPCTL0 IO_ADDR_CCM(0x4) +#define CCM_SPCTL0 IO_ADDR_CCM(0xc) +#define CCM_PCDR IO_ADDR_CCM(0x20) + +/* SCM register addresses */ +#define IO_ADDR_SCM(off) (MX1_IO_ADDRESS(MX1_SCM_BASE_ADDR + (off))) + +#define SCM_GCCR IO_ADDR_SCM(0xc) + +static const char *prem_sel_clks[] = { "clk32_premult", "clk16m", }; +static const char *clko_sel_clks[] = { "per1", "hclk", "clk48m", "clk16m", "prem", + "fclk", }; +enum imx1_clks { + dummy, clk32, clk16m_ext, clk16m, clk32_premult, prem, mpll, spll, mcu, + fclk, hclk, clk48m, per1, per2, per3, clko, dma_gate, csi_gate, + mma_gate, usbd_gate, clk_max +}; + +static struct clk *clk[clk_max]; + +int __init mx1_clocks_init(unsigned long fref) +{ + int i; + + clk[dummy] = imx_clk_fixed("dummy", 0); + clk[clk32] = imx_clk_fixed("clk32", fref); + clk[clk16m_ext] = imx_clk_fixed("clk16m_ext", 16000000); + clk[clk16m] = imx_clk_gate("clk16m", "clk16m_ext", CCM_CSCR, 17); + clk[clk32_premult] = imx_clk_fixed_factor("clk32_premult", "clk32", 512, 1); + clk[prem] = imx_clk_mux("prem", CCM_CSCR, 16, 1, prem_sel_clks, + ARRAY_SIZE(prem_sel_clks)); + clk[mpll] = imx_clk_pllv1("mpll", "clk32_premult", CCM_MPCTL0); + clk[spll] = imx_clk_pllv1("spll", "prem", CCM_SPCTL0); + clk[mcu] = imx_clk_divider("mcu", "clk32_premult", CCM_CSCR, 15, 1); + clk[fclk] = imx_clk_divider("fclk", "mpll", CCM_CSCR, 15, 1); + clk[hclk] = imx_clk_divider("hclk", "spll", CCM_CSCR, 10, 4); + clk[clk48m] = imx_clk_divider("clk48m", "spll", CCM_CSCR, 26, 3); + clk[per1] = imx_clk_divider("per1", "spll", CCM_PCDR, 0, 4); + clk[per2] = imx_clk_divider("per2", "spll", CCM_PCDR, 4, 4); + clk[per3] = imx_clk_divider("per3", "spll", CCM_PCDR, 16, 7); + clk[clko] = imx_clk_mux("clko", CCM_CSCR, 29, 3, clko_sel_clks, + ARRAY_SIZE(clko_sel_clks)); + clk[dma_gate] = imx_clk_gate("dma_gate", "hclk", SCM_GCCR, 4); + clk[csi_gate] = imx_clk_gate("csi_gate", "hclk", SCM_GCCR, 2); + clk[mma_gate] = imx_clk_gate("mma_gate", "hclk", SCM_GCCR, 1); + clk[usbd_gate] = imx_clk_gate("usbd_gate", "clk48m", SCM_GCCR, 0); + + for (i = 0; i < ARRAY_SIZE(clk); i++) + if (IS_ERR(clk[i])) + pr_err("imx1 clk %d: register failed with %ld\n", + i, PTR_ERR(clk[i])); + + clk_register_clkdev(clk[dma_gate], "ahb", "imx-dma"); + clk_register_clkdev(clk[csi_gate], NULL, "mx1-camera.0"); + clk_register_clkdev(clk[mma_gate], "mma", NULL); + clk_register_clkdev(clk[usbd_gate], NULL, "imx_udc.0"); + clk_register_clkdev(clk[per1], "per", "imx-gpt.0"); + clk_register_clkdev(clk[hclk], "ipg", "imx-gpt.0"); + clk_register_clkdev(clk[per1], "per", "imx1-uart.0"); + clk_register_clkdev(clk[hclk], "ipg", "imx1-uart.0"); + clk_register_clkdev(clk[per1], "per", "imx1-uart.1"); + clk_register_clkdev(clk[hclk], "ipg", "imx1-uart.1"); + clk_register_clkdev(clk[per1], "per", "imx1-uart.2"); + clk_register_clkdev(clk[hclk], "ipg", "imx1-uart.2"); + clk_register_clkdev(clk[hclk], NULL, "imx-i2c.0"); + clk_register_clkdev(clk[per2], "per", "imx1-cspi.0"); + clk_register_clkdev(clk[dummy], "ipg", "imx1-cspi.0"); + clk_register_clkdev(clk[per2], "per", "imx1-cspi.1"); + clk_register_clkdev(clk[dummy], "ipg", "imx1-cspi.1"); + clk_register_clkdev(clk[per2], NULL, "imx-mmc.0"); + clk_register_clkdev(clk[per2], "per", "imx-fb.0"); + clk_register_clkdev(clk[dummy], "ipg", "imx-fb.0"); + clk_register_clkdev(clk[dummy], "ahb", "imx-fb.0"); + clk_register_clkdev(clk[hclk], "mshc", NULL); + clk_register_clkdev(clk[per3], "ssi", NULL); + clk_register_clkdev(clk[clk32], NULL, "mxc_rtc.0"); + clk_register_clkdev(clk[clko], "clko", NULL); + + mxc_timer_init(MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR), MX1_TIM1_INT); + + return 0; +} diff --git a/trunk/arch/arm/mach-imx/clk-imx21.c b/trunk/arch/arm/mach-imx/clk-imx21.c new file mode 100644 index 000000000000..ea13e61bd5f3 --- /dev/null +++ b/trunk/arch/arm/mach-imx/clk-imx21.c @@ -0,0 +1,186 @@ +/* + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "clk.h" + +#define IO_ADDR_CCM(off) (MX21_IO_ADDRESS(MX21_CCM_BASE_ADDR + (off))) + +/* Register offsets */ +#define CCM_CSCR IO_ADDR_CCM(0x0) +#define CCM_MPCTL0 IO_ADDR_CCM(0x4) +#define CCM_MPCTL1 IO_ADDR_CCM(0x8) +#define CCM_SPCTL0 IO_ADDR_CCM(0xc) +#define CCM_SPCTL1 IO_ADDR_CCM(0x10) +#define CCM_OSC26MCTL IO_ADDR_CCM(0x14) +#define CCM_PCDR0 IO_ADDR_CCM(0x18) +#define CCM_PCDR1 IO_ADDR_CCM(0x1c) +#define CCM_PCCR0 IO_ADDR_CCM(0x20) +#define CCM_PCCR1 IO_ADDR_CCM(0x24) +#define CCM_CCSR IO_ADDR_CCM(0x28) +#define CCM_PMCTL IO_ADDR_CCM(0x2c) +#define CCM_PMCOUNT IO_ADDR_CCM(0x30) +#define CCM_WKGDCTL IO_ADDR_CCM(0x34) + +static const char *mpll_sel_clks[] = { "fpm", "ckih", }; +static const char *spll_sel_clks[] = { "fpm", "ckih", }; + +enum imx21_clks { + ckil, ckih, fpm, mpll_sel, spll_sel, mpll, spll, fclk, hclk, ipg, per1, + per2, per3, per4, uart1_ipg_gate, uart2_ipg_gate, uart3_ipg_gate, + uart4_ipg_gate, gpt1_ipg_gate, gpt2_ipg_gate, gpt3_ipg_gate, + pwm_ipg_gate, sdhc1_ipg_gate, sdhc2_ipg_gate, lcdc_ipg_gate, + lcdc_hclk_gate, cspi3_ipg_gate, cspi2_ipg_gate, cspi1_ipg_gate, + per4_gate, csi_hclk_gate, usb_div, usb_gate, usb_hclk_gate, ssi1_gate, + ssi2_gate, nfc_div, nfc_gate, dma_gate, dma_hclk_gate, brom_gate, + emma_gate, emma_hclk_gate, slcdc_gate, slcdc_hclk_gate, wdog_gate, + gpio_gate, i2c_gate, kpp_gate, owire_gate, rtc_gate, clk_max +}; + +static struct clk *clk[clk_max]; + +/* + * must be called very early to get information about the + * available clock rate when the timer framework starts + */ +int __init mx21_clocks_init(unsigned long lref, unsigned long href) +{ + int i; + + clk[ckil] = imx_clk_fixed("ckil", lref); + clk[ckih] = imx_clk_fixed("ckih", href); + clk[fpm] = imx_clk_fixed_factor("fpm", "ckil", 512, 1); + clk[mpll_sel] = imx_clk_mux("mpll_sel", CCM_CSCR, 16, 1, mpll_sel_clks, + ARRAY_SIZE(mpll_sel_clks)); + clk[spll_sel] = imx_clk_mux("spll_sel", CCM_CSCR, 17, 1, spll_sel_clks, + ARRAY_SIZE(spll_sel_clks)); + clk[mpll] = imx_clk_pllv1("mpll", "mpll_sel", CCM_MPCTL0); + clk[spll] = imx_clk_pllv1("spll", "spll_sel", CCM_SPCTL0); + clk[fclk] = imx_clk_divider("fclk", "mpll", CCM_CSCR, 29, 3); + clk[hclk] = imx_clk_divider("hclk", "fclk", CCM_CSCR, 10, 4); + clk[ipg] = imx_clk_divider("ipg", "hclk", CCM_CSCR, 9, 1); + clk[per1] = imx_clk_divider("per1", "mpll", CCM_PCDR1, 0, 6); + clk[per2] = imx_clk_divider("per2", "mpll", CCM_PCDR1, 8, 6); + clk[per3] = imx_clk_divider("per3", "mpll", CCM_PCDR1, 16, 6); + clk[per4] = imx_clk_divider("per4", "mpll", CCM_PCDR1, 24, 6); + clk[uart1_ipg_gate] = imx_clk_gate("uart1_ipg_gate", "ipg", CCM_PCCR0, 0); + clk[uart2_ipg_gate] = imx_clk_gate("uart2_ipg_gate", "ipg", CCM_PCCR0, 1); + clk[uart3_ipg_gate] = imx_clk_gate("uart3_ipg_gate", "ipg", CCM_PCCR0, 2); + clk[uart4_ipg_gate] = imx_clk_gate("uart4_ipg_gate", "ipg", CCM_PCCR0, 3); + clk[gpt1_ipg_gate] = imx_clk_gate("gpt1_ipg_gate", "ipg", CCM_PCCR1, 25); + clk[gpt2_ipg_gate] = imx_clk_gate("gpt2_ipg_gate", "ipg", CCM_PCCR1, 26); + clk[gpt3_ipg_gate] = imx_clk_gate("gpt3_ipg_gate", "ipg", CCM_PCCR1, 27); + clk[pwm_ipg_gate] = imx_clk_gate("pwm_ipg_gate", "ipg", CCM_PCCR1, 28); + clk[sdhc1_ipg_gate] = imx_clk_gate("sdhc1_ipg_gate", "ipg", CCM_PCCR0, 9); + clk[sdhc2_ipg_gate] = imx_clk_gate("sdhc2_ipg_gate", "ipg", CCM_PCCR0, 10); + clk[lcdc_ipg_gate] = imx_clk_gate("lcdc_ipg_gate", "ipg", CCM_PCCR0, 18); + clk[lcdc_hclk_gate] = imx_clk_gate("lcdc_hclk_gate", "hclk", CCM_PCCR0, 26); + clk[cspi3_ipg_gate] = imx_clk_gate("cspi3_ipg_gate", "ipg", CCM_PCCR1, 23); + clk[cspi2_ipg_gate] = imx_clk_gate("cspi2_ipg_gate", "ipg", CCM_PCCR0, 5); + clk[cspi1_ipg_gate] = imx_clk_gate("cspi1_ipg_gate", "ipg", CCM_PCCR0, 4); + clk[per4_gate] = imx_clk_gate("per4_gate", "per4", CCM_PCCR0, 22); + clk[csi_hclk_gate] = imx_clk_gate("csi_hclk_gate", "hclk", CCM_PCCR0, 31); + clk[usb_div] = imx_clk_divider("usb_div", "spll", CCM_CSCR, 26, 3); + clk[usb_gate] = imx_clk_gate("usb_gate", "usb_div", CCM_PCCR0, 14); + clk[usb_hclk_gate] = imx_clk_gate("usb_hclk_gate", "hclk", CCM_PCCR0, 24); + clk[ssi1_gate] = imx_clk_gate("ssi1_gate", "ipg", CCM_PCCR0, 6); + clk[ssi2_gate] = imx_clk_gate("ssi2_gate", "ipg", CCM_PCCR0, 7); + clk[nfc_div] = imx_clk_divider("nfc_div", "ipg", CCM_PCDR0, 12, 4); + clk[nfc_gate] = imx_clk_gate("nfc_gate", "nfc_div", CCM_PCCR0, 19); + clk[dma_gate] = imx_clk_gate("dma_gate", "ipg", CCM_PCCR0, 13); + clk[dma_hclk_gate] = imx_clk_gate("dma_hclk_gate", "hclk", CCM_PCCR0, 30); + clk[brom_gate] = imx_clk_gate("brom_gate", "hclk", CCM_PCCR0, 28); + clk[emma_gate] = imx_clk_gate("emma_gate", "ipg", CCM_PCCR0, 15); + clk[emma_hclk_gate] = imx_clk_gate("emma_hclk_gate", "hclk", CCM_PCCR0, 27); + clk[slcdc_gate] = imx_clk_gate("slcdc_gate", "ipg", CCM_PCCR0, 25); + clk[slcdc_hclk_gate] = imx_clk_gate("slcdc_hclk_gate", "hclk", CCM_PCCR0, 21); + clk[wdog_gate] = imx_clk_gate("wdog_gate", "ipg", CCM_PCCR1, 24); + clk[gpio_gate] = imx_clk_gate("gpio_gate", "ipg", CCM_PCCR0, 11); + clk[i2c_gate] = imx_clk_gate("i2c_gate", "ipg", CCM_PCCR0, 12); + clk[kpp_gate] = imx_clk_gate("kpp_gate", "ipg", CCM_PCCR1, 30); + clk[owire_gate] = imx_clk_gate("owire_gate", "ipg", CCM_PCCR1, 31); + clk[rtc_gate] = imx_clk_gate("rtc_gate", "ipg", CCM_PCCR1, 29); + + for (i = 0; i < ARRAY_SIZE(clk); i++) + if (IS_ERR(clk[i])) + pr_err("i.MX21 clk %d: register failed with %ld\n", + i, PTR_ERR(clk[i])); + + clk_register_clkdev(clk[per1], "per1", NULL); + clk_register_clkdev(clk[per2], "per2", NULL); + clk_register_clkdev(clk[per3], "per3", NULL); + clk_register_clkdev(clk[per4], "per4", NULL); + clk_register_clkdev(clk[per1], "per", "imx21-uart.0"); + clk_register_clkdev(clk[uart1_ipg_gate], "ipg", "imx21-uart.0"); + clk_register_clkdev(clk[per1], "per", "imx21-uart.1"); + clk_register_clkdev(clk[uart2_ipg_gate], "ipg", "imx21-uart.1"); + clk_register_clkdev(clk[per1], "per", "imx21-uart.2"); + clk_register_clkdev(clk[uart3_ipg_gate], "ipg", "imx21-uart.2"); + clk_register_clkdev(clk[per1], "per", "imx21-uart.3"); + clk_register_clkdev(clk[uart4_ipg_gate], "ipg", "imx21-uart.3"); + clk_register_clkdev(clk[gpt1_ipg_gate], "ipg", "imx-gpt.0"); + clk_register_clkdev(clk[per1], "per", "imx-gpt.0"); + clk_register_clkdev(clk[gpt2_ipg_gate], "ipg", "imx-gpt.1"); + clk_register_clkdev(clk[per1], "per", "imx-gpt.1"); + clk_register_clkdev(clk[gpt3_ipg_gate], "ipg", "imx-gpt.2"); + clk_register_clkdev(clk[per1], "per", "imx-gpt.2"); + clk_register_clkdev(clk[pwm_ipg_gate], "pwm", "mxc_pwm.0"); + clk_register_clkdev(clk[per2], "per", "imx21-cspi.0"); + clk_register_clkdev(clk[cspi1_ipg_gate], "ipg", "imx21-cspi.0"); + clk_register_clkdev(clk[per2], "per", "imx21-cspi.1"); + clk_register_clkdev(clk[cspi2_ipg_gate], "ipg", "imx21-cspi.1"); + clk_register_clkdev(clk[per2], "per", "imx21-cspi.2"); + clk_register_clkdev(clk[cspi3_ipg_gate], "ipg", "imx21-cspi.2"); + clk_register_clkdev(clk[per3], "per", "imx-fb.0"); + clk_register_clkdev(clk[lcdc_ipg_gate], "ipg", "imx-fb.0"); + clk_register_clkdev(clk[lcdc_hclk_gate], "ahb", "imx-fb.0"); + clk_register_clkdev(clk[usb_gate], "per", "imx21-hcd.0"); + clk_register_clkdev(clk[usb_hclk_gate], "ahb", "imx21-hcd.0"); + clk_register_clkdev(clk[nfc_gate], NULL, "mxc_nand.0"); + clk_register_clkdev(clk[dma_hclk_gate], "ahb", "imx-dma"); + clk_register_clkdev(clk[dma_gate], "ipg", "imx-dma"); + clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0"); + clk_register_clkdev(clk[i2c_gate], NULL, "imx-i2c.0"); + clk_register_clkdev(clk[kpp_gate], NULL, "mxc-keypad"); + clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1.0"); + clk_register_clkdev(clk[brom_gate], "brom", NULL); + clk_register_clkdev(clk[emma_gate], "emma", NULL); + clk_register_clkdev(clk[slcdc_gate], "slcdc", NULL); + clk_register_clkdev(clk[gpio_gate], "gpio", NULL); + clk_register_clkdev(clk[rtc_gate], "rtc", NULL); + clk_register_clkdev(clk[csi_hclk_gate], "csi", NULL); + clk_register_clkdev(clk[ssi1_gate], "ssi1", NULL); + clk_register_clkdev(clk[ssi2_gate], "ssi2", NULL); + clk_register_clkdev(clk[sdhc1_ipg_gate], "sdhc1", NULL); + clk_register_clkdev(clk[sdhc2_ipg_gate], "sdhc2", NULL); + + mxc_timer_init(MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR), MX21_INT_GPT1); + + return 0; +} diff --git a/trunk/arch/arm/mach-imx/clk-imx25.c b/trunk/arch/arm/mach-imx/clk-imx25.c new file mode 100644 index 000000000000..fdd8cc87c9fe --- /dev/null +++ b/trunk/arch/arm/mach-imx/clk-imx25.c @@ -0,0 +1,248 @@ +/* + * Copyright (C) 2009 by Sascha Hauer, Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "clk.h" + +#define CRM_BASE MX25_IO_ADDRESS(MX25_CRM_BASE_ADDR) + +#define CCM_MPCTL 0x00 +#define CCM_UPCTL 0x04 +#define CCM_CCTL 0x08 +#define CCM_CGCR0 0x0C +#define CCM_CGCR1 0x10 +#define CCM_CGCR2 0x14 +#define CCM_PCDR0 0x18 +#define CCM_PCDR1 0x1C +#define CCM_PCDR2 0x20 +#define CCM_PCDR3 0x24 +#define CCM_RCSR 0x28 +#define CCM_CRDR 0x2C +#define CCM_DCVR0 0x30 +#define CCM_DCVR1 0x34 +#define CCM_DCVR2 0x38 +#define CCM_DCVR3 0x3c +#define CCM_LTR0 0x40 +#define CCM_LTR1 0x44 +#define CCM_LTR2 0x48 +#define CCM_LTR3 0x4c +#define CCM_MCR 0x64 + +#define ccm(x) (CRM_BASE + (x)) + +static const char *cpu_sel_clks[] = { "mpll", "mpll_cpu_3_4", }; +static const char *per_sel_clks[] = { "ahb", "upll", }; + +enum mx25_clks { + dummy, osc, mpll, upll, mpll_cpu_3_4, cpu_sel, cpu, ahb, usb_div, ipg, + per0_sel, per1_sel, per2_sel, per3_sel, per4_sel, per5_sel, per6_sel, + per7_sel, per8_sel, per9_sel, per10_sel, per11_sel, per12_sel, + per13_sel, per14_sel, per15_sel, per0, per1, per2, per3, per4, per5, + per6, per7, per8, per9, per10, per11, per12, per13, per14, per15, + csi_ipg_per, esdhc1_ipg_per, esdhc2_ipg_per, gpt_ipg_per, i2c_ipg_per, + lcdc_ipg_per, nfc_ipg_per, ssi1_ipg_per, ssi2_ipg_per, uart_ipg_per, + csi_ahb, esdhc1_ahb, esdhc2_ahb, fec_ahb, lcdc_ahb, sdma_ahb, + usbotg_ahb, can1_ipg, can2_ipg, csi_ipg, cspi1_ipg, cspi2_ipg, + cspi3_ipg, dryice_ipg, esdhc1_ipg, esdhc2_ipg, fec_ipg, iim_ipg, + kpp_ipg, lcdc_ipg, pwm1_ipg, pwm2_ipg, pwm3_ipg, pwm4_ipg, sdma_ipg, + ssi1_ipg, ssi2_ipg, tsc_ipg, uart1_ipg, uart2_ipg, uart3_ipg, + uart4_ipg, uart5_ipg, wdt_ipg, clk_max +}; + +static struct clk *clk[clk_max]; + +int __init mx25_clocks_init(void) +{ + int i; + + clk[dummy] = imx_clk_fixed("dummy", 0); + clk[osc] = imx_clk_fixed("osc", 24000000); + clk[mpll] = imx_clk_pllv1("mpll", "osc", ccm(CCM_MPCTL)); + clk[upll] = imx_clk_pllv1("upll", "osc", ccm(CCM_UPCTL)); + clk[mpll_cpu_3_4] = imx_clk_fixed_factor("mpll_cpu_3_4", "mpll", 3, 4); + clk[cpu_sel] = imx_clk_mux("cpu_sel", ccm(CCM_CCTL), 14, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks)); + clk[cpu] = imx_clk_divider("cpu", "cpu_sel", ccm(CCM_CCTL), 30, 2); + clk[ahb] = imx_clk_divider("ahb", "cpu", ccm(CCM_CCTL), 28, 2); + clk[usb_div] = imx_clk_divider("usb_div", "upll", ccm(CCM_CCTL), 16, 6); + clk[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2); + clk[per0_sel] = imx_clk_mux("per0_sel", ccm(CCM_MCR), 0, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); + clk[per1_sel] = imx_clk_mux("per1_sel", ccm(CCM_MCR), 1, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); + clk[per2_sel] = imx_clk_mux("per2_sel", ccm(CCM_MCR), 2, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); + clk[per3_sel] = imx_clk_mux("per3_sel", ccm(CCM_MCR), 3, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); + clk[per4_sel] = imx_clk_mux("per4_sel", ccm(CCM_MCR), 4, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); + clk[per5_sel] = imx_clk_mux("per5_sel", ccm(CCM_MCR), 5, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); + clk[per6_sel] = imx_clk_mux("per6_sel", ccm(CCM_MCR), 6, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); + clk[per7_sel] = imx_clk_mux("per7_sel", ccm(CCM_MCR), 7, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); + clk[per8_sel] = imx_clk_mux("per8_sel", ccm(CCM_MCR), 8, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); + clk[per9_sel] = imx_clk_mux("per9_sel", ccm(CCM_MCR), 9, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); + clk[per10_sel] = imx_clk_mux("per10_sel", ccm(CCM_MCR), 10, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); + clk[per11_sel] = imx_clk_mux("per11_sel", ccm(CCM_MCR), 11, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); + clk[per12_sel] = imx_clk_mux("per12_sel", ccm(CCM_MCR), 12, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); + clk[per13_sel] = imx_clk_mux("per13_sel", ccm(CCM_MCR), 13, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); + clk[per14_sel] = imx_clk_mux("per14_sel", ccm(CCM_MCR), 14, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); + clk[per15_sel] = imx_clk_mux("per15_sel", ccm(CCM_MCR), 15, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); + clk[per0] = imx_clk_divider("per0", "per0_sel", ccm(CCM_PCDR0), 0, 6); + clk[per1] = imx_clk_divider("per1", "per1_sel", ccm(CCM_PCDR0), 8, 6); + clk[per2] = imx_clk_divider("per2", "per2_sel", ccm(CCM_PCDR0), 16, 6); + clk[per3] = imx_clk_divider("per3", "per3_sel", ccm(CCM_PCDR0), 24, 6); + clk[per4] = imx_clk_divider("per4", "per4_sel", ccm(CCM_PCDR1), 0, 6); + clk[per5] = imx_clk_divider("per5", "per5_sel", ccm(CCM_PCDR1), 8, 6); + clk[per6] = imx_clk_divider("per6", "per6_sel", ccm(CCM_PCDR1), 16, 6); + clk[per7] = imx_clk_divider("per7", "per7_sel", ccm(CCM_PCDR1), 24, 6); + clk[per8] = imx_clk_divider("per8", "per8_sel", ccm(CCM_PCDR2), 0, 6); + clk[per9] = imx_clk_divider("per9", "per9_sel", ccm(CCM_PCDR2), 8, 6); + clk[per10] = imx_clk_divider("per10", "per10_sel", ccm(CCM_PCDR2), 16, 6); + clk[per11] = imx_clk_divider("per11", "per11_sel", ccm(CCM_PCDR2), 24, 6); + clk[per12] = imx_clk_divider("per12", "per12_sel", ccm(CCM_PCDR3), 0, 6); + clk[per13] = imx_clk_divider("per13", "per13_sel", ccm(CCM_PCDR3), 8, 6); + clk[per14] = imx_clk_divider("per14", "per14_sel", ccm(CCM_PCDR3), 16, 6); + clk[per15] = imx_clk_divider("per15", "per15_sel", ccm(CCM_PCDR3), 24, 6); + clk[csi_ipg_per] = imx_clk_gate("csi_ipg_per", "per0", ccm(CCM_CGCR0), 0); + clk[esdhc1_ipg_per] = imx_clk_gate("esdhc1_ipg_per", "per3", ccm(CCM_CGCR0), 3); + clk[esdhc2_ipg_per] = imx_clk_gate("esdhc2_ipg_per", "per4", ccm(CCM_CGCR0), 4); + clk[gpt_ipg_per] = imx_clk_gate("gpt_ipg_per", "per5", ccm(CCM_CGCR0), 5); + clk[i2c_ipg_per] = imx_clk_gate("i2c_ipg_per", "per6", ccm(CCM_CGCR0), 6); + clk[lcdc_ipg_per] = imx_clk_gate("lcdc_ipg_per", "per8", ccm(CCM_CGCR0), 7); + clk[nfc_ipg_per] = imx_clk_gate("nfc_ipg_per", "ipg_per", ccm(CCM_CGCR0), 8); + clk[ssi1_ipg_per] = imx_clk_gate("ssi1_ipg_per", "per13", ccm(CCM_CGCR0), 13); + clk[ssi2_ipg_per] = imx_clk_gate("ssi2_ipg_per", "per14", ccm(CCM_CGCR0), 14); + clk[uart_ipg_per] = imx_clk_gate("uart_ipg_per", "per15", ccm(CCM_CGCR0), 15); + clk[csi_ahb] = imx_clk_gate("csi_ahb", "ahb", ccm(CCM_CGCR0), 18); + clk[esdhc1_ahb] = imx_clk_gate("esdhc1_ahb", "ahb", ccm(CCM_CGCR0), 21); + clk[esdhc2_ahb] = imx_clk_gate("esdhc2_ahb", "ahb", ccm(CCM_CGCR0), 22); + clk[fec_ahb] = imx_clk_gate("fec_ahb", "ahb", ccm(CCM_CGCR0), 23); + clk[lcdc_ahb] = imx_clk_gate("lcdc_ahb", "ahb", ccm(CCM_CGCR0), 24); + clk[sdma_ahb] = imx_clk_gate("sdma_ahb", "ahb", ccm(CCM_CGCR0), 26); + clk[usbotg_ahb] = imx_clk_gate("usbotg_ahb", "ahb", ccm(CCM_CGCR0), 28); + clk[can1_ipg] = imx_clk_gate("can1_ipg", "ipg", ccm(CCM_CGCR1), 2); + clk[can2_ipg] = imx_clk_gate("can2_ipg", "ipg", ccm(CCM_CGCR1), 3); + clk[csi_ipg] = imx_clk_gate("csi_ipg", "ipg", ccm(CCM_CGCR1), 4); + clk[cspi1_ipg] = imx_clk_gate("cspi1_ipg", "ipg", ccm(CCM_CGCR1), 5); + clk[cspi2_ipg] = imx_clk_gate("cspi2_ipg", "ipg", ccm(CCM_CGCR1), 6); + clk[cspi3_ipg] = imx_clk_gate("cspi3_ipg", "ipg", ccm(CCM_CGCR1), 7); + clk[dryice_ipg] = imx_clk_gate("dryice_ipg", "ipg", ccm(CCM_CGCR1), 8); + clk[esdhc1_ipg] = imx_clk_gate("esdhc1_ipg", "ipg", ccm(CCM_CGCR1), 13); + clk[esdhc2_ipg] = imx_clk_gate("esdhc2_ipg", "ipg", ccm(CCM_CGCR1), 14); + clk[fec_ipg] = imx_clk_gate("fec_ipg", "ipg", ccm(CCM_CGCR1), 15); + clk[iim_ipg] = imx_clk_gate("iim_ipg", "ipg", ccm(CCM_CGCR1), 26); + clk[kpp_ipg] = imx_clk_gate("kpp_ipg", "ipg", ccm(CCM_CGCR1), 28); + clk[lcdc_ipg] = imx_clk_gate("lcdc_ipg", "ipg", ccm(CCM_CGCR1), 29); + clk[pwm1_ipg] = imx_clk_gate("pwm1_ipg", "ipg", ccm(CCM_CGCR1), 31); + clk[pwm2_ipg] = imx_clk_gate("pwm2_ipg", "ipg", ccm(CCM_CGCR2), 0); + clk[pwm3_ipg] = imx_clk_gate("pwm3_ipg", "ipg", ccm(CCM_CGCR2), 1); + clk[pwm4_ipg] = imx_clk_gate("pwm4_ipg", "ipg", ccm(CCM_CGCR2), 2); + clk[sdma_ipg] = imx_clk_gate("sdma_ipg", "ipg", ccm(CCM_CGCR2), 6); + clk[ssi1_ipg] = imx_clk_gate("ssi1_ipg", "ipg", ccm(CCM_CGCR2), 11); + clk[ssi2_ipg] = imx_clk_gate("ssi2_ipg", "ipg", ccm(CCM_CGCR2), 12); + clk[tsc_ipg] = imx_clk_gate("tsc_ipg", "ipg", ccm(CCM_CGCR2), 13); + clk[uart1_ipg] = imx_clk_gate("uart1_ipg", "ipg", ccm(CCM_CGCR2), 14); + clk[uart2_ipg] = imx_clk_gate("uart2_ipg", "ipg", ccm(CCM_CGCR2), 15); + clk[uart3_ipg] = imx_clk_gate("uart3_ipg", "ipg", ccm(CCM_CGCR2), 16); + clk[uart4_ipg] = imx_clk_gate("uart4_ipg", "ipg", ccm(CCM_CGCR2), 17); + clk[uart5_ipg] = imx_clk_gate("uart5_ipg", "ipg", ccm(CCM_CGCR2), 18); + clk[wdt_ipg] = imx_clk_gate("wdt_ipg", "ipg", ccm(CCM_CGCR2), 19); + + for (i = 0; i < ARRAY_SIZE(clk); i++) + if (IS_ERR(clk[i])) + pr_err("i.MX25 clk %d: register failed with %ld\n", + i, PTR_ERR(clk[i])); + + /* i.mx25 has the i.mx21 type uart */ + clk_register_clkdev(clk[uart1_ipg], "ipg", "imx21-uart.0"); + clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.0"); + clk_register_clkdev(clk[uart2_ipg], "ipg", "imx21-uart.1"); + clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.1"); + clk_register_clkdev(clk[uart3_ipg], "ipg", "imx21-uart.2"); + clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.2"); + clk_register_clkdev(clk[uart4_ipg], "ipg", "imx21-uart.3"); + clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.3"); + clk_register_clkdev(clk[uart5_ipg], "ipg", "imx21-uart.4"); + clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.4"); + clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0"); + clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0"); + clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.0"); + clk_register_clkdev(clk[usbotg_ahb], "ahb", "mxc-ehci.0"); + clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.0"); + clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.1"); + clk_register_clkdev(clk[usbotg_ahb], "ahb", "mxc-ehci.1"); + clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.1"); + clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2"); + clk_register_clkdev(clk[usbotg_ahb], "ahb", "mxc-ehci.2"); + clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.2"); + clk_register_clkdev(clk[ipg], "ipg", "fsl-usb2-udc"); + clk_register_clkdev(clk[usbotg_ahb], "ahb", "fsl-usb2-udc"); + clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc"); + clk_register_clkdev(clk[nfc_ipg_per], NULL, "mxc_nand.0"); + /* i.mx25 has the i.mx35 type cspi */ + clk_register_clkdev(clk[cspi1_ipg], NULL, "imx35-cspi.0"); + clk_register_clkdev(clk[cspi2_ipg], NULL, "imx35-cspi.1"); + clk_register_clkdev(clk[cspi3_ipg], NULL, "imx35-cspi.2"); + clk_register_clkdev(clk[pwm1_ipg], "ipg", "mxc_pwm.0"); + clk_register_clkdev(clk[per10], "per", "mxc_pwm.0"); + clk_register_clkdev(clk[pwm1_ipg], "ipg", "mxc_pwm.1"); + clk_register_clkdev(clk[per10], "per", "mxc_pwm.1"); + clk_register_clkdev(clk[pwm1_ipg], "ipg", "mxc_pwm.2"); + clk_register_clkdev(clk[per10], "per", "mxc_pwm.2"); + clk_register_clkdev(clk[pwm1_ipg], "ipg", "mxc_pwm.3"); + clk_register_clkdev(clk[per10], "per", "mxc_pwm.3"); + clk_register_clkdev(clk[kpp_ipg], NULL, "imx-keypad"); + clk_register_clkdev(clk[tsc_ipg], NULL, "mx25-adc"); + clk_register_clkdev(clk[i2c_ipg_per], NULL, "imx-i2c.0"); + clk_register_clkdev(clk[i2c_ipg_per], NULL, "imx-i2c.1"); + clk_register_clkdev(clk[i2c_ipg_per], NULL, "imx-i2c.2"); + clk_register_clkdev(clk[fec_ipg], "ipg", "imx25-fec.0"); + clk_register_clkdev(clk[fec_ahb], "ahb", "imx25-fec.0"); + clk_register_clkdev(clk[dryice_ipg], NULL, "imxdi_rtc.0"); + clk_register_clkdev(clk[lcdc_ipg_per], "per", "imx-fb.0"); + clk_register_clkdev(clk[lcdc_ipg], "ipg", "imx-fb.0"); + clk_register_clkdev(clk[lcdc_ahb], "ahb", "imx-fb.0"); + clk_register_clkdev(clk[wdt_ipg], NULL, "imx2-wdt.0"); + clk_register_clkdev(clk[ssi1_ipg_per], "per", "imx-ssi.0"); + clk_register_clkdev(clk[ssi1_ipg], "ipg", "imx-ssi.0"); + clk_register_clkdev(clk[ssi2_ipg_per], "per", "imx-ssi.1"); + clk_register_clkdev(clk[ssi2_ipg], "ipg", "imx-ssi.1"); + clk_register_clkdev(clk[esdhc1_ipg_per], "per", "sdhci-esdhc-imx25.0"); + clk_register_clkdev(clk[esdhc1_ipg], "ipg", "sdhci-esdhc-imx25.0"); + clk_register_clkdev(clk[esdhc1_ahb], "ahb", "sdhci-esdhc-imx25.0"); + clk_register_clkdev(clk[esdhc2_ipg_per], "per", "sdhci-esdhc-imx25.1"); + clk_register_clkdev(clk[esdhc2_ipg], "ipg", "sdhci-esdhc-imx25.1"); + clk_register_clkdev(clk[esdhc2_ahb], "ahb", "sdhci-esdhc-imx25.1"); + clk_register_clkdev(clk[csi_ipg_per], "per", "mx2-camera.0"); + clk_register_clkdev(clk[csi_ipg], "ipg", "mx2-camera.0"); + clk_register_clkdev(clk[csi_ahb], "ahb", "mx2-camera.0"); + clk_register_clkdev(clk[dummy], "audmux", NULL); + clk_register_clkdev(clk[can1_ipg], NULL, "flexcan.0"); + clk_register_clkdev(clk[can2_ipg], NULL, "flexcan.1"); + /* i.mx25 has the i.mx35 type sdma */ + clk_register_clkdev(clk[sdma_ipg], "ipg", "imx35-sdma"); + clk_register_clkdev(clk[sdma_ahb], "ahb", "imx35-sdma"); + clk_register_clkdev(clk[iim_ipg], "iim", NULL); + + mxc_timer_init(MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54); + return 0; +} diff --git a/trunk/arch/arm/mach-imx/clk-imx27.c b/trunk/arch/arm/mach-imx/clk-imx27.c new file mode 100644 index 000000000000..295cbd7c08dc --- /dev/null +++ b/trunk/arch/arm/mach-imx/clk-imx27.c @@ -0,0 +1,289 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "clk.h" + +#define IO_ADDR_CCM(off) (MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR + (off))) + +/* Register offsets */ +#define CCM_CSCR IO_ADDR_CCM(0x0) +#define CCM_MPCTL0 IO_ADDR_CCM(0x4) +#define CCM_MPCTL1 IO_ADDR_CCM(0x8) +#define CCM_SPCTL0 IO_ADDR_CCM(0xc) +#define CCM_SPCTL1 IO_ADDR_CCM(0x10) +#define CCM_OSC26MCTL IO_ADDR_CCM(0x14) +#define CCM_PCDR0 IO_ADDR_CCM(0x18) +#define CCM_PCDR1 IO_ADDR_CCM(0x1c) +#define CCM_PCCR0 IO_ADDR_CCM(0x20) +#define CCM_PCCR1 IO_ADDR_CCM(0x24) +#define CCM_CCSR IO_ADDR_CCM(0x28) +#define CCM_PMCTL IO_ADDR_CCM(0x2c) +#define CCM_PMCOUNT IO_ADDR_CCM(0x30) +#define CCM_WKGDCTL IO_ADDR_CCM(0x34) + +#define CCM_CSCR_UPDATE_DIS (1 << 31) +#define CCM_CSCR_SSI2 (1 << 23) +#define CCM_CSCR_SSI1 (1 << 22) +#define CCM_CSCR_VPU (1 << 21) +#define CCM_CSCR_MSHC (1 << 20) +#define CCM_CSCR_SPLLRES (1 << 19) +#define CCM_CSCR_MPLLRES (1 << 18) +#define CCM_CSCR_SP (1 << 17) +#define CCM_CSCR_MCU (1 << 16) +#define CCM_CSCR_OSC26MDIV (1 << 4) +#define CCM_CSCR_OSC26M (1 << 3) +#define CCM_CSCR_FPM (1 << 2) +#define CCM_CSCR_SPEN (1 << 1) +#define CCM_CSCR_MPEN (1 << 0) + +/* i.MX27 TO 2+ */ +#define CCM_CSCR_ARM_SRC (1 << 15) + +#define CCM_SPCTL1_LF (1 << 15) +#define CCM_SPCTL1_BRMO (1 << 6) + +static const char *vpu_sel_clks[] = { "spll", "mpll_main2", }; +static const char *cpu_sel_clks[] = { "mpll_main2", "mpll", }; +static const char *clko_sel_clks[] = { + "ckil", "prem", "ckih", "ckih", + "ckih", "mpll", "spll", "cpu_div", + "ahb", "ipg", "per1_div", "per2_div", + "per3_div", "per4_div", "ssi1_div", "ssi2_div", + "nfc_div", "mshc_div", "vpu_div", "60m", + "32k", "usb_div", "dptc", +}; + +static const char *ssi_sel_clks[] = { "spll", "mpll", }; + +enum mx27_clks { + dummy, ckih, ckil, mpll, spll, mpll_main2, ahb, ipg, nfc_div, per1_div, + per2_div, per3_div, per4_div, vpu_sel, vpu_div, usb_div, cpu_sel, + clko_sel, cpu_div, clko_div, ssi1_sel, ssi2_sel, ssi1_div, ssi2_div, + clko_en, ssi2_ipg_gate, ssi1_ipg_gate, slcdc_ipg_gate, sdhc3_ipg_gate, + sdhc2_ipg_gate, sdhc1_ipg_gate, scc_ipg_gate, sahara_ipg_gate, + rtc_ipg_gate, pwm_ipg_gate, owire_ipg_gate, lcdc_ipg_gate, + kpp_ipg_gate, iim_ipg_gate, i2c2_ipg_gate, i2c1_ipg_gate, + gpt6_ipg_gate, gpt5_ipg_gate, gpt4_ipg_gate, gpt3_ipg_gate, + gpt2_ipg_gate, gpt1_ipg_gate, gpio_ipg_gate, fec_ipg_gate, + emma_ipg_gate, dma_ipg_gate, cspi3_ipg_gate, cspi2_ipg_gate, + cspi1_ipg_gate, nfc_baud_gate, ssi2_baud_gate, ssi1_baud_gate, + vpu_baud_gate, per4_gate, per3_gate, per2_gate, per1_gate, + usb_ahb_gate, slcdc_ahb_gate, sahara_ahb_gate, lcdc_ahb_gate, + vpu_ahb_gate, fec_ahb_gate, emma_ahb_gate, emi_ahb_gate, dma_ahb_gate, + csi_ahb_gate, brom_ahb_gate, ata_ahb_gate, wdog_ipg_gate, usb_ipg_gate, + uart6_ipg_gate, uart5_ipg_gate, uart4_ipg_gate, uart3_ipg_gate, + uart2_ipg_gate, uart1_ipg_gate, clk_max +}; + +static struct clk *clk[clk_max]; + +int __init mx27_clocks_init(unsigned long fref) +{ + int i; + + clk[dummy] = imx_clk_fixed("dummy", 0); + clk[ckih] = imx_clk_fixed("ckih", fref); + clk[ckil] = imx_clk_fixed("ckil", 32768); + clk[mpll] = imx_clk_pllv1("mpll", "ckih", CCM_MPCTL0); + clk[spll] = imx_clk_pllv1("spll", "ckih", CCM_SPCTL0); + clk[mpll_main2] = imx_clk_fixed_factor("mpll_main2", "mpll", 2, 3); + + if (mx27_revision() >= IMX_CHIP_REVISION_2_0) { + clk[ahb] = imx_clk_divider("ahb", "mpll_main2", CCM_CSCR, 8, 2); + clk[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2); + } else { + clk[ahb] = imx_clk_divider("ahb", "mpll_main2", CCM_CSCR, 9, 4); + clk[ipg] = imx_clk_divider("ipg", "ahb", CCM_CSCR, 8, 1); + } + + clk[nfc_div] = imx_clk_divider("nfc_div", "ahb", CCM_PCDR0, 6, 4); + clk[per1_div] = imx_clk_divider("per1_div", "mpll_main2", CCM_PCDR1, 0, 6); + clk[per2_div] = imx_clk_divider("per2_div", "mpll_main2", CCM_PCDR1, 8, 6); + clk[per3_div] = imx_clk_divider("per3_div", "mpll_main2", CCM_PCDR1, 16, 6); + clk[per4_div] = imx_clk_divider("per4_div", "mpll_main2", CCM_PCDR1, 24, 6); + clk[vpu_sel] = imx_clk_mux("vpu_sel", CCM_CSCR, 21, 1, vpu_sel_clks, ARRAY_SIZE(vpu_sel_clks)); + clk[vpu_div] = imx_clk_divider("vpu_div", "vpu_sel", CCM_PCDR0, 10, 3); + clk[usb_div] = imx_clk_divider("usb_div", "spll", CCM_CSCR, 28, 3); + clk[cpu_sel] = imx_clk_mux("cpu_sel", CCM_CSCR, 15, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks)); + clk[clko_sel] = imx_clk_mux("clko_sel", CCM_CCSR, 0, 5, clko_sel_clks, ARRAY_SIZE(clko_sel_clks)); + if (mx27_revision() >= IMX_CHIP_REVISION_2_0) + clk[cpu_div] = imx_clk_divider("cpu_div", "cpu_sel", CCM_CSCR, 12, 2); + else + clk[cpu_div] = imx_clk_divider("cpu_div", "cpu_sel", CCM_CSCR, 13, 3); + clk[clko_div] = imx_clk_divider("clko_div", "clko_sel", CCM_PCDR0, 22, 3); + clk[ssi1_sel] = imx_clk_mux("ssi1_sel", CCM_CSCR, 22, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks)); + clk[ssi2_sel] = imx_clk_mux("ssi2_sel", CCM_CSCR, 23, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks)); + clk[ssi1_div] = imx_clk_divider("ssi1_div", "ssi1_sel", CCM_PCDR0, 16, 6); + clk[ssi2_div] = imx_clk_divider("ssi2_div", "ssi2_sel", CCM_PCDR0, 26, 3); + clk[clko_en] = imx_clk_gate("clko_en", "clko_div", CCM_PCCR0, 0); + clk[ssi2_ipg_gate] = imx_clk_gate("ssi2_ipg_gate", "ipg", CCM_PCCR0, 0); + clk[ssi1_ipg_gate] = imx_clk_gate("ssi1_ipg_gate", "ipg", CCM_PCCR0, 1); + clk[slcdc_ipg_gate] = imx_clk_gate("slcdc_ipg_gate", "ipg", CCM_PCCR0, 2); + clk[sdhc3_ipg_gate] = imx_clk_gate("sdhc3_ipg_gate", "ipg", CCM_PCCR0, 3); + clk[sdhc2_ipg_gate] = imx_clk_gate("sdhc2_ipg_gate", "ipg", CCM_PCCR0, 4); + clk[sdhc1_ipg_gate] = imx_clk_gate("sdhc1_ipg_gate", "ipg", CCM_PCCR0, 5); + clk[scc_ipg_gate] = imx_clk_gate("scc_ipg_gate", "ipg", CCM_PCCR0, 6); + clk[sahara_ipg_gate] = imx_clk_gate("sahara_ipg_gate", "ipg", CCM_PCCR0, 7); + clk[rtc_ipg_gate] = imx_clk_gate("rtc_ipg_gate", "ipg", CCM_PCCR0, 9); + clk[pwm_ipg_gate] = imx_clk_gate("pwm_ipg_gate", "ipg", CCM_PCCR0, 11); + clk[owire_ipg_gate] = imx_clk_gate("owire_ipg_gate", "ipg", CCM_PCCR0, 12); + clk[lcdc_ipg_gate] = imx_clk_gate("lcdc_ipg_gate", "ipg", CCM_PCCR0, 14); + clk[kpp_ipg_gate] = imx_clk_gate("kpp_ipg_gate", "ipg", CCM_PCCR0, 15); + clk[iim_ipg_gate] = imx_clk_gate("iim_ipg_gate", "ipg", CCM_PCCR0, 16); + clk[i2c2_ipg_gate] = imx_clk_gate("i2c2_ipg_gate", "ipg", CCM_PCCR0, 17); + clk[i2c1_ipg_gate] = imx_clk_gate("i2c1_ipg_gate", "ipg", CCM_PCCR0, 18); + clk[gpt6_ipg_gate] = imx_clk_gate("gpt6_ipg_gate", "ipg", CCM_PCCR0, 19); + clk[gpt5_ipg_gate] = imx_clk_gate("gpt5_ipg_gate", "ipg", CCM_PCCR0, 20); + clk[gpt4_ipg_gate] = imx_clk_gate("gpt4_ipg_gate", "ipg", CCM_PCCR0, 21); + clk[gpt3_ipg_gate] = imx_clk_gate("gpt3_ipg_gate", "ipg", CCM_PCCR0, 22); + clk[gpt2_ipg_gate] = imx_clk_gate("gpt2_ipg_gate", "ipg", CCM_PCCR0, 23); + clk[gpt1_ipg_gate] = imx_clk_gate("gpt1_ipg_gate", "ipg", CCM_PCCR0, 24); + clk[gpio_ipg_gate] = imx_clk_gate("gpio_ipg_gate", "ipg", CCM_PCCR0, 25); + clk[fec_ipg_gate] = imx_clk_gate("fec_ipg_gate", "ipg", CCM_PCCR0, 26); + clk[emma_ipg_gate] = imx_clk_gate("emma_ipg_gate", "ipg", CCM_PCCR0, 27); + clk[dma_ipg_gate] = imx_clk_gate("dma_ipg_gate", "ipg", CCM_PCCR0, 28); + clk[cspi3_ipg_gate] = imx_clk_gate("cspi3_ipg_gate", "ipg", CCM_PCCR0, 29); + clk[cspi2_ipg_gate] = imx_clk_gate("cspi2_ipg_gate", "ipg", CCM_PCCR0, 30); + clk[cspi1_ipg_gate] = imx_clk_gate("cspi1_ipg_gate", "ipg", CCM_PCCR0, 31); + clk[nfc_baud_gate] = imx_clk_gate("nfc_baud_gate", "nfc_div", CCM_PCCR1, 3); + clk[ssi2_baud_gate] = imx_clk_gate("ssi2_baud_gate", "ssi2_div", CCM_PCCR1, 4); + clk[ssi1_baud_gate] = imx_clk_gate("ssi1_baud_gate", "ssi1_div", CCM_PCCR1, 5); + clk[vpu_baud_gate] = imx_clk_gate("vpu_baud_gate", "vpu_div", CCM_PCCR1, 6); + clk[per4_gate] = imx_clk_gate("per4_gate", "per4_div", CCM_PCCR1, 7); + clk[per3_gate] = imx_clk_gate("per3_gate", "per3_div", CCM_PCCR1, 8); + clk[per2_gate] = imx_clk_gate("per2_gate", "per2_div", CCM_PCCR1, 9); + clk[per1_gate] = imx_clk_gate("per1_gate", "per1_div", CCM_PCCR1, 10); + clk[usb_ahb_gate] = imx_clk_gate("usb_ahb_gate", "ahb", CCM_PCCR1, 11); + clk[slcdc_ahb_gate] = imx_clk_gate("slcdc_ahb_gate", "ahb", CCM_PCCR1, 12); + clk[sahara_ahb_gate] = imx_clk_gate("sahara_ahb_gate", "ahb", CCM_PCCR1, 13); + clk[lcdc_ahb_gate] = imx_clk_gate("lcdc_ahb_gate", "ahb", CCM_PCCR1, 15); + clk[vpu_ahb_gate] = imx_clk_gate("vpu_ahb_gate", "ahb", CCM_PCCR1, 16); + clk[fec_ahb_gate] = imx_clk_gate("fec_ahb_gate", "ahb", CCM_PCCR1, 17); + clk[emma_ahb_gate] = imx_clk_gate("emma_ahb_gate", "ahb", CCM_PCCR1, 18); + clk[emi_ahb_gate] = imx_clk_gate("emi_ahb_gate", "ahb", CCM_PCCR1, 19); + clk[dma_ahb_gate] = imx_clk_gate("dma_ahb_gate", "ahb", CCM_PCCR1, 20); + clk[csi_ahb_gate] = imx_clk_gate("csi_ahb_gate", "ahb", CCM_PCCR1, 21); + clk[brom_ahb_gate] = imx_clk_gate("brom_ahb_gate", "ahb", CCM_PCCR1, 22); + clk[ata_ahb_gate] = imx_clk_gate("ata_ahb_gate", "ahb", CCM_PCCR1, 23); + clk[wdog_ipg_gate] = imx_clk_gate("wdog_ipg_gate", "ipg", CCM_PCCR1, 24); + clk[usb_ipg_gate] = imx_clk_gate("usb_ipg_gate", "ipg", CCM_PCCR1, 25); + clk[uart6_ipg_gate] = imx_clk_gate("uart6_ipg_gate", "ipg", CCM_PCCR1, 26); + clk[uart5_ipg_gate] = imx_clk_gate("uart5_ipg_gate", "ipg", CCM_PCCR1, 27); + clk[uart4_ipg_gate] = imx_clk_gate("uart4_ipg_gate", "ipg", CCM_PCCR1, 28); + clk[uart3_ipg_gate] = imx_clk_gate("uart3_ipg_gate", "ipg", CCM_PCCR1, 29); + clk[uart2_ipg_gate] = imx_clk_gate("uart2_ipg_gate", "ipg", CCM_PCCR1, 30); + clk[uart1_ipg_gate] = imx_clk_gate("uart1_ipg_gate", "ipg", CCM_PCCR1, 31); + + for (i = 0; i < ARRAY_SIZE(clk); i++) + if (IS_ERR(clk[i])) + pr_err("i.MX27 clk %d: register failed with %ld\n", + i, PTR_ERR(clk[i])); + + clk_register_clkdev(clk[uart1_ipg_gate], "ipg", "imx21-uart.0"); + clk_register_clkdev(clk[per1_gate], "per", "imx21-uart.0"); + clk_register_clkdev(clk[uart2_ipg_gate], "ipg", "imx21-uart.1"); + clk_register_clkdev(clk[per1_gate], "per", "imx21-uart.1"); + clk_register_clkdev(clk[uart3_ipg_gate], "ipg", "imx21-uart.2"); + clk_register_clkdev(clk[per1_gate], "per", "imx21-uart.2"); + clk_register_clkdev(clk[uart4_ipg_gate], "ipg", "imx21-uart.3"); + clk_register_clkdev(clk[per1_gate], "per", "imx21-uart.3"); + clk_register_clkdev(clk[uart5_ipg_gate], "ipg", "imx21-uart.4"); + clk_register_clkdev(clk[per1_gate], "per", "imx21-uart.4"); + clk_register_clkdev(clk[uart6_ipg_gate], "ipg", "imx21-uart.5"); + clk_register_clkdev(clk[per1_gate], "per", "imx21-uart.5"); + clk_register_clkdev(clk[gpt1_ipg_gate], "ipg", "imx-gpt.0"); + clk_register_clkdev(clk[per1_gate], "per", "imx-gpt.0"); + clk_register_clkdev(clk[gpt2_ipg_gate], "ipg", "imx-gpt.1"); + clk_register_clkdev(clk[per1_gate], "per", "imx-gpt.1"); + clk_register_clkdev(clk[gpt3_ipg_gate], "ipg", "imx-gpt.2"); + clk_register_clkdev(clk[per1_gate], "per", "imx-gpt.2"); + clk_register_clkdev(clk[gpt4_ipg_gate], "ipg", "imx-gpt.3"); + clk_register_clkdev(clk[per1_gate], "per", "imx-gpt.3"); + clk_register_clkdev(clk[gpt5_ipg_gate], "ipg", "imx-gpt.4"); + clk_register_clkdev(clk[per1_gate], "per", "imx-gpt.4"); + clk_register_clkdev(clk[gpt6_ipg_gate], "ipg", "imx-gpt.5"); + clk_register_clkdev(clk[per1_gate], "per", "imx-gpt.5"); + clk_register_clkdev(clk[pwm_ipg_gate], NULL, "mxc_pwm.0"); + clk_register_clkdev(clk[per2_gate], "per", "mxc-mmc.0"); + clk_register_clkdev(clk[sdhc1_ipg_gate], "ipg", "mxc-mmc.0"); + clk_register_clkdev(clk[per2_gate], "per", "mxc-mmc.1"); + clk_register_clkdev(clk[sdhc2_ipg_gate], "ipg", "mxc-mmc.1"); + clk_register_clkdev(clk[per2_gate], "per", "mxc-mmc.2"); + clk_register_clkdev(clk[sdhc2_ipg_gate], "ipg", "mxc-mmc.2"); + clk_register_clkdev(clk[cspi1_ipg_gate], NULL, "imx27-cspi.0"); + clk_register_clkdev(clk[cspi2_ipg_gate], NULL, "imx27-cspi.1"); + clk_register_clkdev(clk[cspi3_ipg_gate], NULL, "imx27-cspi.2"); + clk_register_clkdev(clk[per3_gate], "per", "imx-fb.0"); + clk_register_clkdev(clk[lcdc_ipg_gate], "ipg", "imx-fb.0"); + clk_register_clkdev(clk[lcdc_ahb_gate], "ahb", "imx-fb.0"); + clk_register_clkdev(clk[csi_ahb_gate], NULL, "mx2-camera.0"); + clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc"); + clk_register_clkdev(clk[usb_ipg_gate], "ipg", "fsl-usb2-udc"); + clk_register_clkdev(clk[usb_ahb_gate], "ahb", "fsl-usb2-udc"); + clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.0"); + clk_register_clkdev(clk[usb_ipg_gate], "ipg", "mxc-ehci.0"); + clk_register_clkdev(clk[usb_ahb_gate], "ahb", "mxc-ehci.0"); + clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.1"); + clk_register_clkdev(clk[usb_ipg_gate], "ipg", "mxc-ehci.1"); + clk_register_clkdev(clk[usb_ahb_gate], "ahb", "mxc-ehci.1"); + clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.2"); + clk_register_clkdev(clk[usb_ipg_gate], "ipg", "mxc-ehci.2"); + clk_register_clkdev(clk[usb_ahb_gate], "ahb", "mxc-ehci.2"); + clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "imx-ssi.0"); + clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "imx-ssi.1"); + clk_register_clkdev(clk[nfc_baud_gate], NULL, "mxc_nand.0"); + clk_register_clkdev(clk[vpu_baud_gate], "per", "imx-vpu"); + clk_register_clkdev(clk[vpu_ahb_gate], "ahb", "imx-vpu"); + clk_register_clkdev(clk[dma_ahb_gate], "ahb", "imx-dma"); + clk_register_clkdev(clk[dma_ipg_gate], "ipg", "imx-dma"); + clk_register_clkdev(clk[fec_ipg_gate], "ipg", "imx27-fec.0"); + clk_register_clkdev(clk[fec_ahb_gate], "ahb", "imx27-fec.0"); + clk_register_clkdev(clk[wdog_ipg_gate], NULL, "imx2-wdt.0"); + clk_register_clkdev(clk[i2c1_ipg_gate], NULL, "imx-i2c.0"); + clk_register_clkdev(clk[i2c2_ipg_gate], NULL, "imx-i2c.1"); + clk_register_clkdev(clk[owire_ipg_gate], NULL, "mxc_w1.0"); + clk_register_clkdev(clk[kpp_ipg_gate], NULL, "imx-keypad"); + clk_register_clkdev(clk[emma_ahb_gate], "ahb", "imx-emma"); + clk_register_clkdev(clk[emma_ipg_gate], "ipg", "imx-emma"); + clk_register_clkdev(clk[iim_ipg_gate], "iim", NULL); + clk_register_clkdev(clk[gpio_ipg_gate], "gpio", NULL); + clk_register_clkdev(clk[brom_ahb_gate], "brom", NULL); + clk_register_clkdev(clk[ata_ahb_gate], "ata", NULL); + clk_register_clkdev(clk[rtc_ipg_gate], "rtc", NULL); + clk_register_clkdev(clk[scc_ipg_gate], "scc", NULL); + clk_register_clkdev(clk[cpu_div], "cpu", NULL); + clk_register_clkdev(clk[emi_ahb_gate], "emi_ahb" , NULL); + clk_register_clkdev(clk[ssi1_baud_gate], "bitrate" , "imx-ssi.0"); + clk_register_clkdev(clk[ssi2_baud_gate], "bitrate" , "imx-ssi.1"); + + mxc_timer_init(MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR), MX27_INT_GPT1); + + clk_prepare_enable(clk[emi_ahb_gate]); + + return 0; +} + +#ifdef CONFIG_OF +int __init mx27_clocks_init_dt(void) +{ + struct device_node *np; + u32 fref = 26000000; /* default */ + + for_each_compatible_node(np, NULL, "fixed-clock") { + if (!of_device_is_compatible(np, "fsl,imx-osc26m")) + continue; + + if (!of_property_read_u32(np, "clock-frequency", &fref)) + break; + } + + return mx27_clocks_init(fref); +} +#endif diff --git a/trunk/arch/arm/mach-imx/clk-imx31.c b/trunk/arch/arm/mach-imx/clk-imx31.c new file mode 100644 index 000000000000..c9a06d800f8e --- /dev/null +++ b/trunk/arch/arm/mach-imx/clk-imx31.c @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2012 Sascha Hauer + * + * 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. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "clk.h" +#include "crmregs-imx3.h" + +static const char *mcu_main_sel[] = { "spll", "mpll", }; +static const char *per_sel[] = { "per_div", "ipg", }; +static const char *csi_sel[] = { "upll", "spll", }; +static const char *fir_sel[] = { "mcu_main", "upll", "spll" }; + +enum mx31_clks { + ckih, ckil, mpll, spll, upll, mcu_main, hsp, ahb, nfc, ipg, per_div, + per, csi, fir, csi_div, usb_div_pre, usb_div_post, fir_div_pre, + fir_div_post, sdhc1_gate, sdhc2_gate, gpt_gate, epit1_gate, epit2_gate, + iim_gate, ata_gate, sdma_gate, cspi3_gate, rng_gate, uart1_gate, + uart2_gate, ssi1_gate, i2c1_gate, i2c2_gate, i2c3_gate, hantro_gate, + mstick1_gate, mstick2_gate, csi_gate, rtc_gate, wdog_gate, pwm_gate, + sim_gate, ect_gate, usb_gate, kpp_gate, ipu_gate, uart3_gate, + uart4_gate, uart5_gate, owire_gate, ssi2_gate, cspi1_gate, cspi2_gate, + gacc_gate, emi_gate, rtic_gate, firi_gate, clk_max +}; + +static struct clk *clk[clk_max]; + +int __init mx31_clocks_init(unsigned long fref) +{ + void __iomem *base = MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR); + int i; + + clk[ckih] = imx_clk_fixed("ckih", fref); + clk[ckil] = imx_clk_fixed("ckil", 32768); + clk[mpll] = imx_clk_pllv1("mpll", "ckih", base + MXC_CCM_MPCTL); + clk[spll] = imx_clk_pllv1("spll", "ckih", base + MXC_CCM_SRPCTL); + clk[upll] = imx_clk_pllv1("upll", "ckih", base + MXC_CCM_UPCTL); + clk[mcu_main] = imx_clk_mux("mcu_main", base + MXC_CCM_PMCR0, 31, 1, mcu_main_sel, ARRAY_SIZE(mcu_main_sel)); + clk[hsp] = imx_clk_divider("hsp", "mcu_main", base + MXC_CCM_PDR0, 11, 3); + clk[ahb] = imx_clk_divider("ahb", "mcu_main", base + MXC_CCM_PDR0, 3, 3); + clk[nfc] = imx_clk_divider("nfc", "ahb", base + MXC_CCM_PDR0, 8, 3); + clk[ipg] = imx_clk_divider("ipg", "ahb", base + MXC_CCM_PDR0, 6, 2); + clk[per_div] = imx_clk_divider("per_div", "upll", base + MXC_CCM_PDR0, 16, 5); + clk[per] = imx_clk_mux("per", base + MXC_CCM_CCMR, 24, 1, per_sel, ARRAY_SIZE(per_sel)); + clk[csi] = imx_clk_mux("csi_sel", base + MXC_CCM_CCMR, 25, 1, csi_sel, ARRAY_SIZE(csi_sel)); + clk[fir] = imx_clk_mux("fir_sel", base + MXC_CCM_CCMR, 11, 2, fir_sel, ARRAY_SIZE(fir_sel)); + clk[csi_div] = imx_clk_divider("csi_div", "csi_sel", base + MXC_CCM_PDR0, 23, 9); + clk[usb_div_pre] = imx_clk_divider("usb_div_pre", "upll", base + MXC_CCM_PDR1, 30, 2); + clk[usb_div_post] = imx_clk_divider("usb_div_post", "usb_div_pre", base + MXC_CCM_PDR1, 27, 3); + clk[fir_div_pre] = imx_clk_divider("fir_div_pre", "fir_sel", base + MXC_CCM_PDR1, 24, 3); + clk[fir_div_post] = imx_clk_divider("fir_div_post", "fir_div_pre", base + MXC_CCM_PDR1, 23, 6); + clk[sdhc1_gate] = imx_clk_gate2("sdhc1_gate", "per", base + MXC_CCM_CGR0, 0); + clk[sdhc2_gate] = imx_clk_gate2("sdhc2_gate", "per", base + MXC_CCM_CGR0, 2); + clk[gpt_gate] = imx_clk_gate2("gpt_gate", "per", base + MXC_CCM_CGR0, 4); + clk[epit1_gate] = imx_clk_gate2("epit1_gate", "per", base + MXC_CCM_CGR0, 6); + clk[epit2_gate] = imx_clk_gate2("epit2_gate", "per", base + MXC_CCM_CGR0, 8); + clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", base + MXC_CCM_CGR0, 10); + clk[ata_gate] = imx_clk_gate2("ata_gate", "ipg", base + MXC_CCM_CGR0, 12); + clk[sdma_gate] = imx_clk_gate2("sdma_gate", "ahb", base + MXC_CCM_CGR0, 14); + clk[cspi3_gate] = imx_clk_gate2("cspi3_gate", "ipg", base + MXC_CCM_CGR0, 16); + clk[rng_gate] = imx_clk_gate2("rng_gate", "ipg", base + MXC_CCM_CGR0, 18); + clk[uart1_gate] = imx_clk_gate2("uart1_gate", "per", base + MXC_CCM_CGR0, 20); + clk[uart2_gate] = imx_clk_gate2("uart2_gate", "per", base + MXC_CCM_CGR0, 22); + clk[ssi1_gate] = imx_clk_gate2("ssi1_gate", "spll", base + MXC_CCM_CGR0, 24); + clk[i2c1_gate] = imx_clk_gate2("i2c1_gate", "per", base + MXC_CCM_CGR0, 26); + clk[i2c2_gate] = imx_clk_gate2("i2c2_gate", "per", base + MXC_CCM_CGR0, 28); + clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "per", base + MXC_CCM_CGR0, 30); + clk[hantro_gate] = imx_clk_gate2("hantro_gate", "per", base + MXC_CCM_CGR1, 0); + clk[mstick1_gate] = imx_clk_gate2("mstick1_gate", "per", base + MXC_CCM_CGR1, 2); + clk[mstick2_gate] = imx_clk_gate2("mstick2_gate", "per", base + MXC_CCM_CGR1, 4); + clk[csi_gate] = imx_clk_gate2("csi_gate", "csi_div", base + MXC_CCM_CGR1, 6); + clk[rtc_gate] = imx_clk_gate2("rtc_gate", "ipg", base + MXC_CCM_CGR1, 8); + clk[wdog_gate] = imx_clk_gate2("wdog_gate", "ipg", base + MXC_CCM_CGR1, 10); + clk[pwm_gate] = imx_clk_gate2("pwm_gate", "per", base + MXC_CCM_CGR1, 12); + clk[sim_gate] = imx_clk_gate2("sim_gate", "per", base + MXC_CCM_CGR1, 14); + clk[ect_gate] = imx_clk_gate2("ect_gate", "per", base + MXC_CCM_CGR1, 16); + clk[usb_gate] = imx_clk_gate2("usb_gate", "ahb", base + MXC_CCM_CGR1, 18); + clk[kpp_gate] = imx_clk_gate2("kpp_gate", "ipg", base + MXC_CCM_CGR1, 20); + clk[ipu_gate] = imx_clk_gate2("ipu_gate", "hsp", base + MXC_CCM_CGR1, 22); + clk[uart3_gate] = imx_clk_gate2("uart3_gate", "per", base + MXC_CCM_CGR1, 24); + clk[uart4_gate] = imx_clk_gate2("uart4_gate", "per", base + MXC_CCM_CGR1, 26); + clk[uart5_gate] = imx_clk_gate2("uart5_gate", "per", base + MXC_CCM_CGR1, 28); + clk[owire_gate] = imx_clk_gate2("owire_gate", "per", base + MXC_CCM_CGR1, 30); + clk[ssi2_gate] = imx_clk_gate2("ssi2_gate", "spll", base + MXC_CCM_CGR2, 0); + clk[cspi1_gate] = imx_clk_gate2("cspi1_gate", "ipg", base + MXC_CCM_CGR2, 2); + clk[cspi2_gate] = imx_clk_gate2("cspi2_gate", "ipg", base + MXC_CCM_CGR2, 4); + clk[gacc_gate] = imx_clk_gate2("gacc_gate", "per", base + MXC_CCM_CGR2, 6); + clk[emi_gate] = imx_clk_gate2("emi_gate", "ahb", base + MXC_CCM_CGR2, 8); + clk[rtic_gate] = imx_clk_gate2("rtic_gate", "ahb", base + MXC_CCM_CGR2, 10); + clk[firi_gate] = imx_clk_gate2("firi_gate", "upll", base+MXC_CCM_CGR2, 12); + + for (i = 0; i < ARRAY_SIZE(clk); i++) + if (IS_ERR(clk[i])) + pr_err("imx31 clk %d: register failed with %ld\n", + i, PTR_ERR(clk[i])); + + clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0"); + clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0"); + clk_register_clkdev(clk[cspi1_gate], NULL, "imx31-cspi.0"); + clk_register_clkdev(clk[cspi2_gate], NULL, "imx31-cspi.1"); + clk_register_clkdev(clk[cspi3_gate], NULL, "imx31-cspi.2"); + clk_register_clkdev(clk[pwm_gate], "pwm", NULL); + clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0"); + clk_register_clkdev(clk[rtc_gate], "rtc", NULL); + clk_register_clkdev(clk[epit1_gate], "epit", NULL); + clk_register_clkdev(clk[epit2_gate], "epit", NULL); + clk_register_clkdev(clk[nfc], NULL, "mxc_nand.0"); + clk_register_clkdev(clk[ipu_gate], NULL, "ipu-core"); + clk_register_clkdev(clk[ipu_gate], NULL, "mx3_sdc_fb"); + clk_register_clkdev(clk[kpp_gate], "kpp", NULL); + clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.0"); + clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.0"); + clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.0"); + clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.1"); + clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.1"); + clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.1"); + clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.2"); + clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.2"); + clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2"); + clk_register_clkdev(clk[usb_div_post], "per", "fsl-usb2-udc"); + clk_register_clkdev(clk[usb_gate], "ahb", "fsl-usb2-udc"); + clk_register_clkdev(clk[ipg], "ipg", "fsl-usb2-udc"); + clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0"); + /* i.mx31 has the i.mx21 type uart */ + clk_register_clkdev(clk[uart1_gate], "per", "imx21-uart.0"); + clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.0"); + clk_register_clkdev(clk[uart2_gate], "per", "imx21-uart.1"); + clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.1"); + clk_register_clkdev(clk[uart3_gate], "per", "imx21-uart.2"); + clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.2"); + clk_register_clkdev(clk[uart4_gate], "per", "imx21-uart.3"); + clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.3"); + clk_register_clkdev(clk[uart5_gate], "per", "imx21-uart.4"); + clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.4"); + clk_register_clkdev(clk[i2c1_gate], NULL, "imx-i2c.0"); + clk_register_clkdev(clk[i2c2_gate], NULL, "imx-i2c.1"); + clk_register_clkdev(clk[i2c3_gate], NULL, "imx-i2c.2"); + clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1.0"); + clk_register_clkdev(clk[sdhc1_gate], NULL, "mxc-mmc.0"); + clk_register_clkdev(clk[sdhc2_gate], NULL, "mxc-mmc.1"); + clk_register_clkdev(clk[ssi1_gate], NULL, "imx-ssi.0"); + clk_register_clkdev(clk[ssi2_gate], NULL, "imx-ssi.1"); + clk_register_clkdev(clk[firi_gate], "firi", NULL); + clk_register_clkdev(clk[ata_gate], NULL, "pata_imx"); + clk_register_clkdev(clk[rtic_gate], "rtic", NULL); + clk_register_clkdev(clk[rng_gate], "rng", NULL); + clk_register_clkdev(clk[sdma_gate], NULL, "imx31-sdma"); + clk_register_clkdev(clk[iim_gate], "iim", NULL); + + clk_set_parent(clk[csi], clk[upll]); + clk_prepare_enable(clk[emi_gate]); + clk_prepare_enable(clk[iim_gate]); + mx31_revision(); + clk_disable_unprepare(clk[iim_gate]); + + mxc_timer_init(MX31_IO_ADDRESS(MX31_GPT1_BASE_ADDR), MX31_INT_GPT); + + return 0; +} diff --git a/trunk/arch/arm/mach-imx/clk-imx35.c b/trunk/arch/arm/mach-imx/clk-imx35.c new file mode 100644 index 000000000000..920a8cc42726 --- /dev/null +++ b/trunk/arch/arm/mach-imx/clk-imx35.c @@ -0,0 +1,276 @@ +/* + * Copyright (C) 2012 Sascha Hauer, Pengutronix + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "crmregs-imx3.h" +#include "clk.h" + +struct arm_ahb_div { + unsigned char arm, ahb, sel; +}; + +static struct arm_ahb_div clk_consumer[] = { + { .arm = 1, .ahb = 4, .sel = 0}, + { .arm = 1, .ahb = 3, .sel = 1}, + { .arm = 2, .ahb = 2, .sel = 0}, + { .arm = 0, .ahb = 0, .sel = 0}, + { .arm = 0, .ahb = 0, .sel = 0}, + { .arm = 0, .ahb = 0, .sel = 0}, + { .arm = 4, .ahb = 1, .sel = 0}, + { .arm = 1, .ahb = 5, .sel = 0}, + { .arm = 1, .ahb = 8, .sel = 0}, + { .arm = 1, .ahb = 6, .sel = 1}, + { .arm = 2, .ahb = 4, .sel = 0}, + { .arm = 0, .ahb = 0, .sel = 0}, + { .arm = 0, .ahb = 0, .sel = 0}, + { .arm = 0, .ahb = 0, .sel = 0}, + { .arm = 4, .ahb = 2, .sel = 0}, + { .arm = 0, .ahb = 0, .sel = 0}, +}; + +static char hsp_div_532[] = { 4, 8, 3, 0 }; +static char hsp_div_400[] = { 3, 6, 3, 0 }; + +static const char *std_sel[] = {"ppll", "arm"}; +static const char *ipg_per_sel[] = {"ahb_per_div", "arm_per_div"}; + +enum mx35_clks { + ckih, mpll, ppll, mpll_075, arm, hsp, hsp_div, hsp_sel, ahb, ipg, + arm_per_div, ahb_per_div, ipg_per, uart_sel, uart_div, esdhc_sel, + esdhc1_div, esdhc2_div, esdhc3_div, spdif_sel, spdif_div_pre, + spdif_div_post, ssi_sel, ssi1_div_pre, ssi1_div_post, ssi2_div_pre, + ssi2_div_post, usb_sel, usb_div, nfc_div, asrc_gate, pata_gate, + audmux_gate, can1_gate, can2_gate, cspi1_gate, cspi2_gate, ect_gate, + edio_gate, emi_gate, epit1_gate, epit2_gate, esai_gate, esdhc1_gate, + esdhc2_gate, esdhc3_gate, fec_gate, gpio1_gate, gpio2_gate, gpio3_gate, + gpt_gate, i2c1_gate, i2c2_gate, i2c3_gate, iomuxc_gate, ipu_gate, + kpp_gate, mlb_gate, mshc_gate, owire_gate, pwm_gate, rngc_gate, + rtc_gate, rtic_gate, scc_gate, sdma_gate, spba_gate, spdif_gate, + ssi1_gate, ssi2_gate, uart1_gate, uart2_gate, uart3_gate, usbotg_gate, + wdog_gate, max_gate, admux_gate, csi_gate, iim_gate, gpu2d_gate, + clk_max +}; + +static struct clk *clk[clk_max]; + +int __init mx35_clocks_init() +{ + void __iomem *base = MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR); + u32 pdr0, consumer_sel, hsp_sel; + struct arm_ahb_div *aad; + unsigned char *hsp_div; + int i; + + pdr0 = __raw_readl(base + MXC_CCM_PDR0); + consumer_sel = (pdr0 >> 16) & 0xf; + aad = &clk_consumer[consumer_sel]; + if (!aad->arm) { + pr_err("i.MX35 clk: illegal consumer mux selection 0x%x\n", consumer_sel); + /* + * We are basically stuck. Continue with a default entry and hope we + * get far enough to actually show the above message + */ + aad = &clk_consumer[0]; + } + + clk[ckih] = imx_clk_fixed("ckih", 24000000); + clk[mpll] = imx_clk_pllv1("mpll", "ckih", base + MX35_CCM_MPCTL); + clk[ppll] = imx_clk_pllv1("ppll", "ckih", base + MX35_CCM_PPCTL); + + clk[mpll] = imx_clk_fixed_factor("mpll_075", "mpll", 3, 4); + + if (aad->sel) + clk[arm] = imx_clk_fixed_factor("arm", "mpll_075", 1, aad->arm); + else + clk[arm] = imx_clk_fixed_factor("arm", "mpll", 1, aad->arm); + + if (clk_get_rate(clk[arm]) > 400000000) + hsp_div = hsp_div_532; + else + hsp_div = hsp_div_400; + + hsp_sel = (pdr0 >> 20) & 0x3; + if (!hsp_div[hsp_sel]) { + pr_err("i.MX35 clk: illegal hsp clk selection 0x%x\n", hsp_sel); + hsp_sel = 0; + } + + clk[hsp] = imx_clk_fixed_factor("hsp", "arm", 1, hsp_div[hsp_sel]); + + clk[ahb] = imx_clk_fixed_factor("ahb", "arm", 1, aad->ahb); + clk[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2); + + clk[arm_per_div] = imx_clk_divider("arm_per_div", "arm", base + MX35_CCM_PDR4, 16, 6); + clk[ahb_per_div] = imx_clk_divider("ahb_per_div", "ahb", base + MXC_CCM_PDR0, 12, 3); + clk[ipg_per] = imx_clk_mux("ipg_per", base + MXC_CCM_PDR0, 26, 1, ipg_per_sel, ARRAY_SIZE(ipg_per_sel)); + + clk[uart_sel] = imx_clk_mux("uart_sel", base + MX35_CCM_PDR3, 14, 1, std_sel, ARRAY_SIZE(std_sel)); + clk[uart_div] = imx_clk_divider("uart_div", "uart_sel", base + MX35_CCM_PDR4, 10, 6); + + clk[esdhc_sel] = imx_clk_mux("esdhc_sel", base + MX35_CCM_PDR4, 9, 1, std_sel, ARRAY_SIZE(std_sel)); + clk[esdhc1_div] = imx_clk_divider("esdhc1_div", "esdhc_sel", base + MX35_CCM_PDR3, 0, 6); + clk[esdhc2_div] = imx_clk_divider("esdhc2_div", "esdhc_sel", base + MX35_CCM_PDR3, 8, 6); + clk[esdhc3_div] = imx_clk_divider("esdhc3_div", "esdhc_sel", base + MX35_CCM_PDR3, 16, 6); + + clk[spdif_sel] = imx_clk_mux("spdif_sel", base + MX35_CCM_PDR3, 22, 1, std_sel, ARRAY_SIZE(std_sel)); + clk[spdif_div_pre] = imx_clk_divider("spdif_div_pre", "spdif_sel", base + MX35_CCM_PDR3, 29, 3); /* divide by 1 not allowed */ + clk[spdif_div_post] = imx_clk_divider("spdif_div_post", "spdif_div_pre", base + MX35_CCM_PDR3, 23, 6); + + clk[ssi_sel] = imx_clk_mux("ssi_sel", base + MX35_CCM_PDR2, 6, 1, std_sel, ARRAY_SIZE(std_sel)); + clk[ssi1_div_pre] = imx_clk_divider("ssi1_div_pre", "ssi_sel", base + MX35_CCM_PDR2, 24, 3); + clk[ssi1_div_post] = imx_clk_divider("ssi1_div_post", "ssi1_div_pre", base + MX35_CCM_PDR2, 0, 6); + clk[ssi2_div_pre] = imx_clk_divider("ssi2_div_pre", "ssi_sel", base + MX35_CCM_PDR2, 27, 3); + clk[ssi2_div_post] = imx_clk_divider("ssi2_div_post", "ssi2_div_pre", base + MX35_CCM_PDR2, 8, 6); + + clk[usb_sel] = imx_clk_mux("usb_sel", base + MX35_CCM_PDR4, 9, 1, std_sel, ARRAY_SIZE(std_sel)); + clk[usb_div] = imx_clk_divider("usb_div", "usb_sel", base + MX35_CCM_PDR4, 22, 6); + + clk[nfc_div] = imx_clk_divider("nfc_div", "ahb", base + MX35_CCM_PDR4, 28, 4); + + clk[asrc_gate] = imx_clk_gate2("asrc_gate", "ipg", base + MX35_CCM_CGR0, 0); + clk[pata_gate] = imx_clk_gate2("pata_gate", "ipg", base + MX35_CCM_CGR0, 2); + clk[audmux_gate] = imx_clk_gate2("audmux_gate", "ipg", base + MX35_CCM_CGR0, 4); + clk[can1_gate] = imx_clk_gate2("can1_gate", "ipg", base + MX35_CCM_CGR0, 6); + clk[can2_gate] = imx_clk_gate2("can2_gate", "ipg", base + MX35_CCM_CGR0, 8); + clk[cspi1_gate] = imx_clk_gate2("cspi1_gate", "ipg", base + MX35_CCM_CGR0, 10); + clk[cspi2_gate] = imx_clk_gate2("cspi2_gate", "ipg", base + MX35_CCM_CGR0, 12); + clk[ect_gate] = imx_clk_gate2("ect_gate", "ipg", base + MX35_CCM_CGR0, 14); + clk[edio_gate] = imx_clk_gate2("edio_gate", "ipg", base + MX35_CCM_CGR0, 16); + clk[emi_gate] = imx_clk_gate2("emi_gate", "ipg", base + MX35_CCM_CGR0, 18); + clk[epit1_gate] = imx_clk_gate2("epit1_gate", "ipg", base + MX35_CCM_CGR0, 20); + clk[epit2_gate] = imx_clk_gate2("epit2_gate", "ipg", base + MX35_CCM_CGR0, 22); + clk[esai_gate] = imx_clk_gate2("esai_gate", "ipg", base + MX35_CCM_CGR0, 24); + clk[esdhc1_gate] = imx_clk_gate2("esdhc1_gate", "esdhc1_div", base + MX35_CCM_CGR0, 26); + clk[esdhc2_gate] = imx_clk_gate2("esdhc2_gate", "esdhc2_div", base + MX35_CCM_CGR0, 28); + clk[esdhc3_gate] = imx_clk_gate2("esdhc3_gate", "esdhc3_div", base + MX35_CCM_CGR0, 30); + + clk[fec_gate] = imx_clk_gate2("fec_gate", "ipg", base + MX35_CCM_CGR1, 0); + clk[gpio1_gate] = imx_clk_gate2("gpio1_gate", "ipg", base + MX35_CCM_CGR1, 2); + clk[gpio2_gate] = imx_clk_gate2("gpio2_gate", "ipg", base + MX35_CCM_CGR1, 4); + clk[gpio3_gate] = imx_clk_gate2("gpio3_gate", "ipg", base + MX35_CCM_CGR1, 6); + clk[gpt_gate] = imx_clk_gate2("gpt_gate", "ipg", base + MX35_CCM_CGR1, 8); + clk[i2c1_gate] = imx_clk_gate2("i2c1_gate", "ipg_per", base + MX35_CCM_CGR1, 10); + clk[i2c2_gate] = imx_clk_gate2("i2c2_gate", "ipg_per", base + MX35_CCM_CGR1, 12); + clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "ipg_per", base + MX35_CCM_CGR1, 14); + clk[iomuxc_gate] = imx_clk_gate2("iomuxc_gate", "ipg", base + MX35_CCM_CGR1, 16); + clk[ipu_gate] = imx_clk_gate2("ipu_gate", "hsp", base + MX35_CCM_CGR1, 18); + clk[kpp_gate] = imx_clk_gate2("kpp_gate", "ipg", base + MX35_CCM_CGR1, 20); + clk[mlb_gate] = imx_clk_gate2("mlb_gate", "ahb", base + MX35_CCM_CGR1, 22); + clk[mshc_gate] = imx_clk_gate2("mshc_gate", "dummy", base + MX35_CCM_CGR1, 24); + clk[owire_gate] = imx_clk_gate2("owire_gate", "ipg_per", base + MX35_CCM_CGR1, 26); + clk[pwm_gate] = imx_clk_gate2("pwm_gate", "ipg_per", base + MX35_CCM_CGR1, 28); + clk[rngc_gate] = imx_clk_gate2("rngc_gate", "ipg", base + MX35_CCM_CGR1, 30); + + clk[rtc_gate] = imx_clk_gate2("rtc_gate", "ipg", base + MX35_CCM_CGR2, 0); + clk[rtic_gate] = imx_clk_gate2("rtic_gate", "ahb", base + MX35_CCM_CGR2, 2); + clk[scc_gate] = imx_clk_gate2("scc_gate", "ipg", base + MX35_CCM_CGR2, 4); + clk[sdma_gate] = imx_clk_gate2("sdma_gate", "ahb", base + MX35_CCM_CGR2, 6); + clk[spba_gate] = imx_clk_gate2("spba_gate", "ipg", base + MX35_CCM_CGR2, 8); + clk[spdif_gate] = imx_clk_gate2("spdif_gate", "spdif_div_post", base + MX35_CCM_CGR2, 10); + clk[ssi1_gate] = imx_clk_gate2("ssi1_gate", "ssi1_div_post", base + MX35_CCM_CGR2, 12); + clk[ssi2_gate] = imx_clk_gate2("ssi2_gate", "ssi2_div_post", base + MX35_CCM_CGR2, 14); + clk[uart1_gate] = imx_clk_gate2("uart1_gate", "uart_div", base + MX35_CCM_CGR2, 16); + clk[uart2_gate] = imx_clk_gate2("uart2_gate", "uart_div", base + MX35_CCM_CGR2, 18); + clk[uart3_gate] = imx_clk_gate2("uart3_gate", "uart_div", base + MX35_CCM_CGR2, 20); + clk[usbotg_gate] = imx_clk_gate2("usbotg_gate", "ahb", base + MX35_CCM_CGR2, 22); + clk[wdog_gate] = imx_clk_gate2("wdog_gate", "ipg", base + MX35_CCM_CGR2, 24); + clk[max_gate] = imx_clk_gate2("max_gate", "dummy", base + MX35_CCM_CGR2, 26); + clk[admux_gate] = imx_clk_gate2("admux_gate", "ipg", base + MX35_CCM_CGR2, 30); + + clk[csi_gate] = imx_clk_gate2("csi_gate", "ipg", base + MX35_CCM_CGR3, 0); + clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", base + MX35_CCM_CGR3, 2); + clk[gpu2d_gate] = imx_clk_gate2("gpu2d_gate", "ahb", base + MX35_CCM_CGR3, 4); + + for (i = 0; i < ARRAY_SIZE(clk); i++) + if (IS_ERR(clk[i])) + pr_err("i.MX35 clk %d: register failed with %ld\n", + i, PTR_ERR(clk[i])); + + + clk_register_clkdev(clk[pata_gate], NULL, "pata_imx"); + clk_register_clkdev(clk[can1_gate], NULL, "flexcan.0"); + clk_register_clkdev(clk[can2_gate], NULL, "flexcan.1"); + clk_register_clkdev(clk[cspi1_gate], "per", "imx35-cspi.0"); + clk_register_clkdev(clk[cspi1_gate], "ipg", "imx35-cspi.0"); + clk_register_clkdev(clk[cspi2_gate], "per", "imx35-cspi.1"); + clk_register_clkdev(clk[cspi2_gate], "ipg", "imx35-cspi.1"); + clk_register_clkdev(clk[epit1_gate], NULL, "imx-epit.0"); + clk_register_clkdev(clk[epit2_gate], NULL, "imx-epit.1"); + clk_register_clkdev(clk[esdhc1_gate], "per", "sdhci-esdhc-imx35.0"); + clk_register_clkdev(clk[ipg], "ipg", "sdhci-esdhc-imx35.0"); + clk_register_clkdev(clk[ahb], "ahb", "sdhci-esdhc-imx35.0"); + clk_register_clkdev(clk[esdhc2_gate], "per", "sdhci-esdhc-imx35.1"); + clk_register_clkdev(clk[ipg], "ipg", "sdhci-esdhc-imx35.1"); + clk_register_clkdev(clk[ahb], "ahb", "sdhci-esdhc-imx35.1"); + clk_register_clkdev(clk[esdhc3_gate], "per", "sdhci-esdhc-imx35.2"); + clk_register_clkdev(clk[ipg], "ipg", "sdhci-esdhc-imx35.2"); + clk_register_clkdev(clk[ahb], "ahb", "sdhci-esdhc-imx35.2"); + /* i.mx35 has the i.mx27 type fec */ + clk_register_clkdev(clk[fec_gate], NULL, "imx27-fec.0"); + clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0"); + clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0"); + clk_register_clkdev(clk[i2c1_gate], NULL, "imx-i2c.0"); + clk_register_clkdev(clk[i2c2_gate], NULL, "imx-i2c.1"); + clk_register_clkdev(clk[i2c3_gate], NULL, "imx-i2c.2"); + clk_register_clkdev(clk[ipu_gate], NULL, "ipu-core"); + clk_register_clkdev(clk[ipu_gate], NULL, "mx3_sdc_fb"); + clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1"); + clk_register_clkdev(clk[sdma_gate], NULL, "imx35-sdma"); + clk_register_clkdev(clk[ipg], "ipg", "imx-ssi.0"); + clk_register_clkdev(clk[ssi1_div_post], "per", "imx-ssi.0"); + clk_register_clkdev(clk[ipg], "ipg", "imx-ssi.1"); + clk_register_clkdev(clk[ssi2_div_post], "per", "imx-ssi.1"); + /* i.mx35 has the i.mx21 type uart */ + clk_register_clkdev(clk[uart1_gate], "per", "imx21-uart.0"); + clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.0"); + clk_register_clkdev(clk[uart2_gate], "per", "imx21-uart.1"); + clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.1"); + clk_register_clkdev(clk[uart3_gate], "per", "imx21-uart.2"); + clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.2"); + clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.0"); + clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.0"); + clk_register_clkdev(clk[usbotg_gate], "ahb", "mxc-ehci.0"); + clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.1"); + clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.1"); + clk_register_clkdev(clk[usbotg_gate], "ahb", "mxc-ehci.1"); + clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.2"); + clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2"); + clk_register_clkdev(clk[usbotg_gate], "ahb", "mxc-ehci.2"); + clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc"); + clk_register_clkdev(clk[ipg], "ipg", "fsl-usb2-udc"); + clk_register_clkdev(clk[usbotg_gate], "ahb", "fsl-usb2-udc"); + clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0"); + clk_register_clkdev(clk[nfc_div], NULL, "mxc_nand.0"); + + clk_prepare_enable(clk[spba_gate]); + clk_prepare_enable(clk[gpio1_gate]); + clk_prepare_enable(clk[gpio2_gate]); + clk_prepare_enable(clk[gpio3_gate]); + clk_prepare_enable(clk[iim_gate]); + clk_prepare_enable(clk[emi_gate]); + + imx_print_silicon_rev("i.MX35", mx35_revision()); + +#ifdef CONFIG_MXC_USE_EPIT + epit_timer_init(MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1); +#else + mxc_timer_init(MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT); +#endif + + return 0; +} diff --git a/trunk/arch/arm/mach-imx/clk-imx51-imx53.c b/trunk/arch/arm/mach-imx/clk-imx51-imx53.c new file mode 100644 index 000000000000..a2200c77bf70 --- /dev/null +++ b/trunk/arch/arm/mach-imx/clk-imx51-imx53.c @@ -0,0 +1,504 @@ +/* + * Copyright (C) 2011 Sascha Hauer, Pengutronix + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "crm-regs-imx5.h" +#include "clk.h" + +/* Low-power Audio Playback Mode clock */ +static const char *lp_apm_sel[] = { "osc", }; + +/* This is used multiple times */ +static const char *standard_pll_sel[] = { "pll1_sw", "pll2_sw", "pll3_sw", "lp_apm", }; +static const char *periph_apm_sel[] = { "pll1_sw", "pll3_sw", "lp_apm", }; +static const char *main_bus_sel[] = { "pll2_sw", "periph_apm", }; +static const char *per_lp_apm_sel[] = { "main_bus", "lp_apm", }; +static const char *per_root_sel[] = { "per_podf", "ipg", }; +static const char *esdhc_c_sel[] = { "esdhc_a_podf", "esdhc_b_podf", }; +static const char *esdhc_d_sel[] = { "esdhc_a_podf", "esdhc_b_podf", }; +static const char *ssi_apm_sels[] = { "ckih1", "lp_amp", "ckih2", }; +static const char *ssi_clk_sels[] = { "pll1_sw", "pll2_sw", "pll3_sw", "ssi_apm", }; +static const char *ssi3_clk_sels[] = { "ssi1_root_gate", "ssi2_root_gate", }; +static const char *ssi_ext1_com_sels[] = { "ssi_ext1_podf", "ssi1_root_gate", }; +static const char *ssi_ext2_com_sels[] = { "ssi_ext2_podf", "ssi2_root_gate", }; +static const char *emi_slow_sel[] = { "main_bus", "ahb", }; +static const char *usb_phy_sel_str[] = { "osc", "usb_phy_podf", }; +static const char *mx51_ipu_di0_sel[] = { "di_pred", "osc", "ckih1", "tve_di", }; +static const char *mx53_ipu_di0_sel[] = { "di_pred", "osc", "ckih1", "di_pll4_podf", "dummy", "ldb_di0", }; +static const char *mx53_ldb_di0_sel[] = { "pll3_sw", "pll4_sw", }; +static const char *mx51_ipu_di1_sel[] = { "di_pred", "osc", "ckih1", "tve_di", "ipp_di1", }; +static const char *mx53_ipu_di1_sel[] = { "di_pred", "osc", "ckih1", "tve_di", "ipp_di1", "ldb_di1", }; +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 *ipu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", }; +static const char *vpu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", }; + +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, + 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, + gpt_gate, fec_gate, usboh3_per_gate, esdhc1_ipg_gate, esdhc2_ipg_gate, + esdhc3_ipg_gate, esdhc4_ipg_gate, ssi1_ipg_gate, ssi2_ipg_gate, + ssi3_ipg_gate, ecspi1_ipg_gate, ecspi1_per_gate, ecspi2_ipg_gate, + ecspi2_per_gate, cspi_ipg_gate, sdma_gate, emi_slow_gate, ipu_s, + ipu_gate, nfc_gate, ipu_di1_gate, vpu_s, vpu_gate, + vpu_reference_gate, uart4_ipg_gate, uart4_per_gate, uart5_ipg_gate, + uart5_per_gate, tve_gate, tve_pred, esdhc1_per_gate, esdhc2_per_gate, + esdhc3_per_gate, esdhc4_per_gate, usb_phy_gate, hsi2c_gate, + mipi_hsc1_gate, mipi_hsc2_gate, mipi_esc_gate, mipi_hsp_gate, + ldb_di1_div_3_5, ldb_di1_div, ldb_di0_div_3_5, ldb_di0_div, + ldb_di1_gate, can2_serial_gate, can2_ipg_gate, i2c3_gate, lp_apm, + periph_apm, main_bus, ahb_max, aips_tz1, aips_tz2, tmax1, tmax2, + tmax3, spba, uart_sel, esdhc_a_sel, esdhc_b_sel, esdhc_a_podf, + esdhc_b_podf, ecspi_sel, usboh3_sel, usb_phy_sel, iim_gate, + usboh3_gate, emi_fast_gate, ipu_di0_gate,gpc_dvfs, pll1_sw, pll2_sw, + pll3_sw, ipu_di0_sel, ipu_di1_sel, tve_ext_sel, mx51_mipi, pll4_sw, + ldb_di1_sel, di_pll4_podf, ldb_di0_sel, ldb_di0_gate, usb_phy1_gate, + usb_phy2_gate, per_lp_apm, per_pred1, per_pred2, per_podf, per_root, + ssi_apm, ssi1_root_sel, ssi2_root_sel, ssi3_root_sel, ssi_ext1_sel, + ssi_ext2_sel, ssi_ext1_com_sel, ssi_ext2_com_sel, ssi1_root_pred, + ssi1_root_podf, ssi2_root_pred, ssi2_root_podf, ssi_ext1_pred, + ssi_ext1_podf, ssi_ext2_pred, ssi_ext2_podf, ssi1_root_gate, + ssi2_root_gate, ssi3_root_gate, ssi_ext1_gate, ssi_ext2_gate, + clk_max +}; + +static struct clk *clk[clk_max]; + +static void __init mx5_clocks_common_init(unsigned long rate_ckil, + unsigned long rate_osc, unsigned long rate_ckih1, + unsigned long rate_ckih2) +{ + int i; + + clk[dummy] = imx_clk_fixed("dummy", 0); + clk[ckil] = imx_clk_fixed("ckil", rate_ckil); + clk[osc] = imx_clk_fixed("osc", rate_osc); + clk[ckih1] = imx_clk_fixed("ckih1", rate_ckih1); + clk[ckih2] = imx_clk_fixed("ckih2", rate_ckih2); + + clk[lp_apm] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 9, 1, + lp_apm_sel, ARRAY_SIZE(lp_apm_sel)); + clk[periph_apm] = imx_clk_mux("periph_apm", MXC_CCM_CBCMR, 12, 2, + periph_apm_sel, ARRAY_SIZE(periph_apm_sel)); + clk[main_bus] = imx_clk_mux("main_bus", MXC_CCM_CBCDR, 25, 1, + main_bus_sel, ARRAY_SIZE(main_bus_sel)); + clk[per_lp_apm] = imx_clk_mux("per_lp_apm", MXC_CCM_CBCMR, 1, 1, + per_lp_apm_sel, ARRAY_SIZE(per_lp_apm_sel)); + clk[per_pred1] = imx_clk_divider("per_pred1", "per_lp_apm", MXC_CCM_CBCDR, 6, 2); + clk[per_pred2] = imx_clk_divider("per_pred2", "per_pred1", MXC_CCM_CBCDR, 3, 3); + clk[per_podf] = imx_clk_divider("per_podf", "per_pred2", MXC_CCM_CBCDR, 0, 3); + clk[per_root] = imx_clk_mux("per_root", MXC_CCM_CBCMR, 0, 1, + per_root_sel, ARRAY_SIZE(per_root_sel)); + clk[ahb] = imx_clk_divider("ahb", "main_bus", MXC_CCM_CBCDR, 10, 3); + clk[ahb_max] = imx_clk_gate2("ahb_max", "ahb", MXC_CCM_CCGR0, 28); + clk[aips_tz1] = imx_clk_gate2("aips_tz1", "ahb", MXC_CCM_CCGR0, 24); + clk[aips_tz2] = imx_clk_gate2("aips_tz2", "ahb", MXC_CCM_CCGR0, 26); + clk[tmax1] = imx_clk_gate2("tmax1", "ahb", MXC_CCM_CCGR1, 0); + clk[tmax2] = imx_clk_gate2("tmax2", "ahb", MXC_CCM_CCGR1, 2); + clk[tmax3] = imx_clk_gate2("tmax3", "ahb", MXC_CCM_CCGR1, 4); + clk[spba] = imx_clk_gate2("spba", "ipg", MXC_CCM_CCGR5, 0); + clk[ipg] = imx_clk_divider("ipg", "ahb", MXC_CCM_CBCDR, 8, 2); + clk[axi_a] = imx_clk_divider("axi_a", "main_bus", MXC_CCM_CBCDR, 16, 3); + clk[axi_b] = imx_clk_divider("axi_b", "main_bus", MXC_CCM_CBCDR, 19, 3); + clk[uart_sel] = imx_clk_mux("uart_sel", MXC_CCM_CSCMR1, 24, 2, + standard_pll_sel, ARRAY_SIZE(standard_pll_sel)); + clk[uart_pred] = imx_clk_divider("uart_pred", "uart_sel", MXC_CCM_CSCDR1, 3, 3); + clk[uart_root] = imx_clk_divider("uart_root", "uart_pred", MXC_CCM_CSCDR1, 0, 3); + + clk[esdhc_a_sel] = imx_clk_mux("esdhc_a_sel", MXC_CCM_CSCMR1, 20, 2, + standard_pll_sel, ARRAY_SIZE(standard_pll_sel)); + clk[esdhc_b_sel] = imx_clk_mux("esdhc_b_sel", MXC_CCM_CSCMR1, 16, 2, + standard_pll_sel, ARRAY_SIZE(standard_pll_sel)); + clk[esdhc_a_pred] = imx_clk_divider("esdhc_a_pred", "esdhc_a_sel", MXC_CCM_CSCDR1, 16, 3); + clk[esdhc_a_podf] = imx_clk_divider("esdhc_a_podf", "esdhc_a_pred", MXC_CCM_CSCDR1, 11, 3); + clk[esdhc_b_pred] = imx_clk_divider("esdhc_b_pred", "esdhc_b_sel", MXC_CCM_CSCDR1, 22, 3); + clk[esdhc_b_podf] = imx_clk_divider("esdhc_b_podf", "esdhc_b_pred", MXC_CCM_CSCDR1, 19, 3); + clk[esdhc_c_s] = imx_clk_mux("esdhc_c_sel", MXC_CCM_CSCMR1, 19, 1, esdhc_c_sel, ARRAY_SIZE(esdhc_c_sel)); + clk[esdhc_d_s] = imx_clk_mux("esdhc_d_sel", MXC_CCM_CSCMR1, 18, 1, esdhc_d_sel, ARRAY_SIZE(esdhc_d_sel)); + + clk[emi_sel] = imx_clk_mux("emi_sel", MXC_CCM_CBCDR, 26, 1, + emi_slow_sel, ARRAY_SIZE(emi_slow_sel)); + clk[emi_slow_podf] = imx_clk_divider("emi_slow_podf", "emi_sel", MXC_CCM_CBCDR, 22, 3); + clk[nfc_podf] = imx_clk_divider("nfc_podf", "emi_slow_podf", MXC_CCM_CBCDR, 13, 3); + clk[ecspi_sel] = imx_clk_mux("ecspi_sel", MXC_CCM_CSCMR1, 4, 2, + standard_pll_sel, ARRAY_SIZE(standard_pll_sel)); + clk[ecspi_pred] = imx_clk_divider("ecspi_pred", "ecspi_sel", MXC_CCM_CSCDR2, 25, 3); + clk[ecspi_podf] = imx_clk_divider("ecspi_podf", "ecspi_pred", MXC_CCM_CSCDR2, 19, 6); + clk[usboh3_sel] = imx_clk_mux("usboh3_sel", MXC_CCM_CSCMR1, 22, 2, + standard_pll_sel, ARRAY_SIZE(standard_pll_sel)); + clk[usboh3_pred] = imx_clk_divider("usboh3_pred", "usboh3_sel", MXC_CCM_CSCDR1, 8, 3); + clk[usboh3_podf] = imx_clk_divider("usboh3_podf", "usboh3_pred", MXC_CCM_CSCDR1, 6, 2); + clk[usb_phy_pred] = imx_clk_divider("usb_phy_pred", "pll3_sw", MXC_CCM_CDCDR, 3, 3); + clk[usb_phy_podf] = imx_clk_divider("usb_phy_podf", "usb_phy_pred", MXC_CCM_CDCDR, 0, 3); + clk[usb_phy_sel] = imx_clk_mux("usb_phy_sel", MXC_CCM_CSCMR1, 26, 1, + 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); + clk[uart2_ipg_gate] = imx_clk_gate2("uart2_ipg_gate", "ipg", MXC_CCM_CCGR1, 10); + clk[uart2_per_gate] = imx_clk_gate2("uart2_per_gate", "uart_root", MXC_CCM_CCGR1, 12); + clk[uart3_ipg_gate] = imx_clk_gate2("uart3_ipg_gate", "ipg", MXC_CCM_CCGR1, 14); + clk[uart3_per_gate] = imx_clk_gate2("uart3_per_gate", "uart_root", MXC_CCM_CCGR1, 16); + clk[i2c1_gate] = imx_clk_gate2("i2c1_gate", "per_root", MXC_CCM_CCGR1, 18); + clk[i2c2_gate] = imx_clk_gate2("i2c2_gate", "per_root", MXC_CCM_CCGR1, 20); + clk[gpt_ipg_gate] = imx_clk_gate2("gpt_ipg_gate", "ipg", MXC_CCM_CCGR2, 20); + clk[pwm1_ipg_gate] = imx_clk_gate2("pwm1_ipg_gate", "ipg", MXC_CCM_CCGR2, 10); + clk[pwm1_hf_gate] = imx_clk_gate2("pwm1_hf_gate", "ipg", MXC_CCM_CCGR2, 12); + clk[pwm2_ipg_gate] = imx_clk_gate2("pwm2_ipg_gate", "ipg", MXC_CCM_CCGR2, 14); + clk[pwm2_hf_gate] = imx_clk_gate2("pwm2_hf_gate", "ipg", MXC_CCM_CCGR2, 16); + clk[gpt_gate] = imx_clk_gate2("gpt_gate", "per_root", MXC_CCM_CCGR2, 18); + clk[fec_gate] = imx_clk_gate2("fec_gate", "ipg", MXC_CCM_CCGR2, 24); + clk[usboh3_gate] = imx_clk_gate2("usboh3_gate", "ipg", MXC_CCM_CCGR2, 26); + clk[usboh3_per_gate] = imx_clk_gate2("usboh3_per_gate", "usboh3_podf", MXC_CCM_CCGR2, 28); + clk[esdhc1_ipg_gate] = imx_clk_gate2("esdhc1_ipg_gate", "ipg", MXC_CCM_CCGR3, 0); + clk[esdhc2_ipg_gate] = imx_clk_gate2("esdhc2_ipg_gate", "ipg", MXC_CCM_CCGR3, 4); + clk[esdhc3_ipg_gate] = imx_clk_gate2("esdhc3_ipg_gate", "ipg", MXC_CCM_CCGR3, 8); + clk[esdhc4_ipg_gate] = imx_clk_gate2("esdhc4_ipg_gate", "ipg", MXC_CCM_CCGR3, 12); + clk[ssi1_ipg_gate] = imx_clk_gate2("ssi1_ipg_gate", "ipg", MXC_CCM_CCGR3, 16); + clk[ssi2_ipg_gate] = imx_clk_gate2("ssi2_ipg_gate", "ipg", MXC_CCM_CCGR3, 20); + clk[ssi3_ipg_gate] = imx_clk_gate2("ssi3_ipg_gate", "ipg", MXC_CCM_CCGR3, 24); + clk[ecspi1_ipg_gate] = imx_clk_gate2("ecspi1_ipg_gate", "ipg", MXC_CCM_CCGR4, 18); + clk[ecspi1_per_gate] = imx_clk_gate2("ecspi1_per_gate", "ecspi_podf", MXC_CCM_CCGR4, 20); + clk[ecspi2_ipg_gate] = imx_clk_gate2("ecspi2_ipg_gate", "ipg", MXC_CCM_CCGR4, 22); + clk[ecspi2_per_gate] = imx_clk_gate2("ecspi2_per_gate", "ecspi_podf", MXC_CCM_CCGR4, 24); + clk[cspi_ipg_gate] = imx_clk_gate2("cspi_ipg_gate", "ipg", MXC_CCM_CCGR4, 26); + clk[sdma_gate] = imx_clk_gate2("sdma_gate", "ipg", MXC_CCM_CCGR4, 30); + clk[emi_fast_gate] = imx_clk_gate2("emi_fast_gate", "dummy", MXC_CCM_CCGR5, 14); + clk[emi_slow_gate] = imx_clk_gate2("emi_slow_gate", "emi_slow_podf", MXC_CCM_CCGR5, 16); + clk[ipu_s] = imx_clk_mux("ipu_sel", MXC_CCM_CBCMR, 6, 2, ipu_sel, ARRAY_SIZE(ipu_sel)); + clk[ipu_gate] = imx_clk_gate2("ipu_gate", "ipu_sel", MXC_CCM_CCGR5, 10); + 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[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); + clk[uart4_ipg_gate] = imx_clk_gate2("uart4_ipg_gate", "ipg", MXC_CCM_CCGR7, 8); + clk[uart4_per_gate] = imx_clk_gate2("uart4_per_gate", "uart_root", MXC_CCM_CCGR7, 10); + clk[uart5_ipg_gate] = imx_clk_gate2("uart5_ipg_gate", "ipg", MXC_CCM_CCGR7, 12); + clk[uart5_per_gate] = imx_clk_gate2("uart5_per_gate", "uart_root", MXC_CCM_CCGR7, 14); + clk[gpc_dvfs] = imx_clk_gate2("gpc_dvfs", "dummy", MXC_CCM_CCGR5, 24); + + clk[ssi_apm] = imx_clk_mux("ssi_apm", MXC_CCM_CSCMR1, 8, 2, ssi_apm_sels, ARRAY_SIZE(ssi_apm_sels)); + clk[ssi1_root_sel] = imx_clk_mux("ssi1_root_sel", MXC_CCM_CSCMR1, 14, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels)); + clk[ssi2_root_sel] = imx_clk_mux("ssi2_root_sel", MXC_CCM_CSCMR1, 12, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels)); + clk[ssi3_root_sel] = imx_clk_mux("ssi3_root_sel", MXC_CCM_CSCMR1, 11, 1, ssi3_clk_sels, ARRAY_SIZE(ssi3_clk_sels)); + clk[ssi_ext1_sel] = imx_clk_mux("ssi_ext1_sel", MXC_CCM_CSCMR1, 28, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels)); + clk[ssi_ext2_sel] = imx_clk_mux("ssi_ext2_sel", MXC_CCM_CSCMR1, 30, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels)); + clk[ssi_ext1_com_sel] = imx_clk_mux("ssi_ext1_com_sel", MXC_CCM_CSCMR1, 0, 1, ssi_ext1_com_sels, ARRAY_SIZE(ssi_ext1_com_sels)); + clk[ssi_ext2_com_sel] = imx_clk_mux("ssi_ext2_com_sel", MXC_CCM_CSCMR1, 1, 1, ssi_ext2_com_sels, ARRAY_SIZE(ssi_ext2_com_sels)); + clk[ssi1_root_pred] = imx_clk_divider("ssi1_root_pred", "ssi1_root_sel", MXC_CCM_CS1CDR, 6, 3); + clk[ssi1_root_podf] = imx_clk_divider("ssi1_root_podf", "ssi1_root_pred", MXC_CCM_CS1CDR, 0, 6); + clk[ssi2_root_pred] = imx_clk_divider("ssi2_root_pred", "ssi2_root_sel", MXC_CCM_CS2CDR, 6, 3); + clk[ssi2_root_podf] = imx_clk_divider("ssi2_root_podf", "ssi2_root_pred", MXC_CCM_CS2CDR, 0, 6); + clk[ssi_ext1_pred] = imx_clk_divider("ssi_ext1_pred", "ssi_ext1_sel", MXC_CCM_CS1CDR, 22, 3); + clk[ssi_ext1_podf] = imx_clk_divider("ssi_ext1_podf", "ssi_ext1_pred", MXC_CCM_CS1CDR, 16, 6); + clk[ssi_ext2_pred] = imx_clk_divider("ssi_ext2_pred", "ssi_ext2_sel", MXC_CCM_CS2CDR, 22, 3); + clk[ssi_ext2_podf] = imx_clk_divider("ssi_ext2_podf", "ssi_ext2_pred", MXC_CCM_CS2CDR, 16, 6); + clk[ssi1_root_gate] = imx_clk_gate2("ssi1_root_gate", "ssi1_root_podf", MXC_CCM_CCGR3, 18); + clk[ssi2_root_gate] = imx_clk_gate2("ssi2_root_gate", "ssi2_root_podf", MXC_CCM_CCGR3, 22); + clk[ssi3_root_gate] = imx_clk_gate2("ssi3_root_gate", "ssi3_root_sel", MXC_CCM_CCGR3, 26); + clk[ssi_ext1_gate] = imx_clk_gate2("ssi_ext1_gate", "ssi_ext1_com_sel", MXC_CCM_CCGR3, 28); + clk[ssi_ext2_gate] = imx_clk_gate2("ssi_ext2_gate", "ssi_ext2_com_sel", MXC_CCM_CCGR3, 30); + + for (i = 0; i < ARRAY_SIZE(clk); i++) + if (IS_ERR(clk[i])) + pr_err("i.MX5 clk %d: register failed with %ld\n", + i, PTR_ERR(clk[i])); + + clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0"); + clk_register_clkdev(clk[gpt_ipg_gate], "ipg", "imx-gpt.0"); + clk_register_clkdev(clk[uart1_per_gate], "per", "imx21-uart.0"); + clk_register_clkdev(clk[uart1_ipg_gate], "ipg", "imx21-uart.0"); + clk_register_clkdev(clk[uart2_per_gate], "per", "imx21-uart.1"); + clk_register_clkdev(clk[uart2_ipg_gate], "ipg", "imx21-uart.1"); + clk_register_clkdev(clk[uart3_per_gate], "per", "imx21-uart.2"); + clk_register_clkdev(clk[uart3_ipg_gate], "ipg", "imx21-uart.2"); + clk_register_clkdev(clk[uart4_per_gate], "per", "imx21-uart.3"); + clk_register_clkdev(clk[uart4_ipg_gate], "ipg", "imx21-uart.3"); + clk_register_clkdev(clk[uart5_per_gate], "per", "imx21-uart.4"); + clk_register_clkdev(clk[uart5_ipg_gate], "ipg", "imx21-uart.4"); + clk_register_clkdev(clk[ecspi1_per_gate], "per", "imx51-ecspi.0"); + clk_register_clkdev(clk[ecspi1_ipg_gate], "ipg", "imx51-ecspi.0"); + clk_register_clkdev(clk[ecspi2_per_gate], "per", "imx51-ecspi.1"); + clk_register_clkdev(clk[ecspi2_ipg_gate], "ipg", "imx51-ecspi.1"); + clk_register_clkdev(clk[cspi_ipg_gate], NULL, "imx51-cspi.0"); + clk_register_clkdev(clk[pwm1_ipg_gate], "pwm", "mxc_pwm.0"); + clk_register_clkdev(clk[pwm2_ipg_gate], "pwm", "mxc_pwm.1"); + clk_register_clkdev(clk[i2c1_gate], NULL, "imx-i2c.0"); + clk_register_clkdev(clk[i2c2_gate], NULL, "imx-i2c.1"); + clk_register_clkdev(clk[usboh3_per_gate], "per", "mxc-ehci.0"); + clk_register_clkdev(clk[usboh3_gate], "ipg", "mxc-ehci.0"); + clk_register_clkdev(clk[usboh3_gate], "ahb", "mxc-ehci.0"); + clk_register_clkdev(clk[usboh3_per_gate], "per", "mxc-ehci.1"); + clk_register_clkdev(clk[usboh3_gate], "ipg", "mxc-ehci.1"); + clk_register_clkdev(clk[usboh3_gate], "ahb", "mxc-ehci.1"); + clk_register_clkdev(clk[usboh3_per_gate], "per", "mxc-ehci.2"); + clk_register_clkdev(clk[usboh3_gate], "ipg", "mxc-ehci.2"); + clk_register_clkdev(clk[usboh3_gate], "ahb", "mxc-ehci.2"); + clk_register_clkdev(clk[usboh3_per_gate], "per", "fsl-usb2-udc"); + clk_register_clkdev(clk[usboh3_gate], "ipg", "fsl-usb2-udc"); + clk_register_clkdev(clk[usboh3_gate], "ahb", "fsl-usb2-udc"); + clk_register_clkdev(clk[nfc_gate], NULL, "mxc_nand"); + clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "imx-ssi.0"); + clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "imx-ssi.1"); + clk_register_clkdev(clk[ssi3_ipg_gate], NULL, "imx-ssi.2"); + clk_register_clkdev(clk[ssi_ext1_gate], "ssi_ext1", NULL); + clk_register_clkdev(clk[ssi_ext2_gate], "ssi_ext2", NULL); + clk_register_clkdev(clk[sdma_gate], NULL, "imx35-sdma"); + clk_register_clkdev(clk[cpu_podf], "cpu", NULL); + clk_register_clkdev(clk[iim_gate], "iim", NULL); + 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"); + + /* Set SDHC parents to be PLL2 */ + clk_set_parent(clk[esdhc_a_sel], clk[pll2_sw]); + clk_set_parent(clk[esdhc_b_sel], clk[pll2_sw]); + + /* move usb phy clk to 24MHz */ + clk_set_parent(clk[usb_phy_sel], clk[osc]); + + clk_prepare_enable(clk[gpc_dvfs]); + clk_prepare_enable(clk[ahb_max]); /* esdhc3 */ + clk_prepare_enable(clk[aips_tz1]); + clk_prepare_enable(clk[aips_tz2]); /* fec */ + clk_prepare_enable(clk[spba]); + clk_prepare_enable(clk[emi_fast_gate]); /* fec */ + clk_prepare_enable(clk[tmax1]); + clk_prepare_enable(clk[tmax2]); /* esdhc2, fec */ + clk_prepare_enable(clk[tmax3]); /* esdhc1, esdhc4 */ +} + +int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, + unsigned long rate_ckih1, unsigned long rate_ckih2) +{ + int i; + + clk[pll1_sw] = imx_clk_pllv2("pll1_sw", "osc", MX51_DPLL1_BASE); + clk[pll2_sw] = imx_clk_pllv2("pll2_sw", "osc", MX51_DPLL2_BASE); + clk[pll3_sw] = imx_clk_pllv2("pll3_sw", "osc", MX51_DPLL3_BASE); + clk[ipu_di0_sel] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3, + 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_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); + clk[esdhc2_per_gate] = imx_clk_gate2("esdhc2_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 6); + clk[esdhc3_per_gate] = imx_clk_gate2("esdhc3_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 10); + clk[esdhc4_per_gate] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14); + clk[usb_phy_gate] = imx_clk_gate2("usb_phy_gate", "usb_phy_sel", MXC_CCM_CCGR2, 0); + clk[hsi2c_gate] = imx_clk_gate2("hsi2c_gate", "ipg", MXC_CCM_CCGR1, 22); + clk[mipi_hsc1_gate] = imx_clk_gate2("mipi_hsc1_gate", "ipg", MXC_CCM_CCGR4, 6); + clk[mipi_hsc2_gate] = imx_clk_gate2("mipi_hsc2_gate", "ipg", MXC_CCM_CCGR4, 8); + clk[mipi_esc_gate] = imx_clk_gate2("mipi_esc_gate", "ipg", MXC_CCM_CCGR4, 10); + clk[mipi_hsp_gate] = imx_clk_gate2("mipi_hsp_gate", "ipg", MXC_CCM_CCGR4, 12); + + for (i = 0; i < ARRAY_SIZE(clk); i++) + if (IS_ERR(clk[i])) + pr_err("i.MX51 clk %d: register failed with %ld\n", + i, PTR_ERR(clk[i])); + + mx5_clocks_common_init(rate_ckil, rate_osc, rate_ckih1, rate_ckih2); + + clk_register_clkdev(clk[hsi2c_gate], NULL, "imx-i2c.2"); + clk_register_clkdev(clk[mx51_mipi], "mipi_hsp", NULL); + clk_register_clkdev(clk[vpu_gate], NULL, "imx51-vpu.0"); + clk_register_clkdev(clk[fec_gate], NULL, "imx27-fec.0"); + clk_register_clkdev(clk[gpc_dvfs], "gpc_dvfs", NULL); + clk_register_clkdev(clk[ipu_gate], "bus", "imx51-ipu"); + clk_register_clkdev(clk[ipu_di0_gate], "di0", "imx51-ipu"); + clk_register_clkdev(clk[ipu_di1_gate], "di1", "imx51-ipu"); + clk_register_clkdev(clk[ipu_gate], "hsp", "imx51-ipu"); + clk_register_clkdev(clk[usb_phy_gate], "phy", "mxc-ehci.0"); + clk_register_clkdev(clk[esdhc1_ipg_gate], "ipg", "sdhci-esdhc-imx51.0"); + clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx51.0"); + clk_register_clkdev(clk[esdhc1_per_gate], "per", "sdhci-esdhc-imx51.0"); + clk_register_clkdev(clk[esdhc2_ipg_gate], "ipg", "sdhci-esdhc-imx51.1"); + clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx51.1"); + clk_register_clkdev(clk[esdhc2_per_gate], "per", "sdhci-esdhc-imx51.1"); + clk_register_clkdev(clk[esdhc3_ipg_gate], "ipg", "sdhci-esdhc-imx51.2"); + clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx51.2"); + clk_register_clkdev(clk[esdhc3_per_gate], "per", "sdhci-esdhc-imx51.2"); + clk_register_clkdev(clk[esdhc4_ipg_gate], "ipg", "sdhci-esdhc-imx51.3"); + clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx51.3"); + clk_register_clkdev(clk[esdhc4_per_gate], "per", "sdhci-esdhc-imx51.3"); + clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "83fcc000.ssi"); + clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "70014000.ssi"); + clk_register_clkdev(clk[ssi3_ipg_gate], NULL, "83fe8000.ssi"); + + /* set the usboh3 parent to pll2_sw */ + clk_set_parent(clk[usboh3_sel], clk[pll2_sw]); + + /* set SDHC root clock to 166.25MHZ*/ + clk_set_rate(clk[esdhc_a_podf], 166250000); + clk_set_rate(clk[esdhc_b_podf], 166250000); + + /* System timer */ + mxc_timer_init(MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR), MX51_INT_GPT); + + clk_prepare_enable(clk[iim_gate]); + imx_print_silicon_rev("i.MX51", mx51_revision()); + clk_disable_unprepare(clk[iim_gate]); + + return 0; +} + +int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, + unsigned long rate_ckih1, unsigned long rate_ckih2) +{ + int i; + unsigned long r; + + clk[pll1_sw] = imx_clk_pllv2("pll1_sw", "osc", MX53_DPLL1_BASE); + clk[pll2_sw] = imx_clk_pllv2("pll2_sw", "osc", MX53_DPLL2_BASE); + 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[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_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_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); + clk[esdhc2_per_gate] = imx_clk_gate2("esdhc2_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 6); + clk[esdhc3_per_gate] = imx_clk_gate2("esdhc3_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 10); + clk[esdhc4_per_gate] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14); + clk[usb_phy1_gate] = imx_clk_gate2("usb_phy1_gate", "usb_phy_sel", MXC_CCM_CCGR4, 10); + clk[usb_phy2_gate] = imx_clk_gate2("usb_phy2_gate", "usb_phy_sel", MXC_CCM_CCGR4, 12); + clk[can2_serial_gate] = imx_clk_gate2("can2_serial_gate", "ipg", MXC_CCM_CCGR4, 6); + clk[can2_ipg_gate] = imx_clk_gate2("can2_ipg_gate", "ipg", MXC_CCM_CCGR4, 8); + clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22); + + for (i = 0; i < ARRAY_SIZE(clk); i++) + if (IS_ERR(clk[i])) + pr_err("i.MX53 clk %d: register failed with %ld\n", + i, PTR_ERR(clk[i])); + + mx5_clocks_common_init(rate_ckil, rate_osc, rate_ckih1, rate_ckih2); + + clk_register_clkdev(clk[vpu_gate], NULL, "imx53-vpu.0"); + clk_register_clkdev(clk[i2c3_gate], NULL, "imx-i2c.2"); + clk_register_clkdev(clk[fec_gate], NULL, "imx25-fec.0"); + clk_register_clkdev(clk[ipu_gate], "bus", "imx53-ipu"); + clk_register_clkdev(clk[ipu_di0_gate], "di0", "imx53-ipu"); + clk_register_clkdev(clk[ipu_di1_gate], "di1", "imx53-ipu"); + clk_register_clkdev(clk[ipu_gate], "hsp", "imx53-ipu"); + clk_register_clkdev(clk[usb_phy1_gate], "usb_phy1", "mxc-ehci.0"); + clk_register_clkdev(clk[esdhc1_ipg_gate], "ipg", "sdhci-esdhc-imx53.0"); + clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx53.0"); + clk_register_clkdev(clk[esdhc1_per_gate], "per", "sdhci-esdhc-imx53.0"); + clk_register_clkdev(clk[esdhc2_ipg_gate], "ipg", "sdhci-esdhc-imx53.1"); + clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx53.1"); + clk_register_clkdev(clk[esdhc2_per_gate], "per", "sdhci-esdhc-imx53.1"); + clk_register_clkdev(clk[esdhc3_ipg_gate], "ipg", "sdhci-esdhc-imx53.2"); + clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx53.2"); + clk_register_clkdev(clk[esdhc3_per_gate], "per", "sdhci-esdhc-imx53.2"); + clk_register_clkdev(clk[esdhc4_ipg_gate], "ipg", "sdhci-esdhc-imx53.3"); + clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx53.3"); + clk_register_clkdev(clk[esdhc4_per_gate], "per", "sdhci-esdhc-imx53.3"); + clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "63fcc000.ssi"); + clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "50014000.ssi"); + clk_register_clkdev(clk[ssi3_ipg_gate], NULL, "63fd0000.ssi"); + + /* set SDHC root clock to 200MHZ*/ + clk_set_rate(clk[esdhc_a_podf], 200000000); + clk_set_rate(clk[esdhc_b_podf], 200000000); + + /* System timer */ + mxc_timer_init(MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR), MX53_INT_GPT); + + clk_prepare_enable(clk[iim_gate]); + imx_print_silicon_rev("i.MX53", mx53_revision()); + clk_disable_unprepare(clk[iim_gate]); + + r = clk_round_rate(clk[usboh3_per_gate], 54000000); + clk_set_rate(clk[usboh3_per_gate], r); + + return 0; +} + +#ifdef CONFIG_OF +static void __init clk_get_freq_dt(unsigned long *ckil, unsigned long *osc, + unsigned long *ckih1, unsigned long *ckih2) +{ + struct device_node *np; + + /* retrieve the freqency of fixed clocks from device tree */ + for_each_compatible_node(np, NULL, "fixed-clock") { + u32 rate; + if (of_property_read_u32(np, "clock-frequency", &rate)) + continue; + + if (of_device_is_compatible(np, "fsl,imx-ckil")) + *ckil = rate; + else if (of_device_is_compatible(np, "fsl,imx-osc")) + *osc = rate; + else if (of_device_is_compatible(np, "fsl,imx-ckih1")) + *ckih1 = rate; + else if (of_device_is_compatible(np, "fsl,imx-ckih2")) + *ckih2 = rate; + } +} + +int __init mx51_clocks_init_dt(void) +{ + unsigned long ckil, osc, ckih1, ckih2; + + clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2); + return mx51_clocks_init(ckil, osc, ckih1, ckih2); +} + +int __init mx53_clocks_init_dt(void) +{ + unsigned long ckil, osc, ckih1, ckih2; + + clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2); + return mx53_clocks_init(ckil, osc, ckih1, ckih2); +} +#endif diff --git a/trunk/arch/arm/mach-imx/clk-imx6q.c b/trunk/arch/arm/mach-imx/clk-imx6q.c new file mode 100644 index 000000000000..e1a17ac7b3b4 --- /dev/null +++ b/trunk/arch/arm/mach-imx/clk-imx6q.c @@ -0,0 +1,438 @@ +/* + * Copyright 2011 Freescale Semiconductor, Inc. + * Copyright 2011 Linaro Ltd. + * + * 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 +#include +#include +#include +#include "clk.h" + +#define CCGR0 0x68 +#define CCGR1 0x6c +#define CCGR2 0x70 +#define CCGR3 0x74 +#define CCGR4 0x78 +#define CCGR5 0x7c +#define CCGR6 0x80 +#define CCGR7 0x84 + +#define CLPCR 0x54 +#define BP_CLPCR_LPM 0 +#define BM_CLPCR_LPM (0x3 << 0) +#define BM_CLPCR_BYPASS_PMIC_READY (0x1 << 2) +#define BM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5) +#define BM_CLPCR_SBYOS (0x1 << 6) +#define BM_CLPCR_DIS_REF_OSC (0x1 << 7) +#define BM_CLPCR_VSTBY (0x1 << 8) +#define BP_CLPCR_STBY_COUNT 9 +#define BM_CLPCR_STBY_COUNT (0x3 << 9) +#define BM_CLPCR_COSC_PWRDOWN (0x1 << 11) +#define BM_CLPCR_WB_PER_AT_LPM (0x1 << 16) +#define BM_CLPCR_WB_CORE_AT_LPM (0x1 << 17) +#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS (0x1 << 19) +#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS (0x1 << 21) +#define BM_CLPCR_MASK_CORE0_WFI (0x1 << 22) +#define BM_CLPCR_MASK_CORE1_WFI (0x1 << 23) +#define BM_CLPCR_MASK_CORE2_WFI (0x1 << 24) +#define BM_CLPCR_MASK_CORE3_WFI (0x1 << 25) +#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26) +#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27) + +static void __iomem *ccm_base; + +void __init imx6q_clock_map_io(void) { } + +int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) +{ + u32 val = readl_relaxed(ccm_base + CLPCR); + + val &= ~BM_CLPCR_LPM; + switch (mode) { + case WAIT_CLOCKED: + break; + case WAIT_UNCLOCKED: + val |= 0x1 << BP_CLPCR_LPM; + break; + case STOP_POWER_ON: + val |= 0x2 << BP_CLPCR_LPM; + break; + case WAIT_UNCLOCKED_POWER_OFF: + val |= 0x1 << BP_CLPCR_LPM; + val &= ~BM_CLPCR_VSTBY; + val &= ~BM_CLPCR_SBYOS; + break; + case STOP_POWER_OFF: + val |= 0x2 << BP_CLPCR_LPM; + val |= 0x3 << BP_CLPCR_STBY_COUNT; + val |= BM_CLPCR_VSTBY; + val |= BM_CLPCR_SBYOS; + break; + default: + return -EINVAL; + } + + writel_relaxed(val, ccm_base + CLPCR); + + return 0; +} + +static const char *step_sels[] = { "osc", "pll2_pfd2_396m", }; +static const char *pll1_sw_sels[] = { "pll1_sys", "step", }; +static const char *periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", }; +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 *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", "pll3_pfd1_540m", }; +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 *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 *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", + "dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0", + "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_audio", }; + +enum mx6q_clks { + dummy, ckil, ckih, osc, pll2_pfd0_352m, pll2_pfd1_594m, pll2_pfd2_396m, + pll3_pfd0_720m, pll3_pfd1_540m, pll3_pfd2_508m, pll3_pfd3_454m, + pll2_198m, pll3_120m, pll3_80m, pll3_60m, twd, step, pll1_sw, + periph_pre, periph2_pre, periph_clk2_sel, periph2_clk2_sel, axi_sel, + esai_sel, asrc_sel, spdif_sel, gpu2d_axi, gpu3d_axi, gpu2d_core_sel, + gpu3d_core_sel, gpu3d_shader_sel, ipu1_sel, ipu2_sel, ldb_di0_sel, + ldb_di1_sel, ipu1_di0_pre_sel, ipu1_di1_pre_sel, ipu2_di0_pre_sel, + ipu2_di1_pre_sel, ipu1_di0_sel, ipu1_di1_sel, ipu2_di0_sel, + ipu2_di1_sel, hsi_tx_sel, pcie_axi_sel, ssi1_sel, ssi2_sel, ssi3_sel, + usdhc1_sel, usdhc2_sel, usdhc3_sel, usdhc4_sel, enfc_sel, emi_sel, + emi_slow_sel, vdo_axi_sel, vpu_axi_sel, cko1_sel, periph, periph2, + periph_clk2, periph2_clk2, ipg, ipg_per, esai_pred, esai_podf, + asrc_pred, asrc_podf, spdif_pred, spdif_podf, can_root, ecspi_root, + gpu2d_core_podf, gpu3d_core_podf, gpu3d_shader, ipu1_podf, ipu2_podf, + ldb_di0_podf, ldb_di1_podf, ipu1_di0_pre, ipu1_di1_pre, ipu2_di0_pre, + ipu2_di1_pre, hsi_tx_podf, ssi1_pred, ssi1_podf, ssi2_pred, ssi2_podf, + ssi3_pred, ssi3_podf, uart_serial_podf, usdhc1_podf, usdhc2_podf, + usdhc3_podf, usdhc4_podf, enfc_pred, enfc_podf, emi_podf, + emi_slow_podf, vpu_axi_podf, cko1_podf, axi, mmdc_ch0_axi_podf, + mmdc_ch1_axi_podf, arm, ahb, apbh_dma, asrc, can1_ipg, can1_serial, + can2_ipg, can2_serial, ecspi1, ecspi2, ecspi3, ecspi4, ecspi5, enet, + esai, gpt_ipg, gpt_ipg_per, gpu2d_core, gpu3d_core, hdmi_iahb, + hdmi_isfr, i2c1, i2c2, i2c3, iim, enfc, ipu1, ipu1_di0, ipu1_di1, ipu2, + ipu2_di0, ldb_di0, ldb_di1, ipu2_di1, hsi_tx, mlb, mmdc_ch0_axi, + mmdc_ch1_axi, ocram, openvg_axi, pcie_axi, pwm1, pwm2, pwm3, pwm4, + gpmi_bch_apb, gpmi_bch, gpmi_io, gpmi_apb, sata, sdma, spba, ssi1, + ssi2, ssi3, uart_ipg, uart_serial, usboh3, usdhc1, usdhc2, usdhc3, + usdhc4, vdo_axi, vpu_axi, cko1, pll1_sys, pll2_bus, pll3_usb_otg, + pll4_audio, pll5_video, pll6_mlb, pll7_usb_host, pll8_enet, ssi1_ipg, + ssi2_ipg, ssi3_ipg, rom, + clk_max +}; + +static struct clk *clk[clk_max]; + +static enum mx6q_clks const clks_init_on[] __initconst = { + mmdc_ch0_axi, rom, +}; + +int __init mx6q_clocks_init(void) +{ + struct device_node *np; + void __iomem *base; + int i, irq; + + clk[dummy] = imx_clk_fixed("dummy", 0); + + /* retrieve the freqency of fixed clocks from device tree */ + for_each_compatible_node(np, NULL, "fixed-clock") { + u32 rate; + if (of_property_read_u32(np, "clock-frequency", &rate)) + continue; + + if (of_device_is_compatible(np, "fsl,imx-ckil")) + clk[ckil] = imx_clk_fixed("ckil", rate); + else if (of_device_is_compatible(np, "fsl,imx-ckih1")) + clk[ckih] = imx_clk_fixed("ckih", rate); + else if (of_device_is_compatible(np, "fsl,imx-osc")) + clk[osc] = imx_clk_fixed("osc", rate); + } + + np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop"); + base = of_iomap(np, 0); + WARN_ON(!base); + + /* type name parent_name base gate_mask div_mask */ + clk[pll1_sys] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x2000, 0x7f); + clk[pll2_bus] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x2000, 0x1); + clk[pll3_usb_otg] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc", base + 0x10, 0x2000, 0x3); + clk[pll4_audio] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4_audio", "osc", base + 0x70, 0x2000, 0x7f); + clk[pll5_video] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5_video", "osc", base + 0xa0, 0x2000, 0x7f); + clk[pll6_mlb] = imx_clk_pllv3(IMX_PLLV3_MLB, "pll6_mlb", "osc", base + 0xd0, 0x2000, 0x0); + clk[pll7_usb_host] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host","osc", base + 0x20, 0x2000, 0x3); + clk[pll8_enet] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll8_enet", "osc", base + 0xe0, 0x182000, 0x3); + + /* name parent_name reg idx */ + clk[pll2_pfd0_352m] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0); + clk[pll2_pfd1_594m] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1); + clk[pll2_pfd2_396m] = imx_clk_pfd("pll2_pfd2_396m", "pll2_bus", base + 0x100, 2); + clk[pll3_pfd0_720m] = imx_clk_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0, 0); + clk[pll3_pfd1_540m] = imx_clk_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0, 1); + clk[pll3_pfd2_508m] = imx_clk_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0, 2); + clk[pll3_pfd3_454m] = imx_clk_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0, 3); + + /* name parent_name mult div */ + clk[pll2_198m] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2); + clk[pll3_120m] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4); + clk[pll3_80m] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6); + clk[pll3_60m] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8); + clk[twd] = imx_clk_fixed_factor("twd", "arm", 1, 2); + + np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ccm"); + base = of_iomap(np, 0); + WARN_ON(!base); + ccm_base = base; + + /* name reg shift width parent_names num_parents */ + clk[step] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels)); + clk[pll1_sw] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels)); + clk[periph_pre] = imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels)); + clk[periph2_pre] = imx_clk_mux("periph2_pre", base + 0x18, 21, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels)); + clk[periph_clk2_sel] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 1, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels)); + clk[periph2_clk2_sel] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels)); + clk[axi_sel] = imx_clk_mux("axi_sel", base + 0x14, 6, 2, axi_sels, ARRAY_SIZE(axi_sels)); + clk[esai_sel] = imx_clk_mux("esai_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels)); + clk[asrc_sel] = imx_clk_mux("asrc_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels)); + clk[spdif_sel] = imx_clk_mux("spdif_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels)); + clk[gpu2d_axi] = imx_clk_mux("gpu2d_axi", base + 0x18, 0, 1, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels)); + clk[gpu3d_axi] = imx_clk_mux("gpu3d_axi", base + 0x18, 1, 1, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels)); + clk[gpu2d_core_sel] = imx_clk_mux("gpu2d_core_sel", base + 0x18, 16, 2, gpu2d_core_sels, ARRAY_SIZE(gpu2d_core_sels)); + clk[gpu3d_core_sel] = imx_clk_mux("gpu3d_core_sel", base + 0x18, 4, 2, gpu3d_core_sels, ARRAY_SIZE(gpu3d_core_sels)); + 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[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)); + clk[ipu2_di1_pre_sel] = imx_clk_mux("ipu2_di1_pre_sel", base + 0x38, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels)); + clk[ipu1_di0_sel] = imx_clk_mux("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels, ARRAY_SIZE(ipu1_di0_sels)); + clk[ipu1_di1_sel] = imx_clk_mux("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels, ARRAY_SIZE(ipu1_di1_sels)); + clk[ipu2_di0_sel] = imx_clk_mux("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels, ARRAY_SIZE(ipu2_di0_sels)); + clk[ipu2_di1_sel] = imx_clk_mux("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels, ARRAY_SIZE(ipu2_di1_sels)); + clk[hsi_tx_sel] = imx_clk_mux("hsi_tx_sel", base + 0x30, 28, 1, hsi_tx_sels, ARRAY_SIZE(hsi_tx_sels)); + clk[pcie_axi_sel] = imx_clk_mux("pcie_axi_sel", base + 0x18, 10, 1, pcie_axi_sels, ARRAY_SIZE(pcie_axi_sels)); + clk[ssi1_sel] = imx_clk_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); + clk[ssi2_sel] = imx_clk_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); + clk[ssi3_sel] = imx_clk_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); + clk[usdhc1_sel] = imx_clk_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); + clk[usdhc2_sel] = imx_clk_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); + clk[usdhc3_sel] = imx_clk_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); + clk[usdhc4_sel] = imx_clk_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); + clk[enfc_sel] = imx_clk_mux("enfc_sel", base + 0x2c, 16, 2, enfc_sels, ARRAY_SIZE(enfc_sels)); + clk[emi_sel] = imx_clk_mux("emi_sel", base + 0x1c, 27, 2, emi_sels, ARRAY_SIZE(emi_sels)); + clk[emi_slow_sel] = imx_clk_mux("emi_slow_sel", base + 0x1c, 29, 2, emi_sels, ARRAY_SIZE(emi_sels)); + clk[vdo_axi_sel] = imx_clk_mux("vdo_axi_sel", base + 0x18, 11, 1, vdo_axi_sels, ARRAY_SIZE(vdo_axi_sels)); + clk[vpu_axi_sel] = imx_clk_mux("vpu_axi_sel", base + 0x18, 14, 2, vpu_axi_sels, ARRAY_SIZE(vpu_axi_sels)); + clk[cko1_sel] = imx_clk_mux("cko1_sel", base + 0x60, 0, 4, cko1_sels, ARRAY_SIZE(cko1_sels)); + + /* name reg shift width busy: reg, shift parent_names num_parents */ + clk[periph] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels)); + clk[periph2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels)); + + /* name parent_name reg shift width */ + clk[periph_clk2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3); + clk[periph2_clk2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3); + clk[ipg] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2); + clk[ipg_per] = imx_clk_divider("ipg_per", "ipg", base + 0x1c, 0, 6); + clk[esai_pred] = imx_clk_divider("esai_pred", "esai_sel", base + 0x28, 9, 3); + clk[esai_podf] = imx_clk_divider("esai_podf", "esai_pred", base + 0x28, 25, 3); + clk[asrc_pred] = imx_clk_divider("asrc_pred", "asrc_sel", base + 0x30, 12, 3); + clk[asrc_podf] = imx_clk_divider("asrc_podf", "asrc_pred", base + 0x30, 9, 3); + clk[spdif_pred] = imx_clk_divider("spdif_pred", "spdif_sel", base + 0x30, 25, 3); + clk[spdif_podf] = imx_clk_divider("spdif_podf", "spdif_pred", base + 0x30, 22, 3); + clk[can_root] = imx_clk_divider("can_root", "pll3_usb_otg", base + 0x20, 2, 6); + clk[ecspi_root] = imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6); + clk[gpu2d_core_podf] = imx_clk_divider("gpu2d_core_podf", "gpu2d_core_sel", base + 0x18, 23, 3); + clk[gpu3d_core_podf] = imx_clk_divider("gpu3d_core_podf", "gpu3d_core_sel", base + 0x18, 26, 3); + clk[gpu3d_shader] = imx_clk_divider("gpu3d_shader", "gpu3d_shader_sel", base + 0x18, 29, 3); + 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_podf] = imx_clk_divider("ldb_di0_podf", "ldb_di0_sel", base + 0x20, 10, 1); + clk[ldb_di1_podf] = imx_clk_divider("ldb_di1_podf", "ldb_di1_sel", base + 0x20, 11, 1); + 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); + clk[ipu2_di1_pre] = imx_clk_divider("ipu2_di1_pre", "ipu2_di1_pre_sel", base + 0x38, 12, 3); + clk[hsi_tx_podf] = imx_clk_divider("hsi_tx_podf", "hsi_tx_sel", base + 0x30, 29, 3); + clk[ssi1_pred] = imx_clk_divider("ssi1_pred", "ssi1_sel", base + 0x28, 6, 3); + clk[ssi1_podf] = imx_clk_divider("ssi1_podf", "ssi1_pred", base + 0x28, 0, 6); + clk[ssi2_pred] = imx_clk_divider("ssi2_pred", "ssi2_sel", base + 0x2c, 6, 3); + clk[ssi2_podf] = imx_clk_divider("ssi2_podf", "ssi2_pred", base + 0x2c, 0, 6); + clk[ssi3_pred] = imx_clk_divider("ssi3_pred", "ssi3_sel", base + 0x28, 22, 3); + clk[ssi3_podf] = imx_clk_divider("ssi3_podf", "ssi3_pred", base + 0x28, 16, 6); + clk[uart_serial_podf] = imx_clk_divider("uart_serial_podf", "pll3_80m", base + 0x24, 0, 6); + clk[usdhc1_podf] = imx_clk_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3); + clk[usdhc2_podf] = imx_clk_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3); + clk[usdhc3_podf] = imx_clk_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3); + clk[usdhc4_podf] = imx_clk_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3); + clk[enfc_pred] = imx_clk_divider("enfc_pred", "enfc_sel", base + 0x2c, 18, 3); + clk[enfc_podf] = imx_clk_divider("enfc_podf", "enfc_pred", base + 0x2c, 21, 6); + clk[emi_podf] = imx_clk_divider("emi_podf", "emi_sel", base + 0x1c, 20, 3); + clk[emi_slow_podf] = imx_clk_divider("emi_slow_podf", "emi_slow_sel", base + 0x1c, 23, 3); + clk[vpu_axi_podf] = imx_clk_divider("vpu_axi_podf", "vpu_axi_sel", base + 0x24, 25, 3); + clk[cko1_podf] = imx_clk_divider("cko1_podf", "cko1_sel", base + 0x60, 4, 3); + + /* name parent_name reg shift width busy: reg, shift */ + clk[axi] = imx_clk_busy_divider("axi", "axi_sel", base + 0x14, 16, 3, base + 0x48, 0); + clk[mmdc_ch0_axi_podf] = imx_clk_busy_divider("mmdc_ch0_axi_podf", "periph", base + 0x14, 19, 3, base + 0x48, 4); + clk[mmdc_ch1_axi_podf] = imx_clk_busy_divider("mmdc_ch1_axi_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2); + clk[arm] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16); + clk[ahb] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1); + + /* name parent_name reg shift */ + clk[apbh_dma] = imx_clk_gate2("apbh_dma", "ahb", base + 0x68, 4); + clk[asrc] = imx_clk_gate2("asrc", "asrc_podf", base + 0x68, 6); + clk[can1_ipg] = imx_clk_gate2("can1_ipg", "ipg", base + 0x68, 14); + clk[can1_serial] = imx_clk_gate2("can1_serial", "can_root", base + 0x68, 16); + clk[can2_ipg] = imx_clk_gate2("can2_ipg", "ipg", base + 0x68, 18); + clk[can2_serial] = imx_clk_gate2("can2_serial", "can_root", base + 0x68, 20); + clk[ecspi1] = imx_clk_gate2("ecspi1", "ecspi_root", base + 0x6c, 0); + clk[ecspi2] = imx_clk_gate2("ecspi2", "ecspi_root", base + 0x6c, 2); + clk[ecspi3] = imx_clk_gate2("ecspi3", "ecspi_root", base + 0x6c, 4); + clk[ecspi4] = imx_clk_gate2("ecspi4", "ecspi_root", base + 0x6c, 6); + clk[ecspi5] = imx_clk_gate2("ecspi5", "ecspi_root", base + 0x6c, 8); + clk[enet] = imx_clk_gate2("enet", "ipg", base + 0x6c, 10); + clk[esai] = imx_clk_gate2("esai", "esai_podf", base + 0x6c, 16); + clk[gpt_ipg] = imx_clk_gate2("gpt_ipg", "ipg", base + 0x6c, 20); + clk[gpt_ipg_per] = imx_clk_gate2("gpt_ipg_per", "ipg_per", base + 0x6c, 22); + clk[gpu2d_core] = imx_clk_gate2("gpu2d_core", "gpu2d_core_podf", base + 0x6c, 24); + clk[gpu3d_core] = imx_clk_gate2("gpu3d_core", "gpu3d_core_podf", base + 0x6c, 26); + clk[hdmi_iahb] = imx_clk_gate2("hdmi_iahb", "ahb", base + 0x70, 0); + clk[hdmi_isfr] = imx_clk_gate2("hdmi_isfr", "pll3_pfd1_540m", base + 0x70, 4); + clk[i2c1] = imx_clk_gate2("i2c1", "ipg_per", base + 0x70, 6); + clk[i2c2] = imx_clk_gate2("i2c2", "ipg_per", base + 0x70, 8); + clk[i2c3] = imx_clk_gate2("i2c3", "ipg_per", base + 0x70, 10); + clk[iim] = imx_clk_gate2("iim", "ipg", base + 0x70, 12); + clk[enfc] = imx_clk_gate2("enfc", "enfc_podf", base + 0x70, 14); + clk[ipu1] = imx_clk_gate2("ipu1", "ipu1_podf", base + 0x74, 0); + clk[ipu1_di0] = imx_clk_gate2("ipu1_di0", "ipu1_di0_sel", base + 0x74, 2); + clk[ipu1_di1] = imx_clk_gate2("ipu1_di1", "ipu1_di1_sel", base + 0x74, 4); + clk[ipu2] = imx_clk_gate2("ipu2", "ipu2_podf", base + 0x74, 6); + clk[ipu2_di0] = imx_clk_gate2("ipu2_di0", "ipu2_di0_sel", base + 0x74, 8); + clk[ldb_di0] = imx_clk_gate2("ldb_di0", "ldb_di0_podf", base + 0x74, 12); + clk[ldb_di1] = imx_clk_gate2("ldb_di1", "ldb_di1_podf", base + 0x74, 14); + clk[ipu2_di1] = imx_clk_gate2("ipu2_di1", "ipu2_di1_sel", base + 0x74, 10); + clk[hsi_tx] = imx_clk_gate2("hsi_tx", "hsi_tx_podf", base + 0x74, 16); + clk[mlb] = imx_clk_gate2("mlb", "pll6_mlb", base + 0x74, 18); + clk[mmdc_ch0_axi] = imx_clk_gate2("mmdc_ch0_axi", "mmdc_ch0_axi_podf", base + 0x74, 20); + clk[mmdc_ch1_axi] = imx_clk_gate2("mmdc_ch1_axi", "mmdc_ch1_axi_podf", base + 0x74, 22); + clk[ocram] = imx_clk_gate2("ocram", "ahb", base + 0x74, 28); + clk[openvg_axi] = imx_clk_gate2("openvg_axi", "axi", base + 0x74, 30); + clk[pcie_axi] = imx_clk_gate2("pcie_axi", "pcie_axi_sel", base + 0x78, 0); + clk[pwm1] = imx_clk_gate2("pwm1", "ipg_per", base + 0x78, 16); + clk[pwm2] = imx_clk_gate2("pwm2", "ipg_per", base + 0x78, 18); + clk[pwm3] = imx_clk_gate2("pwm3", "ipg_per", base + 0x78, 20); + clk[pwm4] = imx_clk_gate2("pwm4", "ipg_per", base + 0x78, 22); + clk[gpmi_bch_apb] = imx_clk_gate2("gpmi_bch_apb", "usdhc3", base + 0x78, 24); + clk[gpmi_bch] = imx_clk_gate2("gpmi_bch", "usdhc4", base + 0x78, 26); + clk[gpmi_io] = imx_clk_gate2("gpmi_io", "enfc", base + 0x78, 28); + clk[gpmi_apb] = imx_clk_gate2("gpmi_apb", "usdhc3", base + 0x78, 30); + clk[rom] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0); + clk[sata] = imx_clk_gate2("sata", "ipg", base + 0x7c, 4); + clk[sdma] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); + clk[spba] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); + clk[ssi1_ipg] = imx_clk_gate2("ssi1_ipg", "ipg", base + 0x7c, 18); + clk[ssi2_ipg] = imx_clk_gate2("ssi2_ipg", "ipg", base + 0x7c, 20); + clk[ssi3_ipg] = imx_clk_gate2("ssi3_ipg", "ipg", base + 0x7c, 22); + clk[uart_ipg] = imx_clk_gate2("uart_ipg", "ipg", base + 0x7c, 24); + clk[uart_serial] = imx_clk_gate2("uart_serial", "uart_serial_podf", base + 0x7c, 26); + clk[usboh3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0); + clk[usdhc1] = imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2); + clk[usdhc2] = imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4); + clk[usdhc3] = imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6); + clk[usdhc4] = imx_clk_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8); + clk[vdo_axi] = imx_clk_gate2("vdo_axi", "vdo_axi_sel", base + 0x80, 12); + clk[vpu_axi] = imx_clk_gate2("vpu_axi", "vpu_axi_podf", base + 0x80, 14); + clk[cko1] = imx_clk_gate("cko1", "cko1_podf", base + 0x60, 7); + + for (i = 0; i < ARRAY_SIZE(clk); i++) + if (IS_ERR(clk[i])) + pr_err("i.MX6q clk %d: register failed with %ld\n", + i, PTR_ERR(clk[i])); + + clk_register_clkdev(clk[mmdc_ch0_axi], NULL, "mmdc_ch0_axi"); + clk_register_clkdev(clk[mmdc_ch1_axi], NULL, "mmdc_ch1_axi"); + clk_register_clkdev(clk[gpt_ipg], "ipg", "imx-gpt.0"); + clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0"); + clk_register_clkdev(clk[twd], NULL, "smp_twd"); + clk_register_clkdev(clk[usboh3], NULL, "usboh3"); + clk_register_clkdev(clk[uart_serial], "per", "2020000.serial"); + clk_register_clkdev(clk[uart_ipg], "ipg", "2020000.serial"); + clk_register_clkdev(clk[uart_serial], "per", "21e8000.serial"); + clk_register_clkdev(clk[uart_ipg], "ipg", "21e8000.serial"); + clk_register_clkdev(clk[uart_serial], "per", "21ec000.serial"); + clk_register_clkdev(clk[uart_ipg], "ipg", "21ec000.serial"); + clk_register_clkdev(clk[uart_serial], "per", "21f0000.serial"); + clk_register_clkdev(clk[uart_ipg], "ipg", "21f0000.serial"); + clk_register_clkdev(clk[uart_serial], "per", "21f4000.serial"); + clk_register_clkdev(clk[uart_ipg], "ipg", "21f4000.serial"); + clk_register_clkdev(clk[enet], NULL, "2188000.ethernet"); + clk_register_clkdev(clk[usdhc1], NULL, "2190000.usdhc"); + clk_register_clkdev(clk[usdhc2], NULL, "2194000.usdhc"); + clk_register_clkdev(clk[usdhc3], NULL, "2198000.usdhc"); + clk_register_clkdev(clk[usdhc4], NULL, "219c000.usdhc"); + clk_register_clkdev(clk[i2c1], NULL, "21a0000.i2c"); + clk_register_clkdev(clk[i2c2], NULL, "21a4000.i2c"); + clk_register_clkdev(clk[i2c3], NULL, "21a8000.i2c"); + clk_register_clkdev(clk[ecspi1], NULL, "2008000.ecspi"); + clk_register_clkdev(clk[ecspi2], NULL, "200c000.ecspi"); + clk_register_clkdev(clk[ecspi3], NULL, "2010000.ecspi"); + clk_register_clkdev(clk[ecspi4], NULL, "2014000.ecspi"); + clk_register_clkdev(clk[ecspi5], NULL, "2018000.ecspi"); + clk_register_clkdev(clk[sdma], NULL, "20ec000.sdma"); + clk_register_clkdev(clk[dummy], NULL, "20bc000.wdog"); + clk_register_clkdev(clk[dummy], NULL, "20c0000.wdog"); + clk_register_clkdev(clk[ssi1_ipg], NULL, "2028000.ssi"); + clk_register_clkdev(clk[cko1_sel], "cko1_sel", NULL); + clk_register_clkdev(clk[ahb], "ahb", NULL); + clk_register_clkdev(clk[cko1], "cko1", NULL); + + for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) + clk_prepare_enable(clk[clks_init_on[i]]); + + np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpt"); + base = of_iomap(np, 0); + WARN_ON(!base); + irq = irq_of_parse_and_map(np, 0); + mxc_timer_init(base, irq); + + return 0; +} diff --git a/trunk/arch/arm/mach-imx/clk-pfd.c b/trunk/arch/arm/mach-imx/clk-pfd.c new file mode 100644 index 000000000000..e2ed4160f329 --- /dev/null +++ b/trunk/arch/arm/mach-imx/clk-pfd.c @@ -0,0 +1,147 @@ +/* + * Copyright 2012 Freescale Semiconductor, Inc. + * Copyright 2012 Linaro Ltd. + * + * 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 "clk.h" + +/** + * struct clk_pfd - IMX PFD clock + * @clk_hw: clock source + * @reg: PFD register address + * @idx: the index of PFD encoded in the register + * + * PFD clock found on i.MX6 series. Each register for PFD has 4 clk_pfd + * data encoded, and member idx is used to specify the one. And each + * register has SET, CLR and TOG registers at offset 0x4 0x8 and 0xc. + */ +struct clk_pfd { + struct clk_hw hw; + void __iomem *reg; + u8 idx; +}; + +#define to_clk_pfd(_hw) container_of(_hw, struct clk_pfd, hw) + +#define SET 0x4 +#define CLR 0x8 +#define OTG 0xc + +static int clk_pfd_enable(struct clk_hw *hw) +{ + struct clk_pfd *pfd = to_clk_pfd(hw); + + writel_relaxed(1 << ((pfd->idx + 1) * 8 - 1), pfd->reg + CLR); + + return 0; +} + +static void clk_pfd_disable(struct clk_hw *hw) +{ + struct clk_pfd *pfd = to_clk_pfd(hw); + + writel_relaxed(1 << ((pfd->idx + 1) * 8 - 1), pfd->reg + SET); +} + +static unsigned long clk_pfd_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_pfd *pfd = to_clk_pfd(hw); + u64 tmp = parent_rate; + u8 frac = (readl_relaxed(pfd->reg) >> (pfd->idx * 8)) & 0x3f; + + tmp *= 18; + do_div(tmp, frac); + + return tmp; +} + +static long clk_pfd_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + u64 tmp = *prate; + u8 frac; + + tmp = tmp * 18 + rate / 2; + do_div(tmp, rate); + frac = tmp; + if (frac < 12) + frac = 12; + else if (frac > 35) + frac = 35; + tmp = *prate; + tmp *= 18; + do_div(tmp, frac); + + return tmp; +} + +static int clk_pfd_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_pfd *pfd = to_clk_pfd(hw); + u64 tmp = parent_rate; + u8 frac; + + tmp = tmp * 18 + rate / 2; + do_div(tmp, rate); + frac = tmp; + if (frac < 12) + frac = 12; + else if (frac > 35) + frac = 35; + + writel_relaxed(0x3f << (pfd->idx * 8), pfd->reg + CLR); + writel_relaxed(frac << (pfd->idx * 8), pfd->reg + SET); + + return 0; +} + +static const struct clk_ops clk_pfd_ops = { + .enable = clk_pfd_enable, + .disable = clk_pfd_disable, + .recalc_rate = clk_pfd_recalc_rate, + .round_rate = clk_pfd_round_rate, + .set_rate = clk_pfd_set_rate, +}; + +struct clk *imx_clk_pfd(const char *name, const char *parent_name, + void __iomem *reg, u8 idx) +{ + struct clk_pfd *pfd; + struct clk *clk; + struct clk_init_data init; + + pfd = kzalloc(sizeof(*pfd), GFP_KERNEL); + if (!pfd) + return ERR_PTR(-ENOMEM); + + pfd->reg = reg; + pfd->idx = idx; + + init.name = name; + init.ops = &clk_pfd_ops; + init.flags = 0; + init.parent_names = &parent_name; + init.num_parents = 1; + + pfd->hw.init = &init; + + clk = clk_register(NULL, &pfd->hw); + if (IS_ERR(clk)) + kfree(pfd); + + return clk; +} diff --git a/trunk/arch/arm/mach-imx/clk-pllv1.c b/trunk/arch/arm/mach-imx/clk-pllv1.c new file mode 100644 index 000000000000..2d856f9ccf59 --- /dev/null +++ b/trunk/arch/arm/mach-imx/clk-pllv1.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "clk.h" + +/** + * pll v1 + * + * @clk_hw clock source + * @parent the parent clock name + * @base base address of pll registers + * + * PLL clock version 1, found on i.MX1/21/25/27/31/35 + */ +struct clk_pllv1 { + struct clk_hw hw; + void __iomem *base; +}; + +#define to_clk_pllv1(clk) (container_of(clk, struct clk_pllv1, clk)) + +static unsigned long clk_pllv1_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_pllv1 *pll = to_clk_pllv1(hw); + + return mxc_decode_pll(readl(pll->base), parent_rate); +} + +struct clk_ops clk_pllv1_ops = { + .recalc_rate = clk_pllv1_recalc_rate, +}; + +struct clk *imx_clk_pllv1(const char *name, const char *parent, + void __iomem *base) +{ + struct clk_pllv1 *pll; + struct clk *clk; + struct clk_init_data init; + + pll = kmalloc(sizeof(*pll), GFP_KERNEL); + if (!pll) + return ERR_PTR(-ENOMEM); + + pll->base = base; + + init.name = name; + init.ops = &clk_pllv1_ops; + init.flags = 0; + init.parent_names = &parent; + init.num_parents = 1; + + pll->hw.init = &init; + + clk = clk_register(NULL, &pll->hw); + if (IS_ERR(clk)) + kfree(pll); + + return clk; +} diff --git a/trunk/arch/arm/mach-imx/clk-pllv2.c b/trunk/arch/arm/mach-imx/clk-pllv2.c new file mode 100644 index 000000000000..0440379e3628 --- /dev/null +++ b/trunk/arch/arm/mach-imx/clk-pllv2.c @@ -0,0 +1,266 @@ +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "clk.h" + +#define to_clk_pllv2(clk) (container_of(clk, struct clk_pllv2, clk)) + +/* PLL Register Offsets */ +#define MXC_PLL_DP_CTL 0x00 +#define MXC_PLL_DP_CONFIG 0x04 +#define MXC_PLL_DP_OP 0x08 +#define MXC_PLL_DP_MFD 0x0C +#define MXC_PLL_DP_MFN 0x10 +#define MXC_PLL_DP_MFNMINUS 0x14 +#define MXC_PLL_DP_MFNPLUS 0x18 +#define MXC_PLL_DP_HFS_OP 0x1C +#define MXC_PLL_DP_HFS_MFD 0x20 +#define MXC_PLL_DP_HFS_MFN 0x24 +#define MXC_PLL_DP_MFN_TOGC 0x28 +#define MXC_PLL_DP_DESTAT 0x2c + +/* PLL Register Bit definitions */ +#define MXC_PLL_DP_CTL_MUL_CTRL 0x2000 +#define MXC_PLL_DP_CTL_DPDCK0_2_EN 0x1000 +#define MXC_PLL_DP_CTL_DPDCK0_2_OFFSET 12 +#define MXC_PLL_DP_CTL_ADE 0x800 +#define MXC_PLL_DP_CTL_REF_CLK_DIV 0x400 +#define MXC_PLL_DP_CTL_REF_CLK_SEL_MASK (3 << 8) +#define MXC_PLL_DP_CTL_REF_CLK_SEL_OFFSET 8 +#define MXC_PLL_DP_CTL_HFSM 0x80 +#define MXC_PLL_DP_CTL_PRE 0x40 +#define MXC_PLL_DP_CTL_UPEN 0x20 +#define MXC_PLL_DP_CTL_RST 0x10 +#define MXC_PLL_DP_CTL_RCP 0x8 +#define MXC_PLL_DP_CTL_PLM 0x4 +#define MXC_PLL_DP_CTL_BRM0 0x2 +#define MXC_PLL_DP_CTL_LRF 0x1 + +#define MXC_PLL_DP_CONFIG_BIST 0x8 +#define MXC_PLL_DP_CONFIG_SJC_CE 0x4 +#define MXC_PLL_DP_CONFIG_AREN 0x2 +#define MXC_PLL_DP_CONFIG_LDREQ 0x1 + +#define MXC_PLL_DP_OP_MFI_OFFSET 4 +#define MXC_PLL_DP_OP_MFI_MASK (0xF << 4) +#define MXC_PLL_DP_OP_PDF_OFFSET 0 +#define MXC_PLL_DP_OP_PDF_MASK 0xF + +#define MXC_PLL_DP_MFD_OFFSET 0 +#define MXC_PLL_DP_MFD_MASK 0x07FFFFFF + +#define MXC_PLL_DP_MFN_OFFSET 0x0 +#define MXC_PLL_DP_MFN_MASK 0x07FFFFFF + +#define MXC_PLL_DP_MFN_TOGC_TOG_DIS (1 << 17) +#define MXC_PLL_DP_MFN_TOGC_TOG_EN (1 << 16) +#define MXC_PLL_DP_MFN_TOGC_CNT_OFFSET 0x0 +#define MXC_PLL_DP_MFN_TOGC_CNT_MASK 0xFFFF + +#define MXC_PLL_DP_DESTAT_TOG_SEL (1 << 31) +#define MXC_PLL_DP_DESTAT_MFN 0x07FFFFFF + +#define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */ + +struct clk_pllv2 { + struct clk_hw hw; + void __iomem *base; +}; + +static unsigned long __clk_pllv2_recalc_rate(unsigned long parent_rate, + u32 dp_ctl, u32 dp_op, u32 dp_mfd, u32 dp_mfn) +{ + long mfi, mfn, mfd, pdf, ref_clk, mfn_abs; + unsigned long dbl; + s64 temp; + + dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN; + + pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK; + mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET; + mfi = (mfi <= 5) ? 5 : mfi; + mfd = dp_mfd & MXC_PLL_DP_MFD_MASK; + mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK; + /* Sign extend to 32-bits */ + if (mfn >= 0x04000000) { + mfn |= 0xFC000000; + mfn_abs = -mfn; + } + + ref_clk = 2 * parent_rate; + if (dbl != 0) + ref_clk *= 2; + + ref_clk /= (pdf + 1); + temp = (u64) ref_clk * mfn_abs; + do_div(temp, mfd + 1); + if (mfn < 0) + temp = -temp; + temp = (ref_clk * mfi) + temp; + + return temp; +} + +static unsigned long clk_pllv2_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + u32 dp_op, dp_mfd, dp_mfn, dp_ctl; + void __iomem *pllbase; + struct clk_pllv2 *pll = to_clk_pllv2(hw); + + pllbase = pll->base; + + dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL); + dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP); + dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD); + dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN); + + return __clk_pllv2_recalc_rate(parent_rate, dp_ctl, dp_op, dp_mfd, dp_mfn); +} + +static int __clk_pllv2_set_rate(unsigned long rate, unsigned long parent_rate, + u32 *dp_op, u32 *dp_mfd, u32 *dp_mfn) +{ + u32 reg; + long mfi, pdf, mfn, mfd = 999999; + s64 temp64; + unsigned long quad_parent_rate; + + quad_parent_rate = 4 * parent_rate; + pdf = mfi = -1; + while (++pdf < 16 && mfi < 5) + mfi = rate * (pdf+1) / quad_parent_rate; + if (mfi > 15) + return -EINVAL; + pdf--; + + temp64 = rate * (pdf + 1) - quad_parent_rate * mfi; + do_div(temp64, quad_parent_rate / 1000000); + mfn = (long)temp64; + + reg = mfi << 4 | pdf; + + *dp_op = reg; + *dp_mfd = mfd; + *dp_mfn = mfn; + + return 0; +} + +static int clk_pllv2_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_pllv2 *pll = to_clk_pllv2(hw); + void __iomem *pllbase; + u32 dp_ctl, dp_op, dp_mfd, dp_mfn; + int ret; + + pllbase = pll->base; + + + ret = __clk_pllv2_set_rate(rate, parent_rate, &dp_op, &dp_mfd, &dp_mfn); + if (ret) + return ret; + + dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL); + /* use dpdck0_2 */ + __raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL); + + __raw_writel(dp_op, pllbase + MXC_PLL_DP_OP); + __raw_writel(dp_mfd, pllbase + MXC_PLL_DP_MFD); + __raw_writel(dp_mfn, pllbase + MXC_PLL_DP_MFN); + + return 0; +} + +static long clk_pllv2_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + u32 dp_op, dp_mfd, dp_mfn; + + __clk_pllv2_set_rate(rate, *prate, &dp_op, &dp_mfd, &dp_mfn); + return __clk_pllv2_recalc_rate(*prate, MXC_PLL_DP_CTL_DPDCK0_2_EN, + dp_op, dp_mfd, dp_mfn); +} + +static int clk_pllv2_prepare(struct clk_hw *hw) +{ + struct clk_pllv2 *pll = to_clk_pllv2(hw); + u32 reg; + void __iomem *pllbase; + int i = 0; + + pllbase = pll->base; + reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) | MXC_PLL_DP_CTL_UPEN; + __raw_writel(reg, pllbase + MXC_PLL_DP_CTL); + + /* Wait for lock */ + do { + reg = __raw_readl(pllbase + MXC_PLL_DP_CTL); + if (reg & MXC_PLL_DP_CTL_LRF) + break; + + udelay(1); + } while (++i < MAX_DPLL_WAIT_TRIES); + + if (i == MAX_DPLL_WAIT_TRIES) { + pr_err("MX5: pll locking failed\n"); + return -EINVAL; + } + + return 0; +} + +static void clk_pllv2_unprepare(struct clk_hw *hw) +{ + struct clk_pllv2 *pll = to_clk_pllv2(hw); + u32 reg; + void __iomem *pllbase; + + pllbase = pll->base; + reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) & ~MXC_PLL_DP_CTL_UPEN; + __raw_writel(reg, pllbase + MXC_PLL_DP_CTL); +} + +struct clk_ops clk_pllv2_ops = { + .prepare = clk_pllv2_prepare, + .unprepare = clk_pllv2_unprepare, + .recalc_rate = clk_pllv2_recalc_rate, + .round_rate = clk_pllv2_round_rate, + .set_rate = clk_pllv2_set_rate, +}; + +struct clk *imx_clk_pllv2(const char *name, const char *parent, + void __iomem *base) +{ + struct clk_pllv2 *pll; + struct clk *clk; + struct clk_init_data init; + + pll = kzalloc(sizeof(*pll), GFP_KERNEL); + if (!pll) + return ERR_PTR(-ENOMEM); + + pll->base = base; + + init.name = name; + init.ops = &clk_pllv2_ops; + init.flags = 0; + init.parent_names = &parent; + init.num_parents = 1; + + pll->hw.init = &init; + + clk = clk_register(NULL, &pll->hw); + if (IS_ERR(clk)) + kfree(pll); + + return clk; +} diff --git a/trunk/arch/arm/mach-imx/clk-pllv3.c b/trunk/arch/arm/mach-imx/clk-pllv3.c new file mode 100644 index 000000000000..36aac947bce1 --- /dev/null +++ b/trunk/arch/arm/mach-imx/clk-pllv3.c @@ -0,0 +1,419 @@ +/* + * Copyright 2012 Freescale Semiconductor, Inc. + * Copyright 2012 Linaro Ltd. + * + * 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 "clk.h" + +#define PLL_NUM_OFFSET 0x10 +#define PLL_DENOM_OFFSET 0x20 + +#define BM_PLL_POWER (0x1 << 12) +#define BM_PLL_ENABLE (0x1 << 13) +#define BM_PLL_BYPASS (0x1 << 16) +#define BM_PLL_LOCK (0x1 << 31) + +/** + * struct clk_pllv3 - IMX PLL clock version 3 + * @clk_hw: clock source + * @base: base address of PLL registers + * @powerup_set: set POWER bit to power up the PLL + * @gate_mask: mask of gate bits + * @div_mask: mask of divider bits + * + * IMX PLL clock version 3, found on i.MX6 series. Divider for pllv3 + * is actually a multiplier, and always sits at bit 0. + */ +struct clk_pllv3 { + struct clk_hw hw; + void __iomem *base; + bool powerup_set; + u32 gate_mask; + u32 div_mask; +}; + +#define to_clk_pllv3(_hw) container_of(_hw, struct clk_pllv3, hw) + +static int clk_pllv3_prepare(struct clk_hw *hw) +{ + struct clk_pllv3 *pll = to_clk_pllv3(hw); + unsigned long timeout = jiffies + msecs_to_jiffies(10); + u32 val; + + val = readl_relaxed(pll->base); + val &= ~BM_PLL_BYPASS; + if (pll->powerup_set) + val |= BM_PLL_POWER; + else + val &= ~BM_PLL_POWER; + writel_relaxed(val, pll->base); + + /* Wait for PLL to lock */ + while (!(readl_relaxed(pll->base) & BM_PLL_LOCK)) + if (time_after(jiffies, timeout)) + return -ETIMEDOUT; + + return 0; +} + +static void clk_pllv3_unprepare(struct clk_hw *hw) +{ + struct clk_pllv3 *pll = to_clk_pllv3(hw); + u32 val; + + val = readl_relaxed(pll->base); + val |= BM_PLL_BYPASS; + if (pll->powerup_set) + val &= ~BM_PLL_POWER; + else + val |= BM_PLL_POWER; + writel_relaxed(val, pll->base); +} + +static int clk_pllv3_enable(struct clk_hw *hw) +{ + struct clk_pllv3 *pll = to_clk_pllv3(hw); + u32 val; + + val = readl_relaxed(pll->base); + val |= pll->gate_mask; + writel_relaxed(val, pll->base); + + return 0; +} + +static void clk_pllv3_disable(struct clk_hw *hw) +{ + struct clk_pllv3 *pll = to_clk_pllv3(hw); + u32 val; + + val = readl_relaxed(pll->base); + val &= ~pll->gate_mask; + writel_relaxed(val, pll->base); +} + +static unsigned long clk_pllv3_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_pllv3 *pll = to_clk_pllv3(hw); + u32 div = readl_relaxed(pll->base) & pll->div_mask; + + return (div == 1) ? parent_rate * 22 : parent_rate * 20; +} + +static long clk_pllv3_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + unsigned long parent_rate = *prate; + + return (rate >= parent_rate * 22) ? parent_rate * 22 : + parent_rate * 20; +} + +static int clk_pllv3_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_pllv3 *pll = to_clk_pllv3(hw); + u32 val, div; + + if (rate == parent_rate * 22) + div = 1; + else if (rate == parent_rate * 20) + div = 0; + else + return -EINVAL; + + val = readl_relaxed(pll->base); + val &= ~pll->div_mask; + val |= div; + writel_relaxed(val, pll->base); + + return 0; +} + +static const struct clk_ops clk_pllv3_ops = { + .prepare = clk_pllv3_prepare, + .unprepare = clk_pllv3_unprepare, + .enable = clk_pllv3_enable, + .disable = clk_pllv3_disable, + .recalc_rate = clk_pllv3_recalc_rate, + .round_rate = clk_pllv3_round_rate, + .set_rate = clk_pllv3_set_rate, +}; + +static unsigned long clk_pllv3_sys_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_pllv3 *pll = to_clk_pllv3(hw); + u32 div = readl_relaxed(pll->base) & pll->div_mask; + + return parent_rate * div / 2; +} + +static long clk_pllv3_sys_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + unsigned long parent_rate = *prate; + unsigned long min_rate = parent_rate * 54 / 2; + unsigned long max_rate = parent_rate * 108 / 2; + u32 div; + + if (rate > max_rate) + rate = max_rate; + else if (rate < min_rate) + rate = min_rate; + div = rate * 2 / parent_rate; + + return parent_rate * div / 2; +} + +static int clk_pllv3_sys_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_pllv3 *pll = to_clk_pllv3(hw); + unsigned long min_rate = parent_rate * 54 / 2; + unsigned long max_rate = parent_rate * 108 / 2; + u32 val, div; + + if (rate < min_rate || rate > max_rate) + return -EINVAL; + + div = rate * 2 / parent_rate; + val = readl_relaxed(pll->base); + val &= ~pll->div_mask; + val |= div; + writel_relaxed(val, pll->base); + + return 0; +} + +static const struct clk_ops clk_pllv3_sys_ops = { + .prepare = clk_pllv3_prepare, + .unprepare = clk_pllv3_unprepare, + .enable = clk_pllv3_enable, + .disable = clk_pllv3_disable, + .recalc_rate = clk_pllv3_sys_recalc_rate, + .round_rate = clk_pllv3_sys_round_rate, + .set_rate = clk_pllv3_sys_set_rate, +}; + +static unsigned long clk_pllv3_av_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_pllv3 *pll = to_clk_pllv3(hw); + u32 mfn = readl_relaxed(pll->base + PLL_NUM_OFFSET); + u32 mfd = readl_relaxed(pll->base + PLL_DENOM_OFFSET); + u32 div = readl_relaxed(pll->base) & pll->div_mask; + + return (parent_rate * div) + ((parent_rate / mfd) * mfn); +} + +static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + unsigned long parent_rate = *prate; + unsigned long min_rate = parent_rate * 27; + unsigned long max_rate = parent_rate * 54; + u32 div; + u32 mfn, mfd = 1000000; + s64 temp64; + + if (rate > max_rate) + rate = max_rate; + else if (rate < min_rate) + rate = min_rate; + + div = rate / parent_rate; + temp64 = (u64) (rate - div * parent_rate); + temp64 *= mfd; + do_div(temp64, parent_rate); + mfn = temp64; + + return parent_rate * div + parent_rate / mfd * mfn; +} + +static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_pllv3 *pll = to_clk_pllv3(hw); + unsigned long min_rate = parent_rate * 27; + unsigned long max_rate = parent_rate * 54; + u32 val, div; + u32 mfn, mfd = 1000000; + s64 temp64; + + if (rate < min_rate || rate > max_rate) + return -EINVAL; + + div = rate / parent_rate; + temp64 = (u64) (rate - div * parent_rate); + temp64 *= mfd; + do_div(temp64, parent_rate); + mfn = temp64; + + val = readl_relaxed(pll->base); + val &= ~pll->div_mask; + val |= div; + writel_relaxed(val, pll->base); + writel_relaxed(mfn, pll->base + PLL_NUM_OFFSET); + writel_relaxed(mfd, pll->base + PLL_DENOM_OFFSET); + + return 0; +} + +static const struct clk_ops clk_pllv3_av_ops = { + .prepare = clk_pllv3_prepare, + .unprepare = clk_pllv3_unprepare, + .enable = clk_pllv3_enable, + .disable = clk_pllv3_disable, + .recalc_rate = clk_pllv3_av_recalc_rate, + .round_rate = clk_pllv3_av_round_rate, + .set_rate = clk_pllv3_av_set_rate, +}; + +static unsigned long clk_pllv3_enet_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_pllv3 *pll = to_clk_pllv3(hw); + u32 div = readl_relaxed(pll->base) & pll->div_mask; + + switch (div) { + case 0: + return 25000000; + case 1: + return 50000000; + case 2: + return 100000000; + case 3: + return 125000000; + } + + return 0; +} + +static long clk_pllv3_enet_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + if (rate >= 125000000) + rate = 125000000; + else if (rate >= 100000000) + rate = 100000000; + else if (rate >= 50000000) + rate = 50000000; + else + rate = 25000000; + return rate; +} + +static int clk_pllv3_enet_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_pllv3 *pll = to_clk_pllv3(hw); + u32 val, div; + + switch (rate) { + case 25000000: + div = 0; + break; + case 50000000: + div = 1; + break; + case 100000000: + div = 2; + break; + case 125000000: + div = 3; + break; + default: + return -EINVAL; + } + + val = readl_relaxed(pll->base); + val &= ~pll->div_mask; + val |= div; + writel_relaxed(val, pll->base); + + return 0; +} + +static const struct clk_ops clk_pllv3_enet_ops = { + .prepare = clk_pllv3_prepare, + .unprepare = clk_pllv3_unprepare, + .enable = clk_pllv3_enable, + .disable = clk_pllv3_disable, + .recalc_rate = clk_pllv3_enet_recalc_rate, + .round_rate = clk_pllv3_enet_round_rate, + .set_rate = clk_pllv3_enet_set_rate, +}; + +static const struct clk_ops clk_pllv3_mlb_ops = { + .prepare = clk_pllv3_prepare, + .unprepare = clk_pllv3_unprepare, + .enable = clk_pllv3_enable, + .disable = clk_pllv3_disable, +}; + +struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, + const char *parent_name, void __iomem *base, + u32 gate_mask, u32 div_mask) +{ + struct clk_pllv3 *pll; + const struct clk_ops *ops; + struct clk *clk; + struct clk_init_data init; + + pll = kzalloc(sizeof(*pll), GFP_KERNEL); + if (!pll) + return ERR_PTR(-ENOMEM); + + switch (type) { + case IMX_PLLV3_SYS: + ops = &clk_pllv3_sys_ops; + break; + case IMX_PLLV3_USB: + ops = &clk_pllv3_ops; + pll->powerup_set = true; + break; + case IMX_PLLV3_AV: + ops = &clk_pllv3_av_ops; + break; + case IMX_PLLV3_ENET: + ops = &clk_pllv3_enet_ops; + break; + case IMX_PLLV3_MLB: + ops = &clk_pllv3_mlb_ops; + break; + default: + ops = &clk_pllv3_ops; + } + pll->base = base; + pll->gate_mask = gate_mask; + pll->div_mask = div_mask; + + init.name = name; + init.ops = ops; + init.flags = 0; + init.parent_names = &parent_name; + init.num_parents = 1; + + pll->hw.init = &init; + + clk = clk_register(NULL, &pll->hw); + if (IS_ERR(clk)) + kfree(pll); + + return clk; +} diff --git a/trunk/arch/arm/mach-imx/clk.h b/trunk/arch/arm/mach-imx/clk.h new file mode 100644 index 000000000000..1bf64fe2523c --- /dev/null +++ b/trunk/arch/arm/mach-imx/clk.h @@ -0,0 +1,83 @@ +#ifndef __MACH_IMX_CLK_H +#define __MACH_IMX_CLK_H + +#include +#include +#include + +struct clk *imx_clk_pllv1(const char *name, const char *parent, + void __iomem *base); + +struct clk *imx_clk_pllv2(const char *name, const char *parent, + void __iomem *base); + +enum imx_pllv3_type { + IMX_PLLV3_GENERIC, + IMX_PLLV3_SYS, + IMX_PLLV3_USB, + IMX_PLLV3_AV, + IMX_PLLV3_ENET, + IMX_PLLV3_MLB, +}; + +struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, + const char *parent_name, void __iomem *base, u32 gate_mask, + u32 div_mask); + +struct clk *clk_register_gate2(struct device *dev, const char *name, + const char *parent_name, unsigned long flags, + void __iomem *reg, u8 bit_idx, + u8 clk_gate_flags, spinlock_t *lock); + +static inline struct clk *imx_clk_gate2(const char *name, const char *parent, + void __iomem *reg, u8 shift) +{ + return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, + shift, 0, &imx_ccm_lock); +} + +struct clk *imx_clk_pfd(const char *name, const char *parent_name, + void __iomem *reg, u8 idx); + +struct clk *imx_clk_busy_divider(const char *name, const char *parent_name, + void __iomem *reg, u8 shift, u8 width, + void __iomem *busy_reg, u8 busy_shift); + +struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift, + u8 width, void __iomem *busy_reg, u8 busy_shift, + const char **parent_names, int num_parents); + +static inline struct clk *imx_clk_fixed(const char *name, int rate) +{ + return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate); +} + +static inline struct clk *imx_clk_divider(const char *name, const char *parent, + void __iomem *reg, u8 shift, u8 width) +{ + return clk_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT, + 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) +{ + return clk_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg, + shift, 0, &imx_ccm_lock); +} + +static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg, + u8 shift, u8 width, const char **parents, int num_parents) +{ + return clk_register_mux(NULL, name, parents, num_parents, 0, 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) +{ + return clk_register_fixed_factor(NULL, name, parent, + CLK_SET_RATE_PARENT, mult, div); +} + +#endif diff --git a/trunk/arch/arm/mach-imx/clock-imx1.c b/trunk/arch/arm/mach-imx/clock-imx1.c deleted file mode 100644 index 4aabeb241563..000000000000 --- a/trunk/arch/arm/mach-imx/clock-imx1.c +++ /dev/null @@ -1,636 +0,0 @@ -/* - * Copyright (C) 2008 Sascha Hauer , Pengutronix - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define IO_ADDR_CCM(off) (MX1_IO_ADDRESS(MX1_CCM_BASE_ADDR + (off))) - -/* CCM register addresses */ -#define CCM_CSCR IO_ADDR_CCM(0x0) -#define CCM_MPCTL0 IO_ADDR_CCM(0x4) -#define CCM_SPCTL0 IO_ADDR_CCM(0xc) -#define CCM_PCDR IO_ADDR_CCM(0x20) - -#define CCM_CSCR_CLKO_OFFSET 29 -#define CCM_CSCR_CLKO_MASK (0x7 << 29) -#define CCM_CSCR_USB_OFFSET 26 -#define CCM_CSCR_USB_MASK (0x7 << 26) -#define CCM_CSCR_OSC_EN_SHIFT 17 -#define CCM_CSCR_SYSTEM_SEL (1 << 16) -#define CCM_CSCR_BCLK_OFFSET 10 -#define CCM_CSCR_BCLK_MASK (0xf << 10) -#define CCM_CSCR_PRESC (1 << 15) - -#define CCM_PCDR_PCLK3_OFFSET 16 -#define CCM_PCDR_PCLK3_MASK (0x7f << 16) -#define CCM_PCDR_PCLK2_OFFSET 4 -#define CCM_PCDR_PCLK2_MASK (0xf << 4) -#define CCM_PCDR_PCLK1_OFFSET 0 -#define CCM_PCDR_PCLK1_MASK 0xf - -#define IO_ADDR_SCM(off) (MX1_IO_ADDRESS(MX1_SCM_BASE_ADDR + (off))) - -/* SCM register addresses */ -#define SCM_GCCR IO_ADDR_SCM(0xc) - -#define SCM_GCCR_DMA_CLK_EN_OFFSET 3 -#define SCM_GCCR_CSI_CLK_EN_OFFSET 2 -#define SCM_GCCR_MMA_CLK_EN_OFFSET 1 -#define SCM_GCCR_USBD_CLK_EN_OFFSET 0 - -static int _clk_enable(struct clk *clk) -{ - unsigned int reg; - - reg = __raw_readl(clk->enable_reg); - reg |= 1 << clk->enable_shift; - __raw_writel(reg, clk->enable_reg); - - return 0; -} - -static void _clk_disable(struct clk *clk) -{ - unsigned int reg; - - reg = __raw_readl(clk->enable_reg); - reg &= ~(1 << clk->enable_shift); - __raw_writel(reg, clk->enable_reg); -} - -static int _clk_can_use_parent(const struct clk *clk_arr[], unsigned int size, - struct clk *parent) -{ - int i; - - for (i = 0; i < size; i++) - if (parent == clk_arr[i]) - return i; - - return -EINVAL; -} - -static unsigned long -_clk_simple_round_rate(struct clk *clk, unsigned long rate, unsigned int limit) -{ - int div; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - div = parent_rate / rate; - if (parent_rate % rate) - div++; - - if (div > limit) - div = limit; - - return parent_rate / div; -} - -static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate) -{ - return clk->parent->round_rate(clk->parent, rate); -} - -static int _clk_parent_set_rate(struct clk *clk, unsigned long rate) -{ - return clk->parent->set_rate(clk->parent, rate); -} - -static unsigned long clk16m_get_rate(struct clk *clk) -{ - return 16000000; -} - -static struct clk clk16m = { - .get_rate = clk16m_get_rate, - .enable = _clk_enable, - .enable_reg = CCM_CSCR, - .enable_shift = CCM_CSCR_OSC_EN_SHIFT, - .disable = _clk_disable, -}; - -/* in Hz */ -static unsigned long clk32_rate; - -static unsigned long clk32_get_rate(struct clk *clk) -{ - return clk32_rate; -} - -static struct clk clk32 = { - .get_rate = clk32_get_rate, -}; - -static unsigned long clk32_premult_get_rate(struct clk *clk) -{ - return clk_get_rate(clk->parent) * 512; -} - -static struct clk clk32_premult = { - .parent = &clk32, - .get_rate = clk32_premult_get_rate, -}; - -static const struct clk *prem_clk_clocks[] = { - &clk32_premult, - &clk16m, -}; - -static int prem_clk_set_parent(struct clk *clk, struct clk *parent) -{ - int i; - unsigned int reg = __raw_readl(CCM_CSCR); - - i = _clk_can_use_parent(prem_clk_clocks, ARRAY_SIZE(prem_clk_clocks), - parent); - - switch (i) { - case 0: - reg &= ~CCM_CSCR_SYSTEM_SEL; - break; - case 1: - reg |= CCM_CSCR_SYSTEM_SEL; - break; - default: - return i; - } - - __raw_writel(reg, CCM_CSCR); - - return 0; -} - -static struct clk prem_clk = { - .set_parent = prem_clk_set_parent, -}; - -static unsigned long system_clk_get_rate(struct clk *clk) -{ - return mxc_decode_pll(__raw_readl(CCM_SPCTL0), - clk_get_rate(clk->parent)); -} - -static struct clk system_clk = { - .parent = &prem_clk, - .get_rate = system_clk_get_rate, -}; - -static unsigned long mcu_clk_get_rate(struct clk *clk) -{ - return mxc_decode_pll(__raw_readl(CCM_MPCTL0), - clk_get_rate(clk->parent)); -} - -static struct clk mcu_clk = { - .parent = &clk32_premult, - .get_rate = mcu_clk_get_rate, -}; - -static unsigned long fclk_get_rate(struct clk *clk) -{ - unsigned long fclk = clk_get_rate(clk->parent); - - if (__raw_readl(CCM_CSCR) & CCM_CSCR_PRESC) - fclk /= 2; - - return fclk; -} - -static struct clk fclk = { - .parent = &mcu_clk, - .get_rate = fclk_get_rate, -}; - -/* - * get hclk ( SDRAM, CSI, Memory Stick, I2C, DMA ) - */ -static unsigned long hclk_get_rate(struct clk *clk) -{ - return clk_get_rate(clk->parent) / (((__raw_readl(CCM_CSCR) & - CCM_CSCR_BCLK_MASK) >> CCM_CSCR_BCLK_OFFSET) + 1); -} - -static unsigned long hclk_round_rate(struct clk *clk, unsigned long rate) -{ - return _clk_simple_round_rate(clk, rate, 16); -} - -static int hclk_set_rate(struct clk *clk, unsigned long rate) -{ - unsigned int div; - unsigned int reg; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - div = parent_rate / rate; - - if (div > 16 || div < 1 || ((parent_rate / div) != rate)) - return -EINVAL; - - div--; - - reg = __raw_readl(CCM_CSCR); - reg &= ~CCM_CSCR_BCLK_MASK; - reg |= div << CCM_CSCR_BCLK_OFFSET; - __raw_writel(reg, CCM_CSCR); - - return 0; -} - -static struct clk hclk = { - .parent = &system_clk, - .get_rate = hclk_get_rate, - .round_rate = hclk_round_rate, - .set_rate = hclk_set_rate, -}; - -static unsigned long clk48m_get_rate(struct clk *clk) -{ - return clk_get_rate(clk->parent) / (((__raw_readl(CCM_CSCR) & - CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET) + 1); -} - -static unsigned long clk48m_round_rate(struct clk *clk, unsigned long rate) -{ - return _clk_simple_round_rate(clk, rate, 8); -} - -static int clk48m_set_rate(struct clk *clk, unsigned long rate) -{ - unsigned int div; - unsigned int reg; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - div = parent_rate / rate; - - if (div > 8 || div < 1 || ((parent_rate / div) != rate)) - return -EINVAL; - - div--; - - reg = __raw_readl(CCM_CSCR); - reg &= ~CCM_CSCR_USB_MASK; - reg |= div << CCM_CSCR_USB_OFFSET; - __raw_writel(reg, CCM_CSCR); - - return 0; -} - -static struct clk clk48m = { - .parent = &system_clk, - .get_rate = clk48m_get_rate, - .round_rate = clk48m_round_rate, - .set_rate = clk48m_set_rate, -}; - -/* - * get peripheral clock 1 ( UART[12], Timer[12], PWM ) - */ -static unsigned long perclk1_get_rate(struct clk *clk) -{ - return clk_get_rate(clk->parent) / (((__raw_readl(CCM_PCDR) & - CCM_PCDR_PCLK1_MASK) >> CCM_PCDR_PCLK1_OFFSET) + 1); -} - -static unsigned long perclk1_round_rate(struct clk *clk, unsigned long rate) -{ - return _clk_simple_round_rate(clk, rate, 16); -} - -static int perclk1_set_rate(struct clk *clk, unsigned long rate) -{ - unsigned int div; - unsigned int reg; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - div = parent_rate / rate; - - if (div > 16 || div < 1 || ((parent_rate / div) != rate)) - return -EINVAL; - - div--; - - reg = __raw_readl(CCM_PCDR); - reg &= ~CCM_PCDR_PCLK1_MASK; - reg |= div << CCM_PCDR_PCLK1_OFFSET; - __raw_writel(reg, CCM_PCDR); - - return 0; -} - -/* - * get peripheral clock 2 ( LCD, SD, SPI[12] ) - */ -static unsigned long perclk2_get_rate(struct clk *clk) -{ - return clk_get_rate(clk->parent) / (((__raw_readl(CCM_PCDR) & - CCM_PCDR_PCLK2_MASK) >> CCM_PCDR_PCLK2_OFFSET) + 1); -} - -static unsigned long perclk2_round_rate(struct clk *clk, unsigned long rate) -{ - return _clk_simple_round_rate(clk, rate, 16); -} - -static int perclk2_set_rate(struct clk *clk, unsigned long rate) -{ - unsigned int div; - unsigned int reg; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - div = parent_rate / rate; - - if (div > 16 || div < 1 || ((parent_rate / div) != rate)) - return -EINVAL; - - div--; - - reg = __raw_readl(CCM_PCDR); - reg &= ~CCM_PCDR_PCLK2_MASK; - reg |= div << CCM_PCDR_PCLK2_OFFSET; - __raw_writel(reg, CCM_PCDR); - - return 0; -} - -/* - * get peripheral clock 3 ( SSI ) - */ -static unsigned long perclk3_get_rate(struct clk *clk) -{ - return clk_get_rate(clk->parent) / (((__raw_readl(CCM_PCDR) & - CCM_PCDR_PCLK3_MASK) >> CCM_PCDR_PCLK3_OFFSET) + 1); -} - -static unsigned long perclk3_round_rate(struct clk *clk, unsigned long rate) -{ - return _clk_simple_round_rate(clk, rate, 128); -} - -static int perclk3_set_rate(struct clk *clk, unsigned long rate) -{ - unsigned int div; - unsigned int reg; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - div = parent_rate / rate; - - if (div > 128 || div < 1 || ((parent_rate / div) != rate)) - return -EINVAL; - - div--; - - reg = __raw_readl(CCM_PCDR); - reg &= ~CCM_PCDR_PCLK3_MASK; - reg |= div << CCM_PCDR_PCLK3_OFFSET; - __raw_writel(reg, CCM_PCDR); - - return 0; -} - -static struct clk perclk[] = { - { - .id = 0, - .parent = &system_clk, - .get_rate = perclk1_get_rate, - .round_rate = perclk1_round_rate, - .set_rate = perclk1_set_rate, - }, { - .id = 1, - .parent = &system_clk, - .get_rate = perclk2_get_rate, - .round_rate = perclk2_round_rate, - .set_rate = perclk2_set_rate, - }, { - .id = 2, - .parent = &system_clk, - .get_rate = perclk3_get_rate, - .round_rate = perclk3_round_rate, - .set_rate = perclk3_set_rate, - } -}; - -static const struct clk *clko_clocks[] = { - &perclk[0], - &hclk, - &clk48m, - &clk16m, - &prem_clk, - &fclk, -}; - -static int clko_set_parent(struct clk *clk, struct clk *parent) -{ - int i; - unsigned int reg; - - i = _clk_can_use_parent(clko_clocks, ARRAY_SIZE(clko_clocks), parent); - if (i < 0) - return i; - - reg = __raw_readl(CCM_CSCR) & ~CCM_CSCR_CLKO_MASK; - reg |= i << CCM_CSCR_CLKO_OFFSET; - __raw_writel(reg, CCM_CSCR); - - if (clko_clocks[i]->set_rate && clko_clocks[i]->round_rate) { - clk->set_rate = _clk_parent_set_rate; - clk->round_rate = _clk_parent_round_rate; - } else { - clk->set_rate = NULL; - clk->round_rate = NULL; - } - - return 0; -} - -static struct clk clko_clk = { - .set_parent = clko_set_parent, -}; - -static struct clk dma_clk = { - .parent = &hclk, - .round_rate = _clk_parent_round_rate, - .set_rate = _clk_parent_set_rate, - .enable = _clk_enable, - .enable_reg = SCM_GCCR, - .enable_shift = SCM_GCCR_DMA_CLK_EN_OFFSET, - .disable = _clk_disable, -}; - -static struct clk csi_clk = { - .parent = &hclk, - .round_rate = _clk_parent_round_rate, - .set_rate = _clk_parent_set_rate, - .enable = _clk_enable, - .enable_reg = SCM_GCCR, - .enable_shift = SCM_GCCR_CSI_CLK_EN_OFFSET, - .disable = _clk_disable, -}; - -static struct clk mma_clk = { - .parent = &hclk, - .round_rate = _clk_parent_round_rate, - .set_rate = _clk_parent_set_rate, - .enable = _clk_enable, - .enable_reg = SCM_GCCR, - .enable_shift = SCM_GCCR_MMA_CLK_EN_OFFSET, - .disable = _clk_disable, -}; - -static struct clk usbd_clk = { - .parent = &clk48m, - .round_rate = _clk_parent_round_rate, - .set_rate = _clk_parent_set_rate, - .enable = _clk_enable, - .enable_reg = SCM_GCCR, - .enable_shift = SCM_GCCR_USBD_CLK_EN_OFFSET, - .disable = _clk_disable, -}; - -static struct clk gpt_clk = { - .parent = &perclk[0], - .round_rate = _clk_parent_round_rate, - .set_rate = _clk_parent_set_rate, -}; - -static struct clk uart_clk = { - .parent = &perclk[0], - .round_rate = _clk_parent_round_rate, - .set_rate = _clk_parent_set_rate, -}; - -static struct clk i2c_clk = { - .parent = &hclk, - .round_rate = _clk_parent_round_rate, - .set_rate = _clk_parent_set_rate, -}; - -static struct clk spi_clk = { - .parent = &perclk[1], - .round_rate = _clk_parent_round_rate, - .set_rate = _clk_parent_set_rate, -}; - -static struct clk sdhc_clk = { - .parent = &perclk[1], - .round_rate = _clk_parent_round_rate, - .set_rate = _clk_parent_set_rate, -}; - -static struct clk lcdc_clk = { - .parent = &perclk[1], - .round_rate = _clk_parent_round_rate, - .set_rate = _clk_parent_set_rate, -}; - -static struct clk mshc_clk = { - .parent = &hclk, - .round_rate = _clk_parent_round_rate, - .set_rate = _clk_parent_set_rate, -}; - -static struct clk ssi_clk = { - .parent = &perclk[2], - .round_rate = _clk_parent_round_rate, - .set_rate = _clk_parent_set_rate, -}; - -static struct clk rtc_clk = { - .parent = &clk32, -}; - -#define _REGISTER_CLOCK(d, n, c) \ - { \ - .dev_id = d, \ - .con_id = n, \ - .clk = &c, \ - }, -static struct clk_lookup lookups[] __initdata = { - _REGISTER_CLOCK(NULL, "dma", dma_clk) - _REGISTER_CLOCK("mx1-camera.0", NULL, csi_clk) - _REGISTER_CLOCK(NULL, "mma", mma_clk) - _REGISTER_CLOCK("imx_udc.0", NULL, usbd_clk) - _REGISTER_CLOCK(NULL, "gpt", gpt_clk) - _REGISTER_CLOCK("imx1-uart.0", NULL, uart_clk) - _REGISTER_CLOCK("imx1-uart.1", NULL, uart_clk) - _REGISTER_CLOCK("imx1-uart.2", NULL, uart_clk) - _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk) - _REGISTER_CLOCK("imx1-cspi.0", NULL, spi_clk) - _REGISTER_CLOCK("imx1-cspi.1", NULL, spi_clk) - _REGISTER_CLOCK("imx-mmc.0", NULL, sdhc_clk) - _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk) - _REGISTER_CLOCK(NULL, "mshc", mshc_clk) - _REGISTER_CLOCK(NULL, "ssi", ssi_clk) - _REGISTER_CLOCK("mxc_rtc.0", NULL, rtc_clk) -}; - -int __init mx1_clocks_init(unsigned long fref) -{ - unsigned int reg; - - /* disable clocks we are able to */ - __raw_writel(0, SCM_GCCR); - - clk32_rate = fref; - reg = __raw_readl(CCM_CSCR); - - /* detect clock reference for system PLL */ - if (reg & CCM_CSCR_SYSTEM_SEL) { - prem_clk.parent = &clk16m; - } else { - /* ensure that oscillator is disabled */ - reg &= ~(1 << CCM_CSCR_OSC_EN_SHIFT); - __raw_writel(reg, CCM_CSCR); - prem_clk.parent = &clk32_premult; - } - - /* detect reference for CLKO */ - reg = (reg & CCM_CSCR_CLKO_MASK) >> CCM_CSCR_CLKO_OFFSET; - clko_clk.parent = (struct clk *)clko_clocks[reg]; - - clkdev_add_table(lookups, ARRAY_SIZE(lookups)); - - clk_enable(&hclk); - clk_enable(&fclk); - - mxc_timer_init(&gpt_clk, MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR), - MX1_TIM1_INT); - - return 0; -} diff --git a/trunk/arch/arm/mach-imx/clock-imx21.c b/trunk/arch/arm/mach-imx/clock-imx21.c deleted file mode 100644 index ee15d8c9db08..000000000000 --- a/trunk/arch/arm/mach-imx/clock-imx21.c +++ /dev/null @@ -1,1239 +0,0 @@ -/* - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. - * Copyright 2008 Juergen Beisert, kernel@pengutronix.de - * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -#define IO_ADDR_CCM(off) (MX21_IO_ADDRESS(MX21_CCM_BASE_ADDR + (off))) - -/* Register offsets */ -#define CCM_CSCR IO_ADDR_CCM(0x0) -#define CCM_MPCTL0 IO_ADDR_CCM(0x4) -#define CCM_MPCTL1 IO_ADDR_CCM(0x8) -#define CCM_SPCTL0 IO_ADDR_CCM(0xc) -#define CCM_SPCTL1 IO_ADDR_CCM(0x10) -#define CCM_OSC26MCTL IO_ADDR_CCM(0x14) -#define CCM_PCDR0 IO_ADDR_CCM(0x18) -#define CCM_PCDR1 IO_ADDR_CCM(0x1c) -#define CCM_PCCR0 IO_ADDR_CCM(0x20) -#define CCM_PCCR1 IO_ADDR_CCM(0x24) -#define CCM_CCSR IO_ADDR_CCM(0x28) -#define CCM_PMCTL IO_ADDR_CCM(0x2c) -#define CCM_PMCOUNT IO_ADDR_CCM(0x30) -#define CCM_WKGDCTL IO_ADDR_CCM(0x34) - -#define CCM_CSCR_PRESC_OFFSET 29 -#define CCM_CSCR_PRESC_MASK (0x7 << CCM_CSCR_PRESC_OFFSET) - -#define CCM_CSCR_USB_OFFSET 26 -#define CCM_CSCR_USB_MASK (0x7 << CCM_CSCR_USB_OFFSET) -#define CCM_CSCR_SD_OFFSET 24 -#define CCM_CSCR_SD_MASK (0x3 << CCM_CSCR_SD_OFFSET) -#define CCM_CSCR_SPLLRES (1 << 22) -#define CCM_CSCR_MPLLRES (1 << 21) -#define CCM_CSCR_SSI2_OFFSET 20 -#define CCM_CSCR_SSI2 (1 << CCM_CSCR_SSI2_OFFSET) -#define CCM_CSCR_SSI1_OFFSET 19 -#define CCM_CSCR_SSI1 (1 << CCM_CSCR_SSI1_OFFSET) -#define CCM_CSCR_FIR_OFFSET 18 -#define CCM_CSCR_FIR (1 << CCM_CSCR_FIR_OFFSET) -#define CCM_CSCR_SP (1 << 17) -#define CCM_CSCR_MCU (1 << 16) -#define CCM_CSCR_BCLK_OFFSET 10 -#define CCM_CSCR_BCLK_MASK (0xf << CCM_CSCR_BCLK_OFFSET) -#define CCM_CSCR_IPDIV_OFFSET 9 -#define CCM_CSCR_IPDIV (1 << CCM_CSCR_IPDIV_OFFSET) - -#define CCM_CSCR_OSC26MDIV (1 << 4) -#define CCM_CSCR_OSC26M (1 << 3) -#define CCM_CSCR_FPM (1 << 2) -#define CCM_CSCR_SPEN (1 << 1) -#define CCM_CSCR_MPEN 1 - -#define CCM_MPCTL0_CPLM (1 << 31) -#define CCM_MPCTL0_PD_OFFSET 26 -#define CCM_MPCTL0_PD_MASK (0xf << 26) -#define CCM_MPCTL0_MFD_OFFSET 16 -#define CCM_MPCTL0_MFD_MASK (0x3ff << 16) -#define CCM_MPCTL0_MFI_OFFSET 10 -#define CCM_MPCTL0_MFI_MASK (0xf << 10) -#define CCM_MPCTL0_MFN_OFFSET 0 -#define CCM_MPCTL0_MFN_MASK 0x3ff - -#define CCM_MPCTL1_LF (1 << 15) -#define CCM_MPCTL1_BRMO (1 << 6) - -#define CCM_SPCTL0_CPLM (1 << 31) -#define CCM_SPCTL0_PD_OFFSET 26 -#define CCM_SPCTL0_PD_MASK (0xf << 26) -#define CCM_SPCTL0_MFD_OFFSET 16 -#define CCM_SPCTL0_MFD_MASK (0x3ff << 16) -#define CCM_SPCTL0_MFI_OFFSET 10 -#define CCM_SPCTL0_MFI_MASK (0xf << 10) -#define CCM_SPCTL0_MFN_OFFSET 0 -#define CCM_SPCTL0_MFN_MASK 0x3ff - -#define CCM_SPCTL1_LF (1 << 15) -#define CCM_SPCTL1_BRMO (1 << 6) - -#define CCM_OSC26MCTL_PEAK_OFFSET 16 -#define CCM_OSC26MCTL_PEAK_MASK (0x3 << 16) -#define CCM_OSC26MCTL_AGC_OFFSET 8 -#define CCM_OSC26MCTL_AGC_MASK (0x3f << 8) -#define CCM_OSC26MCTL_ANATEST_OFFSET 0 -#define CCM_OSC26MCTL_ANATEST_MASK 0x3f - -#define CCM_PCDR0_SSI2BAUDDIV_OFFSET 26 -#define CCM_PCDR0_SSI2BAUDDIV_MASK (0x3f << 26) -#define CCM_PCDR0_SSI1BAUDDIV_OFFSET 16 -#define CCM_PCDR0_SSI1BAUDDIV_MASK (0x3f << 16) -#define CCM_PCDR0_NFCDIV_OFFSET 12 -#define CCM_PCDR0_NFCDIV_MASK (0xf << 12) -#define CCM_PCDR0_48MDIV_OFFSET 5 -#define CCM_PCDR0_48MDIV_MASK (0x7 << CCM_PCDR0_48MDIV_OFFSET) -#define CCM_PCDR0_FIRIDIV_OFFSET 0 -#define CCM_PCDR0_FIRIDIV_MASK 0x1f -#define CCM_PCDR1_PERDIV4_OFFSET 24 -#define CCM_PCDR1_PERDIV4_MASK (0x3f << 24) -#define CCM_PCDR1_PERDIV3_OFFSET 16 -#define CCM_PCDR1_PERDIV3_MASK (0x3f << 16) -#define CCM_PCDR1_PERDIV2_OFFSET 8 -#define CCM_PCDR1_PERDIV2_MASK (0x3f << 8) -#define CCM_PCDR1_PERDIV1_OFFSET 0 -#define CCM_PCDR1_PERDIV1_MASK 0x3f - -#define CCM_PCCR_HCLK_CSI_OFFSET 31 -#define CCM_PCCR_HCLK_CSI_REG CCM_PCCR0 -#define CCM_PCCR_HCLK_DMA_OFFSET 30 -#define CCM_PCCR_HCLK_DMA_REG CCM_PCCR0 -#define CCM_PCCR_HCLK_BROM_OFFSET 28 -#define CCM_PCCR_HCLK_BROM_REG CCM_PCCR0 -#define CCM_PCCR_HCLK_EMMA_OFFSET 27 -#define CCM_PCCR_HCLK_EMMA_REG CCM_PCCR0 -#define CCM_PCCR_HCLK_LCDC_OFFSET 26 -#define CCM_PCCR_HCLK_LCDC_REG CCM_PCCR0 -#define CCM_PCCR_HCLK_SLCDC_OFFSET 25 -#define CCM_PCCR_HCLK_SLCDC_REG CCM_PCCR0 -#define CCM_PCCR_HCLK_USBOTG_OFFSET 24 -#define CCM_PCCR_HCLK_USBOTG_REG CCM_PCCR0 -#define CCM_PCCR_HCLK_BMI_OFFSET 23 -#define CCM_PCCR_BMI_MASK (1 << CCM_PCCR_BMI_MASK) -#define CCM_PCCR_HCLK_BMI_REG CCM_PCCR0 -#define CCM_PCCR_PERCLK4_OFFSET 22 -#define CCM_PCCR_PERCLK4_REG CCM_PCCR0 -#define CCM_PCCR_SLCDC_OFFSET 21 -#define CCM_PCCR_SLCDC_REG CCM_PCCR0 -#define CCM_PCCR_FIRI_BAUD_OFFSET 20 -#define CCM_PCCR_FIRI_BAUD_MASK (1 << CCM_PCCR_FIRI_BAUD_MASK) -#define CCM_PCCR_FIRI_BAUD_REG CCM_PCCR0 -#define CCM_PCCR_NFC_OFFSET 19 -#define CCM_PCCR_NFC_REG CCM_PCCR0 -#define CCM_PCCR_LCDC_OFFSET 18 -#define CCM_PCCR_LCDC_REG CCM_PCCR0 -#define CCM_PCCR_SSI1_BAUD_OFFSET 17 -#define CCM_PCCR_SSI1_BAUD_REG CCM_PCCR0 -#define CCM_PCCR_SSI2_BAUD_OFFSET 16 -#define CCM_PCCR_SSI2_BAUD_REG CCM_PCCR0 -#define CCM_PCCR_EMMA_OFFSET 15 -#define CCM_PCCR_EMMA_REG CCM_PCCR0 -#define CCM_PCCR_USBOTG_OFFSET 14 -#define CCM_PCCR_USBOTG_REG CCM_PCCR0 -#define CCM_PCCR_DMA_OFFSET 13 -#define CCM_PCCR_DMA_REG CCM_PCCR0 -#define CCM_PCCR_I2C1_OFFSET 12 -#define CCM_PCCR_I2C1_REG CCM_PCCR0 -#define CCM_PCCR_GPIO_OFFSET 11 -#define CCM_PCCR_GPIO_REG CCM_PCCR0 -#define CCM_PCCR_SDHC2_OFFSET 10 -#define CCM_PCCR_SDHC2_REG CCM_PCCR0 -#define CCM_PCCR_SDHC1_OFFSET 9 -#define CCM_PCCR_SDHC1_REG CCM_PCCR0 -#define CCM_PCCR_FIRI_OFFSET 8 -#define CCM_PCCR_FIRI_MASK (1 << CCM_PCCR_BAUD_MASK) -#define CCM_PCCR_FIRI_REG CCM_PCCR0 -#define CCM_PCCR_SSI2_IPG_OFFSET 7 -#define CCM_PCCR_SSI2_REG CCM_PCCR0 -#define CCM_PCCR_SSI1_IPG_OFFSET 6 -#define CCM_PCCR_SSI1_REG CCM_PCCR0 -#define CCM_PCCR_CSPI2_OFFSET 5 -#define CCM_PCCR_CSPI2_REG CCM_PCCR0 -#define CCM_PCCR_CSPI1_OFFSET 4 -#define CCM_PCCR_CSPI1_REG CCM_PCCR0 -#define CCM_PCCR_UART4_OFFSET 3 -#define CCM_PCCR_UART4_REG CCM_PCCR0 -#define CCM_PCCR_UART3_OFFSET 2 -#define CCM_PCCR_UART3_REG CCM_PCCR0 -#define CCM_PCCR_UART2_OFFSET 1 -#define CCM_PCCR_UART2_REG CCM_PCCR0 -#define CCM_PCCR_UART1_OFFSET 0 -#define CCM_PCCR_UART1_REG CCM_PCCR0 - -#define CCM_PCCR_OWIRE_OFFSET 31 -#define CCM_PCCR_OWIRE_REG CCM_PCCR1 -#define CCM_PCCR_KPP_OFFSET 30 -#define CCM_PCCR_KPP_REG CCM_PCCR1 -#define CCM_PCCR_RTC_OFFSET 29 -#define CCM_PCCR_RTC_REG CCM_PCCR1 -#define CCM_PCCR_PWM_OFFSET 28 -#define CCM_PCCR_PWM_REG CCM_PCCR1 -#define CCM_PCCR_GPT3_OFFSET 27 -#define CCM_PCCR_GPT3_REG CCM_PCCR1 -#define CCM_PCCR_GPT2_OFFSET 26 -#define CCM_PCCR_GPT2_REG CCM_PCCR1 -#define CCM_PCCR_GPT1_OFFSET 25 -#define CCM_PCCR_GPT1_REG CCM_PCCR1 -#define CCM_PCCR_WDT_OFFSET 24 -#define CCM_PCCR_WDT_REG CCM_PCCR1 -#define CCM_PCCR_CSPI3_OFFSET 23 -#define CCM_PCCR_CSPI3_REG CCM_PCCR1 - -#define CCM_PCCR_CSPI1_MASK (1 << CCM_PCCR_CSPI1_OFFSET) -#define CCM_PCCR_CSPI2_MASK (1 << CCM_PCCR_CSPI2_OFFSET) -#define CCM_PCCR_CSPI3_MASK (1 << CCM_PCCR_CSPI3_OFFSET) -#define CCM_PCCR_DMA_MASK (1 << CCM_PCCR_DMA_OFFSET) -#define CCM_PCCR_EMMA_MASK (1 << CCM_PCCR_EMMA_OFFSET) -#define CCM_PCCR_GPIO_MASK (1 << CCM_PCCR_GPIO_OFFSET) -#define CCM_PCCR_GPT1_MASK (1 << CCM_PCCR_GPT1_OFFSET) -#define CCM_PCCR_GPT2_MASK (1 << CCM_PCCR_GPT2_OFFSET) -#define CCM_PCCR_GPT3_MASK (1 << CCM_PCCR_GPT3_OFFSET) -#define CCM_PCCR_HCLK_BROM_MASK (1 << CCM_PCCR_HCLK_BROM_OFFSET) -#define CCM_PCCR_HCLK_CSI_MASK (1 << CCM_PCCR_HCLK_CSI_OFFSET) -#define CCM_PCCR_HCLK_DMA_MASK (1 << CCM_PCCR_HCLK_DMA_OFFSET) -#define CCM_PCCR_HCLK_EMMA_MASK (1 << CCM_PCCR_HCLK_EMMA_OFFSET) -#define CCM_PCCR_HCLK_LCDC_MASK (1 << CCM_PCCR_HCLK_LCDC_OFFSET) -#define CCM_PCCR_HCLK_SLCDC_MASK (1 << CCM_PCCR_HCLK_SLCDC_OFFSET) -#define CCM_PCCR_HCLK_USBOTG_MASK (1 << CCM_PCCR_HCLK_USBOTG_OFFSET) -#define CCM_PCCR_I2C1_MASK (1 << CCM_PCCR_I2C1_OFFSET) -#define CCM_PCCR_KPP_MASK (1 << CCM_PCCR_KPP_OFFSET) -#define CCM_PCCR_LCDC_MASK (1 << CCM_PCCR_LCDC_OFFSET) -#define CCM_PCCR_NFC_MASK (1 << CCM_PCCR_NFC_OFFSET) -#define CCM_PCCR_OWIRE_MASK (1 << CCM_PCCR_OWIRE_OFFSET) -#define CCM_PCCR_PERCLK4_MASK (1 << CCM_PCCR_PERCLK4_OFFSET) -#define CCM_PCCR_PWM_MASK (1 << CCM_PCCR_PWM_OFFSET) -#define CCM_PCCR_RTC_MASK (1 << CCM_PCCR_RTC_OFFSET) -#define CCM_PCCR_SDHC1_MASK (1 << CCM_PCCR_SDHC1_OFFSET) -#define CCM_PCCR_SDHC2_MASK (1 << CCM_PCCR_SDHC2_OFFSET) -#define CCM_PCCR_SLCDC_MASK (1 << CCM_PCCR_SLCDC_OFFSET) -#define CCM_PCCR_SSI1_BAUD_MASK (1 << CCM_PCCR_SSI1_BAUD_OFFSET) -#define CCM_PCCR_SSI1_IPG_MASK (1 << CCM_PCCR_SSI1_IPG_OFFSET) -#define CCM_PCCR_SSI2_BAUD_MASK (1 << CCM_PCCR_SSI2_BAUD_OFFSET) -#define CCM_PCCR_SSI2_IPG_MASK (1 << CCM_PCCR_SSI2_IPG_OFFSET) -#define CCM_PCCR_UART1_MASK (1 << CCM_PCCR_UART1_OFFSET) -#define CCM_PCCR_UART2_MASK (1 << CCM_PCCR_UART2_OFFSET) -#define CCM_PCCR_UART3_MASK (1 << CCM_PCCR_UART3_OFFSET) -#define CCM_PCCR_UART4_MASK (1 << CCM_PCCR_UART4_OFFSET) -#define CCM_PCCR_USBOTG_MASK (1 << CCM_PCCR_USBOTG_OFFSET) -#define CCM_PCCR_WDT_MASK (1 << CCM_PCCR_WDT_OFFSET) - -#define CCM_CCSR_32KSR (1 << 15) - -#define CCM_CCSR_CLKMODE1 (1 << 9) -#define CCM_CCSR_CLKMODE0 (1 << 8) - -#define CCM_CCSR_CLKOSEL_OFFSET 0 -#define CCM_CCSR_CLKOSEL_MASK 0x1f - -#define SYS_FMCR 0x14 /* Functional Muxing Control Reg */ -#define SYS_CHIP_ID 0x00 /* The offset of CHIP ID register */ - -static int _clk_enable(struct clk *clk) -{ - u32 reg; - - reg = __raw_readl(clk->enable_reg); - reg |= 1 << clk->enable_shift; - __raw_writel(reg, clk->enable_reg); - return 0; -} - -static void _clk_disable(struct clk *clk) -{ - u32 reg; - - reg = __raw_readl(clk->enable_reg); - reg &= ~(1 << clk->enable_shift); - __raw_writel(reg, clk->enable_reg); -} - -static unsigned long _clk_generic_round_rate(struct clk *clk, - unsigned long rate, - u32 max_divisor) -{ - u32 div; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - div = parent_rate / rate; - if (parent_rate % rate) - div++; - - if (div > max_divisor) - div = max_divisor; - - return parent_rate / div; -} - -static int _clk_spll_enable(struct clk *clk) -{ - u32 reg; - - reg = __raw_readl(CCM_CSCR); - reg |= CCM_CSCR_SPEN; - __raw_writel(reg, CCM_CSCR); - - while ((__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF) == 0) - ; - return 0; -} - -static void _clk_spll_disable(struct clk *clk) -{ - u32 reg; - - reg = __raw_readl(CCM_CSCR); - reg &= ~CCM_CSCR_SPEN; - __raw_writel(reg, CCM_CSCR); -} - - -#define CSCR() (__raw_readl(CCM_CSCR)) -#define PCDR0() (__raw_readl(CCM_PCDR0)) -#define PCDR1() (__raw_readl(CCM_PCDR1)) - -static unsigned long _clk_perclkx_round_rate(struct clk *clk, - unsigned long rate) -{ - return _clk_generic_round_rate(clk, rate, 64); -} - -static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate) -{ - u32 reg; - u32 div; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - if (clk->id < 0 || clk->id > 3) - return -EINVAL; - - div = parent_rate / rate; - if (div > 64 || div < 1 || ((parent_rate / div) != rate)) - return -EINVAL; - div--; - - reg = - __raw_readl(CCM_PCDR1) & ~(CCM_PCDR1_PERDIV1_MASK << - (clk->id << 3)); - reg |= div << (clk->id << 3); - __raw_writel(reg, CCM_PCDR1); - - return 0; -} - -static unsigned long _clk_usb_recalc(struct clk *clk) -{ - unsigned long usb_pdf; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - usb_pdf = (CSCR() & CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET; - - return parent_rate / (usb_pdf + 1U); -} - -static unsigned long _clk_usb_round_rate(struct clk *clk, - unsigned long rate) -{ - return _clk_generic_round_rate(clk, rate, 8); -} - -static int _clk_usb_set_rate(struct clk *clk, unsigned long rate) -{ - u32 reg; - u32 div; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - div = parent_rate / rate; - if (div > 8 || div < 1 || ((parent_rate / div) != rate)) - return -EINVAL; - div--; - - reg = CSCR() & ~CCM_CSCR_USB_MASK; - reg |= div << CCM_CSCR_USB_OFFSET; - __raw_writel(reg, CCM_CSCR); - - return 0; -} - -static unsigned long _clk_ssix_recalc(struct clk *clk, unsigned long pdf) -{ - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - pdf = (pdf < 2) ? 124UL : pdf; /* MX21 & MX27 TO1 */ - - return 2UL * parent_rate / pdf; -} - -static unsigned long _clk_ssi1_recalc(struct clk *clk) -{ - return _clk_ssix_recalc(clk, - (PCDR0() & CCM_PCDR0_SSI1BAUDDIV_MASK) - >> CCM_PCDR0_SSI1BAUDDIV_OFFSET); -} - -static unsigned long _clk_ssi2_recalc(struct clk *clk) -{ - return _clk_ssix_recalc(clk, - (PCDR0() & CCM_PCDR0_SSI2BAUDDIV_MASK) >> - CCM_PCDR0_SSI2BAUDDIV_OFFSET); -} - -static unsigned long _clk_nfc_recalc(struct clk *clk) -{ - unsigned long nfc_pdf; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - nfc_pdf = (PCDR0() & CCM_PCDR0_NFCDIV_MASK) - >> CCM_PCDR0_NFCDIV_OFFSET; - - return parent_rate / (nfc_pdf + 1); -} - -static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate) -{ - return clk->parent->round_rate(clk->parent, rate); -} - -static int _clk_parent_set_rate(struct clk *clk, unsigned long rate) -{ - return clk->parent->set_rate(clk->parent, rate); -} - -static unsigned long external_high_reference; /* in Hz */ - -static unsigned long get_high_reference_clock_rate(struct clk *clk) -{ - return external_high_reference; -} - -/* - * the high frequency external clock reference - * Default case is 26MHz. - */ -static struct clk ckih_clk = { - .get_rate = get_high_reference_clock_rate, -}; - -static unsigned long external_low_reference; /* in Hz */ - -static unsigned long get_low_reference_clock_rate(struct clk *clk) -{ - return external_low_reference; -} - -/* - * the low frequency external clock reference - * Default case is 32.768kHz. - */ -static struct clk ckil_clk = { - .get_rate = get_low_reference_clock_rate, -}; - - -static unsigned long _clk_fpm_recalc(struct clk *clk) -{ - return clk_get_rate(clk->parent) * 512; -} - -/* Output of frequency pre multiplier */ -static struct clk fpm_clk = { - .parent = &ckil_clk, - .get_rate = _clk_fpm_recalc, -}; - -static unsigned long get_mpll_clk(struct clk *clk) -{ - uint32_t reg; - unsigned long ref_clk; - unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0; - unsigned long long temp; - - ref_clk = clk_get_rate(clk->parent); - - reg = __raw_readl(CCM_MPCTL0); - pdf = (reg & CCM_MPCTL0_PD_MASK) >> CCM_MPCTL0_PD_OFFSET; - mfd = (reg & CCM_MPCTL0_MFD_MASK) >> CCM_MPCTL0_MFD_OFFSET; - mfi = (reg & CCM_MPCTL0_MFI_MASK) >> CCM_MPCTL0_MFI_OFFSET; - mfn = (reg & CCM_MPCTL0_MFN_MASK) >> CCM_MPCTL0_MFN_OFFSET; - - mfi = (mfi <= 5) ? 5 : mfi; - temp = 2LL * ref_clk * mfn; - do_div(temp, mfd + 1); - temp = 2LL * ref_clk * mfi + temp; - do_div(temp, pdf + 1); - - return (unsigned long)temp; -} - -static struct clk mpll_clk = { - .parent = &ckih_clk, - .get_rate = get_mpll_clk, -}; - -static unsigned long _clk_fclk_get_rate(struct clk *clk) -{ - unsigned long parent_rate; - u32 div; - - div = (CSCR() & CCM_CSCR_PRESC_MASK) >> CCM_CSCR_PRESC_OFFSET; - parent_rate = clk_get_rate(clk->parent); - - return parent_rate / (div+1); -} - -static struct clk fclk_clk = { - .parent = &mpll_clk, - .get_rate = _clk_fclk_get_rate -}; - -static unsigned long get_spll_clk(struct clk *clk) -{ - uint32_t reg; - unsigned long ref_clk; - unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0; - unsigned long long temp; - - ref_clk = clk_get_rate(clk->parent); - - reg = __raw_readl(CCM_SPCTL0); - pdf = (reg & CCM_SPCTL0_PD_MASK) >> CCM_SPCTL0_PD_OFFSET; - mfd = (reg & CCM_SPCTL0_MFD_MASK) >> CCM_SPCTL0_MFD_OFFSET; - mfi = (reg & CCM_SPCTL0_MFI_MASK) >> CCM_SPCTL0_MFI_OFFSET; - mfn = (reg & CCM_SPCTL0_MFN_MASK) >> CCM_SPCTL0_MFN_OFFSET; - - mfi = (mfi <= 5) ? 5 : mfi; - temp = 2LL * ref_clk * mfn; - do_div(temp, mfd + 1); - temp = 2LL * ref_clk * mfi + temp; - do_div(temp, pdf + 1); - - return (unsigned long)temp; -} - -static struct clk spll_clk = { - .parent = &ckih_clk, - .get_rate = get_spll_clk, - .enable = _clk_spll_enable, - .disable = _clk_spll_disable, -}; - -static unsigned long get_hclk_clk(struct clk *clk) -{ - unsigned long rate; - unsigned long bclk_pdf; - - bclk_pdf = (CSCR() & CCM_CSCR_BCLK_MASK) - >> CCM_CSCR_BCLK_OFFSET; - - rate = clk_get_rate(clk->parent); - return rate / (bclk_pdf + 1); -} - -static struct clk hclk_clk = { - .parent = &fclk_clk, - .get_rate = get_hclk_clk, -}; - -static unsigned long get_ipg_clk(struct clk *clk) -{ - unsigned long rate; - unsigned long ipg_pdf; - - ipg_pdf = (CSCR() & CCM_CSCR_IPDIV) >> CCM_CSCR_IPDIV_OFFSET; - - rate = clk_get_rate(clk->parent); - return rate / (ipg_pdf + 1); -} - -static struct clk ipg_clk = { - .parent = &hclk_clk, - .get_rate = get_ipg_clk, -}; - -static unsigned long _clk_perclkx_recalc(struct clk *clk) -{ - unsigned long perclk_pdf; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - if (clk->id < 0 || clk->id > 3) - return 0; - - perclk_pdf = (PCDR1() >> (clk->id << 3)) & CCM_PCDR1_PERDIV1_MASK; - - return parent_rate / (perclk_pdf + 1); -} - -static struct clk per_clk[] = { - { - .id = 0, - .parent = &mpll_clk, - .get_rate = _clk_perclkx_recalc, - }, { - .id = 1, - .parent = &mpll_clk, - .get_rate = _clk_perclkx_recalc, - }, { - .id = 2, - .parent = &mpll_clk, - .round_rate = _clk_perclkx_round_rate, - .set_rate = _clk_perclkx_set_rate, - .get_rate = _clk_perclkx_recalc, - /* Enable/Disable done via lcd_clkc[1] */ - }, { - .id = 3, - .parent = &mpll_clk, - .round_rate = _clk_perclkx_round_rate, - .set_rate = _clk_perclkx_set_rate, - .get_rate = _clk_perclkx_recalc, - /* Enable/Disable done via csi_clk[1] */ - }, -}; - -static struct clk uart_ipg_clk[]; - -static struct clk uart_clk[] = { - { - .id = 0, - .parent = &per_clk[0], - .secondary = &uart_ipg_clk[0], - }, { - .id = 1, - .parent = &per_clk[0], - .secondary = &uart_ipg_clk[1], - }, { - .id = 2, - .parent = &per_clk[0], - .secondary = &uart_ipg_clk[2], - }, { - .id = 3, - .parent = &per_clk[0], - .secondary = &uart_ipg_clk[3], - }, -}; - -static struct clk uart_ipg_clk[] = { - { - .id = 0, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_UART1_REG, - .enable_shift = CCM_PCCR_UART1_OFFSET, - .disable = _clk_disable, - }, { - .id = 1, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_UART2_REG, - .enable_shift = CCM_PCCR_UART2_OFFSET, - .disable = _clk_disable, - }, { - .id = 2, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_UART3_REG, - .enable_shift = CCM_PCCR_UART3_OFFSET, - .disable = _clk_disable, - }, { - .id = 3, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_UART4_REG, - .enable_shift = CCM_PCCR_UART4_OFFSET, - .disable = _clk_disable, - }, -}; - -static struct clk gpt_ipg_clk[]; - -static struct clk gpt_clk[] = { - { - .id = 0, - .parent = &per_clk[0], - .secondary = &gpt_ipg_clk[0], - }, { - .id = 1, - .parent = &per_clk[0], - .secondary = &gpt_ipg_clk[1], - }, { - .id = 2, - .parent = &per_clk[0], - .secondary = &gpt_ipg_clk[2], - }, -}; - -static struct clk gpt_ipg_clk[] = { - { - .id = 0, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_GPT1_REG, - .enable_shift = CCM_PCCR_GPT1_OFFSET, - .disable = _clk_disable, - }, { - .id = 1, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_GPT2_REG, - .enable_shift = CCM_PCCR_GPT2_OFFSET, - .disable = _clk_disable, - }, { - .id = 2, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_GPT3_REG, - .enable_shift = CCM_PCCR_GPT3_OFFSET, - .disable = _clk_disable, - }, -}; - -static struct clk pwm_clk[] = { - { - .parent = &per_clk[0], - .secondary = &pwm_clk[1], - }, { - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_PWM_REG, - .enable_shift = CCM_PCCR_PWM_OFFSET, - .disable = _clk_disable, - }, -}; - -static struct clk sdhc_ipg_clk[]; - -static struct clk sdhc_clk[] = { - { - .id = 0, - .parent = &per_clk[1], - .secondary = &sdhc_ipg_clk[0], - }, { - .id = 1, - .parent = &per_clk[1], - .secondary = &sdhc_ipg_clk[1], - }, -}; - -static struct clk sdhc_ipg_clk[] = { - { - .id = 0, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_SDHC1_REG, - .enable_shift = CCM_PCCR_SDHC1_OFFSET, - .disable = _clk_disable, - }, { - .id = 1, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_SDHC2_REG, - .enable_shift = CCM_PCCR_SDHC2_OFFSET, - .disable = _clk_disable, - }, -}; - -static struct clk cspi_ipg_clk[]; - -static struct clk cspi_clk[] = { - { - .id = 0, - .parent = &per_clk[1], - .secondary = &cspi_ipg_clk[0], - }, { - .id = 1, - .parent = &per_clk[1], - .secondary = &cspi_ipg_clk[1], - }, { - .id = 2, - .parent = &per_clk[1], - .secondary = &cspi_ipg_clk[2], - }, -}; - -static struct clk cspi_ipg_clk[] = { - { - .id = 0, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_CSPI1_REG, - .enable_shift = CCM_PCCR_CSPI1_OFFSET, - .disable = _clk_disable, - }, { - .id = 1, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_CSPI2_REG, - .enable_shift = CCM_PCCR_CSPI2_OFFSET, - .disable = _clk_disable, - }, { - .id = 3, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_CSPI3_REG, - .enable_shift = CCM_PCCR_CSPI3_OFFSET, - .disable = _clk_disable, - }, -}; - -static struct clk lcdc_clk[] = { - { - .parent = &per_clk[2], - .secondary = &lcdc_clk[1], - .round_rate = _clk_parent_round_rate, - .set_rate = _clk_parent_set_rate, - }, { - .parent = &ipg_clk, - .secondary = &lcdc_clk[2], - .enable = _clk_enable, - .enable_reg = CCM_PCCR_LCDC_REG, - .enable_shift = CCM_PCCR_LCDC_OFFSET, - .disable = _clk_disable, - }, { - .parent = &hclk_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_HCLK_LCDC_REG, - .enable_shift = CCM_PCCR_HCLK_LCDC_OFFSET, - .disable = _clk_disable, - }, -}; - -static struct clk csi_clk[] = { - { - .parent = &per_clk[3], - .secondary = &csi_clk[1], - .round_rate = _clk_parent_round_rate, - .set_rate = _clk_parent_set_rate, - }, { - .parent = &hclk_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_HCLK_CSI_REG, - .enable_shift = CCM_PCCR_HCLK_CSI_OFFSET, - .disable = _clk_disable, - }, -}; - -static struct clk usb_clk[] = { - { - .parent = &spll_clk, - .secondary = &usb_clk[1], - .get_rate = _clk_usb_recalc, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_USBOTG_REG, - .enable_shift = CCM_PCCR_USBOTG_OFFSET, - .disable = _clk_disable, - .round_rate = _clk_usb_round_rate, - .set_rate = _clk_usb_set_rate, - }, { - .parent = &hclk_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_HCLK_USBOTG_REG, - .enable_shift = CCM_PCCR_HCLK_USBOTG_OFFSET, - .disable = _clk_disable, - } -}; - -static struct clk ssi_ipg_clk[]; - -static struct clk ssi_clk[] = { - { - .id = 0, - .parent = &mpll_clk, - .secondary = &ssi_ipg_clk[0], - .get_rate = _clk_ssi1_recalc, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_SSI1_BAUD_REG, - .enable_shift = CCM_PCCR_SSI1_BAUD_OFFSET, - .disable = _clk_disable, - }, { - .id = 1, - .parent = &mpll_clk, - .secondary = &ssi_ipg_clk[1], - .get_rate = _clk_ssi2_recalc, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_SSI2_BAUD_REG, - .enable_shift = CCM_PCCR_SSI2_BAUD_OFFSET, - .disable = _clk_disable, - }, -}; - -static struct clk ssi_ipg_clk[] = { - { - .id = 0, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_SSI1_REG, - .enable_shift = CCM_PCCR_SSI1_IPG_OFFSET, - .disable = _clk_disable, - }, { - .id = 1, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_SSI2_REG, - .enable_shift = CCM_PCCR_SSI2_IPG_OFFSET, - .disable = _clk_disable, - }, -}; - - -static struct clk nfc_clk = { - .parent = &fclk_clk, - .get_rate = _clk_nfc_recalc, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_NFC_REG, - .enable_shift = CCM_PCCR_NFC_OFFSET, - .disable = _clk_disable, -}; - -static struct clk dma_clk[] = { - { - .parent = &hclk_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_DMA_REG, - .enable_shift = CCM_PCCR_DMA_OFFSET, - .disable = _clk_disable, - .secondary = &dma_clk[1], - }, { - .enable = _clk_enable, - .enable_reg = CCM_PCCR_HCLK_DMA_REG, - .enable_shift = CCM_PCCR_HCLK_DMA_OFFSET, - .disable = _clk_disable, - }, -}; - -static struct clk brom_clk = { - .parent = &hclk_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_HCLK_BROM_REG, - .enable_shift = CCM_PCCR_HCLK_BROM_OFFSET, - .disable = _clk_disable, -}; - -static struct clk emma_clk[] = { - { - .parent = &hclk_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_EMMA_REG, - .enable_shift = CCM_PCCR_EMMA_OFFSET, - .disable = _clk_disable, - .secondary = &emma_clk[1], - }, { - .enable = _clk_enable, - .enable_reg = CCM_PCCR_HCLK_EMMA_REG, - .enable_shift = CCM_PCCR_HCLK_EMMA_OFFSET, - .disable = _clk_disable, - } -}; - -static struct clk slcdc_clk[] = { - { - .parent = &hclk_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_SLCDC_REG, - .enable_shift = CCM_PCCR_SLCDC_OFFSET, - .disable = _clk_disable, - .secondary = &slcdc_clk[1], - }, { - .enable = _clk_enable, - .enable_reg = CCM_PCCR_HCLK_SLCDC_REG, - .enable_shift = CCM_PCCR_HCLK_SLCDC_OFFSET, - .disable = _clk_disable, - } -}; - -static struct clk wdog_clk = { - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_WDT_REG, - .enable_shift = CCM_PCCR_WDT_OFFSET, - .disable = _clk_disable, -}; - -static struct clk gpio_clk = { - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_GPIO_REG, - .enable_shift = CCM_PCCR_GPIO_OFFSET, - .disable = _clk_disable, -}; - -static struct clk i2c_clk = { - .id = 0, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_I2C1_REG, - .enable_shift = CCM_PCCR_I2C1_OFFSET, - .disable = _clk_disable, -}; - -static struct clk kpp_clk = { - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_KPP_REG, - .enable_shift = CCM_PCCR_KPP_OFFSET, - .disable = _clk_disable, -}; - -static struct clk owire_clk = { - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_OWIRE_REG, - .enable_shift = CCM_PCCR_OWIRE_OFFSET, - .disable = _clk_disable, -}; - -static struct clk rtc_clk = { - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR_RTC_REG, - .enable_shift = CCM_PCCR_RTC_OFFSET, - .disable = _clk_disable, -}; - -static unsigned long _clk_clko_round_rate(struct clk *clk, unsigned long rate) -{ - return _clk_generic_round_rate(clk, rate, 8); -} - -static int _clk_clko_set_rate(struct clk *clk, unsigned long rate) -{ - u32 reg; - u32 div; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - div = parent_rate / rate; - - if (div > 8 || div < 1 || ((parent_rate / div) != rate)) - return -EINVAL; - div--; - - reg = __raw_readl(CCM_PCDR0); - - if (clk->parent == &usb_clk[0]) { - reg &= ~CCM_PCDR0_48MDIV_MASK; - reg |= div << CCM_PCDR0_48MDIV_OFFSET; - } - __raw_writel(reg, CCM_PCDR0); - - return 0; -} - -static unsigned long _clk_clko_recalc(struct clk *clk) -{ - u32 div = 0; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - if (clk->parent == &usb_clk[0]) /* 48M */ - div = __raw_readl(CCM_PCDR0) & CCM_PCDR0_48MDIV_MASK - >> CCM_PCDR0_48MDIV_OFFSET; - div++; - - return parent_rate / div; -} - -static struct clk clko_clk; - -static int _clk_clko_set_parent(struct clk *clk, struct clk *parent) -{ - u32 reg; - - reg = __raw_readl(CCM_CCSR) & ~CCM_CCSR_CLKOSEL_MASK; - - if (parent == &ckil_clk) - reg |= 0 << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &fpm_clk) - reg |= 1 << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &ckih_clk) - reg |= 2 << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == mpll_clk.parent) - reg |= 3 << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == spll_clk.parent) - reg |= 4 << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &mpll_clk) - reg |= 5 << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &spll_clk) - reg |= 6 << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &fclk_clk) - reg |= 7 << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &hclk_clk) - reg |= 8 << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &ipg_clk) - reg |= 9 << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &per_clk[0]) - reg |= 0xA << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &per_clk[1]) - reg |= 0xB << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &per_clk[2]) - reg |= 0xC << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &per_clk[3]) - reg |= 0xD << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &ssi_clk[0]) - reg |= 0xE << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &ssi_clk[1]) - reg |= 0xF << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &nfc_clk) - reg |= 0x10 << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &usb_clk[0]) - reg |= 0x14 << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &clko_clk) - reg |= 0x15 << CCM_CCSR_CLKOSEL_OFFSET; - else - return -EINVAL; - - __raw_writel(reg, CCM_CCSR); - - return 0; -} - -static struct clk clko_clk = { - .get_rate = _clk_clko_recalc, - .set_rate = _clk_clko_set_rate, - .round_rate = _clk_clko_round_rate, - .set_parent = _clk_clko_set_parent, -}; - - -#define _REGISTER_CLOCK(d, n, c) \ - { \ - .dev_id = d, \ - .con_id = n, \ - .clk = &c, \ - }, -static struct clk_lookup lookups[] = { -/* It's unlikely that any driver wants one of them directly: - _REGISTER_CLOCK(NULL, "ckih", ckih_clk) - _REGISTER_CLOCK(NULL, "ckil", ckil_clk) - _REGISTER_CLOCK(NULL, "fpm", fpm_clk) - _REGISTER_CLOCK(NULL, "mpll", mpll_clk) - _REGISTER_CLOCK(NULL, "spll", spll_clk) - _REGISTER_CLOCK(NULL, "fclk", fclk_clk) - _REGISTER_CLOCK(NULL, "hclk", hclk_clk) - _REGISTER_CLOCK(NULL, "ipg", ipg_clk) -*/ - _REGISTER_CLOCK(NULL, "perclk1", per_clk[0]) - _REGISTER_CLOCK(NULL, "perclk2", per_clk[1]) - _REGISTER_CLOCK(NULL, "perclk3", per_clk[2]) - _REGISTER_CLOCK(NULL, "perclk4", per_clk[3]) - _REGISTER_CLOCK(NULL, "clko", clko_clk) - _REGISTER_CLOCK("imx21-uart.0", NULL, uart_clk[0]) - _REGISTER_CLOCK("imx21-uart.1", NULL, uart_clk[1]) - _REGISTER_CLOCK("imx21-uart.2", NULL, uart_clk[2]) - _REGISTER_CLOCK("imx21-uart.3", NULL, uart_clk[3]) - _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[0]) - _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[1]) - _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[2]) - _REGISTER_CLOCK(NULL, "pwm", pwm_clk[0]) - _REGISTER_CLOCK(NULL, "sdhc1", sdhc_clk[0]) - _REGISTER_CLOCK(NULL, "sdhc2", sdhc_clk[1]) - _REGISTER_CLOCK("imx21-cspi.0", NULL, cspi_clk[0]) - _REGISTER_CLOCK("imx21-cspi.1", NULL, cspi_clk[1]) - _REGISTER_CLOCK("imx21-cspi.2", NULL, cspi_clk[2]) - _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk[0]) - _REGISTER_CLOCK(NULL, "csi", csi_clk[0]) - _REGISTER_CLOCK("imx21-hcd.0", NULL, usb_clk[0]) - _REGISTER_CLOCK(NULL, "ssi1", ssi_clk[0]) - _REGISTER_CLOCK(NULL, "ssi2", ssi_clk[1]) - _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk) - _REGISTER_CLOCK(NULL, "dma", dma_clk[0]) - _REGISTER_CLOCK(NULL, "brom", brom_clk) - _REGISTER_CLOCK(NULL, "emma", emma_clk[0]) - _REGISTER_CLOCK(NULL, "slcdc", slcdc_clk[0]) - _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk) - _REGISTER_CLOCK(NULL, "gpio", gpio_clk) - _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk) - _REGISTER_CLOCK("mxc-keypad", NULL, kpp_clk) - _REGISTER_CLOCK(NULL, "owire", owire_clk) - _REGISTER_CLOCK(NULL, "rtc", rtc_clk) -}; - -/* - * must be called very early to get information about the - * available clock rate when the timer framework starts - */ -int __init mx21_clocks_init(unsigned long lref, unsigned long href) -{ - u32 cscr; - - external_low_reference = lref; - external_high_reference = href; - - /* detect clock reference for both system PLL */ - cscr = CSCR(); - if (cscr & CCM_CSCR_MCU) - mpll_clk.parent = &ckih_clk; - else - mpll_clk.parent = &fpm_clk; - - if (cscr & CCM_CSCR_SP) - spll_clk.parent = &ckih_clk; - else - spll_clk.parent = &fpm_clk; - - clkdev_add_table(lookups, ARRAY_SIZE(lookups)); - - /* Turn off all clock gates */ - __raw_writel(0, CCM_PCCR0); - __raw_writel(CCM_PCCR_GPT1_MASK, CCM_PCCR1); - - /* This turns of the serial PLL as well */ - spll_clk.disable(&spll_clk); - - /* This will propagate to all children and init all the clock rates. */ - clk_enable(&per_clk[0]); - clk_enable(&gpio_clk); - -#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC) - clk_enable(&uart_clk[0]); -#endif - - mxc_timer_init(&gpt_clk[0], MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR), - MX21_INT_GPT1); - return 0; -} diff --git a/trunk/arch/arm/mach-imx/clock-imx25.c b/trunk/arch/arm/mach-imx/clock-imx25.c deleted file mode 100644 index b0fec74c8c91..000000000000 --- a/trunk/arch/arm/mach-imx/clock-imx25.c +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Copyright (C) 2009 by Sascha Hauer, Pengutronix - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#define CRM_BASE MX25_IO_ADDRESS(MX25_CRM_BASE_ADDR) - -#define CCM_MPCTL 0x00 -#define CCM_UPCTL 0x04 -#define CCM_CCTL 0x08 -#define CCM_CGCR0 0x0C -#define CCM_CGCR1 0x10 -#define CCM_CGCR2 0x14 -#define CCM_PCDR0 0x18 -#define CCM_PCDR1 0x1C -#define CCM_PCDR2 0x20 -#define CCM_PCDR3 0x24 -#define CCM_RCSR 0x28 -#define CCM_CRDR 0x2C -#define CCM_DCVR0 0x30 -#define CCM_DCVR1 0x34 -#define CCM_DCVR2 0x38 -#define CCM_DCVR3 0x3c -#define CCM_LTR0 0x40 -#define CCM_LTR1 0x44 -#define CCM_LTR2 0x48 -#define CCM_LTR3 0x4c - -static unsigned long get_rate_mpll(void) -{ - ulong mpctl = __raw_readl(CRM_BASE + CCM_MPCTL); - - return mxc_decode_pll(mpctl, 24000000); -} - -static unsigned long get_rate_upll(void) -{ - ulong mpctl = __raw_readl(CRM_BASE + CCM_UPCTL); - - return mxc_decode_pll(mpctl, 24000000); -} - -unsigned long get_rate_arm(struct clk *clk) -{ - unsigned long cctl = readl(CRM_BASE + CCM_CCTL); - unsigned long rate = get_rate_mpll(); - - if (cctl & (1 << 14)) - rate = (rate * 3) >> 2; - - return rate / ((cctl >> 30) + 1); -} - -static unsigned long get_rate_ahb(struct clk *clk) -{ - unsigned long cctl = readl(CRM_BASE + CCM_CCTL); - - return get_rate_arm(NULL) / (((cctl >> 28) & 0x3) + 1); -} - -static unsigned long get_rate_ipg(struct clk *clk) -{ - return get_rate_ahb(NULL) >> 1; -} - -static unsigned long get_rate_per(int per) -{ - unsigned long ofs = (per & 0x3) * 8; - unsigned long reg = per & ~0x3; - unsigned long val = (readl(CRM_BASE + CCM_PCDR0 + reg) >> ofs) & 0x3f; - unsigned long fref; - - if (readl(CRM_BASE + 0x64) & (1 << per)) - fref = get_rate_upll(); - else - fref = get_rate_ahb(NULL); - - return fref / (val + 1); -} - -static unsigned long get_rate_uart(struct clk *clk) -{ - return get_rate_per(15); -} - -static unsigned long get_rate_ssi2(struct clk *clk) -{ - return get_rate_per(14); -} - -static unsigned long get_rate_ssi1(struct clk *clk) -{ - return get_rate_per(13); -} - -static unsigned long get_rate_i2c(struct clk *clk) -{ - return get_rate_per(6); -} - -static unsigned long get_rate_nfc(struct clk *clk) -{ - return get_rate_per(8); -} - -static unsigned long get_rate_gpt(struct clk *clk) -{ - return get_rate_per(5); -} - -static unsigned long get_rate_lcdc(struct clk *clk) -{ - return get_rate_per(7); -} - -static unsigned long get_rate_esdhc1(struct clk *clk) -{ - return get_rate_per(3); -} - -static unsigned long get_rate_esdhc2(struct clk *clk) -{ - return get_rate_per(4); -} - -static unsigned long get_rate_csi(struct clk *clk) -{ - return get_rate_per(0); -} - -static unsigned long get_rate_otg(struct clk *clk) -{ - unsigned long cctl = readl(CRM_BASE + CCM_CCTL); - unsigned long rate = get_rate_upll(); - - return (cctl & (1 << 23)) ? 0 : rate / ((0x3F & (cctl >> 16)) + 1); -} - -static int clk_cgcr_enable(struct clk *clk) -{ - u32 reg; - - reg = __raw_readl(clk->enable_reg); - reg |= 1 << clk->enable_shift; - __raw_writel(reg, clk->enable_reg); - - return 0; -} - -static void clk_cgcr_disable(struct clk *clk) -{ - u32 reg; - - reg = __raw_readl(clk->enable_reg); - reg &= ~(1 << clk->enable_shift); - __raw_writel(reg, clk->enable_reg); -} - -#define DEFINE_CLOCK(name, i, er, es, gr, sr, s) \ - static struct clk name = { \ - .id = i, \ - .enable_reg = CRM_BASE + er, \ - .enable_shift = es, \ - .get_rate = gr, \ - .set_rate = sr, \ - .enable = clk_cgcr_enable, \ - .disable = clk_cgcr_disable, \ - .secondary = s, \ - } - -/* - * Note: the following IPG clock gating bits are wrongly marked "Reserved" in - * the i.MX25 Reference Manual Rev 1, table 15-13. The information below is - * taken from the Freescale released BSP. - * - * bit reg offset clock - * - * 0 CGCR1 0 AUDMUX - * 12 CGCR1 12 ESAI - * 16 CGCR1 16 GPIO1 - * 17 CGCR1 17 GPIO2 - * 18 CGCR1 18 GPIO3 - * 23 CGCR1 23 I2C1 - * 24 CGCR1 24 I2C2 - * 25 CGCR1 25 I2C3 - * 27 CGCR1 27 IOMUXC - * 28 CGCR1 28 KPP - * 30 CGCR1 30 OWIRE - * 36 CGCR2 4 RTIC - * 51 CGCR2 19 WDOG - */ - -DEFINE_CLOCK(gpt_clk, 0, CCM_CGCR0, 5, get_rate_gpt, NULL, NULL); -DEFINE_CLOCK(uart_per_clk, 0, CCM_CGCR0, 15, get_rate_uart, NULL, NULL); -DEFINE_CLOCK(ssi1_per_clk, 0, CCM_CGCR0, 13, get_rate_ipg, NULL, NULL); -DEFINE_CLOCK(ssi2_per_clk, 0, CCM_CGCR0, 14, get_rate_ipg, NULL, NULL); -DEFINE_CLOCK(cspi1_clk, 0, CCM_CGCR1, 5, get_rate_ipg, NULL, NULL); -DEFINE_CLOCK(cspi2_clk, 0, CCM_CGCR1, 6, get_rate_ipg, NULL, NULL); -DEFINE_CLOCK(cspi3_clk, 0, CCM_CGCR1, 7, get_rate_ipg, NULL, NULL); -DEFINE_CLOCK(esdhc1_ahb_clk, 0, CCM_CGCR0, 21, get_rate_esdhc1, NULL, NULL); -DEFINE_CLOCK(esdhc1_per_clk, 0, CCM_CGCR0, 3, get_rate_esdhc1, NULL, - &esdhc1_ahb_clk); -DEFINE_CLOCK(esdhc2_ahb_clk, 0, CCM_CGCR0, 22, get_rate_esdhc2, NULL, NULL); -DEFINE_CLOCK(esdhc2_per_clk, 0, CCM_CGCR0, 4, get_rate_esdhc2, NULL, - &esdhc2_ahb_clk); -DEFINE_CLOCK(sdma_ahb_clk, 0, CCM_CGCR0, 26, NULL, NULL, NULL); -DEFINE_CLOCK(fec_ahb_clk, 0, CCM_CGCR0, 23, NULL, NULL, NULL); -DEFINE_CLOCK(lcdc_ahb_clk, 0, CCM_CGCR0, 24, NULL, NULL, NULL); -DEFINE_CLOCK(lcdc_per_clk, 0, CCM_CGCR0, 7, NULL, NULL, &lcdc_ahb_clk); -DEFINE_CLOCK(csi_ahb_clk, 0, CCM_CGCR0, 18, get_rate_csi, NULL, NULL); -DEFINE_CLOCK(csi_per_clk, 0, CCM_CGCR0, 0, get_rate_csi, NULL, &csi_ahb_clk); -DEFINE_CLOCK(uart1_clk, 0, CCM_CGCR2, 14, get_rate_uart, NULL, &uart_per_clk); -DEFINE_CLOCK(uart2_clk, 0, CCM_CGCR2, 15, get_rate_uart, NULL, &uart_per_clk); -DEFINE_CLOCK(uart3_clk, 0, CCM_CGCR2, 16, get_rate_uart, NULL, &uart_per_clk); -DEFINE_CLOCK(uart4_clk, 0, CCM_CGCR2, 17, get_rate_uart, NULL, &uart_per_clk); -DEFINE_CLOCK(uart5_clk, 0, CCM_CGCR2, 18, get_rate_uart, NULL, &uart_per_clk); -DEFINE_CLOCK(nfc_clk, 0, CCM_CGCR0, 8, get_rate_nfc, NULL, NULL); -DEFINE_CLOCK(usbotg_clk, 0, CCM_CGCR0, 28, get_rate_otg, NULL, NULL); -DEFINE_CLOCK(pwm1_clk, 0, CCM_CGCR1, 31, get_rate_ipg, NULL, NULL); -DEFINE_CLOCK(pwm2_clk, 0, CCM_CGCR2, 0, get_rate_ipg, NULL, NULL); -DEFINE_CLOCK(pwm3_clk, 0, CCM_CGCR2, 1, get_rate_ipg, NULL, NULL); -DEFINE_CLOCK(pwm4_clk, 0, CCM_CGCR2, 2, get_rate_ipg, NULL, NULL); -DEFINE_CLOCK(kpp_clk, 0, CCM_CGCR1, 28, get_rate_ipg, NULL, NULL); -DEFINE_CLOCK(tsc_clk, 0, CCM_CGCR2, 13, get_rate_ipg, NULL, NULL); -DEFINE_CLOCK(i2c_clk, 0, CCM_CGCR0, 6, get_rate_i2c, NULL, NULL); -DEFINE_CLOCK(fec_clk, 0, CCM_CGCR1, 15, get_rate_ipg, NULL, &fec_ahb_clk); -DEFINE_CLOCK(dryice_clk, 0, CCM_CGCR1, 8, get_rate_ipg, NULL, NULL); -DEFINE_CLOCK(lcdc_clk, 0, CCM_CGCR1, 29, get_rate_lcdc, NULL, &lcdc_per_clk); -DEFINE_CLOCK(wdt_clk, 0, CCM_CGCR2, 19, get_rate_ipg, NULL, NULL); -DEFINE_CLOCK(ssi1_clk, 0, CCM_CGCR2, 11, get_rate_ssi1, NULL, &ssi1_per_clk); -DEFINE_CLOCK(ssi2_clk, 1, CCM_CGCR2, 12, get_rate_ssi2, NULL, &ssi2_per_clk); -DEFINE_CLOCK(sdma_clk, 0, CCM_CGCR2, 6, get_rate_ipg, NULL, &sdma_ahb_clk); -DEFINE_CLOCK(esdhc1_clk, 0, CCM_CGCR1, 13, get_rate_esdhc1, NULL, - &esdhc1_per_clk); -DEFINE_CLOCK(esdhc2_clk, 1, CCM_CGCR1, 14, get_rate_esdhc2, NULL, - &esdhc2_per_clk); -DEFINE_CLOCK(audmux_clk, 0, CCM_CGCR1, 0, NULL, NULL, NULL); -DEFINE_CLOCK(csi_clk, 0, CCM_CGCR1, 4, get_rate_csi, NULL, &csi_per_clk); -DEFINE_CLOCK(can1_clk, 0, CCM_CGCR1, 2, get_rate_ipg, NULL, NULL); -DEFINE_CLOCK(can2_clk, 1, CCM_CGCR1, 3, get_rate_ipg, NULL, NULL); -DEFINE_CLOCK(iim_clk, 0, CCM_CGCR1, 26, NULL, NULL, NULL); - -#define _REGISTER_CLOCK(d, n, c) \ - { \ - .dev_id = d, \ - .con_id = n, \ - .clk = &c, \ - }, - -static struct clk_lookup lookups[] = { - /* i.mx25 has the i.mx21 type uart */ - _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk) - _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk) - _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk) - _REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk) - _REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk) - _REGISTER_CLOCK("mxc-ehci.0", "usb", usbotg_clk) - _REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk) - _REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk) - _REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk) - _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk) - /* i.mx25 has the i.mx35 type cspi */ - _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi1_clk) - _REGISTER_CLOCK("imx35-cspi.1", NULL, cspi2_clk) - _REGISTER_CLOCK("imx35-cspi.2", NULL, cspi3_clk) - _REGISTER_CLOCK("mxc_pwm.0", NULL, pwm1_clk) - _REGISTER_CLOCK("mxc_pwm.1", NULL, pwm2_clk) - _REGISTER_CLOCK("mxc_pwm.2", NULL, pwm3_clk) - _REGISTER_CLOCK("mxc_pwm.3", NULL, pwm4_clk) - _REGISTER_CLOCK("imx-keypad", NULL, kpp_clk) - _REGISTER_CLOCK("mx25-adc", NULL, tsc_clk) - _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk) - _REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk) - _REGISTER_CLOCK("imx-i2c.2", NULL, i2c_clk) - _REGISTER_CLOCK("imx25-fec.0", NULL, fec_clk) - _REGISTER_CLOCK("imxdi_rtc.0", NULL, dryice_clk) - _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk) - _REGISTER_CLOCK("imx2-wdt.0", NULL, wdt_clk) - _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) - _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) - _REGISTER_CLOCK("sdhci-esdhc-imx25.0", NULL, esdhc1_clk) - _REGISTER_CLOCK("sdhci-esdhc-imx25.1", NULL, esdhc2_clk) - _REGISTER_CLOCK("mx2-camera.0", NULL, csi_clk) - _REGISTER_CLOCK(NULL, "audmux", audmux_clk) - _REGISTER_CLOCK("flexcan.0", NULL, can1_clk) - _REGISTER_CLOCK("flexcan.1", NULL, can2_clk) - /* i.mx25 has the i.mx35 type sdma */ - _REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk) - _REGISTER_CLOCK(NULL, "iim", iim_clk) -}; - -int __init mx25_clocks_init(void) -{ - clkdev_add_table(lookups, ARRAY_SIZE(lookups)); - - /* Turn off all clocks except the ones we need to survive, namely: - * EMI, GPIO1-3 (CCM_CGCR1[18:16]), GPT1, IOMUXC (CCM_CGCR1[27]), IIM, - * SCC - */ - __raw_writel((1 << 19), CRM_BASE + CCM_CGCR0); - __raw_writel((0xf << 16) | (3 << 26), CRM_BASE + CCM_CGCR1); - __raw_writel((1 << 5), CRM_BASE + CCM_CGCR2); -#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC) - clk_enable(&uart1_clk); -#endif - - /* Clock source for lcdc and csi is upll */ - __raw_writel(__raw_readl(CRM_BASE+0x64) | (1 << 7) | (1 << 0), - CRM_BASE + 0x64); - - /* Clock source for gpt is ahb_div */ - __raw_writel(__raw_readl(CRM_BASE+0x64) & ~(1 << 5), CRM_BASE + 0x64); - - clk_enable(&iim_clk); - imx_print_silicon_rev("i.MX25", mx25_revision()); - clk_disable(&iim_clk); - - mxc_timer_init(&gpt_clk, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54); - - return 0; -} diff --git a/trunk/arch/arm/mach-imx/clock-imx27.c b/trunk/arch/arm/mach-imx/clock-imx27.c deleted file mode 100644 index 98e04f5a87dd..000000000000 --- a/trunk/arch/arm/mach-imx/clock-imx27.c +++ /dev/null @@ -1,785 +0,0 @@ -/* - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. - * Copyright 2008 Juergen Beisert, kernel@pengutronix.de - * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#define IO_ADDR_CCM(off) (MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR + (off))) - -/* Register offsets */ -#define CCM_CSCR IO_ADDR_CCM(0x0) -#define CCM_MPCTL0 IO_ADDR_CCM(0x4) -#define CCM_MPCTL1 IO_ADDR_CCM(0x8) -#define CCM_SPCTL0 IO_ADDR_CCM(0xc) -#define CCM_SPCTL1 IO_ADDR_CCM(0x10) -#define CCM_OSC26MCTL IO_ADDR_CCM(0x14) -#define CCM_PCDR0 IO_ADDR_CCM(0x18) -#define CCM_PCDR1 IO_ADDR_CCM(0x1c) -#define CCM_PCCR0 IO_ADDR_CCM(0x20) -#define CCM_PCCR1 IO_ADDR_CCM(0x24) -#define CCM_CCSR IO_ADDR_CCM(0x28) -#define CCM_PMCTL IO_ADDR_CCM(0x2c) -#define CCM_PMCOUNT IO_ADDR_CCM(0x30) -#define CCM_WKGDCTL IO_ADDR_CCM(0x34) - -#define CCM_CSCR_UPDATE_DIS (1 << 31) -#define CCM_CSCR_SSI2 (1 << 23) -#define CCM_CSCR_SSI1 (1 << 22) -#define CCM_CSCR_VPU (1 << 21) -#define CCM_CSCR_MSHC (1 << 20) -#define CCM_CSCR_SPLLRES (1 << 19) -#define CCM_CSCR_MPLLRES (1 << 18) -#define CCM_CSCR_SP (1 << 17) -#define CCM_CSCR_MCU (1 << 16) -#define CCM_CSCR_OSC26MDIV (1 << 4) -#define CCM_CSCR_OSC26M (1 << 3) -#define CCM_CSCR_FPM (1 << 2) -#define CCM_CSCR_SPEN (1 << 1) -#define CCM_CSCR_MPEN (1 << 0) - -/* i.MX27 TO 2+ */ -#define CCM_CSCR_ARM_SRC (1 << 15) - -#define CCM_SPCTL1_LF (1 << 15) -#define CCM_SPCTL1_BRMO (1 << 6) - -static struct clk mpll_main1_clk, mpll_main2_clk; - -static int clk_pccr_enable(struct clk *clk) -{ - unsigned long reg; - - if (!clk->enable_reg) - return 0; - - reg = __raw_readl(clk->enable_reg); - reg |= 1 << clk->enable_shift; - __raw_writel(reg, clk->enable_reg); - - return 0; -} - -static void clk_pccr_disable(struct clk *clk) -{ - unsigned long reg; - - if (!clk->enable_reg) - return; - - reg = __raw_readl(clk->enable_reg); - reg &= ~(1 << clk->enable_shift); - __raw_writel(reg, clk->enable_reg); -} - -static int clk_spll_enable(struct clk *clk) -{ - unsigned long reg; - - reg = __raw_readl(CCM_CSCR); - reg |= CCM_CSCR_SPEN; - __raw_writel(reg, CCM_CSCR); - - while (!(__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF)); - - return 0; -} - -static void clk_spll_disable(struct clk *clk) -{ - unsigned long reg; - - reg = __raw_readl(CCM_CSCR); - reg &= ~CCM_CSCR_SPEN; - __raw_writel(reg, CCM_CSCR); -} - -static int clk_cpu_set_parent(struct clk *clk, struct clk *parent) -{ - int cscr = __raw_readl(CCM_CSCR); - - if (clk->parent == parent) - return 0; - - if (mx27_revision() >= IMX_CHIP_REVISION_2_0) { - if (parent == &mpll_main1_clk) { - cscr |= CCM_CSCR_ARM_SRC; - } else { - if (parent == &mpll_main2_clk) - cscr &= ~CCM_CSCR_ARM_SRC; - else - return -EINVAL; - } - __raw_writel(cscr, CCM_CSCR); - clk->parent = parent; - return 0; - } - return -ENODEV; -} - -static unsigned long round_rate_cpu(struct clk *clk, unsigned long rate) -{ - int div; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - div = parent_rate / rate; - if (parent_rate % rate) - div++; - - if (div > 4) - div = 4; - - return parent_rate / div; -} - -static int set_rate_cpu(struct clk *clk, unsigned long rate) -{ - unsigned int div; - uint32_t reg; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - div = parent_rate / rate; - - if (div > 4 || div < 1 || ((parent_rate / div) != rate)) - return -EINVAL; - - div--; - - reg = __raw_readl(CCM_CSCR); - if (mx27_revision() >= IMX_CHIP_REVISION_2_0) { - reg &= ~(3 << 12); - reg |= div << 12; - reg &= ~(CCM_CSCR_FPM | CCM_CSCR_SPEN); - __raw_writel(reg | CCM_CSCR_UPDATE_DIS, CCM_CSCR); - } else { - printk(KERN_ERR "Can't set CPU frequency!\n"); - } - - return 0; -} - -static unsigned long round_rate_per(struct clk *clk, unsigned long rate) -{ - u32 div; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - div = parent_rate / rate; - if (parent_rate % rate) - div++; - - if (div > 64) - div = 64; - - return parent_rate / div; -} - -static int set_rate_per(struct clk *clk, unsigned long rate) -{ - u32 reg; - u32 div; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - if (clk->id < 0 || clk->id > 3) - return -EINVAL; - - div = parent_rate / rate; - if (div > 64 || div < 1 || ((parent_rate / div) != rate)) - return -EINVAL; - div--; - - reg = __raw_readl(CCM_PCDR1) & ~(0x3f << (clk->id << 3)); - reg |= div << (clk->id << 3); - __raw_writel(reg, CCM_PCDR1); - - return 0; -} - -static unsigned long get_rate_usb(struct clk *clk) -{ - unsigned long usb_pdf; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - usb_pdf = (__raw_readl(CCM_CSCR) >> 28) & 0x7; - - return parent_rate / (usb_pdf + 1U); -} - -static unsigned long get_rate_ssix(struct clk *clk, unsigned long pdf) -{ - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - if (mx27_revision() >= IMX_CHIP_REVISION_2_0) - pdf += 4; /* MX27 TO2+ */ - else - pdf = (pdf < 2) ? 124UL : pdf; /* MX21 & MX27 TO1 */ - - return 2UL * parent_rate / pdf; -} - -static unsigned long get_rate_ssi1(struct clk *clk) -{ - return get_rate_ssix(clk, (__raw_readl(CCM_PCDR0) >> 16) & 0x3f); -} - -static unsigned long get_rate_ssi2(struct clk *clk) -{ - return get_rate_ssix(clk, (__raw_readl(CCM_PCDR0) >> 26) & 0x3f); -} - -static unsigned long get_rate_nfc(struct clk *clk) -{ - unsigned long nfc_pdf; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - if (mx27_revision() >= IMX_CHIP_REVISION_2_0) - nfc_pdf = (__raw_readl(CCM_PCDR0) >> 6) & 0xf; - else - nfc_pdf = (__raw_readl(CCM_PCDR0) >> 12) & 0xf; - - return parent_rate / (nfc_pdf + 1); -} - -static unsigned long get_rate_vpu(struct clk *clk) -{ - unsigned long vpu_pdf; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - if (mx27_revision() >= IMX_CHIP_REVISION_2_0) { - vpu_pdf = (__raw_readl(CCM_PCDR0) >> 10) & 0x3f; - vpu_pdf += 4; - } else { - vpu_pdf = (__raw_readl(CCM_PCDR0) >> 8) & 0xf; - vpu_pdf = (vpu_pdf < 2) ? 124 : vpu_pdf; - } - - return 2UL * parent_rate / vpu_pdf; -} - -static unsigned long round_rate_parent(struct clk *clk, unsigned long rate) -{ - return clk->parent->round_rate(clk->parent, rate); -} - -static unsigned long get_rate_parent(struct clk *clk) -{ - return clk_get_rate(clk->parent); -} - -static int set_rate_parent(struct clk *clk, unsigned long rate) -{ - return clk->parent->set_rate(clk->parent, rate); -} - -/* in Hz */ -static unsigned long external_high_reference = 26000000; - -static unsigned long get_rate_high_reference(struct clk *clk) -{ - return external_high_reference; -} - -/* in Hz */ -static unsigned long external_low_reference = 32768; - -static unsigned long get_rate_low_reference(struct clk *clk) -{ - return external_low_reference; -} - -static unsigned long get_rate_fpm(struct clk *clk) -{ - return clk_get_rate(clk->parent) * 1024; -} - -static unsigned long get_rate_mpll(struct clk *clk) -{ - return mxc_decode_pll(__raw_readl(CCM_MPCTL0), - clk_get_rate(clk->parent)); -} - -static unsigned long get_rate_mpll_main(struct clk *clk) -{ - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - /* i.MX27 TO2: - * clk->id == 0: arm clock source path 1 which is from 2 * MPLL / 2 - * clk->id == 1: arm clock source path 2 which is from 2 * MPLL / 3 - */ - if (mx27_revision() >= IMX_CHIP_REVISION_2_0 && clk->id == 1) - return 2UL * parent_rate / 3UL; - - return parent_rate; -} - -static unsigned long get_rate_spll(struct clk *clk) -{ - uint32_t reg; - unsigned long rate; - - rate = clk_get_rate(clk->parent); - - reg = __raw_readl(CCM_SPCTL0); - - /* On TO2 we have to write the value back. Otherwise we - * read 0 from this register the next time. - */ - if (mx27_revision() >= IMX_CHIP_REVISION_2_0) - __raw_writel(reg, CCM_SPCTL0); - - return mxc_decode_pll(reg, rate); -} - -static unsigned long get_rate_cpu(struct clk *clk) -{ - u32 div; - unsigned long rate; - - if (mx27_revision() >= IMX_CHIP_REVISION_2_0) - div = (__raw_readl(CCM_CSCR) >> 12) & 0x3; - else - div = (__raw_readl(CCM_CSCR) >> 13) & 0x7; - - rate = clk_get_rate(clk->parent); - return rate / (div + 1); -} - -static unsigned long get_rate_ahb(struct clk *clk) -{ - unsigned long rate, bclk_pdf; - - if (mx27_revision() >= IMX_CHIP_REVISION_2_0) - bclk_pdf = (__raw_readl(CCM_CSCR) >> 8) & 0x3; - else - bclk_pdf = (__raw_readl(CCM_CSCR) >> 9) & 0xf; - - rate = clk_get_rate(clk->parent); - return rate / (bclk_pdf + 1); -} - -static unsigned long get_rate_ipg(struct clk *clk) -{ - unsigned long rate, ipg_pdf; - - if (mx27_revision() >= IMX_CHIP_REVISION_2_0) - return clk_get_rate(clk->parent); - else - ipg_pdf = (__raw_readl(CCM_CSCR) >> 8) & 1; - - rate = clk_get_rate(clk->parent); - return rate / (ipg_pdf + 1); -} - -static unsigned long get_rate_per(struct clk *clk) -{ - unsigned long perclk_pdf, parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - if (clk->id < 0 || clk->id > 3) - return 0; - - perclk_pdf = (__raw_readl(CCM_PCDR1) >> (clk->id << 3)) & 0x3f; - - return parent_rate / (perclk_pdf + 1); -} - -/* - * the high frequency external clock reference - * Default case is 26MHz. Could be changed at runtime - * with a call to change_external_high_reference() - */ -static struct clk ckih_clk = { - .get_rate = get_rate_high_reference, -}; - -static struct clk mpll_clk = { - .parent = &ckih_clk, - .get_rate = get_rate_mpll, -}; - -/* For i.MX27 TO2, it is the MPLL path 1 of ARM core - * It provides the clock source whose rate is same as MPLL - */ -static struct clk mpll_main1_clk = { - .id = 0, - .parent = &mpll_clk, - .get_rate = get_rate_mpll_main, -}; - -/* For i.MX27 TO2, it is the MPLL path 2 of ARM core - * It provides the clock source whose rate is same MPLL * 2 / 3 - */ -static struct clk mpll_main2_clk = { - .id = 1, - .parent = &mpll_clk, - .get_rate = get_rate_mpll_main, -}; - -static struct clk ahb_clk = { - .parent = &mpll_main2_clk, - .get_rate = get_rate_ahb, -}; - -static struct clk ipg_clk = { - .parent = &ahb_clk, - .get_rate = get_rate_ipg, -}; - -static struct clk cpu_clk = { - .parent = &mpll_main2_clk, - .set_parent = clk_cpu_set_parent, - .round_rate = round_rate_cpu, - .get_rate = get_rate_cpu, - .set_rate = set_rate_cpu, -}; - -static struct clk spll_clk = { - .parent = &ckih_clk, - .get_rate = get_rate_spll, - .enable = clk_spll_enable, - .disable = clk_spll_disable, -}; - -/* - * the low frequency external clock reference - * Default case is 32.768kHz. - */ -static struct clk ckil_clk = { - .get_rate = get_rate_low_reference, -}; - -/* Output of frequency pre multiplier */ -static struct clk fpm_clk = { - .parent = &ckil_clk, - .get_rate = get_rate_fpm, -}; - -#define PCCR0 CCM_PCCR0 -#define PCCR1 CCM_PCCR1 - -#define DEFINE_CLOCK(name, i, er, es, gr, s, p) \ - static struct clk name = { \ - .id = i, \ - .enable_reg = er, \ - .enable_shift = es, \ - .get_rate = gr, \ - .enable = clk_pccr_enable, \ - .disable = clk_pccr_disable, \ - .secondary = s, \ - .parent = p, \ - } - -#define DEFINE_CLOCK1(name, i, er, es, getsetround, s, p) \ - static struct clk name = { \ - .id = i, \ - .enable_reg = er, \ - .enable_shift = es, \ - .get_rate = get_rate_##getsetround, \ - .set_rate = set_rate_##getsetround, \ - .round_rate = round_rate_##getsetround, \ - .enable = clk_pccr_enable, \ - .disable = clk_pccr_disable, \ - .secondary = s, \ - .parent = p, \ - } - -/* Forward declaration to keep the following list in order */ -static struct clk slcdc_clk1, sahara2_clk1, rtic_clk1, fec_clk1, emma_clk1, - dma_clk1, lcdc_clk2, vpu_clk1; - -/* All clocks we can gate through PCCRx in the order of PCCRx bits */ -DEFINE_CLOCK(ssi2_clk1, 1, PCCR0, 0, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(ssi1_clk1, 0, PCCR0, 1, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(slcdc_clk, 0, PCCR0, 2, NULL, &slcdc_clk1, &ahb_clk); -DEFINE_CLOCK(sdhc3_clk1, 0, PCCR0, 3, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(sdhc2_clk1, 0, PCCR0, 4, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(sdhc1_clk1, 0, PCCR0, 5, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(scc_clk, 0, PCCR0, 6, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(sahara2_clk, 0, PCCR0, 7, NULL, &sahara2_clk1, &ahb_clk); -DEFINE_CLOCK(rtic_clk, 0, PCCR0, 8, NULL, &rtic_clk1, &ahb_clk); -DEFINE_CLOCK(rtc_clk, 0, PCCR0, 9, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(pwm_clk1, 0, PCCR0, 11, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(owire_clk, 0, PCCR0, 12, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(mstick_clk1, 0, PCCR0, 13, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(lcdc_clk1, 0, PCCR0, 14, NULL, &lcdc_clk2, &ipg_clk); -DEFINE_CLOCK(kpp_clk, 0, PCCR0, 15, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(iim_clk, 0, PCCR0, 16, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(i2c2_clk, 1, PCCR0, 17, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(i2c1_clk, 0, PCCR0, 18, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(gpt6_clk1, 0, PCCR0, 29, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(gpt5_clk1, 0, PCCR0, 20, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(gpt4_clk1, 0, PCCR0, 21, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(gpt3_clk1, 0, PCCR0, 22, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(gpt2_clk1, 0, PCCR0, 23, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(gpt1_clk1, 0, PCCR0, 24, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(gpio_clk, 0, PCCR0, 25, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(fec_clk, 0, PCCR0, 26, NULL, &fec_clk1, &ahb_clk); -DEFINE_CLOCK(emma_clk, 0, PCCR0, 27, NULL, &emma_clk1, &ahb_clk); -DEFINE_CLOCK(dma_clk, 0, PCCR0, 28, NULL, &dma_clk1, &ahb_clk); -DEFINE_CLOCK(cspi13_clk1, 0, PCCR0, 29, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(cspi2_clk1, 0, PCCR0, 30, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(cspi1_clk1, 0, PCCR0, 31, NULL, NULL, &ipg_clk); - -DEFINE_CLOCK(mstick_clk, 0, PCCR1, 2, NULL, &mstick_clk1, &ipg_clk); -DEFINE_CLOCK(nfc_clk, 0, PCCR1, 3, get_rate_nfc, NULL, &cpu_clk); -DEFINE_CLOCK(ssi2_clk, 1, PCCR1, 4, get_rate_ssi2, &ssi2_clk1, &mpll_main2_clk); -DEFINE_CLOCK(ssi1_clk, 0, PCCR1, 5, get_rate_ssi1, &ssi1_clk1, &mpll_main2_clk); -DEFINE_CLOCK(vpu_clk, 0, PCCR1, 6, get_rate_vpu, &vpu_clk1, &mpll_main2_clk); -DEFINE_CLOCK1(per4_clk, 3, PCCR1, 7, per, NULL, &mpll_main2_clk); -DEFINE_CLOCK1(per3_clk, 2, PCCR1, 8, per, NULL, &mpll_main2_clk); -DEFINE_CLOCK1(per2_clk, 1, PCCR1, 9, per, NULL, &mpll_main2_clk); -DEFINE_CLOCK1(per1_clk, 0, PCCR1, 10, per, NULL, &mpll_main2_clk); -DEFINE_CLOCK(usb_clk1, 0, PCCR1, 11, NULL, NULL, &ahb_clk); -DEFINE_CLOCK(slcdc_clk1, 0, PCCR1, 12, NULL, NULL, &ahb_clk); -DEFINE_CLOCK(sahara2_clk1, 0, PCCR1, 13, NULL, NULL, &ahb_clk); -DEFINE_CLOCK(rtic_clk1, 0, PCCR1, 14, NULL, NULL, &ahb_clk); -DEFINE_CLOCK(lcdc_clk2, 0, PCCR1, 15, NULL, NULL, &ahb_clk); -DEFINE_CLOCK(vpu_clk1, 0, PCCR1, 16, NULL, NULL, &ahb_clk); -DEFINE_CLOCK(fec_clk1, 0, PCCR1, 17, NULL, NULL, &ahb_clk); -DEFINE_CLOCK(emma_clk1, 0, PCCR1, 18, NULL, NULL, &ahb_clk); -DEFINE_CLOCK(emi_clk, 0, PCCR1, 19, NULL, NULL, &ahb_clk); -DEFINE_CLOCK(dma_clk1, 0, PCCR1, 20, NULL, NULL, &ahb_clk); -DEFINE_CLOCK(csi_clk1, 0, PCCR1, 21, NULL, NULL, &ahb_clk); -DEFINE_CLOCK(brom_clk, 0, PCCR1, 22, NULL, NULL, &ahb_clk); -DEFINE_CLOCK(pata_clk, 0, PCCR1, 23, NULL, NULL, &ahb_clk); -DEFINE_CLOCK(wdog_clk, 0, PCCR1, 24, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(usb_clk, 0, PCCR1, 25, get_rate_usb, &usb_clk1, &spll_clk); -DEFINE_CLOCK(uart6_clk1, 0, PCCR1, 26, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(uart5_clk1, 0, PCCR1, 27, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(uart4_clk1, 0, PCCR1, 28, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(uart3_clk1, 0, PCCR1, 29, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(uart2_clk1, 0, PCCR1, 30, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(uart1_clk1, 0, PCCR1, 31, NULL, NULL, &ipg_clk); - -/* Clocks we cannot directly gate, but drivers need their rates */ -DEFINE_CLOCK(cspi1_clk, 0, NULL, 0, NULL, &cspi1_clk1, &per2_clk); -DEFINE_CLOCK(cspi2_clk, 1, NULL, 0, NULL, &cspi2_clk1, &per2_clk); -DEFINE_CLOCK(cspi3_clk, 2, NULL, 0, NULL, &cspi13_clk1, &per2_clk); -DEFINE_CLOCK(sdhc1_clk, 0, NULL, 0, NULL, &sdhc1_clk1, &per2_clk); -DEFINE_CLOCK(sdhc2_clk, 1, NULL, 0, NULL, &sdhc2_clk1, &per2_clk); -DEFINE_CLOCK(sdhc3_clk, 2, NULL, 0, NULL, &sdhc3_clk1, &per2_clk); -DEFINE_CLOCK(pwm_clk, 0, NULL, 0, NULL, &pwm_clk1, &per1_clk); -DEFINE_CLOCK(gpt1_clk, 0, NULL, 0, NULL, &gpt1_clk1, &per1_clk); -DEFINE_CLOCK(gpt2_clk, 1, NULL, 0, NULL, &gpt2_clk1, &per1_clk); -DEFINE_CLOCK(gpt3_clk, 2, NULL, 0, NULL, &gpt3_clk1, &per1_clk); -DEFINE_CLOCK(gpt4_clk, 3, NULL, 0, NULL, &gpt4_clk1, &per1_clk); -DEFINE_CLOCK(gpt5_clk, 4, NULL, 0, NULL, &gpt5_clk1, &per1_clk); -DEFINE_CLOCK(gpt6_clk, 5, NULL, 0, NULL, &gpt6_clk1, &per1_clk); -DEFINE_CLOCK(uart1_clk, 0, NULL, 0, NULL, &uart1_clk1, &per1_clk); -DEFINE_CLOCK(uart2_clk, 1, NULL, 0, NULL, &uart2_clk1, &per1_clk); -DEFINE_CLOCK(uart3_clk, 2, NULL, 0, NULL, &uart3_clk1, &per1_clk); -DEFINE_CLOCK(uart4_clk, 3, NULL, 0, NULL, &uart4_clk1, &per1_clk); -DEFINE_CLOCK(uart5_clk, 4, NULL, 0, NULL, &uart5_clk1, &per1_clk); -DEFINE_CLOCK(uart6_clk, 5, NULL, 0, NULL, &uart6_clk1, &per1_clk); -DEFINE_CLOCK1(lcdc_clk, 0, NULL, 0, parent, &lcdc_clk1, &per3_clk); -DEFINE_CLOCK1(csi_clk, 0, NULL, 0, parent, &csi_clk1, &per4_clk); - -#define _REGISTER_CLOCK(d, n, c) \ - { \ - .dev_id = d, \ - .con_id = n, \ - .clk = &c, \ - }, - -static struct clk_lookup lookups[] = { - /* i.mx27 has the i.mx21 type uart */ - _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk) - _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk) - _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk) - _REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk) - _REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk) - _REGISTER_CLOCK("imx21-uart.5", NULL, uart6_clk) - _REGISTER_CLOCK(NULL, "gpt1", gpt1_clk) - _REGISTER_CLOCK(NULL, "gpt2", gpt2_clk) - _REGISTER_CLOCK(NULL, "gpt3", gpt3_clk) - _REGISTER_CLOCK(NULL, "gpt4", gpt4_clk) - _REGISTER_CLOCK(NULL, "gpt5", gpt5_clk) - _REGISTER_CLOCK(NULL, "gpt6", gpt6_clk) - _REGISTER_CLOCK("mxc_pwm.0", NULL, pwm_clk) - _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk) - _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk) - _REGISTER_CLOCK("mxc-mmc.2", NULL, sdhc3_clk) - _REGISTER_CLOCK("imx27-cspi.0", NULL, cspi1_clk) - _REGISTER_CLOCK("imx27-cspi.1", NULL, cspi2_clk) - _REGISTER_CLOCK("imx27-cspi.2", NULL, cspi3_clk) - _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk) - _REGISTER_CLOCK("mx2-camera.0", NULL, csi_clk) - _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk) - _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk1) - _REGISTER_CLOCK("mxc-ehci.0", "usb", usb_clk) - _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_clk1) - _REGISTER_CLOCK("mxc-ehci.1", "usb", usb_clk) - _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_clk1) - _REGISTER_CLOCK("mxc-ehci.2", "usb", usb_clk) - _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_clk1) - _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) - _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) - _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk) - _REGISTER_CLOCK(NULL, "vpu", vpu_clk) - _REGISTER_CLOCK(NULL, "dma", dma_clk) - _REGISTER_CLOCK(NULL, "rtic", rtic_clk) - _REGISTER_CLOCK(NULL, "brom", brom_clk) - _REGISTER_CLOCK(NULL, "emma", emma_clk) - _REGISTER_CLOCK("m2m-emmaprp.0", NULL, emma_clk) - _REGISTER_CLOCK(NULL, "slcdc", slcdc_clk) - _REGISTER_CLOCK("imx27-fec.0", NULL, fec_clk) - _REGISTER_CLOCK(NULL, "emi", emi_clk) - _REGISTER_CLOCK(NULL, "sahara2", sahara2_clk) - _REGISTER_CLOCK("pata_imx", NULL, pata_clk) - _REGISTER_CLOCK(NULL, "mstick", mstick_clk) - _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk) - _REGISTER_CLOCK(NULL, "gpio", gpio_clk) - _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk) - _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk) - _REGISTER_CLOCK(NULL, "iim", iim_clk) - _REGISTER_CLOCK(NULL, "kpp", kpp_clk) - _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk) - _REGISTER_CLOCK(NULL, "rtc", rtc_clk) - _REGISTER_CLOCK(NULL, "scc", scc_clk) -}; - -/* Adjust the clock path for TO2 and later */ -static void __init to2_adjust_clocks(void) -{ - unsigned long cscr = __raw_readl(CCM_CSCR); - - if (mx27_revision() >= IMX_CHIP_REVISION_2_0) { - if (cscr & CCM_CSCR_ARM_SRC) - cpu_clk.parent = &mpll_main1_clk; - - if (!(cscr & CCM_CSCR_SSI2)) - ssi1_clk.parent = &spll_clk; - - if (!(cscr & CCM_CSCR_SSI1)) - ssi1_clk.parent = &spll_clk; - - if (!(cscr & CCM_CSCR_VPU)) - vpu_clk.parent = &spll_clk; - } else { - cpu_clk.parent = &mpll_clk; - cpu_clk.set_parent = NULL; - cpu_clk.round_rate = NULL; - cpu_clk.set_rate = NULL; - ahb_clk.parent = &mpll_clk; - - per1_clk.parent = &mpll_clk; - per2_clk.parent = &mpll_clk; - per3_clk.parent = &mpll_clk; - per4_clk.parent = &mpll_clk; - - ssi1_clk.parent = &mpll_clk; - ssi2_clk.parent = &mpll_clk; - - vpu_clk.parent = &mpll_clk; - } -} - -/* - * must be called very early to get information about the - * available clock rate when the timer framework starts - */ -int __init mx27_clocks_init(unsigned long fref) -{ - u32 cscr = __raw_readl(CCM_CSCR); - - external_high_reference = fref; - - /* detect clock reference for both system PLLs */ - if (cscr & CCM_CSCR_MCU) - mpll_clk.parent = &ckih_clk; - else - mpll_clk.parent = &fpm_clk; - - if (cscr & CCM_CSCR_SP) - spll_clk.parent = &ckih_clk; - else - spll_clk.parent = &fpm_clk; - - to2_adjust_clocks(); - - clkdev_add_table(lookups, ARRAY_SIZE(lookups)); - - /* Turn off all clocks we do not need */ - __raw_writel(0, CCM_PCCR0); - __raw_writel((1 << 10) | (1 << 19), CCM_PCCR1); - - spll_clk.disable(&spll_clk); - - /* enable basic clocks */ - clk_enable(&per1_clk); - clk_enable(&gpio_clk); - clk_enable(&emi_clk); - clk_enable(&iim_clk); - imx_print_silicon_rev("i.MX27", mx27_revision()); - clk_disable(&iim_clk); - -#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC) - clk_enable(&uart1_clk); -#endif - - mxc_timer_init(&gpt1_clk, MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR), - MX27_INT_GPT1); - - return 0; -} - -#ifdef CONFIG_OF -int __init mx27_clocks_init_dt(void) -{ - struct device_node *np; - u32 fref = 26000000; /* default */ - - for_each_compatible_node(np, NULL, "fixed-clock") { - if (!of_device_is_compatible(np, "fsl,imx-osc26m")) - continue; - - if (!of_property_read_u32(np, "clock-frequency", &fref)) - break; - } - - return mx27_clocks_init(fref); -} -#endif diff --git a/trunk/arch/arm/mach-imx/clock-imx31.c b/trunk/arch/arm/mach-imx/clock-imx31.c deleted file mode 100644 index 3a943cd4159f..000000000000 --- a/trunk/arch/arm/mach-imx/clock-imx31.c +++ /dev/null @@ -1,630 +0,0 @@ -/* - * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. - * Copyright (C) 2008 by Sascha Hauer - * - * 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 -#include - -#include - -#include -#include -#include -#include - -#include "crmregs-imx3.h" - -#define PRE_DIV_MIN_FREQ 10000000 /* Minimum Frequency after Predivider */ - -static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post) -{ - u32 min_pre, temp_pre, old_err, err; - - if (div >= 512) { - *pre = 8; - *post = 64; - } else if (div >= 64) { - min_pre = (div - 1) / 64 + 1; - old_err = 8; - for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) { - err = div % temp_pre; - if (err == 0) { - *pre = temp_pre; - break; - } - err = temp_pre - err; - if (err < old_err) { - old_err = err; - *pre = temp_pre; - } - } - *post = (div + *pre - 1) / *pre; - } else if (div <= 8) { - *pre = div; - *post = 1; - } else { - *pre = 1; - *post = div; - } -} - -static struct clk mcu_pll_clk; -static struct clk serial_pll_clk; -static struct clk ipg_clk; -static struct clk ckih_clk; - -static int cgr_enable(struct clk *clk) -{ - u32 reg; - - if (!clk->enable_reg) - return 0; - - reg = __raw_readl(clk->enable_reg); - reg |= 3 << clk->enable_shift; - __raw_writel(reg, clk->enable_reg); - - return 0; -} - -static void cgr_disable(struct clk *clk) -{ - u32 reg; - - if (!clk->enable_reg) - return; - - reg = __raw_readl(clk->enable_reg); - reg &= ~(3 << clk->enable_shift); - - /* special case for EMI clock */ - if (clk->enable_reg == MXC_CCM_CGR2 && clk->enable_shift == 8) - reg |= (1 << clk->enable_shift); - - __raw_writel(reg, clk->enable_reg); -} - -static unsigned long pll_ref_get_rate(void) -{ - unsigned long ccmr; - unsigned int prcs; - - ccmr = __raw_readl(MXC_CCM_CCMR); - prcs = (ccmr & MXC_CCM_CCMR_PRCS_MASK) >> MXC_CCM_CCMR_PRCS_OFFSET; - if (prcs == 0x1) - return CKIL_CLK_FREQ * 1024; - else - return clk_get_rate(&ckih_clk); -} - -static unsigned long usb_pll_get_rate(struct clk *clk) -{ - unsigned long reg; - - reg = __raw_readl(MXC_CCM_UPCTL); - - return mxc_decode_pll(reg, pll_ref_get_rate()); -} - -static unsigned long serial_pll_get_rate(struct clk *clk) -{ - unsigned long reg; - - reg = __raw_readl(MXC_CCM_SRPCTL); - - return mxc_decode_pll(reg, pll_ref_get_rate()); -} - -static unsigned long mcu_pll_get_rate(struct clk *clk) -{ - unsigned long reg, ccmr; - - ccmr = __raw_readl(MXC_CCM_CCMR); - - if (!(ccmr & MXC_CCM_CCMR_MPE) || (ccmr & MXC_CCM_CCMR_MDS)) - return clk_get_rate(&ckih_clk); - - reg = __raw_readl(MXC_CCM_MPCTL); - - return mxc_decode_pll(reg, pll_ref_get_rate()); -} - -static int usb_pll_enable(struct clk *clk) -{ - u32 reg; - - reg = __raw_readl(MXC_CCM_CCMR); - reg |= MXC_CCM_CCMR_UPE; - __raw_writel(reg, MXC_CCM_CCMR); - - /* No lock bit on MX31, so using max time from spec */ - udelay(80); - - return 0; -} - -static void usb_pll_disable(struct clk *clk) -{ - u32 reg; - - reg = __raw_readl(MXC_CCM_CCMR); - reg &= ~MXC_CCM_CCMR_UPE; - __raw_writel(reg, MXC_CCM_CCMR); -} - -static int serial_pll_enable(struct clk *clk) -{ - u32 reg; - - reg = __raw_readl(MXC_CCM_CCMR); - reg |= MXC_CCM_CCMR_SPE; - __raw_writel(reg, MXC_CCM_CCMR); - - /* No lock bit on MX31, so using max time from spec */ - udelay(80); - - return 0; -} - -static void serial_pll_disable(struct clk *clk) -{ - u32 reg; - - reg = __raw_readl(MXC_CCM_CCMR); - reg &= ~MXC_CCM_CCMR_SPE; - __raw_writel(reg, MXC_CCM_CCMR); -} - -#define PDR0(mask, off) ((__raw_readl(MXC_CCM_PDR0) & mask) >> off) -#define PDR1(mask, off) ((__raw_readl(MXC_CCM_PDR1) & mask) >> off) -#define PDR2(mask, off) ((__raw_readl(MXC_CCM_PDR2) & mask) >> off) - -static unsigned long mcu_main_get_rate(struct clk *clk) -{ - u32 pmcr0 = __raw_readl(MXC_CCM_PMCR0); - - if ((pmcr0 & MXC_CCM_PMCR0_DFSUP1) == MXC_CCM_PMCR0_DFSUP1_SPLL) - return clk_get_rate(&serial_pll_clk); - else - return clk_get_rate(&mcu_pll_clk); -} - -static unsigned long ahb_get_rate(struct clk *clk) -{ - unsigned long max_pdf; - - max_pdf = PDR0(MXC_CCM_PDR0_MAX_PODF_MASK, - MXC_CCM_PDR0_MAX_PODF_OFFSET); - return clk_get_rate(clk->parent) / (max_pdf + 1); -} - -static unsigned long ipg_get_rate(struct clk *clk) -{ - unsigned long ipg_pdf; - - ipg_pdf = PDR0(MXC_CCM_PDR0_IPG_PODF_MASK, - MXC_CCM_PDR0_IPG_PODF_OFFSET); - return clk_get_rate(clk->parent) / (ipg_pdf + 1); -} - -static unsigned long nfc_get_rate(struct clk *clk) -{ - unsigned long nfc_pdf; - - nfc_pdf = PDR0(MXC_CCM_PDR0_NFC_PODF_MASK, - MXC_CCM_PDR0_NFC_PODF_OFFSET); - return clk_get_rate(clk->parent) / (nfc_pdf + 1); -} - -static unsigned long hsp_get_rate(struct clk *clk) -{ - unsigned long hsp_pdf; - - hsp_pdf = PDR0(MXC_CCM_PDR0_HSP_PODF_MASK, - MXC_CCM_PDR0_HSP_PODF_OFFSET); - return clk_get_rate(clk->parent) / (hsp_pdf + 1); -} - -static unsigned long usb_get_rate(struct clk *clk) -{ - unsigned long usb_pdf, usb_prepdf; - - usb_pdf = PDR1(MXC_CCM_PDR1_USB_PODF_MASK, - MXC_CCM_PDR1_USB_PODF_OFFSET); - usb_prepdf = PDR1(MXC_CCM_PDR1_USB_PRDF_MASK, - MXC_CCM_PDR1_USB_PRDF_OFFSET); - return clk_get_rate(clk->parent) / (usb_prepdf + 1) / (usb_pdf + 1); -} - -static unsigned long csi_get_rate(struct clk *clk) -{ - u32 reg, pre, post; - - reg = __raw_readl(MXC_CCM_PDR0); - pre = (reg & MXC_CCM_PDR0_CSI_PRDF_MASK) >> - MXC_CCM_PDR0_CSI_PRDF_OFFSET; - pre++; - post = (reg & MXC_CCM_PDR0_CSI_PODF_MASK) >> - MXC_CCM_PDR0_CSI_PODF_OFFSET; - post++; - return clk_get_rate(clk->parent) / (pre * post); -} - -static unsigned long csi_round_rate(struct clk *clk, unsigned long rate) -{ - u32 pre, post, parent = clk_get_rate(clk->parent); - u32 div = parent / rate; - - if (parent % rate) - div++; - - __calc_pre_post_dividers(div, &pre, &post); - - return parent / (pre * post); -} - -static int csi_set_rate(struct clk *clk, unsigned long rate) -{ - u32 reg, div, pre, post, parent = clk_get_rate(clk->parent); - - div = parent / rate; - - if ((parent / div) != rate) - return -EINVAL; - - __calc_pre_post_dividers(div, &pre, &post); - - /* Set CSI clock divider */ - reg = __raw_readl(MXC_CCM_PDR0) & - ~(MXC_CCM_PDR0_CSI_PODF_MASK | MXC_CCM_PDR0_CSI_PRDF_MASK); - reg |= (post - 1) << MXC_CCM_PDR0_CSI_PODF_OFFSET; - reg |= (pre - 1) << MXC_CCM_PDR0_CSI_PRDF_OFFSET; - __raw_writel(reg, MXC_CCM_PDR0); - - return 0; -} - -static unsigned long ssi1_get_rate(struct clk *clk) -{ - unsigned long ssi1_pdf, ssi1_prepdf; - - ssi1_pdf = PDR1(MXC_CCM_PDR1_SSI1_PODF_MASK, - MXC_CCM_PDR1_SSI1_PODF_OFFSET); - ssi1_prepdf = PDR1(MXC_CCM_PDR1_SSI1_PRE_PODF_MASK, - MXC_CCM_PDR1_SSI1_PRE_PODF_OFFSET); - return clk_get_rate(clk->parent) / (ssi1_prepdf + 1) / (ssi1_pdf + 1); -} - -static unsigned long ssi2_get_rate(struct clk *clk) -{ - unsigned long ssi2_pdf, ssi2_prepdf; - - ssi2_pdf = PDR1(MXC_CCM_PDR1_SSI2_PODF_MASK, - MXC_CCM_PDR1_SSI2_PODF_OFFSET); - ssi2_prepdf = PDR1(MXC_CCM_PDR1_SSI2_PRE_PODF_MASK, - MXC_CCM_PDR1_SSI2_PRE_PODF_OFFSET); - return clk_get_rate(clk->parent) / (ssi2_prepdf + 1) / (ssi2_pdf + 1); -} - -static unsigned long firi_get_rate(struct clk *clk) -{ - unsigned long firi_pdf, firi_prepdf; - - firi_pdf = PDR1(MXC_CCM_PDR1_FIRI_PODF_MASK, - MXC_CCM_PDR1_FIRI_PODF_OFFSET); - firi_prepdf = PDR1(MXC_CCM_PDR1_FIRI_PRE_PODF_MASK, - MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET); - return clk_get_rate(clk->parent) / (firi_prepdf + 1) / (firi_pdf + 1); -} - -static unsigned long firi_round_rate(struct clk *clk, unsigned long rate) -{ - u32 pre, post; - u32 parent = clk_get_rate(clk->parent); - u32 div = parent / rate; - - if (parent % rate) - div++; - - __calc_pre_post_dividers(div, &pre, &post); - - return parent / (pre * post); - -} - -static int firi_set_rate(struct clk *clk, unsigned long rate) -{ - u32 reg, div, pre, post, parent = clk_get_rate(clk->parent); - - div = parent / rate; - - if ((parent / div) != rate) - return -EINVAL; - - __calc_pre_post_dividers(div, &pre, &post); - - /* Set FIRI clock divider */ - reg = __raw_readl(MXC_CCM_PDR1) & - ~(MXC_CCM_PDR1_FIRI_PODF_MASK | MXC_CCM_PDR1_FIRI_PRE_PODF_MASK); - reg |= (pre - 1) << MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET; - reg |= (post - 1) << MXC_CCM_PDR1_FIRI_PODF_OFFSET; - __raw_writel(reg, MXC_CCM_PDR1); - - return 0; -} - -static unsigned long mbx_get_rate(struct clk *clk) -{ - return clk_get_rate(clk->parent) / 2; -} - -static unsigned long mstick1_get_rate(struct clk *clk) -{ - unsigned long msti_pdf; - - msti_pdf = PDR2(MXC_CCM_PDR2_MST1_PDF_MASK, - MXC_CCM_PDR2_MST1_PDF_OFFSET); - return clk_get_rate(clk->parent) / (msti_pdf + 1); -} - -static unsigned long mstick2_get_rate(struct clk *clk) -{ - unsigned long msti_pdf; - - msti_pdf = PDR2(MXC_CCM_PDR2_MST2_PDF_MASK, - MXC_CCM_PDR2_MST2_PDF_OFFSET); - return clk_get_rate(clk->parent) / (msti_pdf + 1); -} - -static unsigned long ckih_rate; - -static unsigned long clk_ckih_get_rate(struct clk *clk) -{ - return ckih_rate; -} - -static unsigned long clk_ckil_get_rate(struct clk *clk) -{ - return CKIL_CLK_FREQ; -} - -static struct clk ckih_clk = { - .get_rate = clk_ckih_get_rate, -}; - -static struct clk mcu_pll_clk = { - .parent = &ckih_clk, - .get_rate = mcu_pll_get_rate, -}; - -static struct clk mcu_main_clk = { - .parent = &mcu_pll_clk, - .get_rate = mcu_main_get_rate, -}; - -static struct clk serial_pll_clk = { - .parent = &ckih_clk, - .get_rate = serial_pll_get_rate, - .enable = serial_pll_enable, - .disable = serial_pll_disable, -}; - -static struct clk usb_pll_clk = { - .parent = &ckih_clk, - .get_rate = usb_pll_get_rate, - .enable = usb_pll_enable, - .disable = usb_pll_disable, -}; - -static struct clk ahb_clk = { - .parent = &mcu_main_clk, - .get_rate = ahb_get_rate, -}; - -#define DEFINE_CLOCK(name, i, er, es, gr, s, p) \ - static struct clk name = { \ - .id = i, \ - .enable_reg = er, \ - .enable_shift = es, \ - .get_rate = gr, \ - .enable = cgr_enable, \ - .disable = cgr_disable, \ - .secondary = s, \ - .parent = p, \ - } - -#define DEFINE_CLOCK1(name, i, er, es, getsetround, s, p) \ - static struct clk name = { \ - .id = i, \ - .enable_reg = er, \ - .enable_shift = es, \ - .get_rate = getsetround##_get_rate, \ - .set_rate = getsetround##_set_rate, \ - .round_rate = getsetround##_round_rate, \ - .enable = cgr_enable, \ - .disable = cgr_disable, \ - .secondary = s, \ - .parent = p, \ - } - -DEFINE_CLOCK(perclk_clk, 0, NULL, 0, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(ckil_clk, 0, NULL, 0, clk_ckil_get_rate, NULL, NULL); - -DEFINE_CLOCK(sdhc1_clk, 0, MXC_CCM_CGR0, 0, NULL, NULL, &perclk_clk); -DEFINE_CLOCK(sdhc2_clk, 1, MXC_CCM_CGR0, 2, NULL, NULL, &perclk_clk); -DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CGR0, 4, NULL, NULL, &perclk_clk); -DEFINE_CLOCK(epit1_clk, 0, MXC_CCM_CGR0, 6, NULL, NULL, &perclk_clk); -DEFINE_CLOCK(epit2_clk, 1, MXC_CCM_CGR0, 8, NULL, NULL, &perclk_clk); -DEFINE_CLOCK(iim_clk, 0, MXC_CCM_CGR0, 10, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(pata_clk, 0, MXC_CCM_CGR0, 12, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(sdma_clk1, 0, MXC_CCM_CGR0, 14, NULL, NULL, &ahb_clk); -DEFINE_CLOCK(cspi3_clk, 2, MXC_CCM_CGR0, 16, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(rng_clk, 0, MXC_CCM_CGR0, 18, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CGR0, 20, NULL, NULL, &perclk_clk); -DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CGR0, 22, NULL, NULL, &perclk_clk); -DEFINE_CLOCK(ssi1_clk, 0, MXC_CCM_CGR0, 24, ssi1_get_rate, NULL, &serial_pll_clk); -DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CGR0, 26, NULL, NULL, &perclk_clk); -DEFINE_CLOCK(i2c2_clk, 1, MXC_CCM_CGR0, 28, NULL, NULL, &perclk_clk); -DEFINE_CLOCK(i2c3_clk, 2, MXC_CCM_CGR0, 30, NULL, NULL, &perclk_clk); - -DEFINE_CLOCK(mpeg4_clk, 0, MXC_CCM_CGR1, 0, NULL, NULL, &ahb_clk); -DEFINE_CLOCK(mstick1_clk, 0, MXC_CCM_CGR1, 2, mstick1_get_rate, NULL, &usb_pll_clk); -DEFINE_CLOCK(mstick2_clk, 1, MXC_CCM_CGR1, 4, mstick2_get_rate, NULL, &usb_pll_clk); -DEFINE_CLOCK1(csi_clk, 0, MXC_CCM_CGR1, 6, csi, NULL, &serial_pll_clk); -DEFINE_CLOCK(rtc_clk, 0, MXC_CCM_CGR1, 8, NULL, NULL, &ckil_clk); -DEFINE_CLOCK(wdog_clk, 0, MXC_CCM_CGR1, 10, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(pwm_clk, 0, MXC_CCM_CGR1, 12, NULL, NULL, &perclk_clk); -DEFINE_CLOCK(usb_clk2, 0, MXC_CCM_CGR1, 18, usb_get_rate, NULL, &ahb_clk); -DEFINE_CLOCK(kpp_clk, 0, MXC_CCM_CGR1, 20, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(ipu_clk, 0, MXC_CCM_CGR1, 22, hsp_get_rate, NULL, &mcu_main_clk); -DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CGR1, 24, NULL, NULL, &perclk_clk); -DEFINE_CLOCK(uart4_clk, 3, MXC_CCM_CGR1, 26, NULL, NULL, &perclk_clk); -DEFINE_CLOCK(uart5_clk, 4, MXC_CCM_CGR1, 28, NULL, NULL, &perclk_clk); -DEFINE_CLOCK(owire_clk, 0, MXC_CCM_CGR1, 30, NULL, NULL, &perclk_clk); - -DEFINE_CLOCK(ssi2_clk, 1, MXC_CCM_CGR2, 0, ssi2_get_rate, NULL, &serial_pll_clk); -DEFINE_CLOCK(cspi1_clk, 0, MXC_CCM_CGR2, 2, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(cspi2_clk, 1, MXC_CCM_CGR2, 4, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(mbx_clk, 0, MXC_CCM_CGR2, 6, mbx_get_rate, NULL, &ahb_clk); -DEFINE_CLOCK(emi_clk, 0, MXC_CCM_CGR2, 8, NULL, NULL, &ahb_clk); -DEFINE_CLOCK(rtic_clk, 0, MXC_CCM_CGR2, 10, NULL, NULL, &ahb_clk); -DEFINE_CLOCK1(firi_clk, 0, MXC_CCM_CGR2, 12, firi, NULL, &usb_pll_clk); - -DEFINE_CLOCK(sdma_clk2, 0, NULL, 0, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(usb_clk1, 0, NULL, 0, usb_get_rate, NULL, &usb_pll_clk); -DEFINE_CLOCK(nfc_clk, 0, NULL, 0, nfc_get_rate, NULL, &ahb_clk); -DEFINE_CLOCK(scc_clk, 0, NULL, 0, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(ipg_clk, 0, NULL, 0, ipg_get_rate, NULL, &ahb_clk); - -#define _REGISTER_CLOCK(d, n, c) \ - { \ - .dev_id = d, \ - .con_id = n, \ - .clk = &c, \ - }, - -static struct clk_lookup lookups[] = { - _REGISTER_CLOCK(NULL, "emi", emi_clk) - _REGISTER_CLOCK("imx31-cspi.0", NULL, cspi1_clk) - _REGISTER_CLOCK("imx31-cspi.1", NULL, cspi2_clk) - _REGISTER_CLOCK("imx31-cspi.2", NULL, cspi3_clk) - _REGISTER_CLOCK(NULL, "gpt", gpt_clk) - _REGISTER_CLOCK(NULL, "pwm", pwm_clk) - _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk) - _REGISTER_CLOCK(NULL, "rtc", rtc_clk) - _REGISTER_CLOCK(NULL, "epit", epit1_clk) - _REGISTER_CLOCK(NULL, "epit", epit2_clk) - _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk) - _REGISTER_CLOCK("ipu-core", NULL, ipu_clk) - _REGISTER_CLOCK("mx3_sdc_fb", NULL, ipu_clk) - _REGISTER_CLOCK(NULL, "kpp", kpp_clk) - _REGISTER_CLOCK("mxc-ehci.0", "usb", usb_clk1) - _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_clk2) - _REGISTER_CLOCK("mxc-ehci.1", "usb", usb_clk1) - _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_clk2) - _REGISTER_CLOCK("mxc-ehci.2", "usb", usb_clk1) - _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_clk2) - _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk1) - _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk2) - _REGISTER_CLOCK("mx3-camera.0", NULL, csi_clk) - /* i.mx31 has the i.mx21 type uart */ - _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk) - _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk) - _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk) - _REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk) - _REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk) - _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk) - _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk) - _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk) - _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk) - _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk) - _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk) - _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) - _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) - _REGISTER_CLOCK(NULL, "firi", firi_clk) - _REGISTER_CLOCK("pata_imx", NULL, pata_clk) - _REGISTER_CLOCK(NULL, "rtic", rtic_clk) - _REGISTER_CLOCK(NULL, "rng", rng_clk) - _REGISTER_CLOCK("imx31-sdma", NULL, sdma_clk1) - _REGISTER_CLOCK(NULL, "sdma_ipg", sdma_clk2) - _REGISTER_CLOCK(NULL, "mstick", mstick1_clk) - _REGISTER_CLOCK(NULL, "mstick", mstick2_clk) - _REGISTER_CLOCK(NULL, "scc", scc_clk) - _REGISTER_CLOCK(NULL, "iim", iim_clk) - _REGISTER_CLOCK(NULL, "mpeg4", mpeg4_clk) - _REGISTER_CLOCK(NULL, "mbx", mbx_clk) -}; - -int __init mx31_clocks_init(unsigned long fref) -{ - u32 reg; - - ckih_rate = fref; - - clkdev_add_table(lookups, ARRAY_SIZE(lookups)); - - /* change the csi_clk parent if necessary */ - reg = __raw_readl(MXC_CCM_CCMR); - if (!(reg & MXC_CCM_CCMR_CSCS)) - if (clk_set_parent(&csi_clk, &usb_pll_clk)) - pr_err("%s: error changing csi_clk parent\n", __func__); - - - /* Turn off all possible clocks */ - __raw_writel((3 << 4), MXC_CCM_CGR0); - __raw_writel(0, MXC_CCM_CGR1); - __raw_writel((3 << 8) | (3 << 14) | (3 << 16)| - 1 << 27 | 1 << 28, /* Bit 27 and 28 are not defined for - MX32, but still required to be set */ - MXC_CCM_CGR2); - - /* - * Before turning off usb_pll make sure ipg_per_clk is generated - * by ipg_clk and not usb_pll. - */ - __raw_writel(__raw_readl(MXC_CCM_CCMR) | (1 << 24), MXC_CCM_CCMR); - - usb_pll_disable(&usb_pll_clk); - - pr_info("Clock input source is %ld\n", clk_get_rate(&ckih_clk)); - - clk_enable(&gpt_clk); - clk_enable(&emi_clk); - clk_enable(&iim_clk); - mx31_revision(); - clk_disable(&iim_clk); - - clk_enable(&serial_pll_clk); - - if (mx31_revision() >= IMX_CHIP_REVISION_2_0) { - reg = __raw_readl(MXC_CCM_PMCR1); - /* No PLL restart on DVFS switch; enable auto EMI handshake */ - reg |= MXC_CCM_PMCR1_PLLRDIS | MXC_CCM_PMCR1_EMIRQ_EN; - __raw_writel(reg, MXC_CCM_PMCR1); - } - - mxc_timer_init(&ipg_clk, MX31_IO_ADDRESS(MX31_GPT1_BASE_ADDR), - MX31_INT_GPT); - - return 0; -} diff --git a/trunk/arch/arm/mach-imx/clock-imx35.c b/trunk/arch/arm/mach-imx/clock-imx35.c deleted file mode 100644 index e56c1a83eee3..000000000000 --- a/trunk/arch/arm/mach-imx/clock-imx35.c +++ /dev/null @@ -1,536 +0,0 @@ -/* - * Copyright (C) 2009 by Sascha Hauer, Pengutronix - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "crmregs-imx3.h" - -#ifdef HAVE_SET_RATE_SUPPORT -static void calc_dividers(u32 div, u32 *pre, u32 *post, u32 maxpost) -{ - u32 min_pre, temp_pre, old_err, err; - - min_pre = (div - 1) / maxpost + 1; - old_err = 8; - - for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) { - if (div > (temp_pre * maxpost)) - break; - - if (div < (temp_pre * temp_pre)) - continue; - - err = div % temp_pre; - - if (err == 0) { - *pre = temp_pre; - break; - } - - err = temp_pre - err; - - if (err < old_err) { - old_err = err; - *pre = temp_pre; - } - } - - *post = (div + *pre - 1) / *pre; -} - -/* get the best values for a 3-bit divider combined with a 6-bit divider */ -static void calc_dividers_3_6(u32 div, u32 *pre, u32 *post) -{ - if (div >= 512) { - *pre = 8; - *post = 64; - } else if (div >= 64) { - calc_dividers(div, pre, post, 64); - } else if (div <= 8) { - *pre = div; - *post = 1; - } else { - *pre = 1; - *post = div; - } -} - -/* get the best values for two cascaded 3-bit dividers */ -static void calc_dividers_3_3(u32 div, u32 *pre, u32 *post) -{ - if (div >= 64) { - *pre = *post = 8; - } else if (div > 8) { - calc_dividers(div, pre, post, 8); - } else { - *pre = 1; - *post = div; - } -} -#endif - -static unsigned long get_rate_mpll(void) -{ - ulong mpctl = __raw_readl(MX35_CCM_MPCTL); - - return mxc_decode_pll(mpctl, 24000000); -} - -static unsigned long get_rate_ppll(void) -{ - ulong ppctl = __raw_readl(MX35_CCM_PPCTL); - - return mxc_decode_pll(ppctl, 24000000); -} - -struct arm_ahb_div { - unsigned char arm, ahb, sel; -}; - -static struct arm_ahb_div clk_consumer[] = { - { .arm = 1, .ahb = 4, .sel = 0}, - { .arm = 1, .ahb = 3, .sel = 1}, - { .arm = 2, .ahb = 2, .sel = 0}, - { .arm = 0, .ahb = 0, .sel = 0}, - { .arm = 0, .ahb = 0, .sel = 0}, - { .arm = 0, .ahb = 0, .sel = 0}, - { .arm = 4, .ahb = 1, .sel = 0}, - { .arm = 1, .ahb = 5, .sel = 0}, - { .arm = 1, .ahb = 8, .sel = 0}, - { .arm = 1, .ahb = 6, .sel = 1}, - { .arm = 2, .ahb = 4, .sel = 0}, - { .arm = 0, .ahb = 0, .sel = 0}, - { .arm = 0, .ahb = 0, .sel = 0}, - { .arm = 0, .ahb = 0, .sel = 0}, - { .arm = 4, .ahb = 2, .sel = 0}, - { .arm = 0, .ahb = 0, .sel = 0}, -}; - -static unsigned long get_rate_arm(void) -{ - unsigned long pdr0 = __raw_readl(MXC_CCM_PDR0); - struct arm_ahb_div *aad; - unsigned long fref = get_rate_mpll(); - - aad = &clk_consumer[(pdr0 >> 16) & 0xf]; - if (aad->sel) - fref = fref * 3 / 4; - - return fref / aad->arm; -} - -static unsigned long get_rate_ahb(struct clk *clk) -{ - unsigned long pdr0 = __raw_readl(MXC_CCM_PDR0); - struct arm_ahb_div *aad; - unsigned long fref = get_rate_arm(); - - aad = &clk_consumer[(pdr0 >> 16) & 0xf]; - - return fref / aad->ahb; -} - -static unsigned long get_rate_ipg(struct clk *clk) -{ - return get_rate_ahb(NULL) >> 1; -} - -static unsigned long get_rate_uart(struct clk *clk) -{ - unsigned long pdr3 = __raw_readl(MX35_CCM_PDR3); - unsigned long pdr4 = __raw_readl(MX35_CCM_PDR4); - unsigned long div = ((pdr4 >> 10) & 0x3f) + 1; - - if (pdr3 & (1 << 14)) - return get_rate_arm() / div; - else - return get_rate_ppll() / div; -} - -static unsigned long get_rate_sdhc(struct clk *clk) -{ - unsigned long pdr3 = __raw_readl(MX35_CCM_PDR3); - unsigned long div, rate; - - if (pdr3 & (1 << 6)) - rate = get_rate_arm(); - else - rate = get_rate_ppll(); - - switch (clk->id) { - default: - case 0: - div = pdr3 & 0x3f; - break; - case 1: - div = (pdr3 >> 8) & 0x3f; - break; - case 2: - div = (pdr3 >> 16) & 0x3f; - break; - } - - return rate / (div + 1); -} - -static unsigned long get_rate_mshc(struct clk *clk) -{ - unsigned long pdr1 = __raw_readl(MXC_CCM_PDR1); - unsigned long div1, div2, rate; - - if (pdr1 & (1 << 7)) - rate = get_rate_arm(); - else - rate = get_rate_ppll(); - - div1 = (pdr1 >> 29) & 0x7; - div2 = (pdr1 >> 22) & 0x3f; - - return rate / ((div1 + 1) * (div2 + 1)); -} - -static unsigned long get_rate_ssi(struct clk *clk) -{ - unsigned long pdr2 = __raw_readl(MX35_CCM_PDR2); - unsigned long div1, div2, rate; - - if (pdr2 & (1 << 6)) - rate = get_rate_arm(); - else - rate = get_rate_ppll(); - - switch (clk->id) { - default: - case 0: - div1 = pdr2 & 0x3f; - div2 = (pdr2 >> 24) & 0x7; - break; - case 1: - div1 = (pdr2 >> 8) & 0x3f; - div2 = (pdr2 >> 27) & 0x7; - break; - } - - return rate / ((div1 + 1) * (div2 + 1)); -} - -static unsigned long get_rate_csi(struct clk *clk) -{ - unsigned long pdr2 = __raw_readl(MX35_CCM_PDR2); - unsigned long rate; - - if (pdr2 & (1 << 7)) - rate = get_rate_arm(); - else - rate = get_rate_ppll(); - - return rate / (((pdr2 >> 16) & 0x3f) + 1); -} - -static unsigned long get_rate_otg(struct clk *clk) -{ - unsigned long pdr4 = __raw_readl(MX35_CCM_PDR4); - unsigned long rate; - - if (pdr4 & (1 << 9)) - rate = get_rate_arm(); - else - rate = get_rate_ppll(); - - return rate / (((pdr4 >> 22) & 0x3f) + 1); -} - -static unsigned long get_rate_ipg_per(struct clk *clk) -{ - unsigned long pdr0 = __raw_readl(MXC_CCM_PDR0); - unsigned long pdr4 = __raw_readl(MX35_CCM_PDR4); - unsigned long div; - - if (pdr0 & (1 << 26)) { - div = (pdr4 >> 16) & 0x3f; - return get_rate_arm() / (div + 1); - } else { - div = (pdr0 >> 12) & 0x7; - return get_rate_ahb(NULL) / (div + 1); - } -} - -static unsigned long get_rate_hsp(struct clk *clk) -{ - unsigned long hsp_podf = (__raw_readl(MXC_CCM_PDR0) >> 20) & 0x03; - unsigned long fref = get_rate_mpll(); - - if (fref > 400 * 1000 * 1000) { - switch (hsp_podf) { - case 0: - return fref >> 2; - case 1: - return fref >> 3; - case 2: - return fref / 3; - } - } else { - switch (hsp_podf) { - case 0: - case 2: - return fref / 3; - case 1: - return fref / 6; - } - } - - return 0; -} - -static int clk_cgr_enable(struct clk *clk) -{ - u32 reg; - - reg = __raw_readl(clk->enable_reg); - reg |= 3 << clk->enable_shift; - __raw_writel(reg, clk->enable_reg); - - return 0; -} - -static void clk_cgr_disable(struct clk *clk) -{ - u32 reg; - - reg = __raw_readl(clk->enable_reg); - reg &= ~(3 << clk->enable_shift); - __raw_writel(reg, clk->enable_reg); -} - -#define DEFINE_CLOCK(name, i, er, es, gr, sr) \ - static struct clk name = { \ - .id = i, \ - .enable_reg = er, \ - .enable_shift = es, \ - .get_rate = gr, \ - .set_rate = sr, \ - .enable = clk_cgr_enable, \ - .disable = clk_cgr_disable, \ - } - -DEFINE_CLOCK(asrc_clk, 0, MX35_CCM_CGR0, 0, NULL, NULL); -DEFINE_CLOCK(pata_clk, 0, MX35_CCM_CGR0, 2, get_rate_ipg, NULL); -/* DEFINE_CLOCK(audmux_clk, 0, MX35_CCM_CGR0, 4, NULL, NULL); */ -DEFINE_CLOCK(can1_clk, 0, MX35_CCM_CGR0, 6, get_rate_ipg, NULL); -DEFINE_CLOCK(can2_clk, 1, MX35_CCM_CGR0, 8, get_rate_ipg, NULL); -DEFINE_CLOCK(cspi1_clk, 0, MX35_CCM_CGR0, 10, get_rate_ipg, NULL); -DEFINE_CLOCK(cspi2_clk, 1, MX35_CCM_CGR0, 12, get_rate_ipg, NULL); -DEFINE_CLOCK(ect_clk, 0, MX35_CCM_CGR0, 14, get_rate_ipg, NULL); -DEFINE_CLOCK(edio_clk, 0, MX35_CCM_CGR0, 16, NULL, NULL); -DEFINE_CLOCK(emi_clk, 0, MX35_CCM_CGR0, 18, get_rate_ipg, NULL); -DEFINE_CLOCK(epit1_clk, 0, MX35_CCM_CGR0, 20, get_rate_ipg, NULL); -DEFINE_CLOCK(epit2_clk, 1, MX35_CCM_CGR0, 22, get_rate_ipg, NULL); -DEFINE_CLOCK(esai_clk, 0, MX35_CCM_CGR0, 24, NULL, NULL); -DEFINE_CLOCK(esdhc1_clk, 0, MX35_CCM_CGR0, 26, get_rate_sdhc, NULL); -DEFINE_CLOCK(esdhc2_clk, 1, MX35_CCM_CGR0, 28, get_rate_sdhc, NULL); -DEFINE_CLOCK(esdhc3_clk, 2, MX35_CCM_CGR0, 30, get_rate_sdhc, NULL); - -DEFINE_CLOCK(fec_clk, 0, MX35_CCM_CGR1, 0, get_rate_ipg, NULL); -DEFINE_CLOCK(gpio1_clk, 0, MX35_CCM_CGR1, 2, NULL, NULL); -DEFINE_CLOCK(gpio2_clk, 1, MX35_CCM_CGR1, 4, NULL, NULL); -DEFINE_CLOCK(gpio3_clk, 2, MX35_CCM_CGR1, 6, NULL, NULL); -DEFINE_CLOCK(gpt_clk, 0, MX35_CCM_CGR1, 8, get_rate_ipg, NULL); -DEFINE_CLOCK(i2c1_clk, 0, MX35_CCM_CGR1, 10, get_rate_ipg_per, NULL); -DEFINE_CLOCK(i2c2_clk, 1, MX35_CCM_CGR1, 12, get_rate_ipg_per, NULL); -DEFINE_CLOCK(i2c3_clk, 2, MX35_CCM_CGR1, 14, get_rate_ipg_per, NULL); -DEFINE_CLOCK(iomuxc_clk, 0, MX35_CCM_CGR1, 16, NULL, NULL); -DEFINE_CLOCK(ipu_clk, 0, MX35_CCM_CGR1, 18, get_rate_hsp, NULL); -DEFINE_CLOCK(kpp_clk, 0, MX35_CCM_CGR1, 20, get_rate_ipg, NULL); -DEFINE_CLOCK(mlb_clk, 0, MX35_CCM_CGR1, 22, get_rate_ahb, NULL); -DEFINE_CLOCK(mshc_clk, 0, MX35_CCM_CGR1, 24, get_rate_mshc, NULL); -DEFINE_CLOCK(owire_clk, 0, MX35_CCM_CGR1, 26, get_rate_ipg_per, NULL); -DEFINE_CLOCK(pwm_clk, 0, MX35_CCM_CGR1, 28, get_rate_ipg_per, NULL); -DEFINE_CLOCK(rngc_clk, 0, MX35_CCM_CGR1, 30, get_rate_ipg, NULL); - -DEFINE_CLOCK(rtc_clk, 0, MX35_CCM_CGR2, 0, get_rate_ipg, NULL); -DEFINE_CLOCK(rtic_clk, 0, MX35_CCM_CGR2, 2, get_rate_ahb, NULL); -DEFINE_CLOCK(scc_clk, 0, MX35_CCM_CGR2, 4, get_rate_ipg, NULL); -DEFINE_CLOCK(sdma_clk, 0, MX35_CCM_CGR2, 6, NULL, NULL); -DEFINE_CLOCK(spba_clk, 0, MX35_CCM_CGR2, 8, get_rate_ipg, NULL); -DEFINE_CLOCK(spdif_clk, 0, MX35_CCM_CGR2, 10, NULL, NULL); -DEFINE_CLOCK(ssi1_clk, 0, MX35_CCM_CGR2, 12, get_rate_ssi, NULL); -DEFINE_CLOCK(ssi2_clk, 1, MX35_CCM_CGR2, 14, get_rate_ssi, NULL); -DEFINE_CLOCK(uart1_clk, 0, MX35_CCM_CGR2, 16, get_rate_uart, NULL); -DEFINE_CLOCK(uart2_clk, 1, MX35_CCM_CGR2, 18, get_rate_uart, NULL); -DEFINE_CLOCK(uart3_clk, 2, MX35_CCM_CGR2, 20, get_rate_uart, NULL); -DEFINE_CLOCK(usbotg_clk, 0, MX35_CCM_CGR2, 22, get_rate_otg, NULL); -DEFINE_CLOCK(wdog_clk, 0, MX35_CCM_CGR2, 24, NULL, NULL); -DEFINE_CLOCK(max_clk, 0, MX35_CCM_CGR2, 26, NULL, NULL); -DEFINE_CLOCK(audmux_clk, 0, MX35_CCM_CGR2, 30, NULL, NULL); - -DEFINE_CLOCK(csi_clk, 0, MX35_CCM_CGR3, 0, get_rate_csi, NULL); -DEFINE_CLOCK(iim_clk, 0, MX35_CCM_CGR3, 2, NULL, NULL); -DEFINE_CLOCK(gpu2d_clk, 0, MX35_CCM_CGR3, 4, NULL, NULL); - -DEFINE_CLOCK(usbahb_clk, 0, 0, 0, get_rate_ahb, NULL); - -static int clk_dummy_enable(struct clk *clk) -{ - return 0; -} - -static void clk_dummy_disable(struct clk *clk) -{ -} - -static unsigned long get_rate_nfc(struct clk *clk) -{ - unsigned long div1; - - div1 = (__raw_readl(MX35_CCM_PDR4) >> 28) + 1; - - return get_rate_ahb(NULL) / div1; -} - -/* NAND Controller: It seems it can't be disabled */ -static struct clk nfc_clk = { - .id = 0, - .enable_reg = 0, - .enable_shift = 0, - .get_rate = get_rate_nfc, - .set_rate = NULL, /* set_rate_nfc, */ - .enable = clk_dummy_enable, - .disable = clk_dummy_disable -}; - -#define _REGISTER_CLOCK(d, n, c) \ - { \ - .dev_id = d, \ - .con_id = n, \ - .clk = &c, \ - }, - -static struct clk_lookup lookups[] = { - _REGISTER_CLOCK(NULL, "asrc", asrc_clk) - _REGISTER_CLOCK("pata_imx", NULL, pata_clk) - _REGISTER_CLOCK("flexcan.0", NULL, can1_clk) - _REGISTER_CLOCK("flexcan.1", NULL, can2_clk) - _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi1_clk) - _REGISTER_CLOCK("imx35-cspi.1", NULL, cspi2_clk) - _REGISTER_CLOCK(NULL, "ect", ect_clk) - _REGISTER_CLOCK(NULL, "edio", edio_clk) - _REGISTER_CLOCK(NULL, "emi", emi_clk) - _REGISTER_CLOCK("imx-epit.0", NULL, epit1_clk) - _REGISTER_CLOCK("imx-epit.1", NULL, epit2_clk) - _REGISTER_CLOCK(NULL, "esai", esai_clk) - _REGISTER_CLOCK("sdhci-esdhc-imx35.0", NULL, esdhc1_clk) - _REGISTER_CLOCK("sdhci-esdhc-imx35.1", NULL, esdhc2_clk) - _REGISTER_CLOCK("sdhci-esdhc-imx35.2", NULL, esdhc3_clk) - /* i.mx35 has the i.mx27 type fec */ - _REGISTER_CLOCK("imx27-fec.0", NULL, fec_clk) - _REGISTER_CLOCK(NULL, "gpio", gpio1_clk) - _REGISTER_CLOCK(NULL, "gpio", gpio2_clk) - _REGISTER_CLOCK(NULL, "gpio", gpio3_clk) - _REGISTER_CLOCK("gpt.0", NULL, gpt_clk) - _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk) - _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk) - _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk) - _REGISTER_CLOCK(NULL, "iomuxc", iomuxc_clk) - _REGISTER_CLOCK("ipu-core", NULL, ipu_clk) - _REGISTER_CLOCK("mx3_sdc_fb", NULL, ipu_clk) - _REGISTER_CLOCK(NULL, "kpp", kpp_clk) - _REGISTER_CLOCK(NULL, "mlb", mlb_clk) - _REGISTER_CLOCK(NULL, "mshc", mshc_clk) - _REGISTER_CLOCK("mxc_w1", NULL, owire_clk) - _REGISTER_CLOCK(NULL, "pwm", pwm_clk) - _REGISTER_CLOCK(NULL, "rngc", rngc_clk) - _REGISTER_CLOCK(NULL, "rtc", rtc_clk) - _REGISTER_CLOCK(NULL, "rtic", rtic_clk) - _REGISTER_CLOCK(NULL, "scc", scc_clk) - _REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk) - _REGISTER_CLOCK(NULL, "spba", spba_clk) - _REGISTER_CLOCK(NULL, "spdif", spdif_clk) - _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) - _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) - /* i.mx35 has the i.mx21 type uart */ - _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk) - _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk) - _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk) - _REGISTER_CLOCK("mxc-ehci.0", "usb", usbotg_clk) - _REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk) - _REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk) - _REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk) - _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usbahb_clk) - _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk) - _REGISTER_CLOCK(NULL, "max", max_clk) - _REGISTER_CLOCK(NULL, "audmux", audmux_clk) - _REGISTER_CLOCK("mx3-camera.0", NULL, csi_clk) - _REGISTER_CLOCK(NULL, "iim", iim_clk) - _REGISTER_CLOCK(NULL, "gpu2d", gpu2d_clk) - _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk) -}; - -int __init mx35_clocks_init() -{ - unsigned int cgr2 = 3 << 26; - -#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC) - cgr2 |= 3 << 16; -#endif - - clkdev_add_table(lookups, ARRAY_SIZE(lookups)); - - /* Turn off all clocks except the ones we need to survive, namely: - * EMI, GPIO1/2/3, GPT, IOMUX, MAX and eventually uart - */ - __raw_writel((3 << 18), MX35_CCM_CGR0); - __raw_writel((3 << 2) | (3 << 4) | (3 << 6) | (3 << 8) | (3 << 16), - MX35_CCM_CGR1); - __raw_writel(cgr2, MX35_CCM_CGR2); - __raw_writel(0, MX35_CCM_CGR3); - - clk_enable(&iim_clk); - imx_print_silicon_rev("i.MX35", mx35_revision()); - clk_disable(&iim_clk); - - /* - * Check if we came up in internal boot mode. If yes, we need some - * extra clocks turned on, otherwise the MX35 boot ROM code will - * hang after a watchdog reset. - */ - if (!(__raw_readl(MX35_CCM_RCSR) & (3 << 10))) { - /* Additionally turn on UART1, SCC, and IIM clocks */ - clk_enable(&iim_clk); - clk_enable(&uart1_clk); - clk_enable(&scc_clk); - } - -#ifdef CONFIG_MXC_USE_EPIT - epit_timer_init(&epit1_clk, - MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1); -#else - mxc_timer_init(&gpt_clk, - MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT); -#endif - - return 0; -} diff --git a/trunk/arch/arm/mach-imx/clock-imx6q.c b/trunk/arch/arm/mach-imx/clock-imx6q.c deleted file mode 100644 index 111c328f5420..000000000000 --- a/trunk/arch/arm/mach-imx/clock-imx6q.c +++ /dev/null @@ -1,2111 +0,0 @@ -/* - * Copyright 2011 Freescale Semiconductor, Inc. - * Copyright 2011 Linaro Ltd. - * - * 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 -#include -#include -#include -#include -#include -#include - -#define PLL_BASE IMX_IO_ADDRESS(MX6Q_ANATOP_BASE_ADDR) -#define PLL1_SYS (PLL_BASE + 0x000) -#define PLL2_BUS (PLL_BASE + 0x030) -#define PLL3_USB_OTG (PLL_BASE + 0x010) -#define PLL4_AUDIO (PLL_BASE + 0x070) -#define PLL5_VIDEO (PLL_BASE + 0x0a0) -#define PLL6_MLB (PLL_BASE + 0x0d0) -#define PLL7_USB_HOST (PLL_BASE + 0x020) -#define PLL8_ENET (PLL_BASE + 0x0e0) -#define PFD_480 (PLL_BASE + 0x0f0) -#define PFD_528 (PLL_BASE + 0x100) -#define PLL_NUM_OFFSET 0x010 -#define PLL_DENOM_OFFSET 0x020 - -#define PFD0 7 -#define PFD1 15 -#define PFD2 23 -#define PFD3 31 -#define PFD_FRAC_MASK 0x3f - -#define BM_PLL_BYPASS (0x1 << 16) -#define BM_PLL_ENABLE (0x1 << 13) -#define BM_PLL_POWER_DOWN (0x1 << 12) -#define BM_PLL_LOCK (0x1 << 31) -#define BP_PLL_SYS_DIV_SELECT 0 -#define BM_PLL_SYS_DIV_SELECT (0x7f << 0) -#define BP_PLL_BUS_DIV_SELECT 0 -#define BM_PLL_BUS_DIV_SELECT (0x1 << 0) -#define BP_PLL_USB_DIV_SELECT 0 -#define BM_PLL_USB_DIV_SELECT (0x3 << 0) -#define BP_PLL_AV_DIV_SELECT 0 -#define BM_PLL_AV_DIV_SELECT (0x7f << 0) -#define BP_PLL_ENET_DIV_SELECT 0 -#define BM_PLL_ENET_DIV_SELECT (0x3 << 0) -#define BM_PLL_ENET_EN_PCIE (0x1 << 19) -#define BM_PLL_ENET_EN_SATA (0x1 << 20) - -#define CCM_BASE IMX_IO_ADDRESS(MX6Q_CCM_BASE_ADDR) -#define CCR (CCM_BASE + 0x00) -#define CCDR (CCM_BASE + 0x04) -#define CSR (CCM_BASE + 0x08) -#define CCSR (CCM_BASE + 0x0c) -#define CACRR (CCM_BASE + 0x10) -#define CBCDR (CCM_BASE + 0x14) -#define CBCMR (CCM_BASE + 0x18) -#define CSCMR1 (CCM_BASE + 0x1c) -#define CSCMR2 (CCM_BASE + 0x20) -#define CSCDR1 (CCM_BASE + 0x24) -#define CS1CDR (CCM_BASE + 0x28) -#define CS2CDR (CCM_BASE + 0x2c) -#define CDCDR (CCM_BASE + 0x30) -#define CHSCCDR (CCM_BASE + 0x34) -#define CSCDR2 (CCM_BASE + 0x38) -#define CSCDR3 (CCM_BASE + 0x3c) -#define CSCDR4 (CCM_BASE + 0x40) -#define CWDR (CCM_BASE + 0x44) -#define CDHIPR (CCM_BASE + 0x48) -#define CDCR (CCM_BASE + 0x4c) -#define CTOR (CCM_BASE + 0x50) -#define CLPCR (CCM_BASE + 0x54) -#define CISR (CCM_BASE + 0x58) -#define CIMR (CCM_BASE + 0x5c) -#define CCOSR (CCM_BASE + 0x60) -#define CGPR (CCM_BASE + 0x64) -#define CCGR0 (CCM_BASE + 0x68) -#define CCGR1 (CCM_BASE + 0x6c) -#define CCGR2 (CCM_BASE + 0x70) -#define CCGR3 (CCM_BASE + 0x74) -#define CCGR4 (CCM_BASE + 0x78) -#define CCGR5 (CCM_BASE + 0x7c) -#define CCGR6 (CCM_BASE + 0x80) -#define CCGR7 (CCM_BASE + 0x84) -#define CMEOR (CCM_BASE + 0x88) - -#define CG0 0 -#define CG1 2 -#define CG2 4 -#define CG3 6 -#define CG4 8 -#define CG5 10 -#define CG6 12 -#define CG7 14 -#define CG8 16 -#define CG9 18 -#define CG10 20 -#define CG11 22 -#define CG12 24 -#define CG13 26 -#define CG14 28 -#define CG15 30 - -#define BM_CCSR_PLL1_SW_SEL (0x1 << 2) -#define BM_CCSR_STEP_SEL (0x1 << 8) - -#define BP_CACRR_ARM_PODF 0 -#define BM_CACRR_ARM_PODF (0x7 << 0) - -#define BP_CBCDR_PERIPH2_CLK2_PODF 0 -#define BM_CBCDR_PERIPH2_CLK2_PODF (0x7 << 0) -#define BP_CBCDR_MMDC_CH1_AXI_PODF 3 -#define BM_CBCDR_MMDC_CH1_AXI_PODF (0x7 << 3) -#define BP_CBCDR_AXI_SEL 6 -#define BM_CBCDR_AXI_SEL (0x3 << 6) -#define BP_CBCDR_IPG_PODF 8 -#define BM_CBCDR_IPG_PODF (0x3 << 8) -#define BP_CBCDR_AHB_PODF 10 -#define BM_CBCDR_AHB_PODF (0x7 << 10) -#define BP_CBCDR_AXI_PODF 16 -#define BM_CBCDR_AXI_PODF (0x7 << 16) -#define BP_CBCDR_MMDC_CH0_AXI_PODF 19 -#define BM_CBCDR_MMDC_CH0_AXI_PODF (0x7 << 19) -#define BP_CBCDR_PERIPH_CLK_SEL 25 -#define BM_CBCDR_PERIPH_CLK_SEL (0x1 << 25) -#define BP_CBCDR_PERIPH2_CLK_SEL 26 -#define BM_CBCDR_PERIPH2_CLK_SEL (0x1 << 26) -#define BP_CBCDR_PERIPH_CLK2_PODF 27 -#define BM_CBCDR_PERIPH_CLK2_PODF (0x7 << 27) - -#define BP_CBCMR_GPU2D_AXI_SEL 0 -#define BM_CBCMR_GPU2D_AXI_SEL (0x1 << 0) -#define BP_CBCMR_GPU3D_AXI_SEL 1 -#define BM_CBCMR_GPU3D_AXI_SEL (0x1 << 1) -#define BP_CBCMR_GPU3D_CORE_SEL 4 -#define BM_CBCMR_GPU3D_CORE_SEL (0x3 << 4) -#define BP_CBCMR_GPU3D_SHADER_SEL 8 -#define BM_CBCMR_GPU3D_SHADER_SEL (0x3 << 8) -#define BP_CBCMR_PCIE_AXI_SEL 10 -#define BM_CBCMR_PCIE_AXI_SEL (0x1 << 10) -#define BP_CBCMR_VDO_AXI_SEL 11 -#define BM_CBCMR_VDO_AXI_SEL (0x1 << 11) -#define BP_CBCMR_PERIPH_CLK2_SEL 12 -#define BM_CBCMR_PERIPH_CLK2_SEL (0x3 << 12) -#define BP_CBCMR_VPU_AXI_SEL 14 -#define BM_CBCMR_VPU_AXI_SEL (0x3 << 14) -#define BP_CBCMR_GPU2D_CORE_SEL 16 -#define BM_CBCMR_GPU2D_CORE_SEL (0x3 << 16) -#define BP_CBCMR_PRE_PERIPH_CLK_SEL 18 -#define BM_CBCMR_PRE_PERIPH_CLK_SEL (0x3 << 18) -#define BP_CBCMR_PERIPH2_CLK2_SEL 20 -#define BM_CBCMR_PERIPH2_CLK2_SEL (0x1 << 20) -#define BP_CBCMR_PRE_PERIPH2_CLK_SEL 21 -#define BM_CBCMR_PRE_PERIPH2_CLK_SEL (0x3 << 21) -#define BP_CBCMR_GPU2D_CORE_PODF 23 -#define BM_CBCMR_GPU2D_CORE_PODF (0x7 << 23) -#define BP_CBCMR_GPU3D_CORE_PODF 26 -#define BM_CBCMR_GPU3D_CORE_PODF (0x7 << 26) -#define BP_CBCMR_GPU3D_SHADER_PODF 29 -#define BM_CBCMR_GPU3D_SHADER_PODF (0x7 << 29) - -#define BP_CSCMR1_PERCLK_PODF 0 -#define BM_CSCMR1_PERCLK_PODF (0x3f << 0) -#define BP_CSCMR1_SSI1_SEL 10 -#define BM_CSCMR1_SSI1_SEL (0x3 << 10) -#define BP_CSCMR1_SSI2_SEL 12 -#define BM_CSCMR1_SSI2_SEL (0x3 << 12) -#define BP_CSCMR1_SSI3_SEL 14 -#define BM_CSCMR1_SSI3_SEL (0x3 << 14) -#define BP_CSCMR1_USDHC1_SEL 16 -#define BM_CSCMR1_USDHC1_SEL (0x1 << 16) -#define BP_CSCMR1_USDHC2_SEL 17 -#define BM_CSCMR1_USDHC2_SEL (0x1 << 17) -#define BP_CSCMR1_USDHC3_SEL 18 -#define BM_CSCMR1_USDHC3_SEL (0x1 << 18) -#define BP_CSCMR1_USDHC4_SEL 19 -#define BM_CSCMR1_USDHC4_SEL (0x1 << 19) -#define BP_CSCMR1_EMI_PODF 20 -#define BM_CSCMR1_EMI_PODF (0x7 << 20) -#define BP_CSCMR1_EMI_SLOW_PODF 23 -#define BM_CSCMR1_EMI_SLOW_PODF (0x7 << 23) -#define BP_CSCMR1_EMI_SEL 27 -#define BM_CSCMR1_EMI_SEL (0x3 << 27) -#define BP_CSCMR1_EMI_SLOW_SEL 29 -#define BM_CSCMR1_EMI_SLOW_SEL (0x3 << 29) - -#define BP_CSCMR2_CAN_PODF 2 -#define BM_CSCMR2_CAN_PODF (0x3f << 2) -#define BM_CSCMR2_LDB_DI0_IPU_DIV (0x1 << 10) -#define BM_CSCMR2_LDB_DI1_IPU_DIV (0x1 << 11) -#define BP_CSCMR2_ESAI_SEL 19 -#define BM_CSCMR2_ESAI_SEL (0x3 << 19) - -#define BP_CSCDR1_UART_PODF 0 -#define BM_CSCDR1_UART_PODF (0x3f << 0) -#define BP_CSCDR1_USDHC1_PODF 11 -#define BM_CSCDR1_USDHC1_PODF (0x7 << 11) -#define BP_CSCDR1_USDHC2_PODF 16 -#define BM_CSCDR1_USDHC2_PODF (0x7 << 16) -#define BP_CSCDR1_USDHC3_PODF 19 -#define BM_CSCDR1_USDHC3_PODF (0x7 << 19) -#define BP_CSCDR1_USDHC4_PODF 22 -#define BM_CSCDR1_USDHC4_PODF (0x7 << 22) -#define BP_CSCDR1_VPU_AXI_PODF 25 -#define BM_CSCDR1_VPU_AXI_PODF (0x7 << 25) - -#define BP_CS1CDR_SSI1_PODF 0 -#define BM_CS1CDR_SSI1_PODF (0x3f << 0) -#define BP_CS1CDR_SSI1_PRED 6 -#define BM_CS1CDR_SSI1_PRED (0x7 << 6) -#define BP_CS1CDR_ESAI_PRED 9 -#define BM_CS1CDR_ESAI_PRED (0x7 << 9) -#define BP_CS1CDR_SSI3_PODF 16 -#define BM_CS1CDR_SSI3_PODF (0x3f << 16) -#define BP_CS1CDR_SSI3_PRED 22 -#define BM_CS1CDR_SSI3_PRED (0x7 << 22) -#define BP_CS1CDR_ESAI_PODF 25 -#define BM_CS1CDR_ESAI_PODF (0x7 << 25) - -#define BP_CS2CDR_SSI2_PODF 0 -#define BM_CS2CDR_SSI2_PODF (0x3f << 0) -#define BP_CS2CDR_SSI2_PRED 6 -#define BM_CS2CDR_SSI2_PRED (0x7 << 6) -#define BP_CS2CDR_LDB_DI0_SEL 9 -#define BM_CS2CDR_LDB_DI0_SEL (0x7 << 9) -#define BP_CS2CDR_LDB_DI1_SEL 12 -#define BM_CS2CDR_LDB_DI1_SEL (0x7 << 12) -#define BP_CS2CDR_ENFC_SEL 16 -#define BM_CS2CDR_ENFC_SEL (0x3 << 16) -#define BP_CS2CDR_ENFC_PRED 18 -#define BM_CS2CDR_ENFC_PRED (0x7 << 18) -#define BP_CS2CDR_ENFC_PODF 21 -#define BM_CS2CDR_ENFC_PODF (0x3f << 21) - -#define BP_CDCDR_ASRC_SERIAL_SEL 7 -#define BM_CDCDR_ASRC_SERIAL_SEL (0x3 << 7) -#define BP_CDCDR_ASRC_SERIAL_PODF 9 -#define BM_CDCDR_ASRC_SERIAL_PODF (0x7 << 9) -#define BP_CDCDR_ASRC_SERIAL_PRED 12 -#define BM_CDCDR_ASRC_SERIAL_PRED (0x7 << 12) -#define BP_CDCDR_SPDIF_SEL 20 -#define BM_CDCDR_SPDIF_SEL (0x3 << 20) -#define BP_CDCDR_SPDIF_PODF 22 -#define BM_CDCDR_SPDIF_PODF (0x7 << 22) -#define BP_CDCDR_SPDIF_PRED 25 -#define BM_CDCDR_SPDIF_PRED (0x7 << 25) -#define BP_CDCDR_HSI_TX_PODF 29 -#define BM_CDCDR_HSI_TX_PODF (0x7 << 29) -#define BP_CDCDR_HSI_TX_SEL 28 -#define BM_CDCDR_HSI_TX_SEL (0x1 << 28) - -#define BP_CHSCCDR_IPU1_DI0_SEL 0 -#define BM_CHSCCDR_IPU1_DI0_SEL (0x7 << 0) -#define BP_CHSCCDR_IPU1_DI0_PRE_PODF 3 -#define BM_CHSCCDR_IPU1_DI0_PRE_PODF (0x7 << 3) -#define BP_CHSCCDR_IPU1_DI0_PRE_SEL 6 -#define BM_CHSCCDR_IPU1_DI0_PRE_SEL (0x7 << 6) -#define BP_CHSCCDR_IPU1_DI1_SEL 9 -#define BM_CHSCCDR_IPU1_DI1_SEL (0x7 << 9) -#define BP_CHSCCDR_IPU1_DI1_PRE_PODF 12 -#define BM_CHSCCDR_IPU1_DI1_PRE_PODF (0x7 << 12) -#define BP_CHSCCDR_IPU1_DI1_PRE_SEL 15 -#define BM_CHSCCDR_IPU1_DI1_PRE_SEL (0x7 << 15) - -#define BP_CSCDR2_IPU2_DI0_SEL 0 -#define BM_CSCDR2_IPU2_DI0_SEL (0x7) -#define BP_CSCDR2_IPU2_DI0_PRE_PODF 3 -#define BM_CSCDR2_IPU2_DI0_PRE_PODF (0x7 << 3) -#define BP_CSCDR2_IPU2_DI0_PRE_SEL 6 -#define BM_CSCDR2_IPU2_DI0_PRE_SEL (0x7 << 6) -#define BP_CSCDR2_IPU2_DI1_SEL 9 -#define BM_CSCDR2_IPU2_DI1_SEL (0x7 << 9) -#define BP_CSCDR2_IPU2_DI1_PRE_PODF 12 -#define BM_CSCDR2_IPU2_DI1_PRE_PODF (0x7 << 12) -#define BP_CSCDR2_IPU2_DI1_PRE_SEL 15 -#define BM_CSCDR2_IPU2_DI1_PRE_SEL (0x7 << 15) -#define BP_CSCDR2_ECSPI_CLK_PODF 19 -#define BM_CSCDR2_ECSPI_CLK_PODF (0x3f << 19) - -#define BP_CSCDR3_IPU1_HSP_SEL 9 -#define BM_CSCDR3_IPU1_HSP_SEL (0x3 << 9) -#define BP_CSCDR3_IPU1_HSP_PODF 11 -#define BM_CSCDR3_IPU1_HSP_PODF (0x7 << 11) -#define BP_CSCDR3_IPU2_HSP_SEL 14 -#define BM_CSCDR3_IPU2_HSP_SEL (0x3 << 14) -#define BP_CSCDR3_IPU2_HSP_PODF 16 -#define BM_CSCDR3_IPU2_HSP_PODF (0x7 << 16) - -#define BM_CDHIPR_AXI_PODF_BUSY (0x1 << 0) -#define BM_CDHIPR_AHB_PODF_BUSY (0x1 << 1) -#define BM_CDHIPR_MMDC_CH1_PODF_BUSY (0x1 << 2) -#define BM_CDHIPR_PERIPH2_SEL_BUSY (0x1 << 3) -#define BM_CDHIPR_MMDC_CH0_PODF_BUSY (0x1 << 4) -#define BM_CDHIPR_PERIPH_SEL_BUSY (0x1 << 5) -#define BM_CDHIPR_ARM_PODF_BUSY (0x1 << 16) - -#define BP_CLPCR_LPM 0 -#define BM_CLPCR_LPM (0x3 << 0) -#define BM_CLPCR_BYPASS_PMIC_READY (0x1 << 2) -#define BM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5) -#define BM_CLPCR_SBYOS (0x1 << 6) -#define BM_CLPCR_DIS_REF_OSC (0x1 << 7) -#define BM_CLPCR_VSTBY (0x1 << 8) -#define BP_CLPCR_STBY_COUNT 9 -#define BM_CLPCR_STBY_COUNT (0x3 << 9) -#define BM_CLPCR_COSC_PWRDOWN (0x1 << 11) -#define BM_CLPCR_WB_PER_AT_LPM (0x1 << 16) -#define BM_CLPCR_WB_CORE_AT_LPM (0x1 << 17) -#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS (0x1 << 19) -#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS (0x1 << 21) -#define BM_CLPCR_MASK_CORE0_WFI (0x1 << 22) -#define BM_CLPCR_MASK_CORE1_WFI (0x1 << 23) -#define BM_CLPCR_MASK_CORE2_WFI (0x1 << 24) -#define BM_CLPCR_MASK_CORE3_WFI (0x1 << 25) -#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26) -#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27) - -#define BP_CCOSR_CKO1_EN 7 -#define BP_CCOSR_CKO1_PODF 4 -#define BM_CCOSR_CKO1_PODF (0x7 << 4) -#define BP_CCOSR_CKO1_SEL 0 -#define BM_CCOSR_CKO1_SEL (0xf << 0) - -#define FREQ_480M 480000000 -#define FREQ_528M 528000000 -#define FREQ_594M 594000000 -#define FREQ_650M 650000000 -#define FREQ_1300M 1300000000 - -static struct clk pll1_sys; -static struct clk pll2_bus; -static struct clk pll3_usb_otg; -static struct clk pll4_audio; -static struct clk pll5_video; -static struct clk pll6_mlb; -static struct clk pll7_usb_host; -static struct clk pll8_enet; -static struct clk apbh_dma_clk; -static struct clk arm_clk; -static struct clk ipg_clk; -static struct clk ahb_clk; -static struct clk axi_clk; -static struct clk mmdc_ch0_axi_clk; -static struct clk mmdc_ch1_axi_clk; -static struct clk periph_clk; -static struct clk periph_pre_clk; -static struct clk periph_clk2_clk; -static struct clk periph2_clk; -static struct clk periph2_pre_clk; -static struct clk periph2_clk2_clk; -static struct clk gpu2d_core_clk; -static struct clk gpu3d_core_clk; -static struct clk gpu3d_shader_clk; -static struct clk ipg_perclk; -static struct clk emi_clk; -static struct clk emi_slow_clk; -static struct clk can1_clk; -static struct clk uart_clk; -static struct clk usdhc1_clk; -static struct clk usdhc2_clk; -static struct clk usdhc3_clk; -static struct clk usdhc4_clk; -static struct clk vpu_clk; -static struct clk hsi_tx_clk; -static struct clk ipu1_di0_pre_clk; -static struct clk ipu1_di1_pre_clk; -static struct clk ipu2_di0_pre_clk; -static struct clk ipu2_di1_pre_clk; -static struct clk ipu1_clk; -static struct clk ipu2_clk; -static struct clk ssi1_clk; -static struct clk ssi3_clk; -static struct clk esai_clk; -static struct clk ssi2_clk; -static struct clk spdif_clk; -static struct clk asrc_serial_clk; -static struct clk gpu2d_axi_clk; -static struct clk gpu3d_axi_clk; -static struct clk pcie_clk; -static struct clk vdo_axi_clk; -static struct clk ldb_di0_clk; -static struct clk ldb_di1_clk; -static struct clk ipu1_di0_clk; -static struct clk ipu1_di1_clk; -static struct clk ipu2_di0_clk; -static struct clk ipu2_di1_clk; -static struct clk enfc_clk; -static struct clk cko1_clk; -static struct clk dummy_clk = {}; - -static unsigned long external_high_reference; -static unsigned long external_low_reference; -static unsigned long oscillator_reference; - -static unsigned long get_oscillator_reference_clock_rate(struct clk *clk) -{ - return oscillator_reference; -} - -static unsigned long get_high_reference_clock_rate(struct clk *clk) -{ - return external_high_reference; -} - -static unsigned long get_low_reference_clock_rate(struct clk *clk) -{ - return external_low_reference; -} - -static struct clk ckil_clk = { - .get_rate = get_low_reference_clock_rate, -}; - -static struct clk ckih_clk = { - .get_rate = get_high_reference_clock_rate, -}; - -static struct clk osc_clk = { - .get_rate = get_oscillator_reference_clock_rate, -}; - -static inline void __iomem *pll_get_reg_addr(struct clk *pll) -{ - if (pll == &pll1_sys) - return PLL1_SYS; - else if (pll == &pll2_bus) - return PLL2_BUS; - else if (pll == &pll3_usb_otg) - return PLL3_USB_OTG; - else if (pll == &pll4_audio) - return PLL4_AUDIO; - else if (pll == &pll5_video) - return PLL5_VIDEO; - else if (pll == &pll6_mlb) - return PLL6_MLB; - else if (pll == &pll7_usb_host) - return PLL7_USB_HOST; - else if (pll == &pll8_enet) - return PLL8_ENET; - else - BUG(); - - return NULL; -} - -static int pll_enable(struct clk *clk) -{ - int timeout = 0x100000; - void __iomem *reg; - u32 val; - - reg = pll_get_reg_addr(clk); - val = readl_relaxed(reg); - val &= ~BM_PLL_BYPASS; - val &= ~BM_PLL_POWER_DOWN; - /* 480MHz PLLs have the opposite definition for power bit */ - if (clk == &pll3_usb_otg || clk == &pll7_usb_host) - val |= BM_PLL_POWER_DOWN; - writel_relaxed(val, reg); - - /* Wait for PLL to lock */ - while (!(readl_relaxed(reg) & BM_PLL_LOCK) && --timeout) - cpu_relax(); - - if (unlikely(!timeout)) - return -EBUSY; - - /* Enable the PLL output now */ - val = readl_relaxed(reg); - val |= BM_PLL_ENABLE; - writel_relaxed(val, reg); - - return 0; -} - -static void pll_disable(struct clk *clk) -{ - void __iomem *reg; - u32 val; - - reg = pll_get_reg_addr(clk); - val = readl_relaxed(reg); - val &= ~BM_PLL_ENABLE; - val |= BM_PLL_BYPASS; - val |= BM_PLL_POWER_DOWN; - if (clk == &pll3_usb_otg || clk == &pll7_usb_host) - val &= ~BM_PLL_POWER_DOWN; - writel_relaxed(val, reg); -} - -static unsigned long pll1_sys_get_rate(struct clk *clk) -{ - u32 div = (readl_relaxed(PLL1_SYS) & BM_PLL_SYS_DIV_SELECT) >> - BP_PLL_SYS_DIV_SELECT; - - return clk_get_rate(clk->parent) * div / 2; -} - -static int pll1_sys_set_rate(struct clk *clk, unsigned long rate) -{ - u32 val, div; - - if (rate < FREQ_650M || rate > FREQ_1300M) - return -EINVAL; - - div = rate * 2 / clk_get_rate(clk->parent); - val = readl_relaxed(PLL1_SYS); - val &= ~BM_PLL_SYS_DIV_SELECT; - val |= div << BP_PLL_SYS_DIV_SELECT; - writel_relaxed(val, PLL1_SYS); - - return 0; -} - -static unsigned long pll8_enet_get_rate(struct clk *clk) -{ - u32 div = (readl_relaxed(PLL8_ENET) & BM_PLL_ENET_DIV_SELECT) >> - BP_PLL_ENET_DIV_SELECT; - - switch (div) { - case 0: - return 25000000; - case 1: - return 50000000; - case 2: - return 100000000; - case 3: - return 125000000; - } - - return 0; -} - -static int pll8_enet_set_rate(struct clk *clk, unsigned long rate) -{ - u32 val, div; - - switch (rate) { - case 25000000: - div = 0; - break; - case 50000000: - div = 1; - break; - case 100000000: - div = 2; - break; - case 125000000: - div = 3; - break; - default: - return -EINVAL; - } - - val = readl_relaxed(PLL8_ENET); - val &= ~BM_PLL_ENET_DIV_SELECT; - val |= div << BP_PLL_ENET_DIV_SELECT; - writel_relaxed(val, PLL8_ENET); - - return 0; -} - -static unsigned long pll_av_get_rate(struct clk *clk) -{ - void __iomem *reg = (clk == &pll4_audio) ? PLL4_AUDIO : PLL5_VIDEO; - unsigned long parent_rate = clk_get_rate(clk->parent); - u32 mfn = readl_relaxed(reg + PLL_NUM_OFFSET); - u32 mfd = readl_relaxed(reg + PLL_DENOM_OFFSET); - u32 div = (readl_relaxed(reg) & BM_PLL_AV_DIV_SELECT) >> - BP_PLL_AV_DIV_SELECT; - - return (parent_rate * div) + ((parent_rate / mfd) * mfn); -} - -static int pll_av_set_rate(struct clk *clk, unsigned long rate) -{ - void __iomem *reg = (clk == &pll4_audio) ? PLL4_AUDIO : PLL5_VIDEO; - unsigned int parent_rate = clk_get_rate(clk->parent); - u32 val, div; - u32 mfn, mfd = 1000000; - s64 temp64; - - if (rate < FREQ_650M || rate > FREQ_1300M) - return -EINVAL; - - div = rate / parent_rate; - temp64 = (u64) (rate - div * parent_rate); - temp64 *= mfd; - do_div(temp64, parent_rate); - mfn = temp64; - - val = readl_relaxed(reg); - val &= ~BM_PLL_AV_DIV_SELECT; - val |= div << BP_PLL_AV_DIV_SELECT; - writel_relaxed(val, reg); - writel_relaxed(mfn, reg + PLL_NUM_OFFSET); - writel_relaxed(mfd, reg + PLL_DENOM_OFFSET); - - return 0; -} - -static void __iomem *pll_get_div_reg_bit(struct clk *clk, u32 *bp, u32 *bm) -{ - void __iomem *reg; - - if (clk == &pll2_bus) { - reg = PLL2_BUS; - *bp = BP_PLL_BUS_DIV_SELECT; - *bm = BM_PLL_BUS_DIV_SELECT; - } else if (clk == &pll3_usb_otg) { - reg = PLL3_USB_OTG; - *bp = BP_PLL_USB_DIV_SELECT; - *bm = BM_PLL_USB_DIV_SELECT; - } else if (clk == &pll7_usb_host) { - reg = PLL7_USB_HOST; - *bp = BP_PLL_USB_DIV_SELECT; - *bm = BM_PLL_USB_DIV_SELECT; - } else { - BUG(); - } - - return reg; -} - -static unsigned long pll_get_rate(struct clk *clk) -{ - void __iomem *reg; - u32 div, bp, bm; - - reg = pll_get_div_reg_bit(clk, &bp, &bm); - div = (readl_relaxed(reg) & bm) >> bp; - - return (div == 1) ? clk_get_rate(clk->parent) * 22 : - clk_get_rate(clk->parent) * 20; -} - -static int pll_set_rate(struct clk *clk, unsigned long rate) -{ - void __iomem *reg; - u32 val, div, bp, bm; - - if (rate == FREQ_528M) - div = 1; - else if (rate == FREQ_480M) - div = 0; - else - return -EINVAL; - - reg = pll_get_div_reg_bit(clk, &bp, &bm); - val = readl_relaxed(reg); - val &= ~bm; - val |= div << bp; - writel_relaxed(val, reg); - - return 0; -} - -#define pll2_bus_get_rate pll_get_rate -#define pll2_bus_set_rate pll_set_rate -#define pll3_usb_otg_get_rate pll_get_rate -#define pll3_usb_otg_set_rate pll_set_rate -#define pll7_usb_host_get_rate pll_get_rate -#define pll7_usb_host_set_rate pll_set_rate -#define pll4_audio_get_rate pll_av_get_rate -#define pll4_audio_set_rate pll_av_set_rate -#define pll5_video_get_rate pll_av_get_rate -#define pll5_video_set_rate pll_av_set_rate -#define pll6_mlb_get_rate NULL -#define pll6_mlb_set_rate NULL - -#define DEF_PLL(name) \ - static struct clk name = { \ - .enable = pll_enable, \ - .disable = pll_disable, \ - .get_rate = name##_get_rate, \ - .set_rate = name##_set_rate, \ - .parent = &osc_clk, \ - } - -DEF_PLL(pll1_sys); -DEF_PLL(pll2_bus); -DEF_PLL(pll3_usb_otg); -DEF_PLL(pll4_audio); -DEF_PLL(pll5_video); -DEF_PLL(pll6_mlb); -DEF_PLL(pll7_usb_host); -DEF_PLL(pll8_enet); - -static unsigned long pfd_get_rate(struct clk *clk) -{ - u64 tmp = (u64) clk_get_rate(clk->parent) * 18; - u32 frac, bp_frac; - - if (apbh_dma_clk.usecount == 0) - apbh_dma_clk.enable(&apbh_dma_clk); - - bp_frac = clk->enable_shift - 7; - frac = readl_relaxed(clk->enable_reg) >> bp_frac & PFD_FRAC_MASK; - do_div(tmp, frac); - - return tmp; -} - -static int pfd_set_rate(struct clk *clk, unsigned long rate) -{ - u32 val, frac, bp_frac; - u64 tmp = (u64) clk_get_rate(clk->parent) * 18; - - if (apbh_dma_clk.usecount == 0) - apbh_dma_clk.enable(&apbh_dma_clk); - - /* - * Round up the divider so that we don't set a rate - * higher than what is requested - */ - tmp += rate / 2; - do_div(tmp, rate); - frac = tmp; - frac = (frac < 12) ? 12 : frac; - frac = (frac > 35) ? 35 : frac; - - /* - * The frac field always starts from 7 bits lower - * position of enable bit - */ - bp_frac = clk->enable_shift - 7; - val = readl_relaxed(clk->enable_reg); - val &= ~(PFD_FRAC_MASK << bp_frac); - val |= frac << bp_frac; - writel_relaxed(val, clk->enable_reg); - - tmp = (u64) clk_get_rate(clk->parent) * 18; - do_div(tmp, frac); - - if (apbh_dma_clk.usecount == 0) - apbh_dma_clk.disable(&apbh_dma_clk); - - return 0; -} - -static unsigned long pfd_round_rate(struct clk *clk, unsigned long rate) -{ - u32 frac; - u64 tmp; - - tmp = (u64) clk_get_rate(clk->parent) * 18; - tmp += rate / 2; - do_div(tmp, rate); - frac = tmp; - frac = (frac < 12) ? 12 : frac; - frac = (frac > 35) ? 35 : frac; - tmp = (u64) clk_get_rate(clk->parent) * 18; - do_div(tmp, frac); - - return tmp; -} - -static int pfd_enable(struct clk *clk) -{ - u32 val; - - if (apbh_dma_clk.usecount == 0) - apbh_dma_clk.enable(&apbh_dma_clk); - - val = readl_relaxed(clk->enable_reg); - val &= ~(1 << clk->enable_shift); - writel_relaxed(val, clk->enable_reg); - - if (apbh_dma_clk.usecount == 0) - apbh_dma_clk.disable(&apbh_dma_clk); - - return 0; -} - -static void pfd_disable(struct clk *clk) -{ - u32 val; - - if (apbh_dma_clk.usecount == 0) - apbh_dma_clk.enable(&apbh_dma_clk); - - val = readl_relaxed(clk->enable_reg); - val |= 1 << clk->enable_shift; - writel_relaxed(val, clk->enable_reg); - - if (apbh_dma_clk.usecount == 0) - apbh_dma_clk.disable(&apbh_dma_clk); -} - -#define DEF_PFD(name, er, es, p) \ - static struct clk name = { \ - .enable_reg = er, \ - .enable_shift = es, \ - .enable = pfd_enable, \ - .disable = pfd_disable, \ - .get_rate = pfd_get_rate, \ - .set_rate = pfd_set_rate, \ - .round_rate = pfd_round_rate, \ - .parent = p, \ - } - -DEF_PFD(pll2_pfd_352m, PFD_528, PFD0, &pll2_bus); -DEF_PFD(pll2_pfd_594m, PFD_528, PFD1, &pll2_bus); -DEF_PFD(pll2_pfd_400m, PFD_528, PFD2, &pll2_bus); -DEF_PFD(pll3_pfd_720m, PFD_480, PFD0, &pll3_usb_otg); -DEF_PFD(pll3_pfd_540m, PFD_480, PFD1, &pll3_usb_otg); -DEF_PFD(pll3_pfd_508m, PFD_480, PFD2, &pll3_usb_otg); -DEF_PFD(pll3_pfd_454m, PFD_480, PFD3, &pll3_usb_otg); - -static unsigned long twd_clk_get_rate(struct clk *clk) -{ - return clk_get_rate(clk->parent) / 2; -} - -static struct clk twd_clk = { - .parent = &arm_clk, - .get_rate = twd_clk_get_rate, -}; - -static unsigned long pll2_200m_get_rate(struct clk *clk) -{ - return clk_get_rate(clk->parent) / 2; -} - -static struct clk pll2_200m = { - .parent = &pll2_pfd_400m, - .get_rate = pll2_200m_get_rate, -}; - -static unsigned long pll3_120m_get_rate(struct clk *clk) -{ - return clk_get_rate(clk->parent) / 4; -} - -static struct clk pll3_120m = { - .parent = &pll3_usb_otg, - .get_rate = pll3_120m_get_rate, -}; - -static unsigned long pll3_80m_get_rate(struct clk *clk) -{ - return clk_get_rate(clk->parent) / 6; -} - -static struct clk pll3_80m = { - .parent = &pll3_usb_otg, - .get_rate = pll3_80m_get_rate, -}; - -static unsigned long pll3_60m_get_rate(struct clk *clk) -{ - return clk_get_rate(clk->parent) / 8; -} - -static struct clk pll3_60m = { - .parent = &pll3_usb_otg, - .get_rate = pll3_60m_get_rate, -}; - -static int pll1_sw_clk_set_parent(struct clk *clk, struct clk *parent) -{ - u32 val = readl_relaxed(CCSR); - - if (parent == &pll1_sys) { - val &= ~BM_CCSR_PLL1_SW_SEL; - val &= ~BM_CCSR_STEP_SEL; - } else if (parent == &osc_clk) { - val |= BM_CCSR_PLL1_SW_SEL; - val &= ~BM_CCSR_STEP_SEL; - } else if (parent == &pll2_pfd_400m) { - val |= BM_CCSR_PLL1_SW_SEL; - val |= BM_CCSR_STEP_SEL; - } else { - return -EINVAL; - } - - writel_relaxed(val, CCSR); - - return 0; -} - -static struct clk pll1_sw_clk = { - .parent = &pll1_sys, - .set_parent = pll1_sw_clk_set_parent, -}; - -static void calc_pred_podf_dividers(u32 div, u32 *pred, u32 *podf) -{ - u32 min_pred, temp_pred, old_err, err; - - if (div >= 512) { - *pred = 8; - *podf = 64; - } else if (div >= 8) { - min_pred = (div - 1) / 64 + 1; - old_err = 8; - for (temp_pred = 8; temp_pred >= min_pred; temp_pred--) { - err = div % temp_pred; - if (err == 0) { - *pred = temp_pred; - break; - } - err = temp_pred - err; - if (err < old_err) { - old_err = err; - *pred = temp_pred; - } - } - *podf = (div + *pred - 1) / *pred; - } else if (div < 8) { - *pred = div; - *podf = 1; - } -} - -static int _clk_enable(struct clk *clk) -{ - u32 reg; - reg = readl_relaxed(clk->enable_reg); - reg |= 0x3 << clk->enable_shift; - writel_relaxed(reg, clk->enable_reg); - - return 0; -} - -static void _clk_disable(struct clk *clk) -{ - u32 reg; - reg = readl_relaxed(clk->enable_reg); - reg &= ~(0x3 << clk->enable_shift); - writel_relaxed(reg, clk->enable_reg); -} - -static int _clk_enable_1b(struct clk *clk) -{ - u32 reg; - reg = readl_relaxed(clk->enable_reg); - reg |= 0x1 << clk->enable_shift; - writel_relaxed(reg, clk->enable_reg); - - return 0; -} - -static void _clk_disable_1b(struct clk *clk) -{ - u32 reg; - reg = readl_relaxed(clk->enable_reg); - reg &= ~(0x1 << clk->enable_shift); - writel_relaxed(reg, clk->enable_reg); -} - -struct divider { - struct clk *clk; - void __iomem *reg; - u32 bp_pred; - u32 bm_pred; - u32 bp_podf; - u32 bm_podf; -}; - -#define DEF_CLK_DIV1(d, c, r, b) \ - static struct divider d = { \ - .clk = c, \ - .reg = r, \ - .bp_podf = BP_##r##_##b##_PODF, \ - .bm_podf = BM_##r##_##b##_PODF, \ - } - -DEF_CLK_DIV1(arm_div, &arm_clk, CACRR, ARM); -DEF_CLK_DIV1(ipg_div, &ipg_clk, CBCDR, IPG); -DEF_CLK_DIV1(ahb_div, &ahb_clk, CBCDR, AHB); -DEF_CLK_DIV1(axi_div, &axi_clk, CBCDR, AXI); -DEF_CLK_DIV1(mmdc_ch0_axi_div, &mmdc_ch0_axi_clk, CBCDR, MMDC_CH0_AXI); -DEF_CLK_DIV1(mmdc_ch1_axi_div, &mmdc_ch1_axi_clk, CBCDR, MMDC_CH1_AXI); -DEF_CLK_DIV1(periph_clk2_div, &periph_clk2_clk, CBCDR, PERIPH_CLK2); -DEF_CLK_DIV1(periph2_clk2_div, &periph2_clk2_clk, CBCDR, PERIPH2_CLK2); -DEF_CLK_DIV1(gpu2d_core_div, &gpu2d_core_clk, CBCMR, GPU2D_CORE); -DEF_CLK_DIV1(gpu3d_core_div, &gpu3d_core_clk, CBCMR, GPU3D_CORE); -DEF_CLK_DIV1(gpu3d_shader_div, &gpu3d_shader_clk, CBCMR, GPU3D_SHADER); -DEF_CLK_DIV1(ipg_perclk_div, &ipg_perclk, CSCMR1, PERCLK); -DEF_CLK_DIV1(emi_div, &emi_clk, CSCMR1, EMI); -DEF_CLK_DIV1(emi_slow_div, &emi_slow_clk, CSCMR1, EMI_SLOW); -DEF_CLK_DIV1(can_div, &can1_clk, CSCMR2, CAN); -DEF_CLK_DIV1(uart_div, &uart_clk, CSCDR1, UART); -DEF_CLK_DIV1(usdhc1_div, &usdhc1_clk, CSCDR1, USDHC1); -DEF_CLK_DIV1(usdhc2_div, &usdhc2_clk, CSCDR1, USDHC2); -DEF_CLK_DIV1(usdhc3_div, &usdhc3_clk, CSCDR1, USDHC3); -DEF_CLK_DIV1(usdhc4_div, &usdhc4_clk, CSCDR1, USDHC4); -DEF_CLK_DIV1(vpu_div, &vpu_clk, CSCDR1, VPU_AXI); -DEF_CLK_DIV1(hsi_tx_div, &hsi_tx_clk, CDCDR, HSI_TX); -DEF_CLK_DIV1(ipu1_di0_pre_div, &ipu1_di0_pre_clk, CHSCCDR, IPU1_DI0_PRE); -DEF_CLK_DIV1(ipu1_di1_pre_div, &ipu1_di1_pre_clk, CHSCCDR, IPU1_DI1_PRE); -DEF_CLK_DIV1(ipu2_di0_pre_div, &ipu2_di0_pre_clk, CSCDR2, IPU2_DI0_PRE); -DEF_CLK_DIV1(ipu2_di1_pre_div, &ipu2_di1_pre_clk, CSCDR2, IPU2_DI1_PRE); -DEF_CLK_DIV1(ipu1_div, &ipu1_clk, CSCDR3, IPU1_HSP); -DEF_CLK_DIV1(ipu2_div, &ipu2_clk, CSCDR3, IPU2_HSP); -DEF_CLK_DIV1(cko1_div, &cko1_clk, CCOSR, CKO1); - -#define DEF_CLK_DIV2(d, c, r, b) \ - static struct divider d = { \ - .clk = c, \ - .reg = r, \ - .bp_pred = BP_##r##_##b##_PRED, \ - .bm_pred = BM_##r##_##b##_PRED, \ - .bp_podf = BP_##r##_##b##_PODF, \ - .bm_podf = BM_##r##_##b##_PODF, \ - } - -DEF_CLK_DIV2(ssi1_div, &ssi1_clk, CS1CDR, SSI1); -DEF_CLK_DIV2(ssi3_div, &ssi3_clk, CS1CDR, SSI3); -DEF_CLK_DIV2(esai_div, &esai_clk, CS1CDR, ESAI); -DEF_CLK_DIV2(ssi2_div, &ssi2_clk, CS2CDR, SSI2); -DEF_CLK_DIV2(enfc_div, &enfc_clk, CS2CDR, ENFC); -DEF_CLK_DIV2(spdif_div, &spdif_clk, CDCDR, SPDIF); -DEF_CLK_DIV2(asrc_serial_div, &asrc_serial_clk, CDCDR, ASRC_SERIAL); - -static struct divider *dividers[] = { - &arm_div, - &ipg_div, - &ahb_div, - &axi_div, - &mmdc_ch0_axi_div, - &mmdc_ch1_axi_div, - &periph_clk2_div, - &periph2_clk2_div, - &gpu2d_core_div, - &gpu3d_core_div, - &gpu3d_shader_div, - &ipg_perclk_div, - &emi_div, - &emi_slow_div, - &can_div, - &uart_div, - &usdhc1_div, - &usdhc2_div, - &usdhc3_div, - &usdhc4_div, - &vpu_div, - &hsi_tx_div, - &ipu1_di0_pre_div, - &ipu1_di1_pre_div, - &ipu2_di0_pre_div, - &ipu2_di1_pre_div, - &ipu1_div, - &ipu2_div, - &ssi1_div, - &ssi3_div, - &esai_div, - &ssi2_div, - &enfc_div, - &spdif_div, - &asrc_serial_div, - &cko1_div, -}; - -static unsigned long ldb_di_clk_get_rate(struct clk *clk) -{ - u32 val = readl_relaxed(CSCMR2); - - val &= (clk == &ldb_di0_clk) ? BM_CSCMR2_LDB_DI0_IPU_DIV : - BM_CSCMR2_LDB_DI1_IPU_DIV; - if (val) - return clk_get_rate(clk->parent) / 7; - else - return clk_get_rate(clk->parent) * 2 / 7; -} - -static int ldb_di_clk_set_rate(struct clk *clk, unsigned long rate) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - u32 val = readl_relaxed(CSCMR2); - - if (rate * 7 <= parent_rate + parent_rate / 20) - val |= BM_CSCMR2_LDB_DI0_IPU_DIV; - else - val &= ~BM_CSCMR2_LDB_DI0_IPU_DIV; - - writel_relaxed(val, CSCMR2); - - return 0; -} - -static unsigned long ldb_di_clk_round_rate(struct clk *clk, unsigned long rate) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - - if (rate * 7 <= parent_rate + parent_rate / 20) - return parent_rate / 7; - else - return 2 * parent_rate / 7; -} - -static unsigned long _clk_get_rate(struct clk *clk) -{ - struct divider *d; - u32 val, pred, podf; - int i, num; - - if (clk == &ldb_di0_clk || clk == &ldb_di1_clk) - return ldb_di_clk_get_rate(clk); - - num = ARRAY_SIZE(dividers); - for (i = 0; i < num; i++) - if (dividers[i]->clk == clk) { - d = dividers[i]; - break; - } - if (i == num) - return clk_get_rate(clk->parent); - - val = readl_relaxed(d->reg); - pred = ((val & d->bm_pred) >> d->bp_pred) + 1; - podf = ((val & d->bm_podf) >> d->bp_podf) + 1; - - return clk_get_rate(clk->parent) / (pred * podf); -} - -static int clk_busy_wait(struct clk *clk) -{ - int timeout = 0x100000; - u32 bm; - - if (clk == &axi_clk) - bm = BM_CDHIPR_AXI_PODF_BUSY; - else if (clk == &ahb_clk) - bm = BM_CDHIPR_AHB_PODF_BUSY; - else if (clk == &mmdc_ch0_axi_clk) - bm = BM_CDHIPR_MMDC_CH0_PODF_BUSY; - else if (clk == &periph_clk) - bm = BM_CDHIPR_PERIPH_SEL_BUSY; - else if (clk == &arm_clk) - bm = BM_CDHIPR_ARM_PODF_BUSY; - else - return -EINVAL; - - while ((readl_relaxed(CDHIPR) & bm) && --timeout) - cpu_relax(); - - if (unlikely(!timeout)) - return -EBUSY; - - return 0; -} - -static int _clk_set_rate(struct clk *clk, unsigned long rate) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - struct divider *d; - u32 val, div, max_div, pred = 0, podf; - int i, num; - - if (clk == &ldb_di0_clk || clk == &ldb_di1_clk) - return ldb_di_clk_set_rate(clk, rate); - - num = ARRAY_SIZE(dividers); - for (i = 0; i < num; i++) - if (dividers[i]->clk == clk) { - d = dividers[i]; - break; - } - if (i == num) - return -EINVAL; - - max_div = ((d->bm_pred >> d->bp_pred) + 1) * - ((d->bm_podf >> d->bp_podf) + 1); - - div = parent_rate / rate; - if (div == 0) - div++; - - if ((parent_rate / div != rate) || div > max_div) - return -EINVAL; - - if (d->bm_pred) { - calc_pred_podf_dividers(div, &pred, &podf); - } else { - pred = 1; - podf = div; - } - - val = readl_relaxed(d->reg); - val &= ~(d->bm_pred | d->bm_podf); - val |= (pred - 1) << d->bp_pred | (podf - 1) << d->bp_podf; - writel_relaxed(val, d->reg); - - if (clk == &axi_clk || clk == &ahb_clk || - clk == &mmdc_ch0_axi_clk || clk == &arm_clk) - return clk_busy_wait(clk); - - return 0; -} - -static unsigned long _clk_round_rate(struct clk *clk, unsigned long rate) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - u32 div = parent_rate / rate; - u32 div_max, pred = 0, podf; - struct divider *d; - int i, num; - - if (clk == &ldb_di0_clk || clk == &ldb_di1_clk) - return ldb_di_clk_round_rate(clk, rate); - - num = ARRAY_SIZE(dividers); - for (i = 0; i < num; i++) - if (dividers[i]->clk == clk) { - d = dividers[i]; - break; - } - if (i == num) - return -EINVAL; - - if (div == 0 || parent_rate % rate) - div++; - - if (d->bm_pred) { - calc_pred_podf_dividers(div, &pred, &podf); - div = pred * podf; - } else { - div_max = (d->bm_podf >> d->bp_podf) + 1; - if (div > div_max) - div = div_max; - } - - return parent_rate / div; -} - -struct multiplexer { - struct clk *clk; - void __iomem *reg; - u32 bp; - u32 bm; - int pnum; - struct clk *parents[]; -}; - -static struct multiplexer axi_mux = { - .clk = &axi_clk, - .reg = CBCDR, - .bp = BP_CBCDR_AXI_SEL, - .bm = BM_CBCDR_AXI_SEL, - .parents = { - &periph_clk, - &pll2_pfd_400m, - &pll3_pfd_540m, - NULL - }, -}; - -static struct multiplexer periph_mux = { - .clk = &periph_clk, - .reg = CBCDR, - .bp = BP_CBCDR_PERIPH_CLK_SEL, - .bm = BM_CBCDR_PERIPH_CLK_SEL, - .parents = { - &periph_pre_clk, - &periph_clk2_clk, - NULL - }, -}; - -static struct multiplexer periph_pre_mux = { - .clk = &periph_pre_clk, - .reg = CBCMR, - .bp = BP_CBCMR_PRE_PERIPH_CLK_SEL, - .bm = BM_CBCMR_PRE_PERIPH_CLK_SEL, - .parents = { - &pll2_bus, - &pll2_pfd_400m, - &pll2_pfd_352m, - &pll2_200m, - NULL - }, -}; - -static struct multiplexer periph_clk2_mux = { - .clk = &periph_clk2_clk, - .reg = CBCMR, - .bp = BP_CBCMR_PERIPH_CLK2_SEL, - .bm = BM_CBCMR_PERIPH_CLK2_SEL, - .parents = { - &pll3_usb_otg, - &osc_clk, - NULL - }, -}; - -static struct multiplexer periph2_mux = { - .clk = &periph2_clk, - .reg = CBCDR, - .bp = BP_CBCDR_PERIPH2_CLK_SEL, - .bm = BM_CBCDR_PERIPH2_CLK_SEL, - .parents = { - &periph2_pre_clk, - &periph2_clk2_clk, - NULL - }, -}; - -static struct multiplexer periph2_pre_mux = { - .clk = &periph2_pre_clk, - .reg = CBCMR, - .bp = BP_CBCMR_PRE_PERIPH2_CLK_SEL, - .bm = BM_CBCMR_PRE_PERIPH2_CLK_SEL, - .parents = { - &pll2_bus, - &pll2_pfd_400m, - &pll2_pfd_352m, - &pll2_200m, - NULL - }, -}; - -static struct multiplexer periph2_clk2_mux = { - .clk = &periph2_clk2_clk, - .reg = CBCMR, - .bp = BP_CBCMR_PERIPH2_CLK2_SEL, - .bm = BM_CBCMR_PERIPH2_CLK2_SEL, - .parents = { - &pll3_usb_otg, - &osc_clk, - NULL - }, -}; - -static struct multiplexer gpu2d_axi_mux = { - .clk = &gpu2d_axi_clk, - .reg = CBCMR, - .bp = BP_CBCMR_GPU2D_AXI_SEL, - .bm = BM_CBCMR_GPU2D_AXI_SEL, - .parents = { - &axi_clk, - &ahb_clk, - NULL - }, -}; - -static struct multiplexer gpu3d_axi_mux = { - .clk = &gpu3d_axi_clk, - .reg = CBCMR, - .bp = BP_CBCMR_GPU3D_AXI_SEL, - .bm = BM_CBCMR_GPU3D_AXI_SEL, - .parents = { - &axi_clk, - &ahb_clk, - NULL - }, -}; - -static struct multiplexer gpu3d_core_mux = { - .clk = &gpu3d_core_clk, - .reg = CBCMR, - .bp = BP_CBCMR_GPU3D_CORE_SEL, - .bm = BM_CBCMR_GPU3D_CORE_SEL, - .parents = { - &mmdc_ch0_axi_clk, - &pll3_usb_otg, - &pll2_pfd_594m, - &pll2_pfd_400m, - NULL - }, -}; - -static struct multiplexer gpu3d_shader_mux = { - .clk = &gpu3d_shader_clk, - .reg = CBCMR, - .bp = BP_CBCMR_GPU3D_SHADER_SEL, - .bm = BM_CBCMR_GPU3D_SHADER_SEL, - .parents = { - &mmdc_ch0_axi_clk, - &pll3_usb_otg, - &pll2_pfd_594m, - &pll3_pfd_720m, - NULL - }, -}; - -static struct multiplexer pcie_axi_mux = { - .clk = &pcie_clk, - .reg = CBCMR, - .bp = BP_CBCMR_PCIE_AXI_SEL, - .bm = BM_CBCMR_PCIE_AXI_SEL, - .parents = { - &axi_clk, - &ahb_clk, - NULL - }, -}; - -static struct multiplexer vdo_axi_mux = { - .clk = &vdo_axi_clk, - .reg = CBCMR, - .bp = BP_CBCMR_VDO_AXI_SEL, - .bm = BM_CBCMR_VDO_AXI_SEL, - .parents = { - &axi_clk, - &ahb_clk, - NULL - }, -}; - -static struct multiplexer vpu_axi_mux = { - .clk = &vpu_clk, - .reg = CBCMR, - .bp = BP_CBCMR_VPU_AXI_SEL, - .bm = BM_CBCMR_VPU_AXI_SEL, - .parents = { - &axi_clk, - &pll2_pfd_400m, - &pll2_pfd_352m, - NULL - }, -}; - -static struct multiplexer gpu2d_core_mux = { - .clk = &gpu2d_core_clk, - .reg = CBCMR, - .bp = BP_CBCMR_GPU2D_CORE_SEL, - .bm = BM_CBCMR_GPU2D_CORE_SEL, - .parents = { - &axi_clk, - &pll3_usb_otg, - &pll2_pfd_352m, - &pll2_pfd_400m, - NULL - }, -}; - -#define DEF_SSI_MUX(id) \ - static struct multiplexer ssi##id##_mux = { \ - .clk = &ssi##id##_clk, \ - .reg = CSCMR1, \ - .bp = BP_CSCMR1_SSI##id##_SEL, \ - .bm = BM_CSCMR1_SSI##id##_SEL, \ - .parents = { \ - &pll3_pfd_508m, \ - &pll3_pfd_454m, \ - &pll4_audio, \ - NULL \ - }, \ - } - -DEF_SSI_MUX(1); -DEF_SSI_MUX(2); -DEF_SSI_MUX(3); - -#define DEF_USDHC_MUX(id) \ - static struct multiplexer usdhc##id##_mux = { \ - .clk = &usdhc##id##_clk, \ - .reg = CSCMR1, \ - .bp = BP_CSCMR1_USDHC##id##_SEL, \ - .bm = BM_CSCMR1_USDHC##id##_SEL, \ - .parents = { \ - &pll2_pfd_400m, \ - &pll2_pfd_352m, \ - NULL \ - }, \ - } - -DEF_USDHC_MUX(1); -DEF_USDHC_MUX(2); -DEF_USDHC_MUX(3); -DEF_USDHC_MUX(4); - -static struct multiplexer emi_mux = { - .clk = &emi_clk, - .reg = CSCMR1, - .bp = BP_CSCMR1_EMI_SEL, - .bm = BM_CSCMR1_EMI_SEL, - .parents = { - &axi_clk, - &pll3_usb_otg, - &pll2_pfd_400m, - &pll2_pfd_352m, - NULL - }, -}; - -static struct multiplexer emi_slow_mux = { - .clk = &emi_slow_clk, - .reg = CSCMR1, - .bp = BP_CSCMR1_EMI_SLOW_SEL, - .bm = BM_CSCMR1_EMI_SLOW_SEL, - .parents = { - &axi_clk, - &pll3_usb_otg, - &pll2_pfd_400m, - &pll2_pfd_352m, - NULL - }, -}; - -static struct multiplexer esai_mux = { - .clk = &esai_clk, - .reg = CSCMR2, - .bp = BP_CSCMR2_ESAI_SEL, - .bm = BM_CSCMR2_ESAI_SEL, - .parents = { - &pll4_audio, - &pll3_pfd_508m, - &pll3_pfd_454m, - &pll3_usb_otg, - NULL - }, -}; - -#define DEF_LDB_DI_MUX(id) \ - static struct multiplexer ldb_di##id##_mux = { \ - .clk = &ldb_di##id##_clk, \ - .reg = CS2CDR, \ - .bp = BP_CS2CDR_LDB_DI##id##_SEL, \ - .bm = BM_CS2CDR_LDB_DI##id##_SEL, \ - .parents = { \ - &pll5_video, \ - &pll2_pfd_352m, \ - &pll2_pfd_400m, \ - &pll3_pfd_540m, \ - &pll3_usb_otg, \ - NULL \ - }, \ - } - -DEF_LDB_DI_MUX(0); -DEF_LDB_DI_MUX(1); - -static struct multiplexer enfc_mux = { - .clk = &enfc_clk, - .reg = CS2CDR, - .bp = BP_CS2CDR_ENFC_SEL, - .bm = BM_CS2CDR_ENFC_SEL, - .parents = { - &pll2_pfd_352m, - &pll2_bus, - &pll3_usb_otg, - &pll2_pfd_400m, - NULL - }, -}; - -static struct multiplexer spdif_mux = { - .clk = &spdif_clk, - .reg = CDCDR, - .bp = BP_CDCDR_SPDIF_SEL, - .bm = BM_CDCDR_SPDIF_SEL, - .parents = { - &pll4_audio, - &pll3_pfd_508m, - &pll3_pfd_454m, - &pll3_usb_otg, - NULL - }, -}; - -static struct multiplexer asrc_serial_mux = { - .clk = &asrc_serial_clk, - .reg = CDCDR, - .bp = BP_CDCDR_ASRC_SERIAL_SEL, - .bm = BM_CDCDR_ASRC_SERIAL_SEL, - .parents = { - &pll4_audio, - &pll3_pfd_508m, - &pll3_pfd_454m, - &pll3_usb_otg, - NULL - }, -}; - -static struct multiplexer hsi_tx_mux = { - .clk = &hsi_tx_clk, - .reg = CDCDR, - .bp = BP_CDCDR_HSI_TX_SEL, - .bm = BM_CDCDR_HSI_TX_SEL, - .parents = { - &pll3_120m, - &pll2_pfd_400m, - NULL - }, -}; - -#define DEF_IPU_DI_PRE_MUX(r, i, d) \ - static struct multiplexer ipu##i##_di##d##_pre_mux = { \ - .clk = &ipu##i##_di##d##_pre_clk, \ - .reg = r, \ - .bp = BP_##r##_IPU##i##_DI##d##_PRE_SEL, \ - .bm = BM_##r##_IPU##i##_DI##d##_PRE_SEL, \ - .parents = { \ - &mmdc_ch0_axi_clk, \ - &pll3_usb_otg, \ - &pll5_video, \ - &pll2_pfd_352m, \ - &pll2_pfd_400m, \ - &pll3_pfd_540m, \ - NULL \ - }, \ - } - -DEF_IPU_DI_PRE_MUX(CHSCCDR, 1, 0); -DEF_IPU_DI_PRE_MUX(CHSCCDR, 1, 1); -DEF_IPU_DI_PRE_MUX(CSCDR2, 2, 0); -DEF_IPU_DI_PRE_MUX(CSCDR2, 2, 1); - -#define DEF_IPU_DI_MUX(r, i, d) \ - static struct multiplexer ipu##i##_di##d##_mux = { \ - .clk = &ipu##i##_di##d##_clk, \ - .reg = r, \ - .bp = BP_##r##_IPU##i##_DI##d##_SEL, \ - .bm = BM_##r##_IPU##i##_DI##d##_SEL, \ - .parents = { \ - &ipu##i##_di##d##_pre_clk, \ - &dummy_clk, \ - &dummy_clk, \ - &ldb_di0_clk, \ - &ldb_di1_clk, \ - NULL \ - }, \ - } - -DEF_IPU_DI_MUX(CHSCCDR, 1, 0); -DEF_IPU_DI_MUX(CHSCCDR, 1, 1); -DEF_IPU_DI_MUX(CSCDR2, 2, 0); -DEF_IPU_DI_MUX(CSCDR2, 2, 1); - -#define DEF_IPU_MUX(id) \ - static struct multiplexer ipu##id##_mux = { \ - .clk = &ipu##id##_clk, \ - .reg = CSCDR3, \ - .bp = BP_CSCDR3_IPU##id##_HSP_SEL, \ - .bm = BM_CSCDR3_IPU##id##_HSP_SEL, \ - .parents = { \ - &mmdc_ch0_axi_clk, \ - &pll2_pfd_400m, \ - &pll3_120m, \ - &pll3_pfd_540m, \ - NULL \ - }, \ - } - -DEF_IPU_MUX(1); -DEF_IPU_MUX(2); - -static struct multiplexer cko1_mux = { - .clk = &cko1_clk, - .reg = CCOSR, - .bp = BP_CCOSR_CKO1_SEL, - .bm = BM_CCOSR_CKO1_SEL, - .parents = { - &pll3_usb_otg, - &pll2_bus, - &pll1_sys, - &pll5_video, - &dummy_clk, - &axi_clk, - &enfc_clk, - &ipu1_di0_clk, - &ipu1_di1_clk, - &ipu2_di0_clk, - &ipu2_di1_clk, - &ahb_clk, - &ipg_clk, - &ipg_perclk, - &ckil_clk, - &pll4_audio, - NULL - }, -}; - -static struct multiplexer *multiplexers[] = { - &axi_mux, - &periph_mux, - &periph_pre_mux, - &periph_clk2_mux, - &periph2_mux, - &periph2_pre_mux, - &periph2_clk2_mux, - &gpu2d_axi_mux, - &gpu3d_axi_mux, - &gpu3d_core_mux, - &gpu3d_shader_mux, - &pcie_axi_mux, - &vdo_axi_mux, - &vpu_axi_mux, - &gpu2d_core_mux, - &ssi1_mux, - &ssi2_mux, - &ssi3_mux, - &usdhc1_mux, - &usdhc2_mux, - &usdhc3_mux, - &usdhc4_mux, - &emi_mux, - &emi_slow_mux, - &esai_mux, - &ldb_di0_mux, - &ldb_di1_mux, - &enfc_mux, - &spdif_mux, - &asrc_serial_mux, - &hsi_tx_mux, - &ipu1_di0_pre_mux, - &ipu1_di0_mux, - &ipu1_di1_pre_mux, - &ipu1_di1_mux, - &ipu2_di0_pre_mux, - &ipu2_di0_mux, - &ipu2_di1_pre_mux, - &ipu2_di1_mux, - &ipu1_mux, - &ipu2_mux, - &cko1_mux, -}; - -static int _clk_set_parent(struct clk *clk, struct clk *parent) -{ - struct multiplexer *m; - int i, num; - u32 val; - - num = ARRAY_SIZE(multiplexers); - for (i = 0; i < num; i++) - if (multiplexers[i]->clk == clk) { - m = multiplexers[i]; - break; - } - if (i == num) - return -EINVAL; - - i = 0; - while (m->parents[i]) { - if (parent == m->parents[i]) - break; - i++; - } - if (!m->parents[i] || m->parents[i] == &dummy_clk) - return -EINVAL; - - val = readl_relaxed(m->reg); - val &= ~m->bm; - val |= i << m->bp; - writel_relaxed(val, m->reg); - - if (clk == &periph_clk) - return clk_busy_wait(clk); - - return 0; -} - -#define DEF_NG_CLK(name, p) \ - static struct clk name = { \ - .get_rate = _clk_get_rate, \ - .set_rate = _clk_set_rate, \ - .round_rate = _clk_round_rate, \ - .set_parent = _clk_set_parent, \ - .parent = p, \ - } - -DEF_NG_CLK(periph_clk2_clk, &osc_clk); -DEF_NG_CLK(periph_pre_clk, &pll2_bus); -DEF_NG_CLK(periph_clk, &periph_pre_clk); -DEF_NG_CLK(periph2_clk2_clk, &osc_clk); -DEF_NG_CLK(periph2_pre_clk, &pll2_bus); -DEF_NG_CLK(periph2_clk, &periph2_pre_clk); -DEF_NG_CLK(axi_clk, &periph_clk); -DEF_NG_CLK(emi_clk, &axi_clk); -DEF_NG_CLK(arm_clk, &pll1_sw_clk); -DEF_NG_CLK(ahb_clk, &periph_clk); -DEF_NG_CLK(ipg_clk, &ahb_clk); -DEF_NG_CLK(ipg_perclk, &ipg_clk); -DEF_NG_CLK(ipu1_di0_pre_clk, &pll3_pfd_540m); -DEF_NG_CLK(ipu1_di1_pre_clk, &pll3_pfd_540m); -DEF_NG_CLK(ipu2_di0_pre_clk, &pll3_pfd_540m); -DEF_NG_CLK(ipu2_di1_pre_clk, &pll3_pfd_540m); -DEF_NG_CLK(asrc_serial_clk, &pll3_usb_otg); - -#define DEF_CLK(name, er, es, p, s) \ - static struct clk name = { \ - .enable_reg = er, \ - .enable_shift = es, \ - .enable = _clk_enable, \ - .disable = _clk_disable, \ - .get_rate = _clk_get_rate, \ - .set_rate = _clk_set_rate, \ - .round_rate = _clk_round_rate, \ - .set_parent = _clk_set_parent, \ - .parent = p, \ - .secondary = s, \ - } - -#define DEF_CLK_1B(name, er, es, p, s) \ - static struct clk name = { \ - .enable_reg = er, \ - .enable_shift = es, \ - .enable = _clk_enable_1b, \ - .disable = _clk_disable_1b, \ - .get_rate = _clk_get_rate, \ - .set_rate = _clk_set_rate, \ - .round_rate = _clk_round_rate, \ - .set_parent = _clk_set_parent, \ - .parent = p, \ - .secondary = s, \ - } - -DEF_CLK(aips_tz1_clk, CCGR0, CG0, &ahb_clk, NULL); -DEF_CLK(aips_tz2_clk, CCGR0, CG1, &ahb_clk, NULL); -DEF_CLK(apbh_dma_clk, CCGR0, CG2, &ahb_clk, NULL); -DEF_CLK(asrc_clk, CCGR0, CG3, &pll4_audio, NULL); -DEF_CLK(can1_serial_clk, CCGR0, CG8, &pll3_usb_otg, NULL); -DEF_CLK(can1_clk, CCGR0, CG7, &pll3_usb_otg, &can1_serial_clk); -DEF_CLK(can2_serial_clk, CCGR0, CG10, &pll3_usb_otg, NULL); -DEF_CLK(can2_clk, CCGR0, CG9, &pll3_usb_otg, &can2_serial_clk); -DEF_CLK(ecspi1_clk, CCGR1, CG0, &pll3_60m, NULL); -DEF_CLK(ecspi2_clk, CCGR1, CG1, &pll3_60m, NULL); -DEF_CLK(ecspi3_clk, CCGR1, CG2, &pll3_60m, NULL); -DEF_CLK(ecspi4_clk, CCGR1, CG3, &pll3_60m, NULL); -DEF_CLK(ecspi5_clk, CCGR1, CG4, &pll3_60m, NULL); -DEF_CLK(enet_clk, CCGR1, CG5, &ipg_clk, NULL); -DEF_CLK(esai_clk, CCGR1, CG8, &pll3_usb_otg, NULL); -DEF_CLK(gpt_serial_clk, CCGR1, CG11, &ipg_perclk, NULL); -DEF_CLK(gpt_clk, CCGR1, CG10, &ipg_perclk, &gpt_serial_clk); -DEF_CLK(gpu2d_core_clk, CCGR1, CG12, &pll2_pfd_352m, &gpu2d_axi_clk); -DEF_CLK(gpu3d_core_clk, CCGR1, CG13, &pll2_pfd_594m, &gpu3d_axi_clk); -DEF_CLK(gpu3d_shader_clk, CCGR1, CG13, &pll3_pfd_720m, &gpu3d_axi_clk); -DEF_CLK(hdmi_iahb_clk, CCGR2, CG0, &ahb_clk, NULL); -DEF_CLK(hdmi_isfr_clk, CCGR2, CG2, &pll3_pfd_540m, &hdmi_iahb_clk); -DEF_CLK(i2c1_clk, CCGR2, CG3, &ipg_perclk, NULL); -DEF_CLK(i2c2_clk, CCGR2, CG4, &ipg_perclk, NULL); -DEF_CLK(i2c3_clk, CCGR2, CG5, &ipg_perclk, NULL); -DEF_CLK(iim_clk, CCGR2, CG6, &ipg_clk, NULL); -DEF_CLK(enfc_clk, CCGR2, CG7, &pll2_pfd_352m, NULL); -DEF_CLK(ipu1_clk, CCGR3, CG0, &mmdc_ch0_axi_clk, NULL); -DEF_CLK(ipu1_di0_clk, CCGR3, CG1, &ipu1_di0_pre_clk, NULL); -DEF_CLK(ipu1_di1_clk, CCGR3, CG2, &ipu1_di1_pre_clk, NULL); -DEF_CLK(ipu2_clk, CCGR3, CG3, &mmdc_ch0_axi_clk, NULL); -DEF_CLK(ipu2_di0_clk, CCGR3, CG4, &ipu2_di0_pre_clk, NULL); -DEF_CLK(ipu2_di1_clk, CCGR3, CG5, &ipu2_di1_pre_clk, NULL); -DEF_CLK(ldb_di0_clk, CCGR3, CG6, &pll3_pfd_540m, NULL); -DEF_CLK(ldb_di1_clk, CCGR3, CG7, &pll3_pfd_540m, NULL); -DEF_CLK(hsi_tx_clk, CCGR3, CG8, &pll2_pfd_400m, NULL); -DEF_CLK(mlb_clk, CCGR3, CG9, &pll6_mlb, NULL); -DEF_CLK(mmdc_ch0_ipg_clk, CCGR3, CG12, &ipg_clk, NULL); -DEF_CLK(mmdc_ch0_axi_clk, CCGR3, CG10, &periph_clk, &mmdc_ch0_ipg_clk); -DEF_CLK(mmdc_ch1_ipg_clk, CCGR3, CG13, &ipg_clk, NULL); -DEF_CLK(mmdc_ch1_axi_clk, CCGR3, CG11, &periph2_clk, &mmdc_ch1_ipg_clk); -DEF_CLK(openvg_axi_clk, CCGR3, CG13, &axi_clk, NULL); -DEF_CLK(pwm1_clk, CCGR4, CG8, &ipg_perclk, NULL); -DEF_CLK(pwm2_clk, CCGR4, CG9, &ipg_perclk, NULL); -DEF_CLK(pwm3_clk, CCGR4, CG10, &ipg_perclk, NULL); -DEF_CLK(pwm4_clk, CCGR4, CG11, &ipg_perclk, NULL); -DEF_CLK(gpmi_bch_apb_clk, CCGR4, CG12, &usdhc3_clk, NULL); -DEF_CLK(gpmi_bch_clk, CCGR4, CG13, &usdhc4_clk, &gpmi_bch_apb_clk); -DEF_CLK(gpmi_apb_clk, CCGR4, CG15, &usdhc3_clk, &gpmi_bch_clk); -DEF_CLK(gpmi_io_clk, CCGR4, CG14, &enfc_clk, &gpmi_apb_clk); -DEF_CLK(sdma_clk, CCGR5, CG3, &ahb_clk, NULL); -DEF_CLK(spba_clk, CCGR5, CG6, &ipg_clk, NULL); -DEF_CLK(spdif_clk, CCGR5, CG7, &pll3_usb_otg, &spba_clk); -DEF_CLK(ssi1_clk, CCGR5, CG9, &pll3_pfd_508m, NULL); -DEF_CLK(ssi2_clk, CCGR5, CG10, &pll3_pfd_508m, NULL); -DEF_CLK(ssi3_clk, CCGR5, CG11, &pll3_pfd_508m, NULL); -DEF_CLK(uart_serial_clk, CCGR5, CG13, &pll3_usb_otg, NULL); -DEF_CLK(uart_clk, CCGR5, CG12, &pll3_80m, &uart_serial_clk); -DEF_CLK(usboh3_clk, CCGR6, CG0, &ipg_clk, NULL); -DEF_CLK(usdhc1_clk, CCGR6, CG1, &pll2_pfd_400m, NULL); -DEF_CLK(usdhc2_clk, CCGR6, CG2, &pll2_pfd_400m, NULL); -DEF_CLK(usdhc3_clk, CCGR6, CG3, &pll2_pfd_400m, NULL); -DEF_CLK(usdhc4_clk, CCGR6, CG4, &pll2_pfd_400m, NULL); -DEF_CLK(emi_slow_clk, CCGR6, CG5, &axi_clk, NULL); -DEF_CLK(vdo_axi_clk, CCGR6, CG6, &axi_clk, NULL); -DEF_CLK(vpu_clk, CCGR6, CG7, &axi_clk, NULL); -DEF_CLK_1B(cko1_clk, CCOSR, BP_CCOSR_CKO1_EN, &pll2_bus, NULL); - -static int pcie_clk_enable(struct clk *clk) -{ - u32 val; - - val = readl_relaxed(PLL8_ENET); - val |= BM_PLL_ENET_EN_PCIE; - writel_relaxed(val, PLL8_ENET); - - return _clk_enable(clk); -} - -static void pcie_clk_disable(struct clk *clk) -{ - u32 val; - - _clk_disable(clk); - - val = readl_relaxed(PLL8_ENET); - val &= BM_PLL_ENET_EN_PCIE; - writel_relaxed(val, PLL8_ENET); -} - -static struct clk pcie_clk = { - .enable_reg = CCGR4, - .enable_shift = CG0, - .enable = pcie_clk_enable, - .disable = pcie_clk_disable, - .set_parent = _clk_set_parent, - .parent = &axi_clk, - .secondary = &pll8_enet, -}; - -static int sata_clk_enable(struct clk *clk) -{ - u32 val; - - val = readl_relaxed(PLL8_ENET); - val |= BM_PLL_ENET_EN_SATA; - writel_relaxed(val, PLL8_ENET); - - return _clk_enable(clk); -} - -static void sata_clk_disable(struct clk *clk) -{ - u32 val; - - _clk_disable(clk); - - val = readl_relaxed(PLL8_ENET); - val &= BM_PLL_ENET_EN_SATA; - writel_relaxed(val, PLL8_ENET); -} - -static struct clk sata_clk = { - .enable_reg = CCGR5, - .enable_shift = CG2, - .enable = sata_clk_enable, - .disable = sata_clk_disable, - .parent = &ipg_clk, - .secondary = &pll8_enet, -}; - -#define _REGISTER_CLOCK(d, n, c) \ - { \ - .dev_id = d, \ - .con_id = n, \ - .clk = &c, \ - } - -static struct clk_lookup lookups[] = { - _REGISTER_CLOCK("2020000.uart", NULL, uart_clk), - _REGISTER_CLOCK("21e8000.uart", NULL, uart_clk), - _REGISTER_CLOCK("21ec000.uart", NULL, uart_clk), - _REGISTER_CLOCK("21f0000.uart", NULL, uart_clk), - _REGISTER_CLOCK("21f4000.uart", NULL, uart_clk), - _REGISTER_CLOCK("2188000.enet", NULL, enet_clk), - _REGISTER_CLOCK("2190000.usdhc", NULL, usdhc1_clk), - _REGISTER_CLOCK("2194000.usdhc", NULL, usdhc2_clk), - _REGISTER_CLOCK("2198000.usdhc", NULL, usdhc3_clk), - _REGISTER_CLOCK("219c000.usdhc", NULL, usdhc4_clk), - _REGISTER_CLOCK("21a0000.i2c", NULL, i2c1_clk), - _REGISTER_CLOCK("21a4000.i2c", NULL, i2c2_clk), - _REGISTER_CLOCK("21a8000.i2c", NULL, i2c3_clk), - _REGISTER_CLOCK("2008000.ecspi", NULL, ecspi1_clk), - _REGISTER_CLOCK("200c000.ecspi", NULL, ecspi2_clk), - _REGISTER_CLOCK("2010000.ecspi", NULL, ecspi3_clk), - _REGISTER_CLOCK("2014000.ecspi", NULL, ecspi4_clk), - _REGISTER_CLOCK("2018000.ecspi", NULL, ecspi5_clk), - _REGISTER_CLOCK("20ec000.sdma", NULL, sdma_clk), - _REGISTER_CLOCK("20bc000.wdog", NULL, dummy_clk), - _REGISTER_CLOCK("20c0000.wdog", NULL, dummy_clk), - _REGISTER_CLOCK("smp_twd", NULL, twd_clk), - _REGISTER_CLOCK(NULL, "ckih", ckih_clk), - _REGISTER_CLOCK(NULL, "ckil_clk", ckil_clk), - _REGISTER_CLOCK(NULL, "aips_tz1_clk", aips_tz1_clk), - _REGISTER_CLOCK(NULL, "aips_tz2_clk", aips_tz2_clk), - _REGISTER_CLOCK(NULL, "asrc_clk", asrc_clk), - _REGISTER_CLOCK(NULL, "can2_clk", can2_clk), - _REGISTER_CLOCK(NULL, "hdmi_isfr_clk", hdmi_isfr_clk), - _REGISTER_CLOCK(NULL, "iim_clk", iim_clk), - _REGISTER_CLOCK(NULL, "mlb_clk", mlb_clk), - _REGISTER_CLOCK(NULL, "openvg_axi_clk", openvg_axi_clk), - _REGISTER_CLOCK(NULL, "pwm1_clk", pwm1_clk), - _REGISTER_CLOCK(NULL, "pwm2_clk", pwm2_clk), - _REGISTER_CLOCK(NULL, "pwm3_clk", pwm3_clk), - _REGISTER_CLOCK(NULL, "pwm4_clk", pwm4_clk), - _REGISTER_CLOCK(NULL, "gpmi_io_clk", gpmi_io_clk), - _REGISTER_CLOCK(NULL, "usboh3_clk", usboh3_clk), - _REGISTER_CLOCK(NULL, "sata_clk", sata_clk), - _REGISTER_CLOCK(NULL, "cko1_clk", cko1_clk), -}; - -int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) -{ - u32 val = readl_relaxed(CLPCR); - - val &= ~BM_CLPCR_LPM; - switch (mode) { - case WAIT_CLOCKED: - break; - case WAIT_UNCLOCKED: - val |= 0x1 << BP_CLPCR_LPM; - break; - case STOP_POWER_ON: - val |= 0x2 << BP_CLPCR_LPM; - break; - case WAIT_UNCLOCKED_POWER_OFF: - val |= 0x1 << BP_CLPCR_LPM; - val &= ~BM_CLPCR_VSTBY; - val &= ~BM_CLPCR_SBYOS; - break; - case STOP_POWER_OFF: - val |= 0x2 << BP_CLPCR_LPM; - val |= 0x3 << BP_CLPCR_STBY_COUNT; - val |= BM_CLPCR_VSTBY; - val |= BM_CLPCR_SBYOS; - break; - default: - return -EINVAL; - } - writel_relaxed(val, CLPCR); - - return 0; -} - -static struct map_desc imx6q_clock_desc[] = { - imx_map_entry(MX6Q, CCM, MT_DEVICE), - imx_map_entry(MX6Q, ANATOP, MT_DEVICE), -}; - -void __init imx6q_clock_map_io(void) -{ - iotable_init(imx6q_clock_desc, ARRAY_SIZE(imx6q_clock_desc)); -} - -int __init mx6q_clocks_init(void) -{ - struct device_node *np; - void __iomem *base; - int i, irq; - - /* retrieve the freqency of fixed clocks from device tree */ - for_each_compatible_node(np, NULL, "fixed-clock") { - u32 rate; - if (of_property_read_u32(np, "clock-frequency", &rate)) - continue; - - if (of_device_is_compatible(np, "fsl,imx-ckil")) - external_low_reference = rate; - else if (of_device_is_compatible(np, "fsl,imx-ckih1")) - external_high_reference = rate; - else if (of_device_is_compatible(np, "fsl,imx-osc")) - oscillator_reference = rate; - } - - for (i = 0; i < ARRAY_SIZE(lookups); i++) - clkdev_add(&lookups[i]); - - /* only keep necessary clocks on */ - writel_relaxed(0x3 << CG0 | 0x3 << CG1 | 0x3 << CG2, CCGR0); - writel_relaxed(0x3 << CG8 | 0x3 << CG9 | 0x3 << CG10, CCGR2); - writel_relaxed(0x3 << CG10 | 0x3 << CG12, CCGR3); - writel_relaxed(0x3 << CG4 | 0x3 << CG6 | 0x3 << CG7, CCGR4); - writel_relaxed(0x3 << CG0, CCGR5); - writel_relaxed(0, CCGR6); - writel_relaxed(0, CCGR7); - - clk_enable(&uart_clk); - clk_enable(&mmdc_ch0_axi_clk); - - clk_set_rate(&pll4_audio, FREQ_650M); - clk_set_rate(&pll5_video, FREQ_650M); - clk_set_parent(&ipu1_di0_clk, &ipu1_di0_pre_clk); - clk_set_parent(&ipu1_di0_pre_clk, &pll5_video); - clk_set_parent(&gpu3d_shader_clk, &pll2_pfd_594m); - clk_set_rate(&gpu3d_shader_clk, FREQ_594M); - clk_set_parent(&gpu3d_core_clk, &mmdc_ch0_axi_clk); - clk_set_rate(&gpu3d_core_clk, FREQ_528M); - clk_set_parent(&asrc_serial_clk, &pll3_usb_otg); - clk_set_rate(&asrc_serial_clk, 1500000); - clk_set_rate(&enfc_clk, 11000000); - - /* - * Before pinctrl API is available, we have to rely on the pad - * configuration set up by bootloader. For usdhc example here, - * u-boot sets up the pads for 49.5 MHz case, and we have to lower - * the usdhc clock from 198 to 49.5 MHz to match the pad configuration. - * - * FIXME: This is should be removed after pinctrl API is available. - * At that time, usdhc driver can call pinctrl API to change pad - * configuration dynamically per different usdhc clock settings. - */ - clk_set_rate(&usdhc1_clk, 49500000); - clk_set_rate(&usdhc2_clk, 49500000); - clk_set_rate(&usdhc3_clk, 49500000); - clk_set_rate(&usdhc4_clk, 49500000); - - clk_set_parent(&cko1_clk, &ahb_clk); - - np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpt"); - base = of_iomap(np, 0); - WARN_ON(!base); - irq = irq_of_parse_and_map(np, 0); - mxc_timer_init(&gpt_clk, base, irq); - - return 0; -} diff --git a/trunk/arch/arm/mach-imx/clock-mx51-mx53.c b/trunk/arch/arm/mach-imx/clock-mx51-mx53.c deleted file mode 100644 index 08470504a088..000000000000 --- a/trunk/arch/arm/mach-imx/clock-mx51-mx53.c +++ /dev/null @@ -1,1675 +0,0 @@ -/* - * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved. - * Copyright (C) 2009-2010 Amit Kucheria - * - * 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 - -#include -#include -#include - -#include "crm-regs-imx5.h" - -/* External clock values passed-in by the board code */ -static unsigned long external_high_reference, external_low_reference; -static unsigned long oscillator_reference, ckih2_reference; - -static struct clk osc_clk; -static struct clk pll1_main_clk; -static struct clk pll1_sw_clk; -static struct clk pll2_sw_clk; -static struct clk pll3_sw_clk; -static struct clk mx53_pll4_sw_clk; -static struct clk lp_apm_clk; -static struct clk periph_apm_clk; -static struct clk ahb_clk; -static struct clk ipg_clk; -static struct clk usboh3_clk; -static struct clk emi_fast_clk; -static struct clk ipu_clk; -static struct clk mipi_hsc1_clk; -static struct clk esdhc1_clk; -static struct clk esdhc2_clk; -static struct clk esdhc3_mx53_clk; - -#define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */ - -/* calculate best pre and post dividers to get the required divider */ -static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post, - u32 max_pre, u32 max_post) -{ - if (div >= max_pre * max_post) { - *pre = max_pre; - *post = max_post; - } else if (div >= max_pre) { - u32 min_pre, temp_pre, old_err, err; - min_pre = DIV_ROUND_UP(div, max_post); - old_err = max_pre; - for (temp_pre = max_pre; temp_pre >= min_pre; temp_pre--) { - err = div % temp_pre; - if (err == 0) { - *pre = temp_pre; - break; - } - err = temp_pre - err; - if (err < old_err) { - old_err = err; - *pre = temp_pre; - } - } - *post = DIV_ROUND_UP(div, *pre); - } else { - *pre = div; - *post = 1; - } -} - -static void _clk_ccgr_setclk(struct clk *clk, unsigned mode) -{ - u32 reg = __raw_readl(clk->enable_reg); - - reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift); - reg |= mode << clk->enable_shift; - - __raw_writel(reg, clk->enable_reg); -} - -static int _clk_ccgr_enable(struct clk *clk) -{ - _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_ON); - return 0; -} - -static void _clk_ccgr_disable(struct clk *clk) -{ - _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_OFF); -} - -static int _clk_ccgr_enable_inrun(struct clk *clk) -{ - _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_IDLE); - return 0; -} - -static void _clk_ccgr_disable_inwait(struct clk *clk) -{ - _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_IDLE); -} - -/* - * For the 4-to-1 muxed input clock - */ -static inline u32 _get_mux(struct clk *parent, struct clk *m0, - struct clk *m1, struct clk *m2, struct clk *m3) -{ - if (parent == m0) - return 0; - else if (parent == m1) - return 1; - else if (parent == m2) - return 2; - else if (parent == m3) - return 3; - else - BUG(); - - return -EINVAL; -} - -static inline void __iomem *_mx51_get_pll_base(struct clk *pll) -{ - if (pll == &pll1_main_clk) - return MX51_DPLL1_BASE; - else if (pll == &pll2_sw_clk) - return MX51_DPLL2_BASE; - else if (pll == &pll3_sw_clk) - return MX51_DPLL3_BASE; - else - BUG(); - - return NULL; -} - -static inline void __iomem *_mx53_get_pll_base(struct clk *pll) -{ - if (pll == &pll1_main_clk) - return MX53_DPLL1_BASE; - else if (pll == &pll2_sw_clk) - return MX53_DPLL2_BASE; - else if (pll == &pll3_sw_clk) - return MX53_DPLL3_BASE; - else if (pll == &mx53_pll4_sw_clk) - return MX53_DPLL4_BASE; - else - BUG(); - - return NULL; -} - -static inline void __iomem *_get_pll_base(struct clk *pll) -{ - if (cpu_is_mx51()) - return _mx51_get_pll_base(pll); - else - return _mx53_get_pll_base(pll); -} - -static unsigned long clk_pll_get_rate(struct clk *clk) -{ - long mfi, mfn, mfd, pdf, ref_clk, mfn_abs; - unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl; - void __iomem *pllbase; - s64 temp; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - pllbase = _get_pll_base(clk); - - dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL); - pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM; - dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN; - - if (pll_hfsm == 0) { - dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP); - dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD); - dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN); - } else { - dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP); - dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD); - dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN); - } - pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK; - mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET; - mfi = (mfi <= 5) ? 5 : mfi; - mfd = dp_mfd & MXC_PLL_DP_MFD_MASK; - mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK; - /* Sign extend to 32-bits */ - if (mfn >= 0x04000000) { - mfn |= 0xFC000000; - mfn_abs = -mfn; - } - - ref_clk = 2 * parent_rate; - if (dbl != 0) - ref_clk *= 2; - - ref_clk /= (pdf + 1); - temp = (u64) ref_clk * mfn_abs; - do_div(temp, mfd + 1); - if (mfn < 0) - temp = -temp; - temp = (ref_clk * mfi) + temp; - - return temp; -} - -static int _clk_pll_set_rate(struct clk *clk, unsigned long rate) -{ - u32 reg; - void __iomem *pllbase; - - long mfi, pdf, mfn, mfd = 999999; - s64 temp64; - unsigned long quad_parent_rate; - unsigned long pll_hfsm, dp_ctl; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - pllbase = _get_pll_base(clk); - - quad_parent_rate = 4 * parent_rate; - pdf = mfi = -1; - while (++pdf < 16 && mfi < 5) - mfi = rate * (pdf+1) / quad_parent_rate; - if (mfi > 15) - return -EINVAL; - pdf--; - - temp64 = rate * (pdf+1) - quad_parent_rate * mfi; - do_div(temp64, quad_parent_rate/1000000); - mfn = (long)temp64; - - dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL); - /* use dpdck0_2 */ - __raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL); - pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM; - if (pll_hfsm == 0) { - reg = mfi << 4 | pdf; - __raw_writel(reg, pllbase + MXC_PLL_DP_OP); - __raw_writel(mfd, pllbase + MXC_PLL_DP_MFD); - __raw_writel(mfn, pllbase + MXC_PLL_DP_MFN); - } else { - reg = mfi << 4 | pdf; - __raw_writel(reg, pllbase + MXC_PLL_DP_HFS_OP); - __raw_writel(mfd, pllbase + MXC_PLL_DP_HFS_MFD); - __raw_writel(mfn, pllbase + MXC_PLL_DP_HFS_MFN); - } - - return 0; -} - -static int _clk_pll_enable(struct clk *clk) -{ - u32 reg; - void __iomem *pllbase; - int i = 0; - - pllbase = _get_pll_base(clk); - reg = __raw_readl(pllbase + MXC_PLL_DP_CTL); - if (reg & MXC_PLL_DP_CTL_UPEN) - return 0; - - reg |= MXC_PLL_DP_CTL_UPEN; - __raw_writel(reg, pllbase + MXC_PLL_DP_CTL); - - /* Wait for lock */ - do { - reg = __raw_readl(pllbase + MXC_PLL_DP_CTL); - if (reg & MXC_PLL_DP_CTL_LRF) - break; - - udelay(1); - } while (++i < MAX_DPLL_WAIT_TRIES); - - if (i == MAX_DPLL_WAIT_TRIES) { - pr_err("MX5: pll locking failed\n"); - return -EINVAL; - } - - return 0; -} - -static void _clk_pll_disable(struct clk *clk) -{ - u32 reg; - void __iomem *pllbase; - - pllbase = _get_pll_base(clk); - reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) & ~MXC_PLL_DP_CTL_UPEN; - __raw_writel(reg, pllbase + MXC_PLL_DP_CTL); -} - -static int _clk_pll1_sw_set_parent(struct clk *clk, struct clk *parent) -{ - u32 reg, step; - - reg = __raw_readl(MXC_CCM_CCSR); - - /* When switching from pll_main_clk to a bypass clock, first select a - * multiplexed clock in 'step_sel', then shift the glitchless mux - * 'pll1_sw_clk_sel'. - * - * When switching back, do it in reverse order - */ - if (parent == &pll1_main_clk) { - /* Switch to pll1_main_clk */ - reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL; - __raw_writel(reg, MXC_CCM_CCSR); - /* step_clk mux switched to lp_apm, to save power. */ - reg = __raw_readl(MXC_CCM_CCSR); - reg &= ~MXC_CCM_CCSR_STEP_SEL_MASK; - reg |= (MXC_CCM_CCSR_STEP_SEL_LP_APM << - MXC_CCM_CCSR_STEP_SEL_OFFSET); - } else { - if (parent == &lp_apm_clk) { - step = MXC_CCM_CCSR_STEP_SEL_LP_APM; - } else if (parent == &pll2_sw_clk) { - step = MXC_CCM_CCSR_STEP_SEL_PLL2_DIVIDED; - } else if (parent == &pll3_sw_clk) { - step = MXC_CCM_CCSR_STEP_SEL_PLL3_DIVIDED; - } else - return -EINVAL; - - reg &= ~MXC_CCM_CCSR_STEP_SEL_MASK; - reg |= (step << MXC_CCM_CCSR_STEP_SEL_OFFSET); - - __raw_writel(reg, MXC_CCM_CCSR); - /* Switch to step_clk */ - reg = __raw_readl(MXC_CCM_CCSR); - reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL; - } - __raw_writel(reg, MXC_CCM_CCSR); - return 0; -} - -static unsigned long clk_pll1_sw_get_rate(struct clk *clk) -{ - u32 reg, div; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - reg = __raw_readl(MXC_CCM_CCSR); - - if (clk->parent == &pll2_sw_clk) { - div = ((reg & MXC_CCM_CCSR_PLL2_PODF_MASK) >> - MXC_CCM_CCSR_PLL2_PODF_OFFSET) + 1; - } else if (clk->parent == &pll3_sw_clk) { - div = ((reg & MXC_CCM_CCSR_PLL3_PODF_MASK) >> - MXC_CCM_CCSR_PLL3_PODF_OFFSET) + 1; - } else - div = 1; - return parent_rate / div; -} - -static int _clk_pll2_sw_set_parent(struct clk *clk, struct clk *parent) -{ - u32 reg; - - reg = __raw_readl(MXC_CCM_CCSR); - - if (parent == &pll2_sw_clk) - reg &= ~MXC_CCM_CCSR_PLL2_SW_CLK_SEL; - else - reg |= MXC_CCM_CCSR_PLL2_SW_CLK_SEL; - - __raw_writel(reg, MXC_CCM_CCSR); - return 0; -} - -static int _clk_lp_apm_set_parent(struct clk *clk, struct clk *parent) -{ - u32 reg; - - if (parent == &osc_clk) - reg = __raw_readl(MXC_CCM_CCSR) & ~MXC_CCM_CCSR_LP_APM_SEL; - else - return -EINVAL; - - __raw_writel(reg, MXC_CCM_CCSR); - - return 0; -} - -static unsigned long clk_cpu_get_rate(struct clk *clk) -{ - u32 cacrr, div; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - cacrr = __raw_readl(MXC_CCM_CACRR); - div = (cacrr & MXC_CCM_CACRR_ARM_PODF_MASK) + 1; - - return parent_rate / div; -} - -static int clk_cpu_set_rate(struct clk *clk, unsigned long rate) -{ - u32 reg, cpu_podf; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - cpu_podf = parent_rate / rate - 1; - /* use post divider to change freq */ - reg = __raw_readl(MXC_CCM_CACRR); - reg &= ~MXC_CCM_CACRR_ARM_PODF_MASK; - reg |= cpu_podf << MXC_CCM_CACRR_ARM_PODF_OFFSET; - __raw_writel(reg, MXC_CCM_CACRR); - - return 0; -} - -static int _clk_periph_apm_set_parent(struct clk *clk, struct clk *parent) -{ - u32 reg, mux; - int i = 0; - - mux = _get_mux(parent, &pll1_sw_clk, &pll3_sw_clk, &lp_apm_clk, NULL); - - reg = __raw_readl(MXC_CCM_CBCMR) & ~MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK; - reg |= mux << MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET; - __raw_writel(reg, MXC_CCM_CBCMR); - - /* Wait for lock */ - do { - reg = __raw_readl(MXC_CCM_CDHIPR); - if (!(reg & MXC_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY)) - break; - - udelay(1); - } while (++i < MAX_DPLL_WAIT_TRIES); - - if (i == MAX_DPLL_WAIT_TRIES) { - pr_err("MX5: Set parent for periph_apm clock failed\n"); - return -EINVAL; - } - - return 0; -} - -static int _clk_main_bus_set_parent(struct clk *clk, struct clk *parent) -{ - u32 reg; - - reg = __raw_readl(MXC_CCM_CBCDR); - - if (parent == &pll2_sw_clk) - reg &= ~MXC_CCM_CBCDR_PERIPH_CLK_SEL; - else if (parent == &periph_apm_clk) - reg |= MXC_CCM_CBCDR_PERIPH_CLK_SEL; - else - return -EINVAL; - - __raw_writel(reg, MXC_CCM_CBCDR); - - return 0; -} - -static struct clk main_bus_clk = { - .parent = &pll2_sw_clk, - .set_parent = _clk_main_bus_set_parent, -}; - -static unsigned long clk_ahb_get_rate(struct clk *clk) -{ - u32 reg, div; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - reg = __raw_readl(MXC_CCM_CBCDR); - div = ((reg & MXC_CCM_CBCDR_AHB_PODF_MASK) >> - MXC_CCM_CBCDR_AHB_PODF_OFFSET) + 1; - return parent_rate / div; -} - - -static int _clk_ahb_set_rate(struct clk *clk, unsigned long rate) -{ - u32 reg, div; - unsigned long parent_rate; - int i = 0; - - parent_rate = clk_get_rate(clk->parent); - - div = parent_rate / rate; - if (div > 8 || div < 1 || ((parent_rate / div) != rate)) - return -EINVAL; - - reg = __raw_readl(MXC_CCM_CBCDR); - reg &= ~MXC_CCM_CBCDR_AHB_PODF_MASK; - reg |= (div - 1) << MXC_CCM_CBCDR_AHB_PODF_OFFSET; - __raw_writel(reg, MXC_CCM_CBCDR); - - /* Wait for lock */ - do { - reg = __raw_readl(MXC_CCM_CDHIPR); - if (!(reg & MXC_CCM_CDHIPR_AHB_PODF_BUSY)) - break; - - udelay(1); - } while (++i < MAX_DPLL_WAIT_TRIES); - - if (i == MAX_DPLL_WAIT_TRIES) { - pr_err("MX5: clk_ahb_set_rate failed\n"); - return -EINVAL; - } - - return 0; -} - -static unsigned long _clk_ahb_round_rate(struct clk *clk, - unsigned long rate) -{ - u32 div; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - div = parent_rate / rate; - if (div > 8) - div = 8; - else if (div == 0) - div++; - return parent_rate / div; -} - - -static int _clk_max_enable(struct clk *clk) -{ - u32 reg; - - _clk_ccgr_enable(clk); - - /* Handshake with MAX when LPM is entered. */ - reg = __raw_readl(MXC_CCM_CLPCR); - if (cpu_is_mx51()) - reg &= ~MX51_CCM_CLPCR_BYPASS_MAX_LPM_HS; - else if (cpu_is_mx53()) - reg &= ~MX53_CCM_CLPCR_BYPASS_MAX_LPM_HS; - __raw_writel(reg, MXC_CCM_CLPCR); - - return 0; -} - -static void _clk_max_disable(struct clk *clk) -{ - u32 reg; - - _clk_ccgr_disable_inwait(clk); - - /* No Handshake with MAX when LPM is entered as its disabled. */ - reg = __raw_readl(MXC_CCM_CLPCR); - if (cpu_is_mx51()) - reg |= MX51_CCM_CLPCR_BYPASS_MAX_LPM_HS; - else if (cpu_is_mx53()) - reg &= ~MX53_CCM_CLPCR_BYPASS_MAX_LPM_HS; - __raw_writel(reg, MXC_CCM_CLPCR); -} - -static unsigned long clk_ipg_get_rate(struct clk *clk) -{ - u32 reg, div; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - reg = __raw_readl(MXC_CCM_CBCDR); - div = ((reg & MXC_CCM_CBCDR_IPG_PODF_MASK) >> - MXC_CCM_CBCDR_IPG_PODF_OFFSET) + 1; - - return parent_rate / div; -} - -static unsigned long clk_ipg_per_get_rate(struct clk *clk) -{ - u32 reg, prediv1, prediv2, podf; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - if (clk->parent == &main_bus_clk || clk->parent == &lp_apm_clk) { - /* the main_bus_clk is the one before the DVFS engine */ - reg = __raw_readl(MXC_CCM_CBCDR); - prediv1 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED1_MASK) >> - MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET) + 1; - prediv2 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED2_MASK) >> - MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET) + 1; - podf = ((reg & MXC_CCM_CBCDR_PERCLK_PODF_MASK) >> - MXC_CCM_CBCDR_PERCLK_PODF_OFFSET) + 1; - return parent_rate / (prediv1 * prediv2 * podf); - } else if (clk->parent == &ipg_clk) - return parent_rate; - else - BUG(); -} - -static int _clk_ipg_per_set_parent(struct clk *clk, struct clk *parent) -{ - u32 reg; - - reg = __raw_readl(MXC_CCM_CBCMR); - - reg &= ~MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL; - reg &= ~MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL; - - if (parent == &ipg_clk) - reg |= MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL; - else if (parent == &lp_apm_clk) - reg |= MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL; - else if (parent != &main_bus_clk) - return -EINVAL; - - __raw_writel(reg, MXC_CCM_CBCMR); - - return 0; -} - -#define clk_nfc_set_parent NULL - -static unsigned long clk_nfc_get_rate(struct clk *clk) -{ - unsigned long rate; - u32 reg, div; - - reg = __raw_readl(MXC_CCM_CBCDR); - div = ((reg & MXC_CCM_CBCDR_NFC_PODF_MASK) >> - MXC_CCM_CBCDR_NFC_PODF_OFFSET) + 1; - rate = clk_get_rate(clk->parent) / div; - WARN_ON(rate == 0); - return rate; -} - -static unsigned long clk_nfc_round_rate(struct clk *clk, - unsigned long rate) -{ - u32 div; - unsigned long parent_rate = clk_get_rate(clk->parent); - - if (!rate) - return -EINVAL; - - div = parent_rate / rate; - - if (parent_rate % rate) - div++; - - if (div > 8) - return -EINVAL; - - return parent_rate / div; - -} - -static int clk_nfc_set_rate(struct clk *clk, unsigned long rate) -{ - u32 reg, div; - - div = clk_get_rate(clk->parent) / rate; - if (div == 0) - div++; - if (((clk_get_rate(clk->parent) / div) != rate) || (div > 8)) - return -EINVAL; - - reg = __raw_readl(MXC_CCM_CBCDR); - reg &= ~MXC_CCM_CBCDR_NFC_PODF_MASK; - reg |= (div - 1) << MXC_CCM_CBCDR_NFC_PODF_OFFSET; - __raw_writel(reg, MXC_CCM_CBCDR); - - while (__raw_readl(MXC_CCM_CDHIPR) & - MXC_CCM_CDHIPR_NFC_IPG_INT_MEM_PODF_BUSY){ - } - - return 0; -} - -static unsigned long get_high_reference_clock_rate(struct clk *clk) -{ - return external_high_reference; -} - -static unsigned long get_low_reference_clock_rate(struct clk *clk) -{ - return external_low_reference; -} - -static unsigned long get_oscillator_reference_clock_rate(struct clk *clk) -{ - return oscillator_reference; -} - -static unsigned long get_ckih2_reference_clock_rate(struct clk *clk) -{ - return ckih2_reference; -} - -static unsigned long clk_emi_slow_get_rate(struct clk *clk) -{ - u32 reg, div; - - reg = __raw_readl(MXC_CCM_CBCDR); - div = ((reg & MXC_CCM_CBCDR_EMI_PODF_MASK) >> - MXC_CCM_CBCDR_EMI_PODF_OFFSET) + 1; - - return clk_get_rate(clk->parent) / div; -} - -static unsigned long _clk_ddr_hf_get_rate(struct clk *clk) -{ - unsigned long rate; - u32 reg, div; - - reg = __raw_readl(MXC_CCM_CBCDR); - div = ((reg & MXC_CCM_CBCDR_DDR_PODF_MASK) >> - MXC_CCM_CBCDR_DDR_PODF_OFFSET) + 1; - rate = clk_get_rate(clk->parent) / div; - - return rate; -} - -/* External high frequency clock */ -static struct clk ckih_clk = { - .get_rate = get_high_reference_clock_rate, -}; - -static struct clk ckih2_clk = { - .get_rate = get_ckih2_reference_clock_rate, -}; - -static struct clk osc_clk = { - .get_rate = get_oscillator_reference_clock_rate, -}; - -/* External low frequency (32kHz) clock */ -static struct clk ckil_clk = { - .get_rate = get_low_reference_clock_rate, -}; - -static struct clk pll1_main_clk = { - .parent = &osc_clk, - .get_rate = clk_pll_get_rate, - .enable = _clk_pll_enable, - .disable = _clk_pll_disable, -}; - -/* Clock tree block diagram (WIP): - * CCM: Clock Controller Module - * - * PLL output -> | - * | CCM Switcher -> CCM_CLK_ROOT_GEN -> - * PLL bypass -> | - * - */ - -/* PLL1 SW supplies to ARM core */ -static struct clk pll1_sw_clk = { - .parent = &pll1_main_clk, - .set_parent = _clk_pll1_sw_set_parent, - .get_rate = clk_pll1_sw_get_rate, -}; - -/* PLL2 SW supplies to AXI/AHB/IP buses */ -static struct clk pll2_sw_clk = { - .parent = &osc_clk, - .get_rate = clk_pll_get_rate, - .set_rate = _clk_pll_set_rate, - .set_parent = _clk_pll2_sw_set_parent, - .enable = _clk_pll_enable, - .disable = _clk_pll_disable, -}; - -/* PLL3 SW supplies to serial clocks like USB, SSI, etc. */ -static struct clk pll3_sw_clk = { - .parent = &osc_clk, - .set_rate = _clk_pll_set_rate, - .get_rate = clk_pll_get_rate, - .enable = _clk_pll_enable, - .disable = _clk_pll_disable, -}; - -/* PLL4 SW supplies to LVDS Display Bridge(LDB) */ -static struct clk mx53_pll4_sw_clk = { - .parent = &osc_clk, - .set_rate = _clk_pll_set_rate, - .enable = _clk_pll_enable, - .disable = _clk_pll_disable, -}; - -/* Low-power Audio Playback Mode clock */ -static struct clk lp_apm_clk = { - .parent = &osc_clk, - .set_parent = _clk_lp_apm_set_parent, -}; - -static struct clk periph_apm_clk = { - .parent = &pll1_sw_clk, - .set_parent = _clk_periph_apm_set_parent, -}; - -static struct clk cpu_clk = { - .parent = &pll1_sw_clk, - .get_rate = clk_cpu_get_rate, - .set_rate = clk_cpu_set_rate, -}; - -static struct clk ahb_clk = { - .parent = &main_bus_clk, - .get_rate = clk_ahb_get_rate, - .set_rate = _clk_ahb_set_rate, - .round_rate = _clk_ahb_round_rate, -}; - -static struct clk iim_clk = { - .parent = &ipg_clk, - .enable_reg = MXC_CCM_CCGR0, - .enable_shift = MXC_CCM_CCGRx_CG15_OFFSET, -}; - -/* Main IP interface clock for access to registers */ -static struct clk ipg_clk = { - .parent = &ahb_clk, - .get_rate = clk_ipg_get_rate, -}; - -static struct clk ipg_perclk = { - .parent = &lp_apm_clk, - .get_rate = clk_ipg_per_get_rate, - .set_parent = _clk_ipg_per_set_parent, -}; - -static struct clk ahb_max_clk = { - .parent = &ahb_clk, - .enable_reg = MXC_CCM_CCGR0, - .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET, - .enable = _clk_max_enable, - .disable = _clk_max_disable, -}; - -static struct clk aips_tz1_clk = { - .parent = &ahb_clk, - .secondary = &ahb_max_clk, - .enable_reg = MXC_CCM_CCGR0, - .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET, - .enable = _clk_ccgr_enable, - .disable = _clk_ccgr_disable_inwait, -}; - -static struct clk aips_tz2_clk = { - .parent = &ahb_clk, - .secondary = &ahb_max_clk, - .enable_reg = MXC_CCM_CCGR0, - .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET, - .enable = _clk_ccgr_enable, - .disable = _clk_ccgr_disable_inwait, -}; - -static struct clk gpc_dvfs_clk = { - .enable_reg = MXC_CCM_CCGR5, - .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET, - .enable = _clk_ccgr_enable, - .disable = _clk_ccgr_disable, -}; - -static struct clk gpt_32k_clk = { - .id = 0, - .parent = &ckil_clk, -}; - -static struct clk dummy_clk = { - .id = 0, -}; - -static struct clk emi_slow_clk = { - .parent = &pll2_sw_clk, - .enable_reg = MXC_CCM_CCGR5, - .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET, - .enable = _clk_ccgr_enable, - .disable = _clk_ccgr_disable_inwait, - .get_rate = clk_emi_slow_get_rate, -}; - -static int clk_ipu_enable(struct clk *clk) -{ - u32 reg; - - _clk_ccgr_enable(clk); - - /* Enable handshake with IPU when certain clock rates are changed */ - reg = __raw_readl(MXC_CCM_CCDR); - reg &= ~MXC_CCM_CCDR_IPU_HS_MASK; - __raw_writel(reg, MXC_CCM_CCDR); - - /* Enable handshake with IPU when LPM is entered */ - reg = __raw_readl(MXC_CCM_CLPCR); - reg &= ~MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS; - __raw_writel(reg, MXC_CCM_CLPCR); - - return 0; -} - -static void clk_ipu_disable(struct clk *clk) -{ - u32 reg; - - _clk_ccgr_disable(clk); - - /* Disable handshake with IPU whe dividers are changed */ - reg = __raw_readl(MXC_CCM_CCDR); - reg |= MXC_CCM_CCDR_IPU_HS_MASK; - __raw_writel(reg, MXC_CCM_CCDR); - - /* Disable handshake with IPU when LPM is entered */ - reg = __raw_readl(MXC_CCM_CLPCR); - reg |= MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS; - __raw_writel(reg, MXC_CCM_CLPCR); -} - -static struct clk ahbmux1_clk = { - .parent = &ahb_clk, - .secondary = &ahb_max_clk, - .enable_reg = MXC_CCM_CCGR0, - .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET, - .enable = _clk_ccgr_enable, - .disable = _clk_ccgr_disable_inwait, -}; - -static struct clk ipu_sec_clk = { - .parent = &emi_fast_clk, - .secondary = &ahbmux1_clk, -}; - -static struct clk ddr_hf_clk = { - .parent = &pll1_sw_clk, - .get_rate = _clk_ddr_hf_get_rate, -}; - -static struct clk ddr_clk = { - .parent = &ddr_hf_clk, -}; - -/* clock definitions for MIPI HSC unit which has been removed - * from documentation, but not from hardware - */ -static int _clk_hsc_enable(struct clk *clk) -{ - u32 reg; - - _clk_ccgr_enable(clk); - /* Handshake with IPU when certain clock rates are changed. */ - reg = __raw_readl(MXC_CCM_CCDR); - reg &= ~MXC_CCM_CCDR_HSC_HS_MASK; - __raw_writel(reg, MXC_CCM_CCDR); - - reg = __raw_readl(MXC_CCM_CLPCR); - reg &= ~MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS; - __raw_writel(reg, MXC_CCM_CLPCR); - - return 0; -} - -static void _clk_hsc_disable(struct clk *clk) -{ - u32 reg; - - _clk_ccgr_disable(clk); - /* No handshake with HSC as its not enabled. */ - reg = __raw_readl(MXC_CCM_CCDR); - reg |= MXC_CCM_CCDR_HSC_HS_MASK; - __raw_writel(reg, MXC_CCM_CCDR); - - reg = __raw_readl(MXC_CCM_CLPCR); - reg |= MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS; - __raw_writel(reg, MXC_CCM_CLPCR); -} - -static struct clk mipi_hsp_clk = { - .parent = &ipu_clk, - .enable_reg = MXC_CCM_CCGR4, - .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET, - .enable = _clk_hsc_enable, - .disable = _clk_hsc_disable, - .secondary = &mipi_hsc1_clk, -}; - -#define DEFINE_CLOCK_CCGR(name, i, er, es, pfx, p, s) \ - static struct clk name = { \ - .id = i, \ - .enable_reg = er, \ - .enable_shift = es, \ - .get_rate = pfx##_get_rate, \ - .set_rate = pfx##_set_rate, \ - .round_rate = pfx##_round_rate, \ - .set_parent = pfx##_set_parent, \ - .enable = _clk_ccgr_enable, \ - .disable = _clk_ccgr_disable, \ - .parent = p, \ - .secondary = s, \ - } - -#define DEFINE_CLOCK_MAX(name, i, er, es, pfx, p, s) \ - static struct clk name = { \ - .id = i, \ - .enable_reg = er, \ - .enable_shift = es, \ - .get_rate = pfx##_get_rate, \ - .set_rate = pfx##_set_rate, \ - .set_parent = pfx##_set_parent, \ - .enable = _clk_max_enable, \ - .disable = _clk_max_disable, \ - .parent = p, \ - .secondary = s, \ - } - -#define CLK_GET_RATE(name, nr, bitsname) \ -static unsigned long clk_##name##_get_rate(struct clk *clk) \ -{ \ - u32 reg, pred, podf; \ - \ - reg = __raw_readl(MXC_CCM_CSCDR##nr); \ - pred = (reg & MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK) \ - >> MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET; \ - podf = (reg & MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK) \ - >> MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET; \ - \ - return DIV_ROUND_CLOSEST(clk_get_rate(clk->parent), \ - (pred + 1) * (podf + 1)); \ -} - -#define CLK_SET_PARENT(name, nr, bitsname) \ -static int clk_##name##_set_parent(struct clk *clk, struct clk *parent) \ -{ \ - u32 reg, mux; \ - \ - mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, \ - &pll3_sw_clk, &lp_apm_clk); \ - reg = __raw_readl(MXC_CCM_CSCMR##nr) & \ - ~MXC_CCM_CSCMR##nr##_##bitsname##_CLK_SEL_MASK; \ - reg |= mux << MXC_CCM_CSCMR##nr##_##bitsname##_CLK_SEL_OFFSET; \ - __raw_writel(reg, MXC_CCM_CSCMR##nr); \ - \ - return 0; \ -} - -#define CLK_SET_RATE(name, nr, bitsname) \ -static int clk_##name##_set_rate(struct clk *clk, unsigned long rate) \ -{ \ - u32 reg, div, parent_rate; \ - u32 pre = 0, post = 0; \ - \ - parent_rate = clk_get_rate(clk->parent); \ - div = parent_rate / rate; \ - \ - if ((parent_rate / div) != rate) \ - return -EINVAL; \ - \ - __calc_pre_post_dividers(div, &pre, &post, \ - (MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK >> \ - MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET) + 1, \ - (MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK >> \ - MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET) + 1);\ - \ - /* Set sdhc1 clock divider */ \ - reg = __raw_readl(MXC_CCM_CSCDR##nr) & \ - ~(MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK \ - | MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK); \ - reg |= (post - 1) << \ - MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET; \ - reg |= (pre - 1) << \ - MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET; \ - __raw_writel(reg, MXC_CCM_CSCDR##nr); \ - \ - return 0; \ -} - -/* UART */ -CLK_GET_RATE(uart, 1, UART) -CLK_SET_PARENT(uart, 1, UART) - -static struct clk uart_root_clk = { - .parent = &pll2_sw_clk, - .get_rate = clk_uart_get_rate, - .set_parent = clk_uart_set_parent, -}; - -/* USBOH3 */ -CLK_GET_RATE(usboh3, 1, USBOH3) -CLK_SET_PARENT(usboh3, 1, USBOH3) - -static struct clk usboh3_clk = { - .parent = &pll2_sw_clk, - .get_rate = clk_usboh3_get_rate, - .set_parent = clk_usboh3_set_parent, - .enable = _clk_ccgr_enable, - .disable = _clk_ccgr_disable, - .enable_reg = MXC_CCM_CCGR2, - .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET, -}; - -static struct clk usb_ahb_clk = { - .parent = &ipg_clk, - .enable = _clk_ccgr_enable, - .disable = _clk_ccgr_disable, - .enable_reg = MXC_CCM_CCGR2, - .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET, -}; - -static int clk_usb_phy1_set_parent(struct clk *clk, struct clk *parent) -{ - u32 reg; - - reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_USB_PHY_CLK_SEL; - - if (parent == &pll3_sw_clk) - reg |= 1 << MXC_CCM_CSCMR1_USB_PHY_CLK_SEL_OFFSET; - - __raw_writel(reg, MXC_CCM_CSCMR1); - - return 0; -} - -static struct clk usb_phy1_clk = { - .parent = &pll3_sw_clk, - .set_parent = clk_usb_phy1_set_parent, - .enable = _clk_ccgr_enable, - .enable_reg = MXC_CCM_CCGR2, - .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET, - .disable = _clk_ccgr_disable, -}; - -/* eCSPI */ -CLK_GET_RATE(ecspi, 2, CSPI) -CLK_SET_PARENT(ecspi, 1, CSPI) - -static struct clk ecspi_main_clk = { - .parent = &pll3_sw_clk, - .get_rate = clk_ecspi_get_rate, - .set_parent = clk_ecspi_set_parent, -}; - -/* eSDHC */ -CLK_GET_RATE(esdhc1, 1, ESDHC1_MSHC1) -CLK_SET_PARENT(esdhc1, 1, ESDHC1_MSHC1) -CLK_SET_RATE(esdhc1, 1, ESDHC1_MSHC1) - -/* mx51 specific */ -CLK_GET_RATE(esdhc2, 1, ESDHC2_MSHC2) -CLK_SET_PARENT(esdhc2, 1, ESDHC2_MSHC2) -CLK_SET_RATE(esdhc2, 1, ESDHC2_MSHC2) - -static int clk_esdhc3_set_parent(struct clk *clk, struct clk *parent) -{ - u32 reg; - - reg = __raw_readl(MXC_CCM_CSCMR1); - if (parent == &esdhc1_clk) - reg &= ~MXC_CCM_CSCMR1_ESDHC3_CLK_SEL; - else if (parent == &esdhc2_clk) - reg |= MXC_CCM_CSCMR1_ESDHC3_CLK_SEL; - else - return -EINVAL; - __raw_writel(reg, MXC_CCM_CSCMR1); - - return 0; -} - -static int clk_esdhc4_set_parent(struct clk *clk, struct clk *parent) -{ - u32 reg; - - reg = __raw_readl(MXC_CCM_CSCMR1); - if (parent == &esdhc1_clk) - reg &= ~MXC_CCM_CSCMR1_ESDHC4_CLK_SEL; - else if (parent == &esdhc2_clk) - reg |= MXC_CCM_CSCMR1_ESDHC4_CLK_SEL; - else - return -EINVAL; - __raw_writel(reg, MXC_CCM_CSCMR1); - - return 0; -} - -/* mx53 specific */ -static int clk_esdhc2_mx53_set_parent(struct clk *clk, struct clk *parent) -{ - u32 reg; - - reg = __raw_readl(MXC_CCM_CSCMR1); - if (parent == &esdhc1_clk) - reg &= ~MXC_CCM_CSCMR1_ESDHC2_MSHC2_MX53_CLK_SEL; - else if (parent == &esdhc3_mx53_clk) - reg |= MXC_CCM_CSCMR1_ESDHC2_MSHC2_MX53_CLK_SEL; - else - return -EINVAL; - __raw_writel(reg, MXC_CCM_CSCMR1); - - return 0; -} - -CLK_GET_RATE(esdhc3_mx53, 1, ESDHC3_MX53) -CLK_SET_PARENT(esdhc3_mx53, 1, ESDHC3_MX53) -CLK_SET_RATE(esdhc3_mx53, 1, ESDHC3_MX53) - -static int clk_esdhc4_mx53_set_parent(struct clk *clk, struct clk *parent) -{ - u32 reg; - - reg = __raw_readl(MXC_CCM_CSCMR1); - if (parent == &esdhc1_clk) - reg &= ~MXC_CCM_CSCMR1_ESDHC4_CLK_SEL; - else if (parent == &esdhc3_mx53_clk) - reg |= MXC_CCM_CSCMR1_ESDHC4_CLK_SEL; - else - return -EINVAL; - __raw_writel(reg, MXC_CCM_CSCMR1); - - return 0; -} - -#define DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, e, d, p, s) \ - static struct clk name = { \ - .id = i, \ - .enable_reg = er, \ - .enable_shift = es, \ - .get_rate = gr, \ - .set_rate = sr, \ - .enable = e, \ - .disable = d, \ - .parent = p, \ - .secondary = s, \ - } - -#define DEFINE_CLOCK(name, i, er, es, gr, sr, p, s) \ - DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, _clk_ccgr_enable, _clk_ccgr_disable, p, s) - -/* Shared peripheral bus arbiter */ -DEFINE_CLOCK(spba_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG0_OFFSET, - NULL, NULL, &ipg_clk, NULL); - -/* UART */ -DEFINE_CLOCK(uart1_ipg_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG3_OFFSET, - NULL, NULL, &ipg_clk, &aips_tz1_clk); -DEFINE_CLOCK(uart2_ipg_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG5_OFFSET, - NULL, NULL, &ipg_clk, &aips_tz1_clk); -DEFINE_CLOCK(uart3_ipg_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG7_OFFSET, - NULL, NULL, &ipg_clk, &spba_clk); -DEFINE_CLOCK(uart4_ipg_clk, 3, MXC_CCM_CCGR7, MXC_CCM_CCGRx_CG4_OFFSET, - NULL, NULL, &ipg_clk, &spba_clk); -DEFINE_CLOCK(uart5_ipg_clk, 4, MXC_CCM_CCGR7, MXC_CCM_CCGRx_CG6_OFFSET, - NULL, NULL, &ipg_clk, &spba_clk); -DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG4_OFFSET, - NULL, NULL, &uart_root_clk, &uart1_ipg_clk); -DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG6_OFFSET, - NULL, NULL, &uart_root_clk, &uart2_ipg_clk); -DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG8_OFFSET, - NULL, NULL, &uart_root_clk, &uart3_ipg_clk); -DEFINE_CLOCK(uart4_clk, 3, MXC_CCM_CCGR7, MXC_CCM_CCGRx_CG5_OFFSET, - NULL, NULL, &uart_root_clk, &uart4_ipg_clk); -DEFINE_CLOCK(uart5_clk, 4, MXC_CCM_CCGR7, MXC_CCM_CCGRx_CG7_OFFSET, - NULL, NULL, &uart_root_clk, &uart5_ipg_clk); - -/* GPT */ -DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET, - NULL, NULL, &ipg_clk, NULL); -DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET, - NULL, NULL, &ipg_clk, &gpt_ipg_clk); - -DEFINE_CLOCK(pwm1_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG6_OFFSET, - NULL, NULL, &ipg_perclk, NULL); -DEFINE_CLOCK(pwm2_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG8_OFFSET, - NULL, NULL, &ipg_perclk, NULL); - -/* I2C */ -DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG9_OFFSET, - NULL, NULL, &ipg_perclk, NULL); -DEFINE_CLOCK(i2c2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG10_OFFSET, - NULL, NULL, &ipg_perclk, NULL); -DEFINE_CLOCK(hsi2c_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG11_OFFSET, - NULL, NULL, &ipg_clk, NULL); -DEFINE_CLOCK(i2c3_mx53_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG11_OFFSET, - NULL, NULL, &ipg_perclk, NULL); - -/* FEC */ -DEFINE_CLOCK(fec_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG12_OFFSET, - NULL, NULL, &ipg_clk, NULL); - -/* NFC */ -DEFINE_CLOCK_CCGR(nfc_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG10_OFFSET, - clk_nfc, &emi_slow_clk, NULL); - -/* SSI */ -DEFINE_CLOCK(ssi1_ipg_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG8_OFFSET, - NULL, NULL, &ipg_clk, NULL); -DEFINE_CLOCK(ssi1_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG9_OFFSET, - NULL, NULL, &pll3_sw_clk, &ssi1_ipg_clk); -DEFINE_CLOCK(ssi2_ipg_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG10_OFFSET, - NULL, NULL, &ipg_clk, NULL); -DEFINE_CLOCK(ssi2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG11_OFFSET, - NULL, NULL, &pll3_sw_clk, &ssi2_ipg_clk); -DEFINE_CLOCK(ssi3_ipg_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG12_OFFSET, - NULL, NULL, &ipg_clk, NULL); -DEFINE_CLOCK(ssi3_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG13_OFFSET, - NULL, NULL, &pll3_sw_clk, &ssi3_ipg_clk); - -/* eCSPI */ -DEFINE_CLOCK_FULL(ecspi1_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG9_OFFSET, - NULL, NULL, _clk_ccgr_enable_inrun, _clk_ccgr_disable, - &ipg_clk, &spba_clk); -DEFINE_CLOCK(ecspi1_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG10_OFFSET, - NULL, NULL, &ecspi_main_clk, &ecspi1_ipg_clk); -DEFINE_CLOCK_FULL(ecspi2_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG11_OFFSET, - NULL, NULL, _clk_ccgr_enable_inrun, _clk_ccgr_disable, - &ipg_clk, &aips_tz2_clk); -DEFINE_CLOCK(ecspi2_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG12_OFFSET, - NULL, NULL, &ecspi_main_clk, &ecspi2_ipg_clk); - -/* CSPI */ -DEFINE_CLOCK(cspi_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG9_OFFSET, - NULL, NULL, &ipg_clk, &aips_tz2_clk); -DEFINE_CLOCK(cspi_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG13_OFFSET, - NULL, NULL, &ipg_clk, &cspi_ipg_clk); - -/* SDMA */ -DEFINE_CLOCK(sdma_clk, 1, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG15_OFFSET, - NULL, NULL, &ahb_clk, NULL); - -/* eSDHC */ -DEFINE_CLOCK_FULL(esdhc1_ipg_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG0_OFFSET, - NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL); -DEFINE_CLOCK_MAX(esdhc1_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG1_OFFSET, - clk_esdhc1, &pll2_sw_clk, &esdhc1_ipg_clk); -DEFINE_CLOCK_FULL(esdhc2_ipg_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG2_OFFSET, - NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL); -DEFINE_CLOCK_FULL(esdhc3_ipg_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG4_OFFSET, - NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL); -DEFINE_CLOCK_FULL(esdhc4_ipg_clk, 3, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG6_OFFSET, - NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL); - -/* mx51 specific */ -DEFINE_CLOCK_MAX(esdhc2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG3_OFFSET, - clk_esdhc2, &pll2_sw_clk, &esdhc2_ipg_clk); - -static struct clk esdhc3_clk = { - .id = 2, - .parent = &esdhc1_clk, - .set_parent = clk_esdhc3_set_parent, - .enable_reg = MXC_CCM_CCGR3, - .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET, - .enable = _clk_max_enable, - .disable = _clk_max_disable, - .secondary = &esdhc3_ipg_clk, -}; -static struct clk esdhc4_clk = { - .id = 3, - .parent = &esdhc1_clk, - .set_parent = clk_esdhc4_set_parent, - .enable_reg = MXC_CCM_CCGR3, - .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET, - .enable = _clk_max_enable, - .disable = _clk_max_disable, - .secondary = &esdhc4_ipg_clk, -}; - -/* mx53 specific */ -static struct clk esdhc2_mx53_clk = { - .id = 2, - .parent = &esdhc1_clk, - .set_parent = clk_esdhc2_mx53_set_parent, - .enable_reg = MXC_CCM_CCGR3, - .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET, - .enable = _clk_max_enable, - .disable = _clk_max_disable, - .secondary = &esdhc3_ipg_clk, -}; - -DEFINE_CLOCK_MAX(esdhc3_mx53_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG5_OFFSET, - clk_esdhc3_mx53, &pll2_sw_clk, &esdhc2_ipg_clk); - -static struct clk esdhc4_mx53_clk = { - .id = 3, - .parent = &esdhc1_clk, - .set_parent = clk_esdhc4_mx53_set_parent, - .enable_reg = MXC_CCM_CCGR3, - .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET, - .enable = _clk_max_enable, - .disable = _clk_max_disable, - .secondary = &esdhc4_ipg_clk, -}; - -static struct clk sata_clk = { - .parent = &ipg_clk, - .enable = _clk_max_enable, - .enable_reg = MXC_CCM_CCGR4, - .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET, - .disable = _clk_max_disable, -}; - -static struct clk ahci_phy_clk = { - .parent = &usb_phy1_clk, -}; - -static struct clk ahci_dma_clk = { - .parent = &ahb_clk, -}; - -DEFINE_CLOCK(mipi_esc_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG5_OFFSET, NULL, NULL, NULL, &pll2_sw_clk); -DEFINE_CLOCK(mipi_hsc2_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG4_OFFSET, NULL, NULL, &mipi_esc_clk, &pll2_sw_clk); -DEFINE_CLOCK(mipi_hsc1_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG3_OFFSET, NULL, NULL, &mipi_hsc2_clk, &pll2_sw_clk); - -/* IPU */ -DEFINE_CLOCK_FULL(ipu_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG5_OFFSET, - NULL, NULL, clk_ipu_enable, clk_ipu_disable, &ahb_clk, &ipu_sec_clk); - -DEFINE_CLOCK_FULL(emi_fast_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG7_OFFSET, - NULL, NULL, _clk_ccgr_enable, _clk_ccgr_disable_inwait, - &ddr_clk, NULL); - -DEFINE_CLOCK(ipu_di0_clk, 0, MXC_CCM_CCGR6, MXC_CCM_CCGRx_CG5_OFFSET, - NULL, NULL, &pll3_sw_clk, NULL); -DEFINE_CLOCK(ipu_di1_clk, 0, MXC_CCM_CCGR6, MXC_CCM_CCGRx_CG6_OFFSET, - NULL, NULL, &pll3_sw_clk, NULL); - -/* PATA */ -DEFINE_CLOCK(pata_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG0_OFFSET, - NULL, NULL, &ipg_clk, &spba_clk); - -#define _REGISTER_CLOCK(d, n, c) \ - { \ - .dev_id = d, \ - .con_id = n, \ - .clk = &c, \ - }, - -static struct clk_lookup mx51_lookups[] = { - /* i.mx51 has the i.mx21 type uart */ - _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk) - _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk) - _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk) - _REGISTER_CLOCK(NULL, "gpt", gpt_clk) - /* i.mx51 has the i.mx27 type fec */ - _REGISTER_CLOCK("imx27-fec.0", NULL, fec_clk) - _REGISTER_CLOCK("mxc_pwm.0", "pwm", pwm1_clk) - _REGISTER_CLOCK("mxc_pwm.1", "pwm", pwm2_clk) - _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk) - _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk) - _REGISTER_CLOCK("imx-i2c.2", NULL, hsi2c_clk) - _REGISTER_CLOCK("mxc-ehci.0", "usb", usboh3_clk) - _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_ahb_clk) - _REGISTER_CLOCK("mxc-ehci.0", "usb_phy1", usb_phy1_clk) - _REGISTER_CLOCK("mxc-ehci.1", "usb", usboh3_clk) - _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_ahb_clk) - _REGISTER_CLOCK("mxc-ehci.2", "usb", usboh3_clk) - _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_ahb_clk) - _REGISTER_CLOCK("fsl-usb2-udc", "usb", usboh3_clk) - _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", ahb_clk) - _REGISTER_CLOCK("imx-keypad", NULL, dummy_clk) - _REGISTER_CLOCK("mxc_nand", NULL, nfc_clk) - _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) - _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) - _REGISTER_CLOCK("imx-ssi.2", NULL, ssi3_clk) - /* i.mx51 has the i.mx35 type sdma */ - _REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk) - _REGISTER_CLOCK(NULL, "ckih", ckih_clk) - _REGISTER_CLOCK(NULL, "ckih2", ckih2_clk) - _REGISTER_CLOCK(NULL, "gpt_32k", gpt_32k_clk) - _REGISTER_CLOCK("imx51-ecspi.0", NULL, ecspi1_clk) - _REGISTER_CLOCK("imx51-ecspi.1", NULL, ecspi2_clk) - /* i.mx51 has the i.mx35 type cspi */ - _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi_clk) - _REGISTER_CLOCK("sdhci-esdhc-imx51.0", NULL, esdhc1_clk) - _REGISTER_CLOCK("sdhci-esdhc-imx51.1", NULL, esdhc2_clk) - _REGISTER_CLOCK("sdhci-esdhc-imx51.2", NULL, esdhc3_clk) - _REGISTER_CLOCK("sdhci-esdhc-imx51.3", NULL, esdhc4_clk) - _REGISTER_CLOCK(NULL, "cpu_clk", cpu_clk) - _REGISTER_CLOCK(NULL, "iim_clk", iim_clk) - _REGISTER_CLOCK("imx2-wdt.0", NULL, dummy_clk) - _REGISTER_CLOCK("imx2-wdt.1", NULL, dummy_clk) - _REGISTER_CLOCK(NULL, "mipi_hsp", mipi_hsp_clk) - _REGISTER_CLOCK("imx-ipuv3", NULL, ipu_clk) - _REGISTER_CLOCK("imx-ipuv3", "di0", ipu_di0_clk) - _REGISTER_CLOCK("imx-ipuv3", "di1", ipu_di1_clk) - _REGISTER_CLOCK(NULL, "gpc_dvfs", gpc_dvfs_clk) - _REGISTER_CLOCK("pata_imx", NULL, pata_clk) -}; - -static struct clk_lookup mx53_lookups[] = { - /* i.mx53 has the i.mx21 type uart */ - _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk) - _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk) - _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk) - _REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk) - _REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk) - _REGISTER_CLOCK(NULL, "gpt", gpt_clk) - /* i.mx53 has the i.mx25 type fec */ - _REGISTER_CLOCK("imx25-fec.0", NULL, fec_clk) - _REGISTER_CLOCK(NULL, "iim_clk", iim_clk) - _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk) - _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk) - _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_mx53_clk) - /* i.mx53 has the i.mx51 type ecspi */ - _REGISTER_CLOCK("imx51-ecspi.0", NULL, ecspi1_clk) - _REGISTER_CLOCK("imx51-ecspi.1", NULL, ecspi2_clk) - /* i.mx53 has the i.mx25 type cspi */ - _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi_clk) - _REGISTER_CLOCK("sdhci-esdhc-imx53.0", NULL, esdhc1_clk) - _REGISTER_CLOCK("sdhci-esdhc-imx53.1", NULL, esdhc2_mx53_clk) - _REGISTER_CLOCK("sdhci-esdhc-imx53.2", NULL, esdhc3_mx53_clk) - _REGISTER_CLOCK("sdhci-esdhc-imx53.3", NULL, esdhc4_mx53_clk) - _REGISTER_CLOCK("imx2-wdt.0", NULL, dummy_clk) - _REGISTER_CLOCK("imx2-wdt.1", NULL, dummy_clk) - /* i.mx53 has the i.mx35 type sdma */ - _REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk) - _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) - _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) - _REGISTER_CLOCK("imx-ssi.2", NULL, ssi3_clk) - _REGISTER_CLOCK("imx-keypad", NULL, dummy_clk) - _REGISTER_CLOCK("pata_imx", NULL, pata_clk) - _REGISTER_CLOCK("imx53-ahci.0", "ahci", sata_clk) - _REGISTER_CLOCK("imx53-ahci.0", "ahci_phy", ahci_phy_clk) - _REGISTER_CLOCK("imx53-ahci.0", "ahci_dma", ahci_dma_clk) -}; - -static void clk_tree_init(void) -{ - u32 reg; - - ipg_perclk.set_parent(&ipg_perclk, &lp_apm_clk); - - /* - * Initialise the IPG PER CLK dividers to 3. IPG_PER_CLK should be at - * 8MHz, its derived from lp_apm. - * - * FIXME: Verify if true for all boards - */ - reg = __raw_readl(MXC_CCM_CBCDR); - reg &= ~MXC_CCM_CBCDR_PERCLK_PRED1_MASK; - reg &= ~MXC_CCM_CBCDR_PERCLK_PRED2_MASK; - reg &= ~MXC_CCM_CBCDR_PERCLK_PODF_MASK; - reg |= (2 << MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET); - __raw_writel(reg, MXC_CCM_CBCDR); -} - -int __init mx51_clocks_init(unsigned long ckil, unsigned long osc, - unsigned long ckih1, unsigned long ckih2) -{ - int i; - - external_low_reference = ckil; - external_high_reference = ckih1; - ckih2_reference = ckih2; - oscillator_reference = osc; - - for (i = 0; i < ARRAY_SIZE(mx51_lookups); i++) - clkdev_add(&mx51_lookups[i]); - - clk_tree_init(); - - clk_enable(&cpu_clk); - clk_enable(&main_bus_clk); - - clk_enable(&iim_clk); - imx_print_silicon_rev("i.MX51", mx51_revision()); - clk_disable(&iim_clk); - - /* move usb_phy_clk to 24MHz */ - clk_set_parent(&usb_phy1_clk, &osc_clk); - - /* set the usboh3_clk parent to pll2_sw_clk */ - clk_set_parent(&usboh3_clk, &pll2_sw_clk); - - /* Set SDHC parents to be PLL2 */ - clk_set_parent(&esdhc1_clk, &pll2_sw_clk); - clk_set_parent(&esdhc2_clk, &pll2_sw_clk); - - /* set SDHC root clock as 166.25MHZ*/ - clk_set_rate(&esdhc1_clk, 166250000); - clk_set_rate(&esdhc2_clk, 166250000); - - /* System timer */ - mxc_timer_init(&gpt_clk, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR), - MX51_INT_GPT); - return 0; -} - -int __init mx53_clocks_init(unsigned long ckil, unsigned long osc, - unsigned long ckih1, unsigned long ckih2) -{ - int i; - - external_low_reference = ckil; - external_high_reference = ckih1; - ckih2_reference = ckih2; - oscillator_reference = osc; - - for (i = 0; i < ARRAY_SIZE(mx53_lookups); i++) - clkdev_add(&mx53_lookups[i]); - - clk_tree_init(); - - clk_set_parent(&uart_root_clk, &pll3_sw_clk); - clk_enable(&cpu_clk); - clk_enable(&main_bus_clk); - - clk_enable(&iim_clk); - imx_print_silicon_rev("i.MX53", mx53_revision()); - clk_disable(&iim_clk); - - /* Set SDHC parents to be PLL2 */ - clk_set_parent(&esdhc1_clk, &pll2_sw_clk); - clk_set_parent(&esdhc3_mx53_clk, &pll2_sw_clk); - - /* set SDHC root clock as 200MHZ*/ - clk_set_rate(&esdhc1_clk, 200000000); - clk_set_rate(&esdhc3_mx53_clk, 200000000); - - /* System timer */ - mxc_timer_init(&gpt_clk, MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR), - MX53_INT_GPT); - return 0; -} - -#ifdef CONFIG_OF -static void __init clk_get_freq_dt(unsigned long *ckil, unsigned long *osc, - unsigned long *ckih1, unsigned long *ckih2) -{ - struct device_node *np; - - /* retrieve the freqency of fixed clocks from device tree */ - for_each_compatible_node(np, NULL, "fixed-clock") { - u32 rate; - if (of_property_read_u32(np, "clock-frequency", &rate)) - continue; - - if (of_device_is_compatible(np, "fsl,imx-ckil")) - *ckil = rate; - else if (of_device_is_compatible(np, "fsl,imx-osc")) - *osc = rate; - else if (of_device_is_compatible(np, "fsl,imx-ckih1")) - *ckih1 = rate; - else if (of_device_is_compatible(np, "fsl,imx-ckih2")) - *ckih2 = rate; - } -} - -int __init mx51_clocks_init_dt(void) -{ - unsigned long ckil, osc, ckih1, ckih2; - - clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2); - return mx51_clocks_init(ckil, osc, ckih1, ckih2); -} - -int __init mx53_clocks_init_dt(void) -{ - unsigned long ckil, osc, ckih1, ckih2; - - clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2); - return mx53_clocks_init(ckil, osc, ckih1, ckih2); -} -#endif diff --git a/trunk/arch/arm/mach-imx/cpu-imx5.c b/trunk/arch/arm/mach-imx/cpu-imx5.c index aa15c517d06e..8eb15a2fcaf9 100644 --- a/trunk/arch/arm/mach-imx/cpu-imx5.c +++ b/trunk/arch/arm/mach-imx/cpu-imx5.c @@ -62,11 +62,8 @@ EXPORT_SYMBOL(mx51_revision); * Dependent on link order - so the assumption is that vfp_init is called * before us. */ -static int __init mx51_neon_fixup(void) +int __init mx51_neon_fixup(void) { - if (!cpu_is_mx51()) - return 0; - if (mx51_revision() < IMX_CHIP_REVISION_3_0 && (elf_hwcap & HWCAP_NEON)) { elf_hwcap &= ~HWCAP_NEON; @@ -75,7 +72,6 @@ static int __init mx51_neon_fixup(void) return 0; } -late_initcall(mx51_neon_fixup); #endif static int get_mx53_srev(void) diff --git a/trunk/arch/arm/mach-imx/crm-regs-imx5.h b/trunk/arch/arm/mach-imx/crm-regs-imx5.h index 5e11ba7daee2..5e3f1f0f4cab 100644 --- a/trunk/arch/arm/mach-imx/crm-regs-imx5.h +++ b/trunk/arch/arm/mach-imx/crm-regs-imx5.h @@ -23,7 +23,7 @@ #define MX53_DPLL1_BASE MX53_IO_ADDRESS(MX53_PLL1_BASE_ADDR) #define MX53_DPLL2_BASE MX53_IO_ADDRESS(MX53_PLL2_BASE_ADDR) #define MX53_DPLL3_BASE MX53_IO_ADDRESS(MX53_PLL3_BASE_ADDR) -#define MX53_DPLL4_BASE MX53_IO_ADDRESS(MX53_PLL3_BASE_ADDR) +#define MX53_DPLL4_BASE MX53_IO_ADDRESS(MX53_PLL4_BASE_ADDR) /* PLL Register Offsets */ #define MXC_PLL_DP_CTL 0x00 diff --git a/trunk/arch/arm/mach-imx/crmregs-imx3.h b/trunk/arch/arm/mach-imx/crmregs-imx3.h index 53141273df45..a1dfde53e335 100644 --- a/trunk/arch/arm/mach-imx/crmregs-imx3.h +++ b/trunk/arch/arm/mach-imx/crmregs-imx3.h @@ -24,48 +24,47 @@ #define CKIH_CLK_FREQ_27MHZ 27000000 #define CKIL_CLK_FREQ 32768 -#define MXC_CCM_BASE (cpu_is_mx31() ? \ -MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR) : MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR)) +extern void __iomem *mx3_ccm_base; /* Register addresses */ -#define MXC_CCM_CCMR (MXC_CCM_BASE + 0x00) -#define MXC_CCM_PDR0 (MXC_CCM_BASE + 0x04) -#define MXC_CCM_PDR1 (MXC_CCM_BASE + 0x08) -#define MX35_CCM_PDR2 (MXC_CCM_BASE + 0x0C) -#define MXC_CCM_RCSR (MXC_CCM_BASE + 0x0C) -#define MX35_CCM_PDR3 (MXC_CCM_BASE + 0x10) -#define MXC_CCM_MPCTL (MXC_CCM_BASE + 0x10) -#define MX35_CCM_PDR4 (MXC_CCM_BASE + 0x14) -#define MXC_CCM_UPCTL (MXC_CCM_BASE + 0x14) -#define MX35_CCM_RCSR (MXC_CCM_BASE + 0x18) -#define MXC_CCM_SRPCTL (MXC_CCM_BASE + 0x18) -#define MX35_CCM_MPCTL (MXC_CCM_BASE + 0x1C) -#define MXC_CCM_COSR (MXC_CCM_BASE + 0x1C) -#define MX35_CCM_PPCTL (MXC_CCM_BASE + 0x20) -#define MXC_CCM_CGR0 (MXC_CCM_BASE + 0x20) -#define MX35_CCM_ACMR (MXC_CCM_BASE + 0x24) -#define MXC_CCM_CGR1 (MXC_CCM_BASE + 0x24) -#define MX35_CCM_COSR (MXC_CCM_BASE + 0x28) -#define MXC_CCM_CGR2 (MXC_CCM_BASE + 0x28) -#define MX35_CCM_CGR0 (MXC_CCM_BASE + 0x2C) -#define MXC_CCM_WIMR (MXC_CCM_BASE + 0x2C) -#define MX35_CCM_CGR1 (MXC_CCM_BASE + 0x30) -#define MXC_CCM_LDC (MXC_CCM_BASE + 0x30) -#define MX35_CCM_CGR2 (MXC_CCM_BASE + 0x34) -#define MXC_CCM_DCVR0 (MXC_CCM_BASE + 0x34) -#define MX35_CCM_CGR3 (MXC_CCM_BASE + 0x38) -#define MXC_CCM_DCVR1 (MXC_CCM_BASE + 0x38) -#define MXC_CCM_DCVR2 (MXC_CCM_BASE + 0x3C) -#define MXC_CCM_DCVR3 (MXC_CCM_BASE + 0x40) -#define MXC_CCM_LTR0 (MXC_CCM_BASE + 0x44) -#define MXC_CCM_LTR1 (MXC_CCM_BASE + 0x48) -#define MXC_CCM_LTR2 (MXC_CCM_BASE + 0x4C) -#define MXC_CCM_LTR3 (MXC_CCM_BASE + 0x50) -#define MXC_CCM_LTBR0 (MXC_CCM_BASE + 0x54) -#define MXC_CCM_LTBR1 (MXC_CCM_BASE + 0x58) -#define MXC_CCM_PMCR0 (MXC_CCM_BASE + 0x5C) -#define MXC_CCM_PMCR1 (MXC_CCM_BASE + 0x60) -#define MXC_CCM_PDR2 (MXC_CCM_BASE + 0x64) +#define MXC_CCM_CCMR 0x00 +#define MXC_CCM_PDR0 0x04 +#define MXC_CCM_PDR1 0x08 +#define MX35_CCM_PDR2 0x0C +#define MXC_CCM_RCSR 0x0C +#define MX35_CCM_PDR3 0x10 +#define MXC_CCM_MPCTL 0x10 +#define MX35_CCM_PDR4 0x14 +#define MXC_CCM_UPCTL 0x14 +#define MX35_CCM_RCSR 0x18 +#define MXC_CCM_SRPCTL 0x18 +#define MX35_CCM_MPCTL 0x1C +#define MXC_CCM_COSR 0x1C +#define MX35_CCM_PPCTL 0x20 +#define MXC_CCM_CGR0 0x20 +#define MX35_CCM_ACMR 0x24 +#define MXC_CCM_CGR1 0x24 +#define MX35_CCM_COSR 0x28 +#define MXC_CCM_CGR2 0x28 +#define MX35_CCM_CGR0 0x2C +#define MXC_CCM_WIMR 0x2C +#define MX35_CCM_CGR1 0x30 +#define MXC_CCM_LDC 0x30 +#define MX35_CCM_CGR2 0x34 +#define MXC_CCM_DCVR0 0x34 +#define MX35_CCM_CGR3 0x38 +#define MXC_CCM_DCVR1 0x38 +#define MXC_CCM_DCVR2 0x3C +#define MXC_CCM_DCVR3 0x40 +#define MXC_CCM_LTR0 0x44 +#define MXC_CCM_LTR1 0x48 +#define MXC_CCM_LTR2 0x4C +#define MXC_CCM_LTR3 0x50 +#define MXC_CCM_LTBR0 0x54 +#define MXC_CCM_LTBR1 0x58 +#define MXC_CCM_PMCR0 0x5C +#define MXC_CCM_PMCR1 0x60 +#define MXC_CCM_PDR2 0x64 /* Register bit definitions */ #define MXC_CCM_CCMR_WBEN (1 << 27) diff --git a/trunk/arch/arm/mach-imx/hotplug.c b/trunk/arch/arm/mach-imx/hotplug.c index 89493abd497c..20ed2d56c1af 100644 --- a/trunk/arch/arm/mach-imx/hotplug.c +++ b/trunk/arch/arm/mach-imx/hotplug.c @@ -12,6 +12,7 @@ #include #include +#include #include int platform_cpu_kill(unsigned int cpu) @@ -19,6 +20,44 @@ int platform_cpu_kill(unsigned int cpu) return 1; } +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" + /* + * Turn off coherency + */ + " mrc p15, 0, %0, c1, c0, 1\n" + " bic %0, %0, %3\n" + " mcr p15, 0, %0, c1, c0, 1\n" + " mrc p15, 0, %0, c1, c0, 0\n" + " bic %0, %0, %2\n" + " mcr p15, 0, %0, c1, c0, 0\n" + : "=&r" (v) + : "r" (0), "Ir" (CR_C), "Ir" (0x40) + : "cc"); +} + +static inline void cpu_leave_lowpower(void) +{ + unsigned int v; + + asm volatile( + "mrc p15, 0, %0, c1, c0, 0\n" + " orr %0, %0, %1\n" + " mcr p15, 0, %0, c1, c0, 0\n" + " mrc p15, 0, %0, c1, c0, 1\n" + " orr %0, %0, %2\n" + " mcr p15, 0, %0, c1, c0, 1\n" + : "=&r" (v) + : "Ir" (CR_C), "Ir" (0x40) + : "cc"); +} + /* * platform-specific code to shutdown a CPU * @@ -26,9 +65,10 @@ int platform_cpu_kill(unsigned int cpu) */ void platform_cpu_die(unsigned int cpu) { - flush_cache_all(); + cpu_enter_lowpower(); imx_enable_cpu(cpu, false); cpu_do_idle(); + cpu_leave_lowpower(); /* We should never return from idle */ panic("cpu %d unexpectedly exit from shutdown\n", cpu); diff --git a/trunk/arch/arm/mach-imx/imx27-dt.c b/trunk/arch/arm/mach-imx/imx27-dt.c index ed38d03c61f2..eee0cc8d92a4 100644 --- a/trunk/arch/arm/mach-imx/imx27-dt.c +++ b/trunk/arch/arm/mach-imx/imx27-dt.c @@ -29,6 +29,7 @@ static const struct of_dev_auxdata imx27_auxdata_lookup[] __initconst = { OF_DEV_AUXDATA("fsl,imx27-cspi", MX27_CSPI2_BASE_ADDR, "imx27-cspi.1", NULL), OF_DEV_AUXDATA("fsl,imx27-cspi", MX27_CSPI3_BASE_ADDR, "imx27-cspi.2", NULL), OF_DEV_AUXDATA("fsl,imx27-wdt", MX27_WDOG_BASE_ADDR, "imx2-wdt.0", NULL), + OF_DEV_AUXDATA("fsl,imx27-nand", MX27_NFC_BASE_ADDR, "mxc_nand.0", NULL), { /* sentinel */ } }; diff --git a/trunk/arch/arm/mach-imx/imx51-dt.c b/trunk/arch/arm/mach-imx/imx51-dt.c index 5f577fbda2c8..18e78dba4298 100644 --- a/trunk/arch/arm/mach-imx/imx51-dt.c +++ b/trunk/arch/arm/mach-imx/imx51-dt.c @@ -118,6 +118,7 @@ DT_MACHINE_START(IMX51_DT, "Freescale i.MX51 (Device Tree Support)") .handle_irq = imx51_handle_irq, .timer = &imx51_timer, .init_machine = imx51_dt_init, + .init_late = imx51_init_late, .dt_compat = imx51_dt_board_compat, .restart = mxc_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-imx/imx53-dt.c b/trunk/arch/arm/mach-imx/imx53-dt.c index 574eca4b89a5..eb04b6248e48 100644 --- a/trunk/arch/arm/mach-imx/imx53-dt.c +++ b/trunk/arch/arm/mach-imx/imx53-dt.c @@ -10,6 +10,9 @@ * http://www.gnu.org/copyleft/gpl.html */ +#include +#include +#include #include #include #include @@ -81,6 +84,19 @@ static const struct of_device_id imx53_iomuxc_of_match[] __initconst = { { /* sentinel */ } }; +static void __init imx53_qsb_init(void) +{ + struct clk *clk; + + clk = clk_get_sys(NULL, "ssi_ext1"); + if (IS_ERR(clk)) { + pr_err("failed to get clk ssi_ext1\n"); + return; + } + + clk_register_clkdev(clk, NULL, "0-000a"); +} + static void __init imx53_dt_init(void) { struct device_node *node; @@ -99,6 +115,9 @@ static void __init imx53_dt_init(void) of_node_put(node); } + if (of_machine_is_compatible("fsl,imx53-qsb")) + imx53_qsb_init(); + of_platform_populate(NULL, of_default_bus_match_table, imx53_auxdata_lookup, NULL); } diff --git a/trunk/arch/arm/mach-imx/lluart.c b/trunk/arch/arm/mach-imx/lluart.c index 0213f8dcee81..c40a34c00489 100644 --- a/trunk/arch/arm/mach-imx/lluart.c +++ b/trunk/arch/arm/mach-imx/lluart.c @@ -17,6 +17,12 @@ #include static struct map_desc imx_lluart_desc = { +#ifdef CONFIG_DEBUG_IMX6Q_UART2 + .virtual = MX6Q_IO_P2V(MX6Q_UART2_BASE_ADDR), + .pfn = __phys_to_pfn(MX6Q_UART2_BASE_ADDR), + .length = MX6Q_UART2_SIZE, + .type = MT_DEVICE, +#endif #ifdef CONFIG_DEBUG_IMX6Q_UART4 .virtual = MX6Q_IO_P2V(MX6Q_UART4_BASE_ADDR), .pfn = __phys_to_pfn(MX6Q_UART4_BASE_ADDR), diff --git a/trunk/arch/arm/mach-imx/mach-cpuimx35.c b/trunk/arch/arm/mach-imx/mach-cpuimx35.c index c515f8ede1a1..6450303f1a7a 100644 --- a/trunk/arch/arm/mach-imx/mach-cpuimx35.c +++ b/trunk/arch/arm/mach-imx/mach-cpuimx35.c @@ -70,7 +70,6 @@ static struct i2c_board_info eukrea_cpuimx35_i2c_devices[] = { I2C_BOARD_INFO("pcf8563", 0x51), }, { I2C_BOARD_INFO("tsc2007", 0x48), - .type = "tsc2007", .platform_data = &tsc2007_info, .irq = IMX_GPIO_TO_IRQ(TSC2007_IRQGPIO), }, diff --git a/trunk/arch/arm/mach-imx/mach-cpuimx51sd.c b/trunk/arch/arm/mach-imx/mach-cpuimx51sd.c index ce341a6874fc..1e09de50cbcd 100644 --- a/trunk/arch/arm/mach-imx/mach-cpuimx51sd.c +++ b/trunk/arch/arm/mach-imx/mach-cpuimx51sd.c @@ -142,7 +142,6 @@ static struct i2c_board_info eukrea_cpuimx51sd_i2c_devices[] = { I2C_BOARD_INFO("pcf8563", 0x51), }, { I2C_BOARD_INFO("tsc2007", 0x49), - .type = "tsc2007", .platform_data = &tsc2007_info, }, }; @@ -369,5 +368,6 @@ MACHINE_START(EUKREA_CPUIMX51SD, "Eukrea CPUIMX51SD") .handle_irq = imx51_handle_irq, .timer = &mxc_timer, .init_machine = eukrea_cpuimx51sd_init, + .init_late = imx51_init_late, .restart = mxc_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-imx/mach-imx27_visstrim_m10.c b/trunk/arch/arm/mach-imx/mach-imx27_visstrim_m10.c index dff82eb57cd9..f76edb96a48a 100644 --- a/trunk/arch/arm/mach-imx/mach-imx27_visstrim_m10.c +++ b/trunk/arch/arm/mach-imx/mach-imx27_visstrim_m10.c @@ -116,6 +116,8 @@ static const int visstrim_m10_pins[] __initconst = { PB23_PF_USB_PWR, PB24_PF_USB_OC, /* CSI */ + TVP5150_RSTN | GPIO_GPIO | GPIO_OUT, + TVP5150_PWDN | GPIO_GPIO | GPIO_OUT, PB10_PF_CSI_D0, PB11_PF_CSI_D1, PB12_PF_CSI_D2, @@ -147,6 +149,24 @@ static struct gpio visstrim_m10_version_gpios[] = { { MOTHERBOARD_BIT2, GPIOF_IN, "mother-version-2" }, }; +static const struct gpio visstrim_m10_gpios[] __initconst = { + { + .gpio = TVP5150_RSTN, + .flags = GPIOF_DIR_OUT | GPIOF_INIT_HIGH, + .label = "tvp5150_rstn", + }, + { + .gpio = TVP5150_PWDN, + .flags = GPIOF_DIR_OUT | GPIOF_INIT_LOW, + .label = "tvp5150_pwdn", + }, + { + .gpio = OTG_PHY_CS_GPIO, + .flags = GPIOF_DIR_OUT | GPIOF_INIT_LOW, + .label = "usbotg_cs", + }, +}; + /* Camera */ static int visstrim_camera_power(struct device *dev, int on) { @@ -190,13 +210,6 @@ static void __init visstrim_camera_init(void) struct platform_device *pdev; int dma; - /* Initialize tvp5150 gpios */ - mxc_gpio_mode(TVP5150_RSTN | GPIO_GPIO | GPIO_OUT); - mxc_gpio_mode(TVP5150_PWDN | GPIO_GPIO | GPIO_OUT); - gpio_set_value(TVP5150_RSTN, 1); - gpio_set_value(TVP5150_PWDN, 0); - ndelay(1); - gpio_set_value(TVP5150_PWDN, 1); ndelay(1); gpio_set_value(TVP5150_RSTN, 0); @@ -377,10 +390,6 @@ static struct i2c_board_info visstrim_m10_i2c_devices[] = { /* USB OTG */ static int otg_phy_init(struct platform_device *pdev) { - gpio_set_value(OTG_PHY_CS_GPIO, 0); - - mdelay(10); - return mx27_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED); } @@ -435,6 +444,11 @@ static void __init visstrim_m10_board_init(void) if (ret) pr_err("Failed to setup pins (%d)\n", ret); + ret = gpio_request_array(visstrim_m10_gpios, + ARRAY_SIZE(visstrim_m10_gpios)); + if (ret) + pr_err("Failed to request gpios (%d)\n", ret); + imx27_add_imx_ssi(0, &visstrim_m10_ssi_pdata); imx27_add_imx_uart0(&uart_pdata); diff --git a/trunk/arch/arm/mach-imx/mach-imx6q.c b/trunk/arch/arm/mach-imx/mach-imx6q.c index 3df360a52c17..b47e98b7d539 100644 --- a/trunk/arch/arm/mach-imx/mach-imx6q.c +++ b/trunk/arch/arm/mach-imx/mach-imx6q.c @@ -10,6 +10,8 @@ * http://www.gnu.org/copyleft/gpl.html */ +#include +#include #include #include #include @@ -64,18 +66,53 @@ void imx6q_restart(char mode, const char *cmd) /* For imx6q sabrelite board: set KSZ9021RN RGMII pad skew */ static int ksz9021rn_phy_fixup(struct phy_device *phydev) { - /* min rx data delay */ - phy_write(phydev, 0x0b, 0x8105); - phy_write(phydev, 0x0c, 0x0000); + if (IS_ENABLED(CONFIG_PHYLIB)) { + /* min rx data delay */ + phy_write(phydev, 0x0b, 0x8105); + phy_write(phydev, 0x0c, 0x0000); - /* max rx/tx clock delay, min rx/tx control delay */ - phy_write(phydev, 0x0b, 0x8104); - phy_write(phydev, 0x0c, 0xf0f0); - phy_write(phydev, 0x0b, 0x104); + /* max rx/tx clock delay, min rx/tx control delay */ + phy_write(phydev, 0x0b, 0x8104); + phy_write(phydev, 0x0c, 0xf0f0); + phy_write(phydev, 0x0b, 0x104); + } return 0; } +static void __init imx6q_sabrelite_cko1_setup(void) +{ + struct clk *cko1_sel, *ahb, *cko1; + unsigned long rate; + + cko1_sel = clk_get_sys(NULL, "cko1_sel"); + ahb = clk_get_sys(NULL, "ahb"); + cko1 = clk_get_sys(NULL, "cko1"); + if (IS_ERR(cko1_sel) || IS_ERR(ahb) || IS_ERR(cko1)) { + pr_err("cko1 setup failed!\n"); + goto put_clk; + } + clk_set_parent(cko1_sel, ahb); + rate = clk_round_rate(cko1, 16000000); + clk_set_rate(cko1, rate); + clk_register_clkdev(cko1, NULL, "0-000a"); +put_clk: + if (!IS_ERR(cko1_sel)) + clk_put(cko1_sel); + if (!IS_ERR(ahb)) + clk_put(ahb); + if (!IS_ERR(cko1)) + clk_put(cko1); +} + +static void __init imx6q_sabrelite_init(void) +{ + if (IS_ENABLED(CONFIG_PHYLIB)) + phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK, + ksz9021rn_phy_fixup); + imx6q_sabrelite_cko1_setup(); +} + static void __init imx6q_init_machine(void) { /* @@ -85,8 +122,7 @@ static void __init imx6q_init_machine(void) pinctrl_provide_dummies(); if (of_machine_is_compatible("fsl,imx6q-sabrelite")) - phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK, - ksz9021rn_phy_fixup); + imx6q_sabrelite_init(); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); @@ -139,6 +175,7 @@ static struct sys_timer imx6q_timer = { static const char *imx6q_dt_compat[] __initdata = { "fsl,imx6q-arm2", "fsl,imx6q-sabrelite", + "fsl,imx6q-sabresd", "fsl,imx6q", NULL, }; diff --git a/trunk/arch/arm/mach-imx/mach-mx21ads.c b/trunk/arch/arm/mach-imx/mach-mx21ads.c index d14bbe949a4f..3e7401fca76c 100644 --- a/trunk/arch/arm/mach-imx/mach-mx21ads.c +++ b/trunk/arch/arm/mach-imx/mach-mx21ads.c @@ -32,7 +32,7 @@ * Memory-mapped I/O on MX21ADS base board */ #define MX21ADS_MMIO_BASE_ADDR 0xf5000000 -#define MX21ADS_MMIO_SIZE SZ_16M +#define MX21ADS_MMIO_SIZE 0xc00000 #define MX21ADS_REG_ADDR(offset) (void __force __iomem *) \ (MX21ADS_MMIO_BASE_ADDR + (offset)) diff --git a/trunk/arch/arm/mach-imx/mach-mx51_3ds.c b/trunk/arch/arm/mach-imx/mach-mx51_3ds.c index 83eab4176ca4..3c5b163923f6 100644 --- a/trunk/arch/arm/mach-imx/mach-mx51_3ds.c +++ b/trunk/arch/arm/mach-imx/mach-mx51_3ds.c @@ -175,5 +175,6 @@ MACHINE_START(MX51_3DS, "Freescale MX51 3-Stack Board") .handle_irq = imx51_handle_irq, .timer = &mx51_3ds_timer, .init_machine = mx51_3ds_init, + .init_late = imx51_init_late, .restart = mxc_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-imx/mach-mx51_babbage.c b/trunk/arch/arm/mach-imx/mach-mx51_babbage.c index e4b822e9f719..dde397014d4b 100644 --- a/trunk/arch/arm/mach-imx/mach-mx51_babbage.c +++ b/trunk/arch/arm/mach-imx/mach-mx51_babbage.c @@ -163,6 +163,12 @@ static iomux_v3_cfg_t mx51babbage_pads[] = { MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK, MX51_PAD_CSPI1_SS0__GPIO4_24, MX51_PAD_CSPI1_SS1__GPIO4_25, + + /* Audio */ + MX51_PAD_AUD3_BB_TXD__AUD3_TXD, + MX51_PAD_AUD3_BB_RXD__AUD3_RXD, + MX51_PAD_AUD3_BB_CK__AUD3_TXC, + MX51_PAD_AUD3_BB_FS__AUD3_TXFS, }; /* Serial ports */ @@ -426,5 +432,6 @@ MACHINE_START(MX51_BABBAGE, "Freescale MX51 Babbage Board") .handle_irq = imx51_handle_irq, .timer = &mx51_babbage_timer, .init_machine = mx51_babbage_init, + .init_late = imx51_init_late, .restart = mxc_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-imx/mach-mx51_efikamx.c b/trunk/arch/arm/mach-imx/mach-mx51_efikamx.c index 86e96ef11f9d..8d09c0126cab 100644 --- a/trunk/arch/arm/mach-imx/mach-mx51_efikamx.c +++ b/trunk/arch/arm/mach-imx/mach-mx51_efikamx.c @@ -207,29 +207,32 @@ static void mx51_efikamx_power_off(void) static int __init mx51_efikamx_power_init(void) { - if (machine_is_mx51_efikamx()) { - pwgt1 = regulator_get(NULL, "pwgt1"); - pwgt2 = regulator_get(NULL, "pwgt2"); - if (!IS_ERR(pwgt1) && !IS_ERR(pwgt2)) { - regulator_enable(pwgt1); - regulator_enable(pwgt2); - } - gpio_request(EFIKAMX_POWEROFF, "poweroff"); - pm_power_off = mx51_efikamx_power_off; - - /* enable coincell charger. maybe need a small power driver ? */ - coincell = regulator_get(NULL, "coincell"); - if (!IS_ERR(coincell)) { - regulator_set_voltage(coincell, 3000000, 3000000); - regulator_enable(coincell); - } - - regulator_has_full_constraints(); + pwgt1 = regulator_get(NULL, "pwgt1"); + pwgt2 = regulator_get(NULL, "pwgt2"); + if (!IS_ERR(pwgt1) && !IS_ERR(pwgt2)) { + regulator_enable(pwgt1); + regulator_enable(pwgt2); + } + gpio_request(EFIKAMX_POWEROFF, "poweroff"); + pm_power_off = mx51_efikamx_power_off; + + /* enable coincell charger. maybe need a small power driver ? */ + coincell = regulator_get(NULL, "coincell"); + if (!IS_ERR(coincell)) { + regulator_set_voltage(coincell, 3000000, 3000000); + regulator_enable(coincell); } + regulator_has_full_constraints(); + return 0; } -late_initcall(mx51_efikamx_power_init); + +static void __init mx51_efikamx_init_late(void) +{ + imx51_init_late(); + mx51_efikamx_power_init(); +} static void __init mx51_efikamx_init(void) { @@ -292,5 +295,6 @@ MACHINE_START(MX51_EFIKAMX, "Genesi Efika MX (Smarttop)") .handle_irq = imx51_handle_irq, .timer = &mx51_efikamx_timer, .init_machine = mx51_efikamx_init, + .init_late = mx51_efikamx_init_late, .restart = mx51_efikamx_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-imx/mach-mx51_efikasb.c b/trunk/arch/arm/mach-imx/mach-mx51_efikasb.c index 88f837a6cc76..fdbd181b97ef 100644 --- a/trunk/arch/arm/mach-imx/mach-mx51_efikasb.c +++ b/trunk/arch/arm/mach-imx/mach-mx51_efikasb.c @@ -211,22 +211,25 @@ static void mx51_efikasb_power_off(void) static int __init mx51_efikasb_power_init(void) { - if (machine_is_mx51_efikasb()) { - pwgt1 = regulator_get(NULL, "pwgt1"); - pwgt2 = regulator_get(NULL, "pwgt2"); - if (!IS_ERR(pwgt1) && !IS_ERR(pwgt2)) { - regulator_enable(pwgt1); - regulator_enable(pwgt2); - } - gpio_request(EFIKASB_POWEROFF, "poweroff"); - pm_power_off = mx51_efikasb_power_off; - - regulator_has_full_constraints(); + pwgt1 = regulator_get(NULL, "pwgt1"); + pwgt2 = regulator_get(NULL, "pwgt2"); + if (!IS_ERR(pwgt1) && !IS_ERR(pwgt2)) { + regulator_enable(pwgt1); + regulator_enable(pwgt2); } + gpio_request(EFIKASB_POWEROFF, "poweroff"); + pm_power_off = mx51_efikasb_power_off; + + regulator_has_full_constraints(); return 0; } -late_initcall(mx51_efikasb_power_init); + +static void __init mx51_efikasb_init_late(void) +{ + imx51_init_late(); + mx51_efikasb_power_init(); +} /* 01 R1.3 board 10 R2.0 board */ @@ -287,6 +290,7 @@ MACHINE_START(MX51_EFIKASB, "Genesi Efika MX (Smartbook)") .init_irq = mx51_init_irq, .handle_irq = imx51_handle_irq, .init_machine = efikasb_board_init, + .init_late = mx51_efikasb_init_late, .timer = &mx51_efikasb_timer, .restart = mxc_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-imx/mach-pcm037.c b/trunk/arch/arm/mach-imx/mach-pcm037.c index 10c9795934a3..0a40004154f2 100644 --- a/trunk/arch/arm/mach-imx/mach-pcm037.c +++ b/trunk/arch/arm/mach-imx/mach-pcm037.c @@ -694,6 +694,11 @@ static void __init pcm037_reserve(void) MX3_CAMERA_BUF_SIZE); } +static void __init pcm037_init_late(void) +{ + pcm037_eet_init_devices(); +} + MACHINE_START(PCM037, "Phytec Phycore pcm037") /* Maintainer: Pengutronix */ .atag_offset = 0x100, @@ -704,5 +709,6 @@ MACHINE_START(PCM037, "Phytec Phycore pcm037") .handle_irq = imx31_handle_irq, .timer = &pcm037_timer, .init_machine = pcm037_init, + .init_late = pcm037_init_late, .restart = mxc_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-imx/mach-pcm037_eet.c b/trunk/arch/arm/mach-imx/mach-pcm037_eet.c index 1b7606bef8f4..11ffa81ad17d 100644 --- a/trunk/arch/arm/mach-imx/mach-pcm037_eet.c +++ b/trunk/arch/arm/mach-imx/mach-pcm037_eet.c @@ -160,9 +160,9 @@ static const struct gpio_keys_platform_data .rep = 0, /* No auto-repeat */ }; -static int __init eet_init_devices(void) +int __init pcm037_eet_init_devices(void) { - if (!machine_is_pcm037() || pcm037_variant() != PCM037_EET) + if (pcm037_variant() != PCM037_EET) return 0; mxc_iomux_setup_multiple_pins(pcm037_eet_pins, @@ -176,4 +176,3 @@ static int __init eet_init_devices(void) return 0; } -late_initcall(eet_init_devices); diff --git a/trunk/arch/arm/mach-imx/mm-imx3.c b/trunk/arch/arm/mach-imx/mm-imx3.c index 9128d15b1eb7..a8983b9778d1 100644 --- a/trunk/arch/arm/mach-imx/mm-imx3.c +++ b/trunk/arch/arm/mach-imx/mm-imx3.c @@ -32,6 +32,10 @@ #include #include +#include "crmregs-imx3.h" + +void __iomem *mx3_ccm_base; + static void imx3_idle(void) { unsigned long reg = 0; @@ -82,6 +86,7 @@ static void __iomem *imx3_ioremap_caller(unsigned long phys_addr, size_t size, void __init imx3_init_l2x0(void) { +#ifdef CONFIG_CACHE_L2X0 void __iomem *l2x0_base; void __iomem *clkctl_base; @@ -111,6 +116,7 @@ void __init imx3_init_l2x0(void) } l2x0_init(l2x0_base, 0x00030024, 0x00000000); +#endif } #ifdef CONFIG_SOC_IMX31 @@ -138,6 +144,7 @@ void __init imx31_init_early(void) mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR)); arch_ioremap_caller = imx3_ioremap_caller; arm_pm_idle = imx3_idle; + mx3_ccm_base = MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR); } void __init mx31_init_irq(void) @@ -174,6 +181,8 @@ void __init imx31_soc_init(void) mxc_register_gpio("imx31-gpio", 1, MX31_GPIO2_BASE_ADDR, SZ_16K, MX31_INT_GPIO2, 0); mxc_register_gpio("imx31-gpio", 2, MX31_GPIO3_BASE_ADDR, SZ_16K, MX31_INT_GPIO3, 0); + pinctrl_provide_dummies(); + if (to_version == 1) { strncpy(imx31_sdma_pdata.fw_name, "sdma-imx31-to1.bin", strlen(imx31_sdma_pdata.fw_name)); @@ -211,6 +220,7 @@ void __init imx35_init_early(void) mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR)); arm_pm_idle = imx3_idle; arch_ioremap_caller = imx3_ioremap_caller; + mx3_ccm_base = MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR); } void __init mx35_init_irq(void) diff --git a/trunk/arch/arm/mach-imx/mm-imx5.c b/trunk/arch/arm/mach-imx/mm-imx5.c index ba91e6b31cf4..1d003053d562 100644 --- a/trunk/arch/arm/mach-imx/mm-imx5.c +++ b/trunk/arch/arm/mach-imx/mm-imx5.c @@ -33,6 +33,7 @@ static void imx5_idle(void) gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs"); if (IS_ERR(gpc_dvfs_clk)) return; + clk_prepare(gpc_dvfs_clk); } clk_enable(gpc_dvfs_clk); mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); @@ -201,6 +202,8 @@ void __init imx51_soc_init(void) mxc_register_gpio("imx31-gpio", 2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_INT_GPIO3_LOW, MX51_INT_GPIO3_HIGH); mxc_register_gpio("imx31-gpio", 3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_INT_GPIO4_LOW, MX51_INT_GPIO4_HIGH); + pinctrl_provide_dummies(); + /* i.mx51 has the i.mx35 type sdma */ imx_add_imx_sdma("imx35-sdma", MX51_SDMA_BASE_ADDR, MX51_INT_SDMA, &imx51_sdma_pdata); @@ -236,3 +239,8 @@ void __init imx53_soc_init(void) platform_device_register_simple("imx31-audmux", 0, imx53_audmux_res, ARRAY_SIZE(imx53_audmux_res)); } + +void __init imx51_init_late(void) +{ + mx51_neon_fixup(); +} diff --git a/trunk/arch/arm/mach-imx/pcm037.h b/trunk/arch/arm/mach-imx/pcm037.h index d6929721a5fd..7d167690e17d 100644 --- a/trunk/arch/arm/mach-imx/pcm037.h +++ b/trunk/arch/arm/mach-imx/pcm037.h @@ -8,4 +8,10 @@ enum pcm037_board_variant { extern enum pcm037_board_variant pcm037_variant(void); +#ifdef CONFIG_MACH_PCM037_EET +int pcm037_eet_init_devices(void); +#else +static inline int pcm037_eet_init_devices(void) { return 0; } +#endif + #endif diff --git a/trunk/arch/arm/mach-imx/pm-imx3.c b/trunk/arch/arm/mach-imx/pm-imx3.c index b3752439632e..822103bdb709 100644 --- a/trunk/arch/arm/mach-imx/pm-imx3.c +++ b/trunk/arch/arm/mach-imx/pm-imx3.c @@ -21,14 +21,14 @@ */ void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode) { - int reg = __raw_readl(MXC_CCM_CCMR); + int reg = __raw_readl(mx3_ccm_base + MXC_CCM_CCMR); reg &= ~MXC_CCM_CCMR_LPM_MASK; switch (mode) { case MX3_WAIT: if (cpu_is_mx35()) reg |= MXC_CCM_CCMR_LPM_WAIT_MX35; - __raw_writel(reg, MXC_CCM_CCMR); + __raw_writel(reg, mx3_ccm_base + MXC_CCM_CCMR); break; default: pr_err("Unknown cpu power mode: %d\n", mode); diff --git a/trunk/arch/arm/mach-ixp4xx/common.c b/trunk/arch/arm/mach-ixp4xx/common.c index ebbd7fc90eb4..a9f80943d01f 100644 --- a/trunk/arch/arm/mach-ixp4xx/common.c +++ b/trunk/arch/arm/mach-ixp4xx/common.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -107,7 +108,7 @@ static signed char irq2gpio[32] = { 7, 8, 9, 10, 11, 12, -1, -1, }; -int gpio_to_irq(int gpio) +static int ixp4xx_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) { int irq; @@ -117,7 +118,6 @@ int gpio_to_irq(int gpio) } return -EINVAL; } -EXPORT_SYMBOL(gpio_to_irq); int irq_to_gpio(unsigned int irq) { @@ -383,12 +383,56 @@ static struct platform_device *ixp46x_devices[] __initdata = { unsigned long ixp4xx_exp_bus_size; EXPORT_SYMBOL(ixp4xx_exp_bus_size); +static int ixp4xx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) +{ + gpio_line_config(gpio, IXP4XX_GPIO_IN); + + return 0; +} + +static int ixp4xx_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, + int level) +{ + gpio_line_set(gpio, level); + gpio_line_config(gpio, IXP4XX_GPIO_OUT); + + return 0; +} + +static int ixp4xx_gpio_get_value(struct gpio_chip *chip, unsigned gpio) +{ + int value; + + gpio_line_get(gpio, &value); + + return value; +} + +static void ixp4xx_gpio_set_value(struct gpio_chip *chip, unsigned gpio, + int value) +{ + gpio_line_set(gpio, value); +} + +static struct gpio_chip ixp4xx_gpio_chip = { + .label = "IXP4XX_GPIO_CHIP", + .direction_input = ixp4xx_gpio_direction_input, + .direction_output = ixp4xx_gpio_direction_output, + .get = ixp4xx_gpio_get_value, + .set = ixp4xx_gpio_set_value, + .to_irq = ixp4xx_gpio_to_irq, + .base = 0, + .ngpio = 16, +}; + void __init ixp4xx_sys_init(void) { ixp4xx_exp_bus_size = SZ_16M; platform_add_devices(ixp4xx_devices, ARRAY_SIZE(ixp4xx_devices)); + gpiochip_add(&ixp4xx_gpio_chip); + if (cpu_is_ixp46x()) { int region; diff --git a/trunk/arch/arm/mach-ixp4xx/include/mach/gpio.h b/trunk/arch/arm/mach-ixp4xx/include/mach/gpio.h index 83d6b4ed60bb..ef37f2635b0e 100644 --- a/trunk/arch/arm/mach-ixp4xx/include/mach/gpio.h +++ b/trunk/arch/arm/mach-ixp4xx/include/mach/gpio.h @@ -1,79 +1,2 @@ -/* - * arch/arm/mach-ixp4xx/include/mach/gpio.h - * - * IXP4XX GPIO wrappers for arch-neutral GPIO calls - * - * Written by Milan Svoboda - * Based on PXA implementation by Philipp Zabel - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ASM_ARCH_IXP4XX_GPIO_H -#define __ASM_ARCH_IXP4XX_GPIO_H - -#include -#include - -#define __ARM_GPIOLIB_COMPLEX - -static inline int gpio_request(unsigned gpio, const char *label) -{ - return 0; -} - -static inline void gpio_free(unsigned gpio) -{ - might_sleep(); - - return; -} - -static inline int gpio_direction_input(unsigned gpio) -{ - gpio_line_config(gpio, IXP4XX_GPIO_IN); - return 0; -} - -static inline int gpio_direction_output(unsigned gpio, int level) -{ - gpio_line_set(gpio, level); - gpio_line_config(gpio, IXP4XX_GPIO_OUT); - return 0; -} - -static inline int gpio_get_value(unsigned gpio) -{ - int value; - - gpio_line_get(gpio, &value); - - return value; -} - -static inline void gpio_set_value(unsigned gpio, int value) -{ - gpio_line_set(gpio, value); -} - -#include /* cansleep wrappers */ - -extern int gpio_to_irq(int gpio); -#define gpio_to_irq gpio_to_irq -extern int irq_to_gpio(unsigned int irq); - -#endif +/* empty */ diff --git a/trunk/arch/arm/mach-ixp4xx/ixdp425-setup.c b/trunk/arch/arm/mach-ixp4xx/ixdp425-setup.c index 3d742aee1773..108a9d3f382d 100644 --- a/trunk/arch/arm/mach-ixp4xx/ixdp425-setup.c +++ b/trunk/arch/arm/mach-ixp4xx/ixdp425-setup.c @@ -60,8 +60,6 @@ static struct platform_device ixdp425_flash = { #if defined(CONFIG_MTD_NAND_PLATFORM) || \ defined(CONFIG_MTD_NAND_PLATFORM_MODULE) -const char *part_probes[] = { "cmdlinepart", NULL }; - static struct mtd_partition ixdp425_partitions[] = { { .name = "ixp400 NAND FS 0", @@ -100,8 +98,6 @@ static struct platform_nand_data ixdp425_flash_nand_data = { .chip = { .nr_chips = 1, .chip_delay = 30, - .options = NAND_NO_AUTOINCR, - .part_probe_types = part_probes, .partitions = ixdp425_partitions, .nr_partitions = ARRAY_SIZE(ixdp425_partitions), }, diff --git a/trunk/arch/arm/mach-kirkwood/board-dreamplug.c b/trunk/arch/arm/mach-kirkwood/board-dreamplug.c index 985453994dd3..55e357ab2923 100644 --- a/trunk/arch/arm/mach-kirkwood/board-dreamplug.c +++ b/trunk/arch/arm/mach-kirkwood/board-dreamplug.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/arm/mach-kirkwood/board-dt.c b/trunk/arch/arm/mach-kirkwood/board-dt.c index 10d1969b9e3a..edc3f8a9d45e 100644 --- a/trunk/arch/arm/mach-kirkwood/board-dt.c +++ b/trunk/arch/arm/mach-kirkwood/board-dt.c @@ -43,6 +43,9 @@ static void __init kirkwood_dt_init(void) kirkwood_l2_init(); #endif + /* Setup root of clk tree */ + kirkwood_clk_init(); + /* internal devices that every board has */ kirkwood_wdt_init(); kirkwood_xor0_init(); diff --git a/trunk/arch/arm/mach-kirkwood/board-iconnect.c b/trunk/arch/arm/mach-kirkwood/board-iconnect.c index 2222c5739519..b0d3cc49269d 100644 --- a/trunk/arch/arm/mach-kirkwood/board-iconnect.c +++ b/trunk/arch/arm/mach-kirkwood/board-iconnect.c @@ -20,9 +20,6 @@ #include #include #include -#include -#include -#include #include #include #include diff --git a/trunk/arch/arm/mach-kirkwood/common.c b/trunk/arch/arm/mach-kirkwood/common.c index 3ad037385a5e..f261cd242643 100644 --- a/trunk/arch/arm/mach-kirkwood/common.c +++ b/trunk/arch/arm/mach-kirkwood/common.c @@ -15,7 +15,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -32,6 +33,7 @@ #include #include #include +#include #include "common.h" /***************************************************************************** @@ -61,20 +63,191 @@ void __init kirkwood_map_io(void) iotable_init(kirkwood_io_desc, ARRAY_SIZE(kirkwood_io_desc)); } -/* - * Default clock control bits. Any bit _not_ set in this variable - * will be cleared from the hardware after platform devices have been - * registered. Some reserved bits must be set to 1. - */ -unsigned int kirkwood_clk_ctrl = CGC_DUNIT | CGC_RESERVED; +/***************************************************************************** + * CLK tree + ****************************************************************************/ + +static void disable_sata0(void) +{ + /* Disable PLL and IVREF */ + writel(readl(SATA0_PHY_MODE_2) & ~0xf, SATA0_PHY_MODE_2); + /* Disable PHY */ + writel(readl(SATA0_IF_CTRL) | 0x200, SATA0_IF_CTRL); +} + +static void disable_sata1(void) +{ + /* Disable PLL and IVREF */ + writel(readl(SATA1_PHY_MODE_2) & ~0xf, SATA1_PHY_MODE_2); + /* Disable PHY */ + writel(readl(SATA1_IF_CTRL) | 0x200, SATA1_IF_CTRL); +} + +static void disable_pcie0(void) +{ + writel(readl(PCIE_LINK_CTRL) | 0x10, PCIE_LINK_CTRL); + while (1) + if (readl(PCIE_STATUS) & 0x1) + break; + writel(readl(PCIE_LINK_CTRL) & ~0x10, PCIE_LINK_CTRL); +} + +static void disable_pcie1(void) +{ + u32 dev, rev; + + kirkwood_pcie_id(&dev, &rev); + + if (dev == MV88F6282_DEV_ID) { + writel(readl(PCIE1_LINK_CTRL) | 0x10, PCIE1_LINK_CTRL); + while (1) + if (readl(PCIE1_STATUS) & 0x1) + break; + writel(readl(PCIE1_LINK_CTRL) & ~0x10, PCIE1_LINK_CTRL); + } +} + +/* An extended version of the gated clk. This calls fn() before + * disabling the clock. We use this to turn off PHYs etc. */ +struct clk_gate_fn { + struct clk_gate gate; + void (*fn)(void); +}; + +#define to_clk_gate_fn(_gate) container_of(_gate, struct clk_gate_fn, gate) +#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) + +static void clk_gate_fn_disable(struct clk_hw *hw) +{ + struct clk_gate *gate = to_clk_gate(hw); + struct clk_gate_fn *gate_fn = to_clk_gate_fn(gate); + + if (gate_fn->fn) + gate_fn->fn(); + + clk_gate_ops.disable(hw); +} + +static struct clk_ops clk_gate_fn_ops; + +static struct clk __init *clk_register_gate_fn(struct device *dev, + const char *name, + const char *parent_name, unsigned long flags, + void __iomem *reg, u8 bit_idx, + u8 clk_gate_flags, spinlock_t *lock, + void (*fn)(void)) +{ + struct clk_gate_fn *gate_fn; + struct clk *clk; + struct clk_init_data init; + + gate_fn = kzalloc(sizeof(struct clk_gate_fn), GFP_KERNEL); + if (!gate_fn) { + pr_err("%s: could not allocate gated clk\n", __func__); + return ERR_PTR(-ENOMEM); + } + + init.name = name; + init.ops = &clk_gate_fn_ops; + init.flags = flags; + init.parent_names = (parent_name ? &parent_name : NULL); + init.num_parents = (parent_name ? 1 : 0); + + /* struct clk_gate assignments */ + gate_fn->gate.reg = reg; + gate_fn->gate.bit_idx = bit_idx; + gate_fn->gate.flags = clk_gate_flags; + gate_fn->gate.lock = lock; + gate_fn->gate.hw.init = &init; + gate_fn->fn = fn; + + /* ops is the gate ops, but with our disable function */ + if (clk_gate_fn_ops.disable != clk_gate_fn_disable) { + clk_gate_fn_ops = clk_gate_ops; + clk_gate_fn_ops.disable = clk_gate_fn_disable; + } + clk = clk_register(dev, &gate_fn->gate.hw); + + if (IS_ERR(clk)) + kfree(gate_fn); + + return clk; +} + +static DEFINE_SPINLOCK(gating_lock); +static struct clk *tclk; + +static struct clk __init *kirkwood_register_gate(const char *name, u8 bit_idx) +{ + return clk_register_gate(NULL, name, "tclk", 0, + (void __iomem *)CLOCK_GATING_CTRL, + bit_idx, 0, &gating_lock); +} + +static struct clk __init *kirkwood_register_gate_fn(const char *name, + u8 bit_idx, + void (*fn)(void)) +{ + return clk_register_gate_fn(NULL, name, "tclk", 0, + (void __iomem *)CLOCK_GATING_CTRL, + bit_idx, 0, &gating_lock, fn); +} + +static struct clk *ge0, *ge1; + +void __init kirkwood_clk_init(void) +{ + struct clk *runit, *sata0, *sata1, *usb0, *sdio; + struct clk *crypto, *xor0, *xor1, *pex0, *pex1, *audio; + + tclk = clk_register_fixed_rate(NULL, "tclk", NULL, + CLK_IS_ROOT, kirkwood_tclk); + + runit = kirkwood_register_gate("runit", CGC_BIT_RUNIT); + ge0 = kirkwood_register_gate("ge0", CGC_BIT_GE0); + ge1 = kirkwood_register_gate("ge1", CGC_BIT_GE1); + sata0 = kirkwood_register_gate_fn("sata0", CGC_BIT_SATA0, + disable_sata0); + sata1 = kirkwood_register_gate_fn("sata1", CGC_BIT_SATA1, + disable_sata1); + usb0 = kirkwood_register_gate("usb0", CGC_BIT_USB0); + sdio = kirkwood_register_gate("sdio", CGC_BIT_SDIO); + crypto = kirkwood_register_gate("crypto", CGC_BIT_CRYPTO); + xor0 = kirkwood_register_gate("xor0", CGC_BIT_XOR0); + xor1 = kirkwood_register_gate("xor1", CGC_BIT_XOR1); + pex0 = kirkwood_register_gate_fn("pex0", CGC_BIT_PEX0, + disable_pcie0); + pex1 = kirkwood_register_gate_fn("pex1", CGC_BIT_PEX1, + disable_pcie1); + audio = kirkwood_register_gate("audio", CGC_BIT_AUDIO); + kirkwood_register_gate("tdm", CGC_BIT_TDM); + kirkwood_register_gate("tsu", CGC_BIT_TSU); + + /* clkdev entries, mapping clks to devices */ + orion_clkdev_add(NULL, "orion_spi.0", runit); + orion_clkdev_add(NULL, "orion_spi.1", runit); + orion_clkdev_add(NULL, MV643XX_ETH_NAME ".0", ge0); + orion_clkdev_add(NULL, MV643XX_ETH_NAME ".1", ge1); + orion_clkdev_add(NULL, "orion_wdt", tclk); + orion_clkdev_add("0", "sata_mv.0", sata0); + orion_clkdev_add("1", "sata_mv.0", sata1); + orion_clkdev_add(NULL, "orion-ehci.0", usb0); + orion_clkdev_add(NULL, "orion_nand", runit); + orion_clkdev_add(NULL, "mvsdio", sdio); + orion_clkdev_add(NULL, "mv_crypto", crypto); + orion_clkdev_add(NULL, MV_XOR_SHARED_NAME ".0", xor0); + orion_clkdev_add(NULL, MV_XOR_SHARED_NAME ".1", xor1); + orion_clkdev_add("0", "pcie", pex0); + orion_clkdev_add("1", "pcie", pex1); + orion_clkdev_add(NULL, "kirkwood-i2s", audio); +} /***************************************************************************** * EHCI0 ****************************************************************************/ void __init kirkwood_ehci_init(void) { - kirkwood_clk_ctrl |= CGC_USB0; orion_ehci_init(USB_PHYS_BASE, IRQ_KIRKWOOD_USB, EHCI_PHY_NA); } @@ -84,11 +257,12 @@ void __init kirkwood_ehci_init(void) ****************************************************************************/ void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data) { - kirkwood_clk_ctrl |= CGC_GE0; - orion_ge00_init(eth_data, GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM, - IRQ_KIRKWOOD_GE00_ERR, kirkwood_tclk); + IRQ_KIRKWOOD_GE00_ERR); + /* The interface forgets the MAC address assigned by u-boot if + the clock is turned off, so claim the clk now. */ + clk_prepare_enable(ge0); } @@ -97,12 +271,10 @@ void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data) ****************************************************************************/ void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data) { - - kirkwood_clk_ctrl |= CGC_GE1; - orion_ge01_init(eth_data, GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM, - IRQ_KIRKWOOD_GE01_ERR, kirkwood_tclk); + IRQ_KIRKWOOD_GE01_ERR); + clk_prepare_enable(ge1); } @@ -144,7 +316,6 @@ static struct platform_device kirkwood_nand_flash = { void __init kirkwood_nand_init(struct mtd_partition *parts, int nr_parts, int chip_delay) { - kirkwood_clk_ctrl |= CGC_RUNIT; kirkwood_nand_data.parts = parts; kirkwood_nand_data.nr_parts = nr_parts; kirkwood_nand_data.chip_delay = chip_delay; @@ -154,7 +325,6 @@ void __init kirkwood_nand_init(struct mtd_partition *parts, int nr_parts, void __init kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts, int (*dev_ready)(struct mtd_info *)) { - kirkwood_clk_ctrl |= CGC_RUNIT; kirkwood_nand_data.parts = parts; kirkwood_nand_data.nr_parts = nr_parts; kirkwood_nand_data.dev_ready = dev_ready; @@ -175,10 +345,6 @@ static void __init kirkwood_rtc_init(void) ****************************************************************************/ void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data) { - kirkwood_clk_ctrl |= CGC_SATA0; - if (sata_data->n_ports > 1) - kirkwood_clk_ctrl |= CGC_SATA1; - orion_sata_init(sata_data, SATA_PHYS_BASE, IRQ_KIRKWOOD_SATA); } @@ -221,7 +387,6 @@ void __init kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data) mvsdio_data->clock = 100000000; else mvsdio_data->clock = 200000000; - kirkwood_clk_ctrl |= CGC_SDIO; kirkwood_sdio.dev.platform_data = mvsdio_data; platform_device_register(&kirkwood_sdio); } @@ -232,8 +397,7 @@ void __init kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data) ****************************************************************************/ void __init kirkwood_spi_init() { - kirkwood_clk_ctrl |= CGC_RUNIT; - orion_spi_init(SPI_PHYS_BASE, kirkwood_tclk); + orion_spi_init(SPI_PHYS_BASE); } @@ -253,7 +417,7 @@ void __init kirkwood_i2c_init(void) void __init kirkwood_uart0_init(void) { orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE, - IRQ_KIRKWOOD_UART_0, kirkwood_tclk); + IRQ_KIRKWOOD_UART_0, tclk); } @@ -263,7 +427,7 @@ void __init kirkwood_uart0_init(void) void __init kirkwood_uart1_init(void) { orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE, - IRQ_KIRKWOOD_UART_1, kirkwood_tclk); + IRQ_KIRKWOOD_UART_1, tclk); } /***************************************************************************** @@ -271,7 +435,6 @@ void __init kirkwood_uart1_init(void) ****************************************************************************/ void __init kirkwood_crypto_init(void) { - kirkwood_clk_ctrl |= CGC_CRYPTO; orion_crypto_init(CRYPTO_PHYS_BASE, KIRKWOOD_SRAM_PHYS_BASE, KIRKWOOD_SRAM_SIZE, IRQ_KIRKWOOD_CRYPTO); } @@ -282,8 +445,6 @@ void __init kirkwood_crypto_init(void) ****************************************************************************/ void __init kirkwood_xor0_init(void) { - kirkwood_clk_ctrl |= CGC_XOR0; - orion_xor0_init(XOR0_PHYS_BASE, XOR0_HIGH_PHYS_BASE, IRQ_KIRKWOOD_XOR_00, IRQ_KIRKWOOD_XOR_01); } @@ -294,8 +455,6 @@ void __init kirkwood_xor0_init(void) ****************************************************************************/ void __init kirkwood_xor1_init(void) { - kirkwood_clk_ctrl |= CGC_XOR1; - orion_xor1_init(XOR1_PHYS_BASE, XOR1_HIGH_PHYS_BASE, IRQ_KIRKWOOD_XOR_10, IRQ_KIRKWOOD_XOR_11); } @@ -306,7 +465,7 @@ void __init kirkwood_xor1_init(void) ****************************************************************************/ void __init kirkwood_wdt_init(void) { - orion_wdt_init(kirkwood_tclk); + orion_wdt_init(); } @@ -382,7 +541,6 @@ static struct platform_device kirkwood_pcm_device = { void __init kirkwood_audio_init(void) { - kirkwood_clk_ctrl |= CGC_AUDIO; platform_device_register(&kirkwood_i2s_device); platform_device_register(&kirkwood_pcm_device); } @@ -466,6 +624,9 @@ void __init kirkwood_init(void) kirkwood_l2_init(); #endif + /* Setup root of clk tree */ + kirkwood_clk_init(); + /* internal devices that every board has */ kirkwood_rtc_init(); kirkwood_wdt_init(); @@ -478,72 +639,6 @@ void __init kirkwood_init(void) #endif } -static int __init kirkwood_clock_gate(void) -{ - unsigned int curr = readl(CLOCK_GATING_CTRL); - u32 dev, rev; - -#ifdef CONFIG_OF - struct device_node *np; -#endif - kirkwood_pcie_id(&dev, &rev); - printk(KERN_DEBUG "Gating clock of unused units\n"); - printk(KERN_DEBUG "before: 0x%08x\n", curr); - - /* Make sure those units are accessible */ - writel(curr | CGC_SATA0 | CGC_SATA1 | CGC_PEX0 | CGC_PEX1, CLOCK_GATING_CTRL); - -#ifdef CONFIG_OF - np = of_find_compatible_node(NULL, NULL, "mrvl,orion-nand"); - if (np && of_device_is_available(np)) { - kirkwood_clk_ctrl |= CGC_RUNIT; - of_node_put(np); - } -#endif - - /* For SATA: first shutdown the phy */ - if (!(kirkwood_clk_ctrl & CGC_SATA0)) { - /* Disable PLL and IVREF */ - writel(readl(SATA0_PHY_MODE_2) & ~0xf, SATA0_PHY_MODE_2); - /* Disable PHY */ - writel(readl(SATA0_IF_CTRL) | 0x200, SATA0_IF_CTRL); - } - if (!(kirkwood_clk_ctrl & CGC_SATA1)) { - /* Disable PLL and IVREF */ - writel(readl(SATA1_PHY_MODE_2) & ~0xf, SATA1_PHY_MODE_2); - /* Disable PHY */ - writel(readl(SATA1_IF_CTRL) | 0x200, SATA1_IF_CTRL); - } - - /* For PCIe: first shutdown the phy */ - if (!(kirkwood_clk_ctrl & CGC_PEX0)) { - writel(readl(PCIE_LINK_CTRL) | 0x10, PCIE_LINK_CTRL); - while (1) - if (readl(PCIE_STATUS) & 0x1) - break; - writel(readl(PCIE_LINK_CTRL) & ~0x10, PCIE_LINK_CTRL); - } - - /* For PCIe 1: first shutdown the phy */ - if (dev == MV88F6282_DEV_ID) { - if (!(kirkwood_clk_ctrl & CGC_PEX1)) { - writel(readl(PCIE1_LINK_CTRL) | 0x10, PCIE1_LINK_CTRL); - while (1) - if (readl(PCIE1_STATUS) & 0x1) - break; - writel(readl(PCIE1_LINK_CTRL) & ~0x10, PCIE1_LINK_CTRL); - } - } else /* keep this bit set for devices that don't have PCIe1 */ - kirkwood_clk_ctrl |= CGC_PEX1; - - /* Now gate clock the required units */ - writel(kirkwood_clk_ctrl, CLOCK_GATING_CTRL); - printk(KERN_DEBUG " after: 0x%08x\n", readl(CLOCK_GATING_CTRL)); - - return 0; -} -late_initcall(kirkwood_clock_gate); - void kirkwood_restart(char mode, const char *cmd) { /* diff --git a/trunk/arch/arm/mach-kirkwood/common.h b/trunk/arch/arm/mach-kirkwood/common.h index a34c41a5172e..9248fa2c165b 100644 --- a/trunk/arch/arm/mach-kirkwood/common.h +++ b/trunk/arch/arm/mach-kirkwood/common.h @@ -50,6 +50,7 @@ void kirkwood_nand_init(struct mtd_partition *parts, int nr_parts, int delay); void kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts, int (*dev_ready)(struct mtd_info *)); void kirkwood_audio_init(void); void kirkwood_restart(char, const char *); +void kirkwood_clk_init(void); /* board init functions for boards not fully converted to fdt */ #ifdef CONFIG_MACH_DREAMPLUG_DT diff --git a/trunk/arch/arm/mach-kirkwood/include/mach/bridge-regs.h b/trunk/arch/arm/mach-kirkwood/include/mach/bridge-regs.h index 957bd7997d7e..a115142f8690 100644 --- a/trunk/arch/arm/mach-kirkwood/include/mach/bridge-regs.h +++ b/trunk/arch/arm/mach-kirkwood/include/mach/bridge-regs.h @@ -38,11 +38,28 @@ #define IRQ_MASK_HIGH_OFF 0x0014 #define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0300) +#define TIMER_PHYS_BASE (BRIDGE_PHYS_BASE | 0x0300) #define L2_CONFIG_REG (BRIDGE_VIRT_BASE | 0x0128) #define L2_WRITETHROUGH 0x00000010 #define CLOCK_GATING_CTRL (BRIDGE_VIRT_BASE | 0x11c) +#define CGC_BIT_GE0 (0) +#define CGC_BIT_PEX0 (2) +#define CGC_BIT_USB0 (3) +#define CGC_BIT_SDIO (4) +#define CGC_BIT_TSU (5) +#define CGC_BIT_DUNIT (6) +#define CGC_BIT_RUNIT (7) +#define CGC_BIT_XOR0 (8) +#define CGC_BIT_AUDIO (9) +#define CGC_BIT_SATA0 (14) +#define CGC_BIT_SATA1 (15) +#define CGC_BIT_XOR1 (16) +#define CGC_BIT_CRYPTO (17) +#define CGC_BIT_PEX1 (18) +#define CGC_BIT_GE1 (19) +#define CGC_BIT_TDM (20) #define CGC_GE0 (1 << 0) #define CGC_PEX0 (1 << 2) #define CGC_USB0 (1 << 3) diff --git a/trunk/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/trunk/arch/arm/mach-kirkwood/include/mach/kirkwood.h index fede3d503efa..c5b68510776b 100644 --- a/trunk/arch/arm/mach-kirkwood/include/mach/kirkwood.h +++ b/trunk/arch/arm/mach-kirkwood/include/mach/kirkwood.h @@ -80,6 +80,7 @@ #define UART1_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2100) #define BRIDGE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x20000) +#define BRIDGE_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x20000) #define CRYPTO_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x30000) diff --git a/trunk/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c b/trunk/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c index 85f6169c2484..6d8364a97810 100644 --- a/trunk/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c +++ b/trunk/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/arm/mach-kirkwood/pcie.c b/trunk/arch/arm/mach-kirkwood/pcie.c index de373176ee67..6e8b2efa3c35 100644 --- a/trunk/arch/arm/mach-kirkwood/pcie.c +++ b/trunk/arch/arm/mach-kirkwood/pcie.c @@ -11,6 +11,7 @@ #include #include #include +#include #include